blob: 412c940afabf35e5111d107fd2ad111aae549b4f [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
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305597
5598static const struct
5599nla_policy
5600qca_wlan_vendor_wifi_logger_get_ring_data_policy
5601[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5602 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5603 = {.type = NLA_U32 },
5604};
5605
5606static int
5607 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5608 struct wireless_dev *wdev,
5609 const void *data,
5610 int data_len)
5611{
5612 int ret;
5613 VOS_STATUS status;
5614 uint32_t ring_id;
5615 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5616 struct nlattr *tb
5617 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5618
5619 ENTER();
5620
5621 ret = wlan_hdd_validate_context(hdd_ctx);
5622 if (0 != ret) {
5623 return ret;
5624 }
5625
5626 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5627 data, data_len,
5628 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5629 hddLog(LOGE, FL("Invalid attribute"));
5630 return -EINVAL;
5631 }
5632
5633 /* Parse and fetch ring id */
5634 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5635 hddLog(LOGE, FL("attr ATTR failed"));
5636 return -EINVAL;
5637 }
5638
5639 ring_id = nla_get_u32(
5640 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5641
5642 hddLog(LOG1, FL("Bug report triggered by framework"));
5643
5644 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5645 WLAN_LOG_INDICATOR_FRAMEWORK,
5646 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305647 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305648 );
5649 if (VOS_STATUS_SUCCESS != status) {
5650 hddLog(LOGE, FL("Failed to trigger bug report"));
5651
5652 return -EINVAL;
5653 }
5654
5655 return 0;
5656
5657
5658}
5659
5660
5661static int
5662 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5663 struct wireless_dev *wdev,
5664 const void *data,
5665 int data_len)
5666{
5667 int ret = 0;
5668
5669 vos_ssr_protect(__func__);
5670 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5671 wdev, data, data_len);
5672 vos_ssr_unprotect(__func__);
5673
5674 return ret;
5675
5676}
5677
5678
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305679static int
5680__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305681 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305682 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305683{
5684 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5685 uint8_t i, feature_sets, max_feature_sets;
5686 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5687 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305688 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5689 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305690
5691 ENTER();
5692
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305693 ret = wlan_hdd_validate_context(pHddCtx);
5694 if (0 != ret)
5695 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305696 return ret;
5697 }
5698
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305699 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5700 data, data_len, NULL)) {
5701 hddLog(LOGE, FL("Invalid ATTR"));
5702 return -EINVAL;
5703 }
5704
5705 /* Parse and fetch max feature set */
5706 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5707 hddLog(LOGE, FL("Attr max feature set size failed"));
5708 return -EINVAL;
5709 }
5710 max_feature_sets = nla_get_u32(
5711 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5712 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5713
5714 /* Fill feature combination matrix */
5715 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305716 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5717 WIFI_FEATURE_P2P;
5718
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305719 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5720 WIFI_FEATURE_SOFT_AP;
5721
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305722 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5723 WIFI_FEATURE_SOFT_AP;
5724
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305725 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5726 WIFI_FEATURE_SOFT_AP |
5727 WIFI_FEATURE_P2P;
5728
5729 /* Add more feature combinations here */
5730
5731 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5732 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5733 hddLog(LOG1, "Feature set matrix");
5734 for (i = 0; i < feature_sets; i++)
5735 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5736
5737 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5738 sizeof(u32) * feature_sets +
5739 NLMSG_HDRLEN);
5740
5741 if (reply_skb) {
5742 if (nla_put_u32(reply_skb,
5743 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5744 feature_sets) ||
5745 nla_put(reply_skb,
5746 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5747 sizeof(u32) * feature_sets, feature_set_matrix)) {
5748 hddLog(LOGE, FL("nla put fail"));
5749 kfree_skb(reply_skb);
5750 return -EINVAL;
5751 }
5752
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305753 ret = cfg80211_vendor_cmd_reply(reply_skb);
5754 EXIT();
5755 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305756 }
5757 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5758 return -ENOMEM;
5759
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305760}
5761
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305762static int
5763wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5764 struct wireless_dev *wdev,
5765 const void *data, int data_len)
5766{
5767 int ret = 0;
5768
5769 vos_ssr_protect(__func__);
5770 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5771 data_len);
5772 vos_ssr_unprotect(__func__);
5773
5774 return ret;
5775}
5776
c_manjeecfd1efb2015-09-25 19:32:34 +05305777
5778static int
5779__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5780 struct wireless_dev *wdev,
5781 const void *data, int data_len)
5782{
5783 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5784 int ret;
5785 ENTER();
5786
5787 ret = wlan_hdd_validate_context(pHddCtx);
5788 if (0 != ret)
5789 {
5790 return ret;
5791 }
5792
5793 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5794 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5795 {
5796 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5797 return -EINVAL;
5798 }
5799 /*call common API for FW mem dump req*/
5800 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5801
5802 EXIT();
5803 return ret;
5804}
5805
5806/**
5807 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5808 * @wiphy: pointer to wireless wiphy structure.
5809 * @wdev: pointer to wireless_dev structure.
5810 * @data: Pointer to the NL data.
5811 * @data_len:Length of @data
5812 *
5813 * This is called when wlan driver needs to get the firmware memory dump
5814 * via vendor specific command.
5815 *
5816 * Return: 0 on success, error number otherwise.
5817 */
5818
5819static int
5820wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5821 struct wireless_dev *wdev,
5822 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305823{
5824 int ret = 0;
5825 vos_ssr_protect(__func__);
5826 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5827 data_len);
5828 vos_ssr_unprotect(__func__);
5829 return ret;
5830}
c_manjeecfd1efb2015-09-25 19:32:34 +05305831
Sushant Kaushik8e644982015-09-23 12:18:54 +05305832static const struct
5833nla_policy
5834qca_wlan_vendor_wifi_logger_start_policy
5835[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5836 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5837 = {.type = NLA_U32 },
5838 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5839 = {.type = NLA_U32 },
5840 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5841 = {.type = NLA_U32 },
5842};
5843
5844/**
5845 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5846 * or disable the collection of packet statistics from the firmware
5847 * @wiphy: WIPHY structure pointer
5848 * @wdev: Wireless device structure pointer
5849 * @data: Pointer to the data received
5850 * @data_len: Length of the data received
5851 *
5852 * This function is used to enable or disable the collection of packet
5853 * statistics from the firmware
5854 *
5855 * Return: 0 on success and errno on failure
5856 */
5857static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5858 struct wireless_dev *wdev,
5859 const void *data,
5860 int data_len)
5861{
5862 eHalStatus status;
5863 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5864 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5865 tAniWifiStartLog start_log;
5866
5867 status = wlan_hdd_validate_context(hdd_ctx);
5868 if (0 != status) {
5869 return -EINVAL;
5870 }
5871
5872 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5873 data, data_len,
5874 qca_wlan_vendor_wifi_logger_start_policy)) {
5875 hddLog(LOGE, FL("Invalid attribute"));
5876 return -EINVAL;
5877 }
5878
5879 /* Parse and fetch ring id */
5880 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5881 hddLog(LOGE, FL("attr ATTR failed"));
5882 return -EINVAL;
5883 }
5884 start_log.ringId = nla_get_u32(
5885 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5886 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5887
5888 /* Parse and fetch verbose level */
5889 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5890 hddLog(LOGE, FL("attr verbose_level failed"));
5891 return -EINVAL;
5892 }
5893 start_log.verboseLevel = nla_get_u32(
5894 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5895 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5896
5897 /* Parse and fetch flag */
5898 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5899 hddLog(LOGE, FL("attr flag failed"));
5900 return -EINVAL;
5901 }
5902 start_log.flag = nla_get_u32(
5903 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5904 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5905
5906 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305907 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5908 !vos_isPktStatsEnabled()))
5909
Sushant Kaushik8e644982015-09-23 12:18:54 +05305910 {
5911 hddLog(LOGE, FL("per pkt stats not enabled"));
5912 return -EINVAL;
5913 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305914
Sushant Kaushik33200572015-08-05 16:46:20 +05305915 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305916 return 0;
5917}
5918
5919/**
5920 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5921 * or disable the collection of packet statistics from the firmware
5922 * @wiphy: WIPHY structure pointer
5923 * @wdev: Wireless device structure pointer
5924 * @data: Pointer to the data received
5925 * @data_len: Length of the data received
5926 *
5927 * This function is used to enable or disable the collection of packet
5928 * statistics from the firmware
5929 *
5930 * Return: 0 on success and errno on failure
5931 */
5932static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5933 struct wireless_dev *wdev,
5934 const void *data,
5935 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305936{
5937 int ret = 0;
5938
5939 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305940
5941 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5942 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305943 vos_ssr_unprotect(__func__);
5944
5945 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305946}
5947
5948
Agarwal Ashish738843c2014-09-25 12:27:56 +05305949static const struct nla_policy
5950wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5951 +1] =
5952{
5953 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5954};
5955
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305956static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305957 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305958 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305959 int data_len)
5960{
5961 struct net_device *dev = wdev->netdev;
5962 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5963 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5964 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5965 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5966 eHalStatus status;
5967 u32 dfsFlag = 0;
5968
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305969 ENTER();
5970
Agarwal Ashish738843c2014-09-25 12:27:56 +05305971 status = wlan_hdd_validate_context(pHddCtx);
5972 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305973 return -EINVAL;
5974 }
5975 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5976 data, data_len,
5977 wlan_hdd_set_no_dfs_flag_config_policy)) {
5978 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5979 return -EINVAL;
5980 }
5981
5982 /* Parse and fetch required bandwidth kbps */
5983 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5984 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5985 return -EINVAL;
5986 }
5987
5988 dfsFlag = nla_get_u32(
5989 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5990 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5991 dfsFlag);
5992
5993 pHddCtx->disable_dfs_flag = dfsFlag;
5994
5995 sme_disable_dfs_channel(hHal, dfsFlag);
5996 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305997
5998 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305999 return 0;
6000}
Atul Mittal115287b2014-07-08 13:26:33 +05306001
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306002static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6003 struct wireless_dev *wdev,
6004 const void *data,
6005 int data_len)
6006{
6007 int ret = 0;
6008
6009 vos_ssr_protect(__func__);
6010 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6011 vos_ssr_unprotect(__func__);
6012
6013 return ret;
6014
6015}
6016
Mukul Sharma2a271632014-10-13 14:59:01 +05306017const struct
6018nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6019{
6020 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6021 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6022};
6023
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306024static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306025 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306026{
6027
6028 u8 bssid[6] = {0};
6029 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6030 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6031 eHalStatus status = eHAL_STATUS_SUCCESS;
6032 v_U32_t isFwrRoamEnabled = FALSE;
6033 int ret;
6034
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306035 ENTER();
6036
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306037 ret = wlan_hdd_validate_context(pHddCtx);
6038 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306039 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306040 }
6041
6042 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6043 data, data_len,
6044 qca_wlan_vendor_attr);
6045 if (ret){
6046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6047 return -EINVAL;
6048 }
6049
6050 /* Parse and fetch Enable flag */
6051 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6053 return -EINVAL;
6054 }
6055
6056 isFwrRoamEnabled = nla_get_u32(
6057 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6058
6059 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6060
6061 /* Parse and fetch bssid */
6062 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6064 return -EINVAL;
6065 }
6066
6067 memcpy(bssid, nla_data(
6068 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6069 sizeof(bssid));
6070 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6071
6072 //Update roaming
6073 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306074 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306075 return status;
6076}
6077
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306078static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6079 struct wireless_dev *wdev, const void *data, int data_len)
6080{
6081 int ret = 0;
6082
6083 vos_ssr_protect(__func__);
6084 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6085 vos_ssr_unprotect(__func__);
6086
6087 return ret;
6088}
6089
Sushant Kaushik847890c2015-09-28 16:05:17 +05306090static const struct
6091nla_policy
6092qca_wlan_vendor_get_wifi_info_policy[
6093 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6094 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6095 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6096};
6097
6098
6099/**
6100 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6101 * @wiphy: pointer to wireless wiphy structure.
6102 * @wdev: pointer to wireless_dev structure.
6103 * @data: Pointer to the data to be passed via vendor interface
6104 * @data_len:Length of the data to be passed
6105 *
6106 * This is called when wlan driver needs to send wifi driver related info
6107 * (driver/fw version) to the user space application upon request.
6108 *
6109 * Return: Return the Success or Failure code.
6110 */
6111static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6112 struct wireless_dev *wdev,
6113 const void *data, int data_len)
6114{
6115 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6116 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6117 tSirVersionString version;
6118 uint32 version_len;
6119 uint8 attr;
6120 int status;
6121 struct sk_buff *reply_skb = NULL;
6122
6123 if (VOS_FTM_MODE == hdd_get_conparam()) {
6124 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6125 return -EINVAL;
6126 }
6127
6128 status = wlan_hdd_validate_context(hdd_ctx);
6129 if (0 != status) {
6130 hddLog(LOGE, FL("HDD context is not valid"));
6131 return -EINVAL;
6132 }
6133
6134 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6135 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6136 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6137 return -EINVAL;
6138 }
6139
6140 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6141 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6142 QWLAN_VERSIONSTR);
6143 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6144 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6145 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6146 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6147 hdd_ctx->fw_Version);
6148 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6149 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6150 } else {
6151 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6152 return -EINVAL;
6153 }
6154
6155 version_len = strlen(version);
6156 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6157 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6158 if (!reply_skb) {
6159 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6160 return -ENOMEM;
6161 }
6162
6163 if (nla_put(reply_skb, attr, version_len, version)) {
6164 hddLog(LOGE, FL("nla put fail"));
6165 kfree_skb(reply_skb);
6166 return -EINVAL;
6167 }
6168
6169 return cfg80211_vendor_cmd_reply(reply_skb);
6170}
6171
6172/**
6173 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6174 * @wiphy: pointer to wireless wiphy structure.
6175 * @wdev: pointer to wireless_dev structure.
6176 * @data: Pointer to the data to be passed via vendor interface
6177 * @data_len:Length of the data to be passed
6178 * @data_len: Length of the data received
6179 *
6180 * This function is used to enable or disable the collection of packet
6181 * statistics from the firmware
6182 *
6183 * Return: 0 on success and errno on failure
6184 */
6185
6186static int
6187wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6188 struct wireless_dev *wdev,
6189 const void *data, int data_len)
6190
6191
6192{
6193 int ret = 0;
6194
6195 vos_ssr_protect(__func__);
6196 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6197 wdev, data, data_len);
6198 vos_ssr_unprotect(__func__);
6199
6200 return ret;
6201}
6202
6203
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306204/*
6205 * define short names for the global vendor params
6206 * used by __wlan_hdd_cfg80211_monitor_rssi()
6207 */
6208#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6209#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6210#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6211#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6212#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6213
6214/**---------------------------------------------------------------------------
6215
6216 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6217 monitor start is completed successfully.
6218
6219 \return - None
6220
6221 --------------------------------------------------------------------------*/
6222void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6223{
6224 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6225
6226 if (NULL == pHddCtx)
6227 {
6228 hddLog(VOS_TRACE_LEVEL_ERROR,
6229 "%s: HDD context is NULL",__func__);
6230 return;
6231 }
6232
6233 if (VOS_STATUS_SUCCESS == status)
6234 {
6235 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6236 }
6237 else
6238 {
6239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6240 }
6241
6242 return;
6243}
6244
6245/**---------------------------------------------------------------------------
6246
6247 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6248 stop is completed successfully.
6249
6250 \return - None
6251
6252 --------------------------------------------------------------------------*/
6253void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6254{
6255 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6256
6257 if (NULL == pHddCtx)
6258 {
6259 hddLog(VOS_TRACE_LEVEL_ERROR,
6260 "%s: HDD context is NULL",__func__);
6261 return;
6262 }
6263
6264 if (VOS_STATUS_SUCCESS == status)
6265 {
6266 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6267 }
6268 else
6269 {
6270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6271 }
6272
6273 return;
6274}
6275
6276/**
6277 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6278 * @wiphy: Pointer to wireless phy
6279 * @wdev: Pointer to wireless device
6280 * @data: Pointer to data
6281 * @data_len: Data length
6282 *
6283 * Return: 0 on success, negative errno on failure
6284 */
6285
6286static int
6287__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6288 struct wireless_dev *wdev,
6289 const void *data,
6290 int data_len)
6291{
6292 struct net_device *dev = wdev->netdev;
6293 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6294 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6295 hdd_station_ctx_t *pHddStaCtx;
6296 struct nlattr *tb[PARAM_MAX + 1];
6297 tpSirRssiMonitorReq pReq;
6298 eHalStatus status;
6299 int ret;
6300 uint32_t control;
6301 static const struct nla_policy policy[PARAM_MAX + 1] = {
6302 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6303 [PARAM_CONTROL] = { .type = NLA_U32 },
6304 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6305 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6306 };
6307
6308 ENTER();
6309
6310 ret = wlan_hdd_validate_context(hdd_ctx);
6311 if (0 != ret) {
6312 return -EINVAL;
6313 }
6314
6315 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6316 hddLog(LOGE, FL("Not in Connected state!"));
6317 return -ENOTSUPP;
6318 }
6319
6320 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6321 hddLog(LOGE, FL("Invalid ATTR"));
6322 return -EINVAL;
6323 }
6324
6325 if (!tb[PARAM_REQUEST_ID]) {
6326 hddLog(LOGE, FL("attr request id failed"));
6327 return -EINVAL;
6328 }
6329
6330 if (!tb[PARAM_CONTROL]) {
6331 hddLog(LOGE, FL("attr control failed"));
6332 return -EINVAL;
6333 }
6334
6335 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6336
6337 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6338 if(NULL == pReq)
6339 {
6340 hddLog(LOGE,
6341 FL("vos_mem_alloc failed "));
6342 return eHAL_STATUS_FAILED_ALLOC;
6343 }
6344 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6345
6346 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6347 pReq->sessionId = pAdapter->sessionId;
6348 pReq->rssiMonitorCbContext = hdd_ctx;
6349 control = nla_get_u32(tb[PARAM_CONTROL]);
6350 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6351
6352 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6353 pReq->requestId, pReq->sessionId, control);
6354
6355 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6356 if (!tb[PARAM_MIN_RSSI]) {
6357 hddLog(LOGE, FL("attr min rssi failed"));
6358 return -EINVAL;
6359 }
6360
6361 if (!tb[PARAM_MAX_RSSI]) {
6362 hddLog(LOGE, FL("attr max rssi failed"));
6363 return -EINVAL;
6364 }
6365
6366 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6367 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6368 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6369
6370 if (!(pReq->minRssi < pReq->maxRssi)) {
6371 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6372 pReq->minRssi, pReq->maxRssi);
6373 return -EINVAL;
6374 }
6375 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6376 pReq->minRssi, pReq->maxRssi);
6377 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6378
6379 }
6380 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6381 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6382 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6383 }
6384 else {
6385 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
6386 return -EINVAL;
6387 }
6388
6389 if (!HAL_STATUS_SUCCESS(status)) {
6390 hddLog(LOGE,
6391 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
6392 return -EINVAL;
6393 }
6394
6395 return 0;
6396}
6397
6398/*
6399 * done with short names for the global vendor params
6400 * used by __wlan_hdd_cfg80211_monitor_rssi()
6401 */
6402#undef PARAM_MAX
6403#undef PARAM_CONTROL
6404#undef PARAM_REQUEST_ID
6405#undef PARAM_MAX_RSSI
6406#undef PARAM_MIN_RSSI
6407
6408/**
6409 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6410 * @wiphy: wiphy structure pointer
6411 * @wdev: Wireless device structure pointer
6412 * @data: Pointer to the data received
6413 * @data_len: Length of @data
6414 *
6415 * Return: 0 on success; errno on failure
6416 */
6417static int
6418wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6419 const void *data, int data_len)
6420{
6421 int ret;
6422
6423 vos_ssr_protect(__func__);
6424 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6425 vos_ssr_unprotect(__func__);
6426
6427 return ret;
6428}
6429
6430/**
6431 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6432 * @hddctx: HDD context
6433 * @data: rssi breached event data
6434 *
6435 * This function reads the rssi breached event %data and fill in the skb with
6436 * NL attributes and send up the NL event.
6437 * This callback execute in atomic context and must not invoke any
6438 * blocking calls.
6439 *
6440 * Return: none
6441 */
6442void hdd_rssi_threshold_breached_cb(void *hddctx,
6443 struct rssi_breach_event *data)
6444{
6445 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6446 int status;
6447 struct sk_buff *skb;
6448
6449 ENTER();
6450 status = wlan_hdd_validate_context(pHddCtx);
6451
6452 if (0 != status) {
6453 return;
6454 }
6455
6456 if (!data) {
6457 hddLog(LOGE, FL("data is null"));
6458 return;
6459 }
6460
6461 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6462#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6463 NULL,
6464#endif
6465 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6466 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6467 GFP_KERNEL);
6468
6469 if (!skb) {
6470 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6471 return;
6472 }
6473
6474 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6475 data->request_id, data->curr_rssi);
6476 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6477 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6478
6479 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6480 data->request_id) ||
6481 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6482 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6483 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6484 data->curr_rssi)) {
6485 hddLog(LOGE, FL("nla put fail"));
6486 goto fail;
6487 }
6488
6489 cfg80211_vendor_event(skb, GFP_KERNEL);
6490 return;
6491
6492fail:
6493 kfree_skb(skb);
6494 return;
6495}
6496
6497
6498
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306499/**
6500 * __wlan_hdd_cfg80211_setband() - set band
6501 * @wiphy: Pointer to wireless phy
6502 * @wdev: Pointer to wireless device
6503 * @data: Pointer to data
6504 * @data_len: Data length
6505 *
6506 * Return: 0 on success, negative errno on failure
6507 */
6508static int
6509__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6510 struct wireless_dev *wdev,
6511 const void *data,
6512 int data_len)
6513{
6514 struct net_device *dev = wdev->netdev;
6515 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6516 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6517 int ret;
6518 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6519 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6520
6521 ENTER();
6522
6523 ret = wlan_hdd_validate_context(hdd_ctx);
6524 if (0 != ret) {
6525 hddLog(LOGE, FL("HDD context is not valid"));
6526 return ret;
6527 }
6528
6529 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6530 policy)) {
6531 hddLog(LOGE, FL("Invalid ATTR"));
6532 return -EINVAL;
6533 }
6534
6535 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6536 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6537 return -EINVAL;
6538 }
6539
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306540 hdd_ctx->isSetBandByNL = TRUE;
6541 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306542 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306543 hdd_ctx->isSetBandByNL = FALSE;
6544
6545 EXIT();
6546 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306547}
6548
6549/**
6550 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6551 * @wiphy: wiphy structure pointer
6552 * @wdev: Wireless device structure pointer
6553 * @data: Pointer to the data received
6554 * @data_len: Length of @data
6555 *
6556 * Return: 0 on success; errno on failure
6557 */
6558static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6559 struct wireless_dev *wdev,
6560 const void *data,
6561 int data_len)
6562{
6563 int ret = 0;
6564
6565 vos_ssr_protect(__func__);
6566 ret = __wlan_hdd_cfg80211_setband(wiphy,
6567 wdev, data, data_len);
6568 vos_ssr_unprotect(__func__);
6569
6570 return ret;
6571}
6572
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306573#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6574/**
6575 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6576 * @hdd_ctx: HDD context
6577 * @request_id: [input] request id
6578 * @pattern_id: [output] pattern id
6579 *
6580 * This function loops through request id to pattern id array
6581 * if the slot is available, store the request id and return pattern id
6582 * if entry exists, return the pattern id
6583 *
6584 * Return: 0 on success and errno on failure
6585 */
6586static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6587 uint32_t request_id,
6588 uint8_t *pattern_id)
6589{
6590 uint32_t i;
6591
6592 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6593 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6594 {
6595 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6596 {
6597 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6598 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6599 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6600 return 0;
6601 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6602 request_id) {
6603 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6604 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6605 return 0;
6606 }
6607 }
6608 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6609 return -EINVAL;
6610}
6611
6612/**
6613 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6614 * @hdd_ctx: HDD context
6615 * @request_id: [input] request id
6616 * @pattern_id: [output] pattern id
6617 *
6618 * This function loops through request id to pattern id array
6619 * reset request id to 0 (slot available again) and
6620 * return pattern id
6621 *
6622 * Return: 0 on success and errno on failure
6623 */
6624static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6625 uint32_t request_id,
6626 uint8_t *pattern_id)
6627{
6628 uint32_t i;
6629
6630 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6631 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6632 {
6633 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6634 {
6635 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6636 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6637 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6638 return 0;
6639 }
6640 }
6641 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6642 return -EINVAL;
6643}
6644
6645
6646/*
6647 * define short names for the global vendor params
6648 * used by __wlan_hdd_cfg80211_offloaded_packets()
6649 */
6650#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6651#define PARAM_REQUEST_ID \
6652 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6653#define PARAM_CONTROL \
6654 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6655#define PARAM_IP_PACKET \
6656 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6657#define PARAM_SRC_MAC_ADDR \
6658 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6659#define PARAM_DST_MAC_ADDR \
6660 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6661#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6662
6663/**
6664 * wlan_hdd_add_tx_ptrn() - add tx pattern
6665 * @adapter: adapter pointer
6666 * @hdd_ctx: hdd context
6667 * @tb: nl attributes
6668 *
6669 * This function reads the NL attributes and forms a AddTxPtrn message
6670 * posts it to SME.
6671 *
6672 */
6673static int
6674wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6675 struct nlattr **tb)
6676{
6677 struct sSirAddPeriodicTxPtrn *add_req;
6678 eHalStatus status;
6679 uint32_t request_id, ret, len;
6680 uint8_t pattern_id = 0;
6681 v_MACADDR_t dst_addr;
6682 uint16_t eth_type = htons(ETH_P_IP);
6683
6684 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6685 {
6686 hddLog(LOGE, FL("Not in Connected state!"));
6687 return -ENOTSUPP;
6688 }
6689
6690 add_req = vos_mem_malloc(sizeof(*add_req));
6691 if (!add_req)
6692 {
6693 hddLog(LOGE, FL("memory allocation failed"));
6694 return -ENOMEM;
6695 }
6696
6697 /* Parse and fetch request Id */
6698 if (!tb[PARAM_REQUEST_ID])
6699 {
6700 hddLog(LOGE, FL("attr request id failed"));
6701 goto fail;
6702 }
6703
6704 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6705 hddLog(LOG1, FL("Request Id: %u"), request_id);
6706 if (request_id == 0)
6707 {
6708 hddLog(LOGE, FL("request_id cannot be zero"));
6709 return -EINVAL;
6710 }
6711
6712 if (!tb[PARAM_PERIOD])
6713 {
6714 hddLog(LOGE, FL("attr period failed"));
6715 goto fail;
6716 }
6717 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6718 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6719 if (add_req->usPtrnIntervalMs == 0)
6720 {
6721 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6722 goto fail;
6723 }
6724
6725 if (!tb[PARAM_SRC_MAC_ADDR])
6726 {
6727 hddLog(LOGE, FL("attr source mac address failed"));
6728 goto fail;
6729 }
6730 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6731 VOS_MAC_ADDR_SIZE);
6732 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6733 MAC_ADDR_ARRAY(add_req->macAddress));
6734
6735 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6736 VOS_MAC_ADDR_SIZE))
6737 {
6738 hddLog(LOGE,
6739 FL("input src mac address and connected ap bssid are different"));
6740 goto fail;
6741 }
6742
6743 if (!tb[PARAM_DST_MAC_ADDR])
6744 {
6745 hddLog(LOGE, FL("attr dst mac address failed"));
6746 goto fail;
6747 }
6748 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6749 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6750 MAC_ADDR_ARRAY(dst_addr.bytes));
6751
6752 if (!tb[PARAM_IP_PACKET])
6753 {
6754 hddLog(LOGE, FL("attr ip packet failed"));
6755 goto fail;
6756 }
6757 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6758 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6759
6760 if (add_req->ucPtrnSize < 0 ||
6761 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6762 HDD_ETH_HEADER_LEN))
6763 {
6764 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6765 add_req->ucPtrnSize);
6766 goto fail;
6767 }
6768
6769 len = 0;
6770 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6771 len += VOS_MAC_ADDR_SIZE;
6772 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6773 VOS_MAC_ADDR_SIZE);
6774 len += VOS_MAC_ADDR_SIZE;
6775 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6776 len += 2;
6777
6778 /*
6779 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6780 * ------------------------------------------------------------
6781 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6782 * ------------------------------------------------------------
6783 */
6784 vos_mem_copy(&add_req->ucPattern[len],
6785 nla_data(tb[PARAM_IP_PACKET]),
6786 add_req->ucPtrnSize);
6787 add_req->ucPtrnSize += len;
6788
6789 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6790 add_req->ucPattern, add_req->ucPtrnSize);
6791
6792 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6793 if (ret)
6794 {
6795 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6796 goto fail;
6797 }
6798 add_req->ucPtrnId = pattern_id;
6799 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6800
6801 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6802 if (!HAL_STATUS_SUCCESS(status))
6803 {
6804 hddLog(LOGE,
6805 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6806 goto fail;
6807 }
6808
6809 EXIT();
6810 vos_mem_free(add_req);
6811 return 0;
6812
6813fail:
6814 vos_mem_free(add_req);
6815 return -EINVAL;
6816}
6817
6818/**
6819 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6820 * @adapter: adapter pointer
6821 * @hdd_ctx: hdd context
6822 * @tb: nl attributes
6823 *
6824 * This function reads the NL attributes and forms a DelTxPtrn message
6825 * posts it to SME.
6826 *
6827 */
6828static int
6829wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6830 struct nlattr **tb)
6831{
6832 struct sSirDelPeriodicTxPtrn *del_req;
6833 eHalStatus status;
6834 uint32_t request_id, ret;
6835 uint8_t pattern_id = 0;
6836
6837 /* Parse and fetch request Id */
6838 if (!tb[PARAM_REQUEST_ID])
6839 {
6840 hddLog(LOGE, FL("attr request id failed"));
6841 return -EINVAL;
6842 }
6843 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6844 if (request_id == 0)
6845 {
6846 hddLog(LOGE, FL("request_id cannot be zero"));
6847 return -EINVAL;
6848 }
6849
6850 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6851 if (ret)
6852 {
6853 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6854 return -EINVAL;
6855 }
6856
6857 del_req = vos_mem_malloc(sizeof(*del_req));
6858 if (!del_req)
6859 {
6860 hddLog(LOGE, FL("memory allocation failed"));
6861 return -ENOMEM;
6862 }
6863
6864 vos_mem_set(del_req, sizeof(*del_req), 0);
6865 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6866 VOS_MAC_ADDR_SIZE);
6867 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6868 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6869 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6870 request_id, pattern_id, del_req->ucPatternIdBitmap);
6871
6872 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6873 if (!HAL_STATUS_SUCCESS(status))
6874 {
6875 hddLog(LOGE,
6876 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6877 goto fail;
6878 }
6879
6880 EXIT();
6881 vos_mem_free(del_req);
6882 return 0;
6883
6884fail:
6885 vos_mem_free(del_req);
6886 return -EINVAL;
6887}
6888
6889
6890/**
6891 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6892 * @wiphy: Pointer to wireless phy
6893 * @wdev: Pointer to wireless device
6894 * @data: Pointer to data
6895 * @data_len: Data length
6896 *
6897 * Return: 0 on success, negative errno on failure
6898 */
6899static int
6900__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6901 struct wireless_dev *wdev,
6902 const void *data,
6903 int data_len)
6904{
6905 struct net_device *dev = wdev->netdev;
6906 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6907 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6908 struct nlattr *tb[PARAM_MAX + 1];
6909 uint8_t control;
6910 int ret;
6911 static const struct nla_policy policy[PARAM_MAX + 1] =
6912 {
6913 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6914 [PARAM_CONTROL] = { .type = NLA_U32 },
6915 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6916 .len = VOS_MAC_ADDR_SIZE },
6917 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6918 .len = VOS_MAC_ADDR_SIZE },
6919 [PARAM_PERIOD] = { .type = NLA_U32 },
6920 };
6921
6922 ENTER();
6923
6924 ret = wlan_hdd_validate_context(hdd_ctx);
6925 if (0 != ret)
6926 {
6927 hddLog(LOGE, FL("HDD context is not valid"));
6928 return ret;
6929 }
6930
6931 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6932 {
6933 hddLog(LOGE,
6934 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6935 return -ENOTSUPP;
6936 }
6937
6938 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
6939 {
6940 hddLog(LOGE, FL("Invalid ATTR"));
6941 return -EINVAL;
6942 }
6943
6944 if (!tb[PARAM_CONTROL])
6945 {
6946 hddLog(LOGE, FL("attr control failed"));
6947 return -EINVAL;
6948 }
6949 control = nla_get_u32(tb[PARAM_CONTROL]);
6950 hddLog(LOG1, FL("Control: %d"), control);
6951
6952 if (control == WLAN_START_OFFLOADED_PACKETS)
6953 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
6954 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
6955 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
6956 else
6957 {
6958 hddLog(LOGE, FL("Invalid control: %d"), control);
6959 return -EINVAL;
6960 }
6961}
6962
6963/*
6964 * done with short names for the global vendor params
6965 * used by __wlan_hdd_cfg80211_offloaded_packets()
6966 */
6967#undef PARAM_MAX
6968#undef PARAM_REQUEST_ID
6969#undef PARAM_CONTROL
6970#undef PARAM_IP_PACKET
6971#undef PARAM_SRC_MAC_ADDR
6972#undef PARAM_DST_MAC_ADDR
6973#undef PARAM_PERIOD
6974
6975/**
6976 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
6977 * @wiphy: wiphy structure pointer
6978 * @wdev: Wireless device structure pointer
6979 * @data: Pointer to the data received
6980 * @data_len: Length of @data
6981 *
6982 * Return: 0 on success; errno on failure
6983 */
6984static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6985 struct wireless_dev *wdev,
6986 const void *data,
6987 int data_len)
6988{
6989 int ret = 0;
6990
6991 vos_ssr_protect(__func__);
6992 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
6993 wdev, data, data_len);
6994 vos_ssr_unprotect(__func__);
6995
6996 return ret;
6997}
6998#endif
6999
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307000static const struct
7001nla_policy
7002qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7003 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7004};
7005
7006/**
7007 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7008 * get link properties like nss, rate flags and operating frequency for
7009 * the connection with the given peer.
7010 * @wiphy: WIPHY structure pointer
7011 * @wdev: Wireless device structure pointer
7012 * @data: Pointer to the data received
7013 * @data_len: Length of the data received
7014 *
7015 * This function return the above link properties on success.
7016 *
7017 * Return: 0 on success and errno on failure
7018 */
7019static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7020 struct wireless_dev *wdev,
7021 const void *data,
7022 int data_len)
7023{
7024 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7025 struct net_device *dev = wdev->netdev;
7026 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7027 hdd_station_ctx_t *hdd_sta_ctx;
7028 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7029 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7030 uint32_t sta_id;
7031 struct sk_buff *reply_skb;
7032 uint32_t rate_flags = 0;
7033 uint8_t nss;
7034 uint8_t final_rate_flags = 0;
7035 uint32_t freq;
7036 v_CONTEXT_t pVosContext = NULL;
7037 ptSapContext pSapCtx = NULL;
7038
7039 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7041 return -EINVAL;
7042 }
7043
7044 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7045 qca_wlan_vendor_attr_policy)) {
7046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7047 return -EINVAL;
7048 }
7049
7050 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7051 hddLog(VOS_TRACE_LEVEL_ERROR,
7052 FL("Attribute peerMac not provided for mode=%d"),
7053 adapter->device_mode);
7054 return -EINVAL;
7055 }
7056
7057 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7058 sizeof(peer_mac));
7059 hddLog(VOS_TRACE_LEVEL_INFO,
7060 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7061 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7062
7063 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7064 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7065 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7066 if ((hdd_sta_ctx->conn_info.connState !=
7067 eConnectionState_Associated) ||
7068 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7069 VOS_MAC_ADDRESS_LEN)) {
7070 hddLog(VOS_TRACE_LEVEL_ERROR,
7071 FL("Not Associated to mac "MAC_ADDRESS_STR),
7072 MAC_ADDR_ARRAY(peer_mac));
7073 return -EINVAL;
7074 }
7075
7076 nss = 1; //pronto supports only one spatial stream
7077 freq = vos_chan_to_freq(
7078 hdd_sta_ctx->conn_info.operationChannel);
7079 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7080
7081 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7082 adapter->device_mode == WLAN_HDD_SOFTAP) {
7083
7084 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7085 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7086 if(pSapCtx == NULL){
7087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7088 FL("psapCtx is NULL"));
7089 return -ENOENT;
7090 }
7091
7092
7093 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7094 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7095 !vos_is_macaddr_broadcast(
7096 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7097 vos_mem_compare(
7098 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7099 peer_mac, VOS_MAC_ADDRESS_LEN))
7100 break;
7101 }
7102
7103 if (WLAN_MAX_STA_COUNT == sta_id) {
7104 hddLog(VOS_TRACE_LEVEL_ERROR,
7105 FL("No active peer with mac="MAC_ADDRESS_STR),
7106 MAC_ADDR_ARRAY(peer_mac));
7107 return -EINVAL;
7108 }
7109
7110 nss = 1; //pronto supports only one spatial stream
7111 freq = vos_chan_to_freq(
7112 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7113 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7114 } else {
7115 hddLog(VOS_TRACE_LEVEL_ERROR,
7116 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7117 MAC_ADDR_ARRAY(peer_mac));
7118 return -EINVAL;
7119 }
7120
7121 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7122 if (rate_flags & eHAL_TX_RATE_VHT80) {
7123 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7124 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7125 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7126 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7127 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7128 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7129 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7130 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7131 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7132 if (rate_flags & eHAL_TX_RATE_HT40)
7133 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7134 }
7135
7136 if (rate_flags & eHAL_TX_RATE_SGI) {
7137 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7138 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7139 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7140 }
7141 }
7142
7143 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7144 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7145
7146 if (NULL == reply_skb) {
7147 hddLog(VOS_TRACE_LEVEL_ERROR,
7148 FL("getLinkProperties: skb alloc failed"));
7149 return -EINVAL;
7150 }
7151
7152 if (nla_put_u8(reply_skb,
7153 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7154 nss) ||
7155 nla_put_u8(reply_skb,
7156 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7157 final_rate_flags) ||
7158 nla_put_u32(reply_skb,
7159 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7160 freq)) {
7161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7162 kfree_skb(reply_skb);
7163 return -EINVAL;
7164 }
7165
7166 return cfg80211_vendor_cmd_reply(reply_skb);
7167}
7168
Sunil Duttc69bccb2014-05-26 21:30:20 +05307169const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7170{
Mukul Sharma2a271632014-10-13 14:59:01 +05307171 {
7172 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7173 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7174 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7175 WIPHY_VENDOR_CMD_NEED_NETDEV |
7176 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307177 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307178 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307179
7180 {
7181 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7182 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7183 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7184 WIPHY_VENDOR_CMD_NEED_NETDEV |
7185 WIPHY_VENDOR_CMD_NEED_RUNNING,
7186 .doit = wlan_hdd_cfg80211_nan_request
7187 },
7188
Sunil Duttc69bccb2014-05-26 21:30:20 +05307189#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7190 {
7191 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7192 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7193 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7194 WIPHY_VENDOR_CMD_NEED_NETDEV |
7195 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307196 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307197 },
7198
7199 {
7200 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7201 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7202 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7203 WIPHY_VENDOR_CMD_NEED_NETDEV |
7204 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307205 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307206 },
7207
7208 {
7209 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7210 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7211 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7212 WIPHY_VENDOR_CMD_NEED_NETDEV |
7213 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307214 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307215 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307216#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307217#ifdef WLAN_FEATURE_EXTSCAN
7218 {
7219 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7220 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7221 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7222 WIPHY_VENDOR_CMD_NEED_NETDEV |
7223 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307224 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307225 },
7226 {
7227 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7228 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7229 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7230 WIPHY_VENDOR_CMD_NEED_NETDEV |
7231 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307232 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307233 },
7234 {
7235 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7236 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7237 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7238 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307239 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307240 },
7241 {
7242 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7243 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7244 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7245 WIPHY_VENDOR_CMD_NEED_NETDEV |
7246 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307247 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307248 },
7249 {
7250 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7251 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7252 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7253 WIPHY_VENDOR_CMD_NEED_NETDEV |
7254 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307255 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307256 },
7257 {
7258 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7259 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7260 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7261 WIPHY_VENDOR_CMD_NEED_NETDEV |
7262 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307263 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307264 },
7265 {
7266 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7267 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7268 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7269 WIPHY_VENDOR_CMD_NEED_NETDEV |
7270 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307271 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307272 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307273 {
7274 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7275 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7276 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7277 WIPHY_VENDOR_CMD_NEED_NETDEV |
7278 WIPHY_VENDOR_CMD_NEED_RUNNING,
7279 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7280 },
7281 {
7282 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7283 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7284 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7285 WIPHY_VENDOR_CMD_NEED_NETDEV |
7286 WIPHY_VENDOR_CMD_NEED_RUNNING,
7287 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7288 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307289#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307290/*EXT TDLS*/
7291 {
7292 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7293 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7294 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7295 WIPHY_VENDOR_CMD_NEED_NETDEV |
7296 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307297 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307298 },
7299 {
7300 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7301 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7302 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7303 WIPHY_VENDOR_CMD_NEED_NETDEV |
7304 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307305 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307306 },
7307 {
7308 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7309 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7310 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7311 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307312 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307313 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307314 {
7315 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7316 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7317 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7318 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307319 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307320 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307321 {
7322 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7323 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7324 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7325 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307326 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307327 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307328 {
7329 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7330 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7331 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7332 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307333 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307334 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307335 {
7336 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7337 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7338 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7339 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307340 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307341 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307342 {
7343 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307344 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7345 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7346 WIPHY_VENDOR_CMD_NEED_NETDEV |
7347 WIPHY_VENDOR_CMD_NEED_RUNNING,
7348 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7349 },
7350 {
7351 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307352 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7353 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7354 WIPHY_VENDOR_CMD_NEED_NETDEV |
7355 WIPHY_VENDOR_CMD_NEED_RUNNING,
7356 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307357 },
7358 {
7359 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7360 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7361 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7362 WIPHY_VENDOR_CMD_NEED_NETDEV,
7363 .doit = wlan_hdd_cfg80211_wifi_logger_start
7364 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307365 {
7366 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7367 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7368 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7369 WIPHY_VENDOR_CMD_NEED_NETDEV|
7370 WIPHY_VENDOR_CMD_NEED_RUNNING,
7371 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307372 },
7373 {
7374 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7375 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7376 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7377 WIPHY_VENDOR_CMD_NEED_NETDEV |
7378 WIPHY_VENDOR_CMD_NEED_RUNNING,
7379 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307380 },
7381 {
7382 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7383 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7384 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7385 WIPHY_VENDOR_CMD_NEED_NETDEV |
7386 WIPHY_VENDOR_CMD_NEED_RUNNING,
7387 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307388 },
7389#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7390 {
7391 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7392 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7393 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7394 WIPHY_VENDOR_CMD_NEED_NETDEV |
7395 WIPHY_VENDOR_CMD_NEED_RUNNING,
7396 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307397 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307398#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307399 {
7400 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7401 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7402 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7403 WIPHY_VENDOR_CMD_NEED_NETDEV |
7404 WIPHY_VENDOR_CMD_NEED_RUNNING,
7405 .doit = wlan_hdd_cfg80211_get_link_properties
7406 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307407};
7408
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007409/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307410static const
7411struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007412{
7413#ifdef FEATURE_WLAN_CH_AVOID
7414 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307415 .vendor_id = QCA_NL80211_VENDOR_ID,
7416 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007417 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307418#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7419#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7420 {
7421 /* Index = 1*/
7422 .vendor_id = QCA_NL80211_VENDOR_ID,
7423 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7424 },
7425 {
7426 /* Index = 2*/
7427 .vendor_id = QCA_NL80211_VENDOR_ID,
7428 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7429 },
7430 {
7431 /* Index = 3*/
7432 .vendor_id = QCA_NL80211_VENDOR_ID,
7433 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7434 },
7435 {
7436 /* Index = 4*/
7437 .vendor_id = QCA_NL80211_VENDOR_ID,
7438 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7439 },
7440 {
7441 /* Index = 5*/
7442 .vendor_id = QCA_NL80211_VENDOR_ID,
7443 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7444 },
7445 {
7446 /* Index = 6*/
7447 .vendor_id = QCA_NL80211_VENDOR_ID,
7448 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7449 },
7450#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307451#ifdef WLAN_FEATURE_EXTSCAN
7452 {
7453 .vendor_id = QCA_NL80211_VENDOR_ID,
7454 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7455 },
7456 {
7457 .vendor_id = QCA_NL80211_VENDOR_ID,
7458 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7459 },
7460 {
7461 .vendor_id = QCA_NL80211_VENDOR_ID,
7462 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7463 },
7464 {
7465 .vendor_id = QCA_NL80211_VENDOR_ID,
7466 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7467 },
7468 {
7469 .vendor_id = QCA_NL80211_VENDOR_ID,
7470 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7471 },
7472 {
7473 .vendor_id = QCA_NL80211_VENDOR_ID,
7474 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7475 },
7476 {
7477 .vendor_id = QCA_NL80211_VENDOR_ID,
7478 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7479 },
7480 {
7481 .vendor_id = QCA_NL80211_VENDOR_ID,
7482 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7483 },
7484 {
7485 .vendor_id = QCA_NL80211_VENDOR_ID,
7486 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7487 },
7488 {
7489 .vendor_id = QCA_NL80211_VENDOR_ID,
7490 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7491 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307492 {
7493 .vendor_id = QCA_NL80211_VENDOR_ID,
7494 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7495 },
7496 {
7497 .vendor_id = QCA_NL80211_VENDOR_ID,
7498 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7499 },
7500 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7501 .vendor_id = QCA_NL80211_VENDOR_ID,
7502 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7503 },
7504 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7505 .vendor_id = QCA_NL80211_VENDOR_ID,
7506 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7507 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307508#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307509/*EXT TDLS*/
7510 {
7511 .vendor_id = QCA_NL80211_VENDOR_ID,
7512 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7513 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307514 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7515 .vendor_id = QCA_NL80211_VENDOR_ID,
7516 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7517 },
7518
Srinivas Dasari030bad32015-02-18 23:23:54 +05307519
7520 {
7521 .vendor_id = QCA_NL80211_VENDOR_ID,
7522 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7523 },
7524
Sushant Kaushik084f6592015-09-10 13:11:56 +05307525 {
7526 .vendor_id = QCA_NL80211_VENDOR_ID,
7527 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307528 },
7529 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7530 .vendor_id = QCA_NL80211_VENDOR_ID,
7531 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7532 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307533
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007534};
7535
Jeff Johnson295189b2012-06-20 16:38:30 -07007536/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307537 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307538 * This function is called by hdd_wlan_startup()
7539 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307540 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007541 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307542struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007543{
7544 struct wiphy *wiphy;
7545 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307546 /*
7547 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007548 */
7549 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7550
7551 if (!wiphy)
7552 {
7553 /* Print error and jump into err label and free the memory */
7554 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7555 return NULL;
7556 }
7557
Sunil Duttc69bccb2014-05-26 21:30:20 +05307558
Jeff Johnson295189b2012-06-20 16:38:30 -07007559 return wiphy;
7560}
7561
7562/*
7563 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307564 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007565 * private ioctl to change the band value
7566 */
7567int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7568{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307569 int i, j;
7570 eNVChannelEnabledType channelEnabledState;
7571
Jeff Johnsone7245742012-09-05 17:12:55 -07007572 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307573
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307574 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007575 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307576
7577 if (NULL == wiphy->bands[i])
7578 {
7579 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7580 __func__, i);
7581 continue;
7582 }
7583
7584 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7585 {
7586 struct ieee80211_supported_band *band = wiphy->bands[i];
7587
7588 channelEnabledState = vos_nv_getChannelEnabledState(
7589 band->channels[j].hw_value);
7590
7591 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7592 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307593 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307594 continue;
7595 }
7596 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7597 {
7598 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7599 continue;
7600 }
7601
7602 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7603 NV_CHANNEL_INVALID == channelEnabledState)
7604 {
7605 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7606 }
7607 else if (NV_CHANNEL_DFS == channelEnabledState)
7608 {
7609 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7610 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7611 }
7612 else
7613 {
7614 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7615 |IEEE80211_CHAN_RADAR);
7616 }
7617 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007618 }
7619 return 0;
7620}
7621/*
7622 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307623 * This function is called by hdd_wlan_startup()
7624 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007625 * This function is used to initialize and register wiphy structure.
7626 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307627int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007628 struct wiphy *wiphy,
7629 hdd_config_t *pCfg
7630 )
7631{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307632 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307633 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7634
Jeff Johnsone7245742012-09-05 17:12:55 -07007635 ENTER();
7636
Jeff Johnson295189b2012-06-20 16:38:30 -07007637 /* Now bind the underlying wlan device with wiphy */
7638 set_wiphy_dev(wiphy, dev);
7639
7640 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007641
Kiet Lam6c583332013-10-14 05:37:09 +05307642#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007643 /* the flag for the other case would be initialzed in
7644 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07007645 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307646#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007647
Amar Singhalfddc28c2013-09-05 13:03:40 -07007648 /* This will disable updating of NL channels from passive to
7649 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307650#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7651 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7652#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007653 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307654#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007655
Amar Singhala49cbc52013-10-08 18:37:44 -07007656
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007657#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007658 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7659 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7660 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007661 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307662#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7663 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
7664#else
7665 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7666#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007667#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007668
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007669#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007670 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007671#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007672 || pCfg->isFastRoamIniFeatureEnabled
7673#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007674#ifdef FEATURE_WLAN_ESE
7675 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007676#endif
7677 )
7678 {
7679 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7680 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007681#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007682#ifdef FEATURE_WLAN_TDLS
7683 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7684 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7685#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307686#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307687 if (pCfg->configPNOScanSupport)
7688 {
7689 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7690 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7691 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7692 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7693 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307694#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007695
Abhishek Singh10d85972015-04-17 10:27:23 +05307696#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7697 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7698#endif
7699
Amar Singhalfddc28c2013-09-05 13:03:40 -07007700#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007701 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7702 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007703 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007704 driver need to determine what to do with both
7705 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007706
7707 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007708#else
7709 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007710#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007711
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307712 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7713
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307714 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007715
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307716 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7717
Jeff Johnson295189b2012-06-20 16:38:30 -07007718 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307719 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7720 | BIT(NL80211_IFTYPE_ADHOC)
7721 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7722 | BIT(NL80211_IFTYPE_P2P_GO)
7723 | BIT(NL80211_IFTYPE_AP);
7724
7725 if (VOS_MONITOR_MODE == hdd_get_conparam())
7726 {
7727 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7728 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007729
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307730 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007731 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307732#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7733 if( pCfg->enableMCC )
7734 {
7735 /* Currently, supports up to two channels */
7736 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007737
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307738 if( !pCfg->allowMCCGODiffBI )
7739 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007740
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307741 }
7742 wiphy->iface_combinations = &wlan_hdd_iface_combination;
7743 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007744#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307745 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007746
Jeff Johnson295189b2012-06-20 16:38:30 -07007747 /* Before registering we need to update the ht capabilitied based
7748 * on ini values*/
7749 if( !pCfg->ShortGI20MhzEnable )
7750 {
7751 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7752 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7753 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7754 }
7755
7756 if( !pCfg->ShortGI40MhzEnable )
7757 {
7758 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
7759 }
7760
7761 if( !pCfg->nChannelBondingMode5GHz )
7762 {
7763 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7764 }
7765
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307766 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307767 if (true == hdd_is_5g_supported(pHddCtx))
7768 {
7769 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
7770 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307771
7772 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
7773 {
7774
7775 if (NULL == wiphy->bands[i])
7776 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05307777 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307778 __func__, i);
7779 continue;
7780 }
7781
7782 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7783 {
7784 struct ieee80211_supported_band *band = wiphy->bands[i];
7785
7786 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
7787 {
7788 // Enable social channels for P2P
7789 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
7790 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7791 else
7792 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7793 continue;
7794 }
7795 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
7796 {
7797 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7798 continue;
7799 }
7800 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 }
7802 /*Initialise the supported cipher suite details*/
7803 wiphy->cipher_suites = hdd_cipher_suites;
7804 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
7805
7806 /*signal strength in mBm (100*dBm) */
7807 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
7808
7809#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05307810 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07007811#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007812
Sunil Duttc69bccb2014-05-26 21:30:20 +05307813 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
7814 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007815 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
7816 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
7817
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307818 EXIT();
7819 return 0;
7820}
7821
7822/* In this function we are registering wiphy. */
7823int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
7824{
7825 ENTER();
7826 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007827 if (0 > wiphy_register(wiphy))
7828 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307829 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07007830 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
7831 return -EIO;
7832 }
7833
7834 EXIT();
7835 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307836}
Jeff Johnson295189b2012-06-20 16:38:30 -07007837
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307838/* In this function we are updating channel list when,
7839 regulatory domain is FCC and country code is US.
7840 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
7841 As per FCC smart phone is not a indoor device.
7842 GO should not opeate on indoor channels */
7843void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
7844{
7845 int j;
7846 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7847 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
7848 //Default counrtycode from NV at the time of wiphy initialization.
7849 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
7850 &defaultCountryCode[0]))
7851 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007852 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307853 }
7854 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
7855 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307856 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
7857 {
7858 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
7859 return;
7860 }
7861 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
7862 {
7863 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
7864 // Mark UNII -1 band channel as passive
7865 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
7866 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
7867 }
7868 }
7869}
7870
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05307871/* This function registers for all frame which supplicant is interested in */
7872void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007873{
Jeff Johnson295189b2012-06-20 16:38:30 -07007874 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7875 /* Register for all P2P action, public action etc frames */
7876 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
7877
Jeff Johnsone7245742012-09-05 17:12:55 -07007878 ENTER();
7879
Jeff Johnson295189b2012-06-20 16:38:30 -07007880 /* Right now we are registering these frame when driver is getting
7881 initialized. Once we will move to 2.6.37 kernel, in which we have
7882 frame register ops, we will move this code as a part of that */
7883 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307884 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007885 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
7886
7887 /* GAS Initial Response */
7888 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
7889 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307890
Jeff Johnson295189b2012-06-20 16:38:30 -07007891 /* GAS Comeback Request */
7892 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
7893 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
7894
7895 /* GAS Comeback Response */
7896 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
7897 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
7898
7899 /* P2P Public Action */
7900 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307901 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07007902 P2P_PUBLIC_ACTION_FRAME_SIZE );
7903
7904 /* P2P Action */
7905 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
7906 (v_U8_t*)P2P_ACTION_FRAME,
7907 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07007908
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05307909 /* WNM BSS Transition Request frame */
7910 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
7911 (v_U8_t*)WNM_BSS_ACTION_FRAME,
7912 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07007913
7914 /* WNM-Notification */
7915 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
7916 (v_U8_t*)WNM_NOTIFICATION_FRAME,
7917 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007918}
7919
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05307920void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007921{
Jeff Johnson295189b2012-06-20 16:38:30 -07007922 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7923 /* Register for all P2P action, public action etc frames */
7924 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
7925
Jeff Johnsone7245742012-09-05 17:12:55 -07007926 ENTER();
7927
Jeff Johnson295189b2012-06-20 16:38:30 -07007928 /* Right now we are registering these frame when driver is getting
7929 initialized. Once we will move to 2.6.37 kernel, in which we have
7930 frame register ops, we will move this code as a part of that */
7931 /* GAS Initial Request */
7932
7933 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7934 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
7935
7936 /* GAS Initial Response */
7937 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7938 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307939
Jeff Johnson295189b2012-06-20 16:38:30 -07007940 /* GAS Comeback Request */
7941 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7942 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
7943
7944 /* GAS Comeback Response */
7945 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7946 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
7947
7948 /* P2P Public Action */
7949 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307950 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 P2P_PUBLIC_ACTION_FRAME_SIZE );
7952
7953 /* P2P Action */
7954 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7955 (v_U8_t*)P2P_ACTION_FRAME,
7956 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07007957 /* WNM-Notification */
7958 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7959 (v_U8_t*)WNM_NOTIFICATION_FRAME,
7960 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007961}
7962
7963#ifdef FEATURE_WLAN_WAPI
7964void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05307965 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07007966{
7967 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7968 tCsrRoamSetKey setKey;
7969 v_BOOL_t isConnected = TRUE;
7970 int status = 0;
7971 v_U32_t roamId= 0xFF;
7972 tANI_U8 *pKeyPtr = NULL;
7973 int n = 0;
7974
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307975 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
7976 __func__, hdd_device_modetoString(pAdapter->device_mode),
7977 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007978
Gopichand Nakkalae7480202013-02-11 15:24:22 +05307979 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 setKey.keyId = key_index; // Store Key ID
7981 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
7982 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
7983 setKey.paeRole = 0 ; // the PAE role
7984 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7985 {
7986 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
7987 }
7988 else
7989 {
7990 isConnected = hdd_connIsConnected(pHddStaCtx);
7991 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
7992 }
7993 setKey.keyLength = key_Len;
7994 pKeyPtr = setKey.Key;
7995 memcpy( pKeyPtr, key, key_Len);
7996
Arif Hussain6d2a3322013-11-17 19:50:10 -08007997 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07007998 __func__, key_Len);
7999 for (n = 0 ; n < key_Len; n++)
8000 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8001 __func__,n,setKey.Key[n]);
8002
8003 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8004 if ( isConnected )
8005 {
8006 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8007 pAdapter->sessionId, &setKey, &roamId );
8008 }
8009 if ( status != 0 )
8010 {
8011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8012 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8013 __LINE__, status );
8014 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8015 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308016 /* Need to clear any trace of key value in the memory.
8017 * Thus zero out the memory even though it is local
8018 * variable.
8019 */
8020 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008021}
8022#endif /* FEATURE_WLAN_WAPI*/
8023
8024#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308025int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008026 beacon_data_t **ppBeacon,
8027 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008028#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308029int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008030 beacon_data_t **ppBeacon,
8031 struct cfg80211_beacon_data *params,
8032 int dtim_period)
8033#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308034{
Jeff Johnson295189b2012-06-20 16:38:30 -07008035 int size;
8036 beacon_data_t *beacon = NULL;
8037 beacon_data_t *old = NULL;
8038 int head_len,tail_len;
8039
Jeff Johnsone7245742012-09-05 17:12:55 -07008040 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008041 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308042 {
8043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8044 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008045 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308046 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008047
8048 old = pAdapter->sessionCtx.ap.beacon;
8049
8050 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308051 {
8052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8053 FL("session(%d) old and new heads points to NULL"),
8054 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008055 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308056 }
8057
8058 if (params->tail && !params->tail_len)
8059 {
8060 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8061 FL("tail_len is zero but tail is not NULL"));
8062 return -EINVAL;
8063 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008064
Jeff Johnson295189b2012-06-20 16:38:30 -07008065#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8066 /* Kernel 3.0 is not updating dtim_period for set beacon */
8067 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308068 {
8069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8070 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308072 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008073#endif
8074
8075 if(params->head)
8076 head_len = params->head_len;
8077 else
8078 head_len = old->head_len;
8079
8080 if(params->tail || !old)
8081 tail_len = params->tail_len;
8082 else
8083 tail_len = old->tail_len;
8084
8085 size = sizeof(beacon_data_t) + head_len + tail_len;
8086
8087 beacon = kzalloc(size, GFP_KERNEL);
8088
8089 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308090 {
8091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8092 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008093 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308094 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008095
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008096#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008097 if(params->dtim_period || !old )
8098 beacon->dtim_period = params->dtim_period;
8099 else
8100 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008101#else
8102 if(dtim_period || !old )
8103 beacon->dtim_period = dtim_period;
8104 else
8105 beacon->dtim_period = old->dtim_period;
8106#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308107
Jeff Johnson295189b2012-06-20 16:38:30 -07008108 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8109 beacon->tail = beacon->head + head_len;
8110 beacon->head_len = head_len;
8111 beacon->tail_len = tail_len;
8112
8113 if(params->head) {
8114 memcpy (beacon->head,params->head,beacon->head_len);
8115 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308116 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 if(old)
8118 memcpy (beacon->head,old->head,beacon->head_len);
8119 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308120
Jeff Johnson295189b2012-06-20 16:38:30 -07008121 if(params->tail) {
8122 memcpy (beacon->tail,params->tail,beacon->tail_len);
8123 }
8124 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308125 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008126 memcpy (beacon->tail,old->tail,beacon->tail_len);
8127 }
8128
8129 *ppBeacon = beacon;
8130
8131 kfree(old);
8132
8133 return 0;
8134
8135}
Jeff Johnson295189b2012-06-20 16:38:30 -07008136
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308137v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8139 const v_U8_t *pIes,
8140#else
8141 v_U8_t *pIes,
8142#endif
8143 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008144{
8145 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308146 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008147 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308148
Jeff Johnson295189b2012-06-20 16:38:30 -07008149 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308150 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008151 elem_id = ptr[0];
8152 elem_len = ptr[1];
8153 left -= 2;
8154 if(elem_len > left)
8155 {
8156 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008157 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008158 eid,elem_len,left);
8159 return NULL;
8160 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308161 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008162 {
8163 return ptr;
8164 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308165
Jeff Johnson295189b2012-06-20 16:38:30 -07008166 left -= elem_len;
8167 ptr += (elem_len + 2);
8168 }
8169 return NULL;
8170}
8171
Jeff Johnson295189b2012-06-20 16:38:30 -07008172/* Check if rate is 11g rate or not */
8173static int wlan_hdd_rate_is_11g(u8 rate)
8174{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008175 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008176 u8 i;
8177 for (i = 0; i < 8; i++)
8178 {
8179 if(rate == gRateArray[i])
8180 return TRUE;
8181 }
8182 return FALSE;
8183}
8184
8185/* Check for 11g rate and set proper 11g only mode */
8186static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8187 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8188{
8189 u8 i, num_rates = pIe[0];
8190
8191 pIe += 1;
8192 for ( i = 0; i < num_rates; i++)
8193 {
8194 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8195 {
8196 /* If rate set have 11g rate than change the mode to 11G */
8197 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8198 if (pIe[i] & BASIC_RATE_MASK)
8199 {
8200 /* If we have 11g rate as basic rate, it means mode
8201 is 11g only mode.
8202 */
8203 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8204 *pCheckRatesfor11g = FALSE;
8205 }
8206 }
8207 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8208 {
8209 *require_ht = TRUE;
8210 }
8211 }
8212 return;
8213}
8214
8215static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8216{
8217 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8218 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8219 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8220 u8 checkRatesfor11g = TRUE;
8221 u8 require_ht = FALSE;
8222 u8 *pIe=NULL;
8223
8224 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8225
8226 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8227 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8228 if (pIe != NULL)
8229 {
8230 pIe += 1;
8231 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8232 &pConfig->SapHw_mode);
8233 }
8234
8235 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8236 WLAN_EID_EXT_SUPP_RATES);
8237 if (pIe != NULL)
8238 {
8239
8240 pIe += 1;
8241 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8242 &pConfig->SapHw_mode);
8243 }
8244
8245 if( pConfig->channel > 14 )
8246 {
8247 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8248 }
8249
8250 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8251 WLAN_EID_HT_CAPABILITY);
8252
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308253 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 {
8255 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8256 if(require_ht)
8257 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8258 }
8259}
8260
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308261static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8262 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8263{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008264 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308265 v_U8_t *pIe = NULL;
8266 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8267
8268 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8269 pBeacon->tail, pBeacon->tail_len);
8270
8271 if (pIe)
8272 {
8273 ielen = pIe[1] + 2;
8274 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8275 {
8276 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8277 }
8278 else
8279 {
8280 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8281 return -EINVAL;
8282 }
8283 *total_ielen += ielen;
8284 }
8285 return 0;
8286}
8287
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008288static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8289 v_U8_t *genie, v_U8_t *total_ielen)
8290{
8291 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8292 int left = pBeacon->tail_len;
8293 v_U8_t *ptr = pBeacon->tail;
8294 v_U8_t elem_id, elem_len;
8295 v_U16_t ielen = 0;
8296
8297 if ( NULL == ptr || 0 == left )
8298 return;
8299
8300 while (left >= 2)
8301 {
8302 elem_id = ptr[0];
8303 elem_len = ptr[1];
8304 left -= 2;
8305 if (elem_len > left)
8306 {
8307 hddLog( VOS_TRACE_LEVEL_ERROR,
8308 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8309 elem_id, elem_len, left);
8310 return;
8311 }
8312 if (IE_EID_VENDOR == elem_id)
8313 {
8314 /* skipping the VSIE's which we don't want to include or
8315 * it will be included by existing code
8316 */
8317 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8318#ifdef WLAN_FEATURE_WFD
8319 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8320#endif
8321 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8322 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8323 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8324 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8325 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8326 {
8327 ielen = ptr[1] + 2;
8328 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8329 {
8330 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8331 *total_ielen += ielen;
8332 }
8333 else
8334 {
8335 hddLog( VOS_TRACE_LEVEL_ERROR,
8336 "IE Length is too big "
8337 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8338 elem_id, elem_len, *total_ielen);
8339 }
8340 }
8341 }
8342
8343 left -= elem_len;
8344 ptr += (elem_len + 2);
8345 }
8346 return;
8347}
8348
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008349#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008350static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8351 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008352#else
8353static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8354 struct cfg80211_beacon_data *params)
8355#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008356{
8357 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308358 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008359 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008360 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008361
8362 genie = vos_mem_malloc(MAX_GENIE_LEN);
8363
8364 if(genie == NULL) {
8365
8366 return -ENOMEM;
8367 }
8368
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308369 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8370 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308372 hddLog(LOGE,
8373 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308374 ret = -EINVAL;
8375 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008376 }
8377
8378#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308379 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8380 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8381 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308382 hddLog(LOGE,
8383 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308384 ret = -EINVAL;
8385 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008386 }
8387#endif
8388
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308389 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8390 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008391 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308392 hddLog(LOGE,
8393 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308394 ret = -EINVAL;
8395 goto done;
8396 }
8397
8398 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8399 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008400 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008401 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008402
8403 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8404 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8405 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8406 {
8407 hddLog(LOGE,
8408 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008409 ret = -EINVAL;
8410 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008411 }
8412
8413 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8414 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8415 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8416 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8417 ==eHAL_STATUS_FAILURE)
8418 {
8419 hddLog(LOGE,
8420 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008421 ret = -EINVAL;
8422 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008423 }
8424
8425 // Added for ProResp IE
8426 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8427 {
8428 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8429 u8 probe_rsp_ie_len[3] = {0};
8430 u8 counter = 0;
8431 /* Check Probe Resp Length if it is greater then 255 then Store
8432 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8433 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8434 Store More then 255 bytes into One Variable.
8435 */
8436 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8437 {
8438 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8439 {
8440 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8441 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8442 }
8443 else
8444 {
8445 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8446 rem_probe_resp_ie_len = 0;
8447 }
8448 }
8449
8450 rem_probe_resp_ie_len = 0;
8451
8452 if (probe_rsp_ie_len[0] > 0)
8453 {
8454 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8455 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8456 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8457 probe_rsp_ie_len[0], NULL,
8458 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8459 {
8460 hddLog(LOGE,
8461 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008462 ret = -EINVAL;
8463 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008464 }
8465 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8466 }
8467
8468 if (probe_rsp_ie_len[1] > 0)
8469 {
8470 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8471 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8472 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8473 probe_rsp_ie_len[1], NULL,
8474 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8475 {
8476 hddLog(LOGE,
8477 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008478 ret = -EINVAL;
8479 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 }
8481 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8482 }
8483
8484 if (probe_rsp_ie_len[2] > 0)
8485 {
8486 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8487 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8488 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8489 probe_rsp_ie_len[2], NULL,
8490 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8491 {
8492 hddLog(LOGE,
8493 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008494 ret = -EINVAL;
8495 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008496 }
8497 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8498 }
8499
8500 if (probe_rsp_ie_len[1] == 0 )
8501 {
8502 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8503 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8504 eANI_BOOLEAN_FALSE) )
8505 {
8506 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008507 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008508 }
8509 }
8510
8511 if (probe_rsp_ie_len[2] == 0 )
8512 {
8513 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8514 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8515 eANI_BOOLEAN_FALSE) )
8516 {
8517 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008518 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008519 }
8520 }
8521
8522 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8523 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8524 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8525 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8526 == eHAL_STATUS_FAILURE)
8527 {
8528 hddLog(LOGE,
8529 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008530 ret = -EINVAL;
8531 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008532 }
8533 }
8534 else
8535 {
8536 // Reset WNI_CFG_PROBE_RSP Flags
8537 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8538
8539 hddLog(VOS_TRACE_LEVEL_INFO,
8540 "%s: No Probe Response IE received in set beacon",
8541 __func__);
8542 }
8543
8544 // Added for AssocResp IE
8545 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8546 {
8547 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8548 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8549 params->assocresp_ies_len, NULL,
8550 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8551 {
8552 hddLog(LOGE,
8553 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008554 ret = -EINVAL;
8555 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008556 }
8557
8558 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8559 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8560 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8561 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8562 == eHAL_STATUS_FAILURE)
8563 {
8564 hddLog(LOGE,
8565 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008566 ret = -EINVAL;
8567 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008568 }
8569 }
8570 else
8571 {
8572 hddLog(VOS_TRACE_LEVEL_INFO,
8573 "%s: No Assoc Response IE received in set beacon",
8574 __func__);
8575
8576 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8577 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8578 eANI_BOOLEAN_FALSE) )
8579 {
8580 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008581 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008582 }
8583 }
8584
Jeff Johnsone7245742012-09-05 17:12:55 -07008585done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008586 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308587 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008588}
Jeff Johnson295189b2012-06-20 16:38:30 -07008589
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308590/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008591 * FUNCTION: wlan_hdd_validate_operation_channel
8592 * called by wlan_hdd_cfg80211_start_bss() and
8593 * wlan_hdd_cfg80211_set_channel()
8594 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308595 * channel list.
8596 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008597VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008598{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308599
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 v_U32_t num_ch = 0;
8601 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8602 u32 indx = 0;
8603 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308604 v_U8_t fValidChannel = FALSE, count = 0;
8605 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308606
Jeff Johnson295189b2012-06-20 16:38:30 -07008607 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8608
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308609 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008610 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308611 /* Validate the channel */
8612 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008613 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308614 if ( channel == rfChannels[count].channelNum )
8615 {
8616 fValidChannel = TRUE;
8617 break;
8618 }
8619 }
8620 if (fValidChannel != TRUE)
8621 {
8622 hddLog(VOS_TRACE_LEVEL_ERROR,
8623 "%s: Invalid Channel [%d]", __func__, channel);
8624 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008625 }
8626 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308627 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008628 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308629 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8630 valid_ch, &num_ch))
8631 {
8632 hddLog(VOS_TRACE_LEVEL_ERROR,
8633 "%s: failed to get valid channel list", __func__);
8634 return VOS_STATUS_E_FAILURE;
8635 }
8636 for (indx = 0; indx < num_ch; indx++)
8637 {
8638 if (channel == valid_ch[indx])
8639 {
8640 break;
8641 }
8642 }
8643
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308644 if (indx >= num_ch)
8645 {
8646 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8647 {
8648 eCsrBand band;
8649 unsigned int freq;
8650
8651 sme_GetFreqBand(hHal, &band);
8652
8653 if (eCSR_BAND_5G == band)
8654 {
8655#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8656 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8657 {
8658 freq = ieee80211_channel_to_frequency(channel,
8659 IEEE80211_BAND_2GHZ);
8660 }
8661 else
8662 {
8663 freq = ieee80211_channel_to_frequency(channel,
8664 IEEE80211_BAND_5GHZ);
8665 }
8666#else
8667 freq = ieee80211_channel_to_frequency(channel);
8668#endif
8669 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8670 return VOS_STATUS_SUCCESS;
8671 }
8672 }
8673
8674 hddLog(VOS_TRACE_LEVEL_ERROR,
8675 "%s: Invalid Channel [%d]", __func__, channel);
8676 return VOS_STATUS_E_FAILURE;
8677 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008678 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308679
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308681
Jeff Johnson295189b2012-06-20 16:38:30 -07008682}
8683
Viral Modi3a32cc52013-02-08 11:14:52 -08008684/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308685 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08008686 * This function is used to set the channel number
8687 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308688static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08008689 struct ieee80211_channel *chan,
8690 enum nl80211_channel_type channel_type
8691 )
8692{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308693 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08008694 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07008695 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08008696 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308697 hdd_context_t *pHddCtx;
8698 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008699
8700 ENTER();
8701
8702 if( NULL == dev )
8703 {
8704 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008705 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008706 return -ENODEV;
8707 }
8708 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308709
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308710 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8711 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
8712 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08008713 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308714 "%s: device_mode = %s (%d) freq = %d", __func__,
8715 hdd_device_modetoString(pAdapter->device_mode),
8716 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308717
8718 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8719 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308720 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08008721 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308722 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008723 }
8724
8725 /*
8726 * Do freq to chan conversion
8727 * TODO: for 11a
8728 */
8729
8730 channel = ieee80211_frequency_to_channel(freq);
8731
8732 /* Check freq range */
8733 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
8734 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
8735 {
8736 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008737 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08008738 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
8739 WNI_CFG_CURRENT_CHANNEL_STAMAX);
8740 return -EINVAL;
8741 }
8742
8743 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8744
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05308745 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
8746 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08008747 {
8748 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
8749 {
8750 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008751 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08008752 return -EINVAL;
8753 }
8754 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8755 "%s: set channel to [%d] for device mode =%d",
8756 __func__, channel,pAdapter->device_mode);
8757 }
8758 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08008759 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08008760 )
8761 {
8762 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8763 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
8764 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8765
8766 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
8767 {
8768 /* Link is up then return cant set channel*/
8769 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008770 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008771 return -EINVAL;
8772 }
8773
8774 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
8775 pHddStaCtx->conn_info.operationChannel = channel;
8776 pRoamProfile->ChannelInfo.ChannelList =
8777 &pHddStaCtx->conn_info.operationChannel;
8778 }
8779 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08008780 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08008781 )
8782 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308783 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8784 {
8785 if(VOS_STATUS_SUCCESS !=
8786 wlan_hdd_validate_operation_channel(pAdapter,channel))
8787 {
8788 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008789 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308790 return -EINVAL;
8791 }
8792 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
8793 }
8794 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08008795 {
8796 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
8797
8798 /* If auto channel selection is configured as enable/ 1 then ignore
8799 channel set by supplicant
8800 */
8801 if ( cfg_param->apAutoChannelSelection )
8802 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308803 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
8804 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08008805 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308806 "%s: set channel to auto channel (0) for device mode =%s (%d)",
8807 __func__, hdd_device_modetoString(pAdapter->device_mode),
8808 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08008809 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308810 else
8811 {
8812 if(VOS_STATUS_SUCCESS !=
8813 wlan_hdd_validate_operation_channel(pAdapter,channel))
8814 {
8815 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008816 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308817 return -EINVAL;
8818 }
8819 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
8820 }
Viral Modi3a32cc52013-02-08 11:14:52 -08008821 }
8822 }
8823 else
8824 {
8825 hddLog(VOS_TRACE_LEVEL_FATAL,
8826 "%s: Invalid device mode failed to set valid channel", __func__);
8827 return -EINVAL;
8828 }
8829 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308830 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008831}
8832
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308833static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
8834 struct net_device *dev,
8835 struct ieee80211_channel *chan,
8836 enum nl80211_channel_type channel_type
8837 )
8838{
8839 int ret;
8840
8841 vos_ssr_protect(__func__);
8842 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
8843 vos_ssr_unprotect(__func__);
8844
8845 return ret;
8846}
8847
Jeff Johnson295189b2012-06-20 16:38:30 -07008848#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8849static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
8850 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008851#else
8852static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
8853 struct cfg80211_beacon_data *params,
8854 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308855 enum nl80211_hidden_ssid hidden_ssid,
8856 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008857#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008858{
8859 tsap_Config_t *pConfig;
8860 beacon_data_t *pBeacon = NULL;
8861 struct ieee80211_mgmt *pMgmt_frame;
8862 v_U8_t *pIe=NULL;
8863 v_U16_t capab_info;
8864 eCsrAuthType RSNAuthType;
8865 eCsrEncryptionType RSNEncryptType;
8866 eCsrEncryptionType mcRSNEncryptType;
8867 int status = VOS_STATUS_SUCCESS;
8868 tpWLAN_SAPEventCB pSapEventCallback;
8869 hdd_hostapd_state_t *pHostapdState;
8870 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
8871 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05308872 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008873 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308874 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07008875 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08008876 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05308877 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07008878 v_BOOL_t MFPCapable = VOS_FALSE;
8879 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308880 v_BOOL_t sapEnable11AC =
8881 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07008882 ENTER();
8883
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308884 iniConfig = pHddCtx->cfg_ini;
8885
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
8887
8888 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8889
8890 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8891
8892 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8893
8894 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
8895
8896 //channel is already set in the set_channel Call back
8897 //pConfig->channel = pCommitConfig->channel;
8898
8899 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308900 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07008901 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
8902
8903 pConfig->dtim_period = pBeacon->dtim_period;
8904
Arif Hussain6d2a3322013-11-17 19:50:10 -08008905 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07008906 pConfig->dtim_period);
8907
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08008908 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07008909 {
8910 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07008911 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05308912 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
8913 {
8914 tANI_BOOLEAN restartNeeded;
8915 pConfig->ieee80211d = 1;
8916 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
8917 sme_setRegInfo(hHal, pConfig->countryCode);
8918 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
8919 }
8920 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008921 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07008922 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07008923 pConfig->ieee80211d = 1;
8924 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
8925 sme_setRegInfo(hHal, pConfig->countryCode);
8926 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07008928 else
8929 {
8930 pConfig->ieee80211d = 0;
8931 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05308932 /*
8933 * If auto channel is configured i.e. channel is 0,
8934 * so skip channel validation.
8935 */
8936 if( AUTO_CHANNEL_SELECT != pConfig->channel )
8937 {
8938 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
8939 {
8940 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008941 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05308942 return -EINVAL;
8943 }
8944 }
8945 else
8946 {
8947 if(1 != pHddCtx->is_dynamic_channel_range_set)
8948 {
8949 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
8950 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
8951 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
8952 }
8953 pHddCtx->is_dynamic_channel_range_set = 0;
8954 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008955 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07008956 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008957 {
8958 pConfig->ieee80211d = 0;
8959 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308960
8961#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8962 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
8963 pConfig->authType = eSAP_OPEN_SYSTEM;
8964 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
8965 pConfig->authType = eSAP_SHARED_KEY;
8966 else
8967 pConfig->authType = eSAP_AUTO_SWITCH;
8968#else
8969 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
8970 pConfig->authType = eSAP_OPEN_SYSTEM;
8971 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
8972 pConfig->authType = eSAP_SHARED_KEY;
8973 else
8974 pConfig->authType = eSAP_AUTO_SWITCH;
8975#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008976
8977 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308978
8979 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
8981
8982 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
8983
8984 /*Set wps station to configured*/
8985 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
8986
8987 if(pIe)
8988 {
8989 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
8990 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008991 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07008992 return -EINVAL;
8993 }
8994 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
8995 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008996 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 /* Check 15 bit of WPS IE as it contain information for wps state
8998 * WPS state
8999 */
9000 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9001 {
9002 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9003 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9004 {
9005 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9006 }
9007 }
9008 }
9009 else
9010 {
9011 pConfig->wps_state = SAP_WPS_DISABLED;
9012 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309013 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009014
c_hpothufe599e92014-06-16 11:38:55 +05309015 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9016 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9017 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9018 eCSR_ENCRYPT_TYPE_NONE;
9019
Jeff Johnson295189b2012-06-20 16:38:30 -07009020 pConfig->RSNWPAReqIELength = 0;
9021 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309022 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009023 WLAN_EID_RSN);
9024 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309025 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009026 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9027 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9028 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309029 /* The actual processing may eventually be more extensive than
9030 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009031 * by the app.
9032 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309033 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009034 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9035 &RSNEncryptType,
9036 &mcRSNEncryptType,
9037 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009038 &MFPCapable,
9039 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 pConfig->pRSNWPAReqIE[1]+2,
9041 pConfig->pRSNWPAReqIE );
9042
9043 if( VOS_STATUS_SUCCESS == status )
9044 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309045 /* Now copy over all the security attributes you have
9046 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009047 * */
9048 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9049 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9050 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9051 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309052 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009053 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009054 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9055 }
9056 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309057
Jeff Johnson295189b2012-06-20 16:38:30 -07009058 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9059 pBeacon->tail, pBeacon->tail_len);
9060
9061 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9062 {
9063 if (pConfig->pRSNWPAReqIE)
9064 {
9065 /*Mixed mode WPA/WPA2*/
9066 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9067 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9068 }
9069 else
9070 {
9071 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9072 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9073 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309074 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009075 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9076 &RSNEncryptType,
9077 &mcRSNEncryptType,
9078 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009079 &MFPCapable,
9080 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009081 pConfig->pRSNWPAReqIE[1]+2,
9082 pConfig->pRSNWPAReqIE );
9083
9084 if( VOS_STATUS_SUCCESS == status )
9085 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309086 /* Now copy over all the security attributes you have
9087 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009088 * */
9089 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9090 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9091 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9092 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309093 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009094 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009095 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9096 }
9097 }
9098 }
9099
Jeff Johnson4416a782013-03-25 14:17:50 -07009100 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9101 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9102 return -EINVAL;
9103 }
9104
Jeff Johnson295189b2012-06-20 16:38:30 -07009105 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9106
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009107#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009108 if (params->ssid != NULL)
9109 {
9110 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9111 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9112 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9113 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9114 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009115#else
9116 if (ssid != NULL)
9117 {
9118 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9119 pConfig->SSIDinfo.ssid.length = ssid_len;
9120 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9121 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9122 }
9123#endif
9124
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309125 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009126 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309127
Jeff Johnson295189b2012-06-20 16:38:30 -07009128 /* default value */
9129 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9130 pConfig->num_accept_mac = 0;
9131 pConfig->num_deny_mac = 0;
9132
9133 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9134 pBeacon->tail, pBeacon->tail_len);
9135
9136 /* pIe for black list is following form:
9137 type : 1 byte
9138 length : 1 byte
9139 OUI : 4 bytes
9140 acl type : 1 byte
9141 no of mac addr in black list: 1 byte
9142 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309143 */
9144 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009145 {
9146 pConfig->SapMacaddr_acl = pIe[6];
9147 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009148 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009149 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309150 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9151 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009152 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9153 for (i = 0; i < pConfig->num_deny_mac; i++)
9154 {
9155 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9156 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309157 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 }
9159 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9160 pBeacon->tail, pBeacon->tail_len);
9161
9162 /* pIe for white list is following form:
9163 type : 1 byte
9164 length : 1 byte
9165 OUI : 4 bytes
9166 acl type : 1 byte
9167 no of mac addr in white list: 1 byte
9168 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309169 */
9170 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009171 {
9172 pConfig->SapMacaddr_acl = pIe[6];
9173 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009174 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009175 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309176 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9177 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009178 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9179 for (i = 0; i < pConfig->num_accept_mac; i++)
9180 {
9181 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9182 acl_entry++;
9183 }
9184 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309185
Jeff Johnson295189b2012-06-20 16:38:30 -07009186 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9187
Jeff Johnsone7245742012-09-05 17:12:55 -07009188#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009189 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309190 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9191 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309192 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9193 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009194 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9195 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309196 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9197 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009198 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309199 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009200 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309201 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009202
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309203 /* If ACS disable and selected channel <= 14
9204 * OR
9205 * ACS enabled and ACS operating band is choosen as 2.4
9206 * AND
9207 * VHT in 2.4G Disabled
9208 * THEN
9209 * Fallback to 11N mode
9210 */
9211 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9212 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309213 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309214 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009215 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309216 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9217 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009218 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9219 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009220 }
9221#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309222
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 // ht_capab is not what the name conveys,this is used for protection bitmap
9224 pConfig->ht_capab =
9225 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9226
9227 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9228 {
9229 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9230 return -EINVAL;
9231 }
9232
9233 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309234 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009235 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9236 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309237 pConfig->obssProtEnabled =
9238 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009239
Chet Lanctot8cecea22014-02-11 19:09:36 -08009240#ifdef WLAN_FEATURE_11W
9241 pConfig->mfpCapable = MFPCapable;
9242 pConfig->mfpRequired = MFPRequired;
9243 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9244 pConfig->mfpCapable, pConfig->mfpRequired);
9245#endif
9246
Arif Hussain6d2a3322013-11-17 19:50:10 -08009247 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009248 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009249 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9250 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9251 (int)pConfig->channel);
9252 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9253 pConfig->SapHw_mode, pConfig->privacy,
9254 pConfig->authType);
9255 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9256 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9257 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9258 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009259
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309260 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009261 {
9262 //Bss already started. just return.
9263 //TODO Probably it should update some beacon params.
9264 hddLog( LOGE, "Bss Already started...Ignore the request");
9265 EXIT();
9266 return 0;
9267 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309268
Agarwal Ashish51325b52014-06-16 16:50:49 +05309269 if (vos_max_concurrent_connections_reached()) {
9270 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9271 return -EINVAL;
9272 }
9273
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 pConfig->persona = pHostapdAdapter->device_mode;
9275
Peng Xu2446a892014-09-05 17:21:18 +05309276 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9277 if ( NULL != psmeConfig)
9278 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309279 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309280 sme_GetConfigParam(hHal, psmeConfig);
9281 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309282#ifdef WLAN_FEATURE_AP_HT40_24G
9283 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9284 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9285 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9286 {
9287 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9288 sme_UpdateConfig (hHal, psmeConfig);
9289 }
9290#endif
Peng Xu2446a892014-09-05 17:21:18 +05309291 vos_mem_free(psmeConfig);
9292 }
Peng Xuafc34e32014-09-25 13:23:55 +05309293 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309294
Jeff Johnson295189b2012-06-20 16:38:30 -07009295 pSapEventCallback = hdd_hostapd_SAPEventCB;
9296 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9297 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9298 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009299 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009300 return -EINVAL;
9301 }
9302
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309303 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009304 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9305
9306 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309307
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309309 {
9310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009311 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009312 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 VOS_ASSERT(0);
9314 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309315
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309317 /* Initialize WMM configuation */
9318 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309319 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009320
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009321#ifdef WLAN_FEATURE_P2P_DEBUG
9322 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9323 {
9324 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9325 {
9326 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9327 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009328 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009329 }
9330 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9331 {
9332 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9333 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009334 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009335 }
9336 }
9337#endif
9338
Jeff Johnson295189b2012-06-20 16:38:30 -07009339 pHostapdState->bCommit = TRUE;
9340 EXIT();
9341
9342 return 0;
9343}
9344
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009345#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309346static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309347 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 struct beacon_parameters *params)
9349{
9350 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309351 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309352 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009353
9354 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309355
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309356 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9357 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9358 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309359 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9360 hdd_device_modetoString(pAdapter->device_mode),
9361 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009362
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309363 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9364 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309365 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009366 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309367 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009368 }
9369
Agarwal Ashish51325b52014-06-16 16:50:49 +05309370 if (vos_max_concurrent_connections_reached()) {
9371 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9372 return -EINVAL;
9373 }
9374
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309375 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 )
9378 {
9379 beacon_data_t *old,*new;
9380
9381 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309382
Jeff Johnson295189b2012-06-20 16:38:30 -07009383 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309384 {
9385 hddLog(VOS_TRACE_LEVEL_WARN,
9386 FL("already beacon info added to session(%d)"),
9387 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009388 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309389 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009390
9391 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9392
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309393 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 {
9395 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009396 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009397 return -EINVAL;
9398 }
9399
9400 pAdapter->sessionCtx.ap.beacon = new;
9401
9402 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9403 }
9404
9405 EXIT();
9406 return status;
9407}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309408
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309409static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9410 struct net_device *dev,
9411 struct beacon_parameters *params)
9412{
9413 int ret;
9414
9415 vos_ssr_protect(__func__);
9416 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9417 vos_ssr_unprotect(__func__);
9418
9419 return ret;
9420}
9421
9422static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 struct net_device *dev,
9424 struct beacon_parameters *params)
9425{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309426 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309427 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9428 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309429 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009430
9431 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309432
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309433 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9434 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9435 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9436 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9437 __func__, hdd_device_modetoString(pAdapter->device_mode),
9438 pAdapter->device_mode);
9439
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309440 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9441 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309442 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009443 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309444 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009445 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309446
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309449 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 {
9451 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309452
Jeff Johnson295189b2012-06-20 16:38:30 -07009453 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309454
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309456 {
9457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9458 FL("session(%d) old and new heads points to NULL"),
9459 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009460 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309461 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009462
9463 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9464
9465 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309466 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009467 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 return -EINVAL;
9469 }
9470
9471 pAdapter->sessionCtx.ap.beacon = new;
9472
9473 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9474 }
9475
9476 EXIT();
9477 return status;
9478}
9479
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309480static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9481 struct net_device *dev,
9482 struct beacon_parameters *params)
9483{
9484 int ret;
9485
9486 vos_ssr_protect(__func__);
9487 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9488 vos_ssr_unprotect(__func__);
9489
9490 return ret;
9491}
9492
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009493#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9494
9495#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309496static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009497 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009498#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309499static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009500 struct net_device *dev)
9501#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009502{
9503 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009504 hdd_context_t *pHddCtx = NULL;
9505 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309506 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309507 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009508
9509 ENTER();
9510
9511 if (NULL == pAdapter)
9512 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009514 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009515 return -ENODEV;
9516 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009517
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309518 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9519 TRACE_CODE_HDD_CFG80211_STOP_AP,
9520 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309521 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9522 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309523 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009524 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309525 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009526 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009527
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009528 pScanInfo = &pHddCtx->scan_info;
9529
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309530 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9531 __func__, hdd_device_modetoString(pAdapter->device_mode),
9532 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009533
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309534 ret = wlan_hdd_scan_abort(pAdapter);
9535
Girish Gowli4bf7a632014-06-12 13:42:11 +05309536 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009537 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9539 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309540
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309541 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009542 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9544 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009545
Jeff Johnsone7245742012-09-05 17:12:55 -07009546 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309547 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009548 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309549 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009550 }
9551
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309552 /* Delete all associated STAs before stopping AP/P2P GO */
9553 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309554 hdd_hostapd_stop(dev);
9555
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009557 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009558 )
9559 {
9560 beacon_data_t *old;
9561
9562 old = pAdapter->sessionCtx.ap.beacon;
9563
9564 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309565 {
9566 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9567 FL("session(%d) beacon data points to NULL"),
9568 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309570 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009571
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009573
9574 mutex_lock(&pHddCtx->sap_lock);
9575 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9576 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009577 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009578 {
9579 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9580
9581 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9582
9583 if (!VOS_IS_STATUS_SUCCESS(status))
9584 {
9585 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009586 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009587 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309588 }
9589 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309591 /* BSS stopped, clear the active sessions for this device mode */
9592 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 }
9594 mutex_unlock(&pHddCtx->sap_lock);
9595
9596 if(status != VOS_STATUS_SUCCESS)
9597 {
9598 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009599 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009600 return -EINVAL;
9601 }
9602
Jeff Johnson4416a782013-03-25 14:17:50 -07009603 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009604 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9605 ==eHAL_STATUS_FAILURE)
9606 {
9607 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009608 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 }
9610
Jeff Johnson4416a782013-03-25 14:17:50 -07009611 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009612 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9613 eANI_BOOLEAN_FALSE) )
9614 {
9615 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009616 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009617 }
9618
9619 // Reset WNI_CFG_PROBE_RSP Flags
9620 wlan_hdd_reset_prob_rspies(pAdapter);
9621
9622 pAdapter->sessionCtx.ap.beacon = NULL;
9623 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009624#ifdef WLAN_FEATURE_P2P_DEBUG
9625 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9626 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9627 {
9628 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9629 "GO got removed");
9630 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9631 }
9632#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009633 }
9634 EXIT();
9635 return status;
9636}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009637
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309638#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9639static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9640 struct net_device *dev)
9641{
9642 int ret;
9643
9644 vos_ssr_protect(__func__);
9645 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9646 vos_ssr_unprotect(__func__);
9647
9648 return ret;
9649}
9650#else
9651static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9652 struct net_device *dev)
9653{
9654 int ret;
9655
9656 vos_ssr_protect(__func__);
9657 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9658 vos_ssr_unprotect(__func__);
9659
9660 return ret;
9661}
9662#endif
9663
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009664#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9665
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309666static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309667 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009668 struct cfg80211_ap_settings *params)
9669{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309670 hdd_adapter_t *pAdapter;
9671 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309672 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009673
9674 ENTER();
9675
Girish Gowlib143d7a2015-02-18 19:39:55 +05309676 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009677 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309679 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309680 return -ENODEV;
9681 }
9682
9683 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9684 if (NULL == pAdapter)
9685 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309687 "%s: HDD adapter is Null", __func__);
9688 return -ENODEV;
9689 }
9690
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309691 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9692 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
9693 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309694 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9695 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309697 "%s: HDD adapter magic is invalid", __func__);
9698 return -ENODEV;
9699 }
9700
9701 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309702 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309703 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309704 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309705 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309706 }
9707
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309708 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
9709 __func__, hdd_device_modetoString(pAdapter->device_mode),
9710 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309711
9712 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009713 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009714 )
9715 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309716 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009717
9718 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309719
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009720 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309721 {
9722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9723 FL("already beacon info added to session(%d)"),
9724 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009725 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309726 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009727
Girish Gowlib143d7a2015-02-18 19:39:55 +05309728#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9729 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9730 &new,
9731 &params->beacon);
9732#else
9733 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9734 &new,
9735 &params->beacon,
9736 params->dtim_period);
9737#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009738
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309739 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009740 {
9741 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309742 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009743 return -EINVAL;
9744 }
9745 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08009746#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07009747 wlan_hdd_cfg80211_set_channel(wiphy, dev,
9748#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
9749 params->channel, params->channel_type);
9750#else
9751 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
9752#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08009753#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009754 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309755 params->ssid_len, params->hidden_ssid,
9756 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009757 }
9758
9759 EXIT();
9760 return status;
9761}
9762
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309763static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
9764 struct net_device *dev,
9765 struct cfg80211_ap_settings *params)
9766{
9767 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009768
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309769 vos_ssr_protect(__func__);
9770 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
9771 vos_ssr_unprotect(__func__);
9772
9773 return ret;
9774}
9775
9776static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009777 struct net_device *dev,
9778 struct cfg80211_beacon_data *params)
9779{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309780 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309781 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309782 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009783
9784 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309785
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309786 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9787 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
9788 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009789 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009790 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309791
9792 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9793 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309794 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009795 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309796 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009797 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009798
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309799 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009800 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309801 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009802 {
9803 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309804
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009805 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309806
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009807 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309808 {
9809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9810 FL("session(%d) beacon data points to NULL"),
9811 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009812 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309813 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009814
9815 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
9816
9817 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309818 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009819 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009820 return -EINVAL;
9821 }
9822
9823 pAdapter->sessionCtx.ap.beacon = new;
9824
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309825 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
9826 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009827 }
9828
9829 EXIT();
9830 return status;
9831}
9832
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309833static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
9834 struct net_device *dev,
9835 struct cfg80211_beacon_data *params)
9836{
9837 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009838
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309839 vos_ssr_protect(__func__);
9840 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
9841 vos_ssr_unprotect(__func__);
9842
9843 return ret;
9844}
9845
9846#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009847
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05309848static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 struct net_device *dev,
9850 struct bss_parameters *params)
9851{
9852 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309853 hdd_context_t *pHddCtx;
9854 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009855
9856 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309857
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309858 if (NULL == pAdapter)
9859 {
9860 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9861 "%s: HDD adapter is Null", __func__);
9862 return -ENODEV;
9863 }
9864 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309865 ret = wlan_hdd_validate_context(pHddCtx);
9866 if (0 != ret)
9867 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309868 return ret;
9869 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309870 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9871 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
9872 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309873 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9874 __func__, hdd_device_modetoString(pAdapter->device_mode),
9875 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009876
9877 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009878 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309879 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009880 {
9881 /* ap_isolate == -1 means that in change bss, upper layer doesn't
9882 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309883 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07009884 {
9885 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309886 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009887 }
9888
9889 EXIT();
9890 return 0;
9891}
9892
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05309893static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
9894 struct net_device *dev,
9895 struct bss_parameters *params)
9896{
9897 int ret;
9898
9899 vos_ssr_protect(__func__);
9900 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
9901 vos_ssr_unprotect(__func__);
9902
9903 return ret;
9904}
Kiet Lam10841362013-11-01 11:36:50 +05309905/* FUNCTION: wlan_hdd_change_country_code_cd
9906* to wait for contry code completion
9907*/
9908void* wlan_hdd_change_country_code_cb(void *pAdapter)
9909{
9910 hdd_adapter_t *call_back_pAdapter = pAdapter;
9911 complete(&call_back_pAdapter->change_country_code);
9912 return NULL;
9913}
9914
Jeff Johnson295189b2012-06-20 16:38:30 -07009915/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309916 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
9918 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309919int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 struct net_device *ndev,
9921 enum nl80211_iftype type,
9922 u32 *flags,
9923 struct vif_params *params
9924 )
9925{
9926 struct wireless_dev *wdev;
9927 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08009928 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07009929 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 tCsrRoamProfile *pRoamProfile = NULL;
9931 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309932 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 eMib_dot11DesiredBssType connectedBssType;
9934 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309935 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009936
9937 ENTER();
9938
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309939 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08009940 {
9941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9942 "%s: Adapter context is null", __func__);
9943 return VOS_STATUS_E_FAILURE;
9944 }
9945
9946 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9947 if (!pHddCtx)
9948 {
9949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9950 "%s: HDD context is null", __func__);
9951 return VOS_STATUS_E_FAILURE;
9952 }
9953
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309954 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9955 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
9956 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309957 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309958 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07009959 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309960 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009961 }
9962
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309963 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9964 __func__, hdd_device_modetoString(pAdapter->device_mode),
9965 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009966
Agarwal Ashish51325b52014-06-16 16:50:49 +05309967 if (vos_max_concurrent_connections_reached()) {
9968 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9969 return -EINVAL;
9970 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309971 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 wdev = ndev->ieee80211_ptr;
9973
9974#ifdef WLAN_BTAMP_FEATURE
9975 if((NL80211_IFTYPE_P2P_CLIENT == type)||
9976 (NL80211_IFTYPE_ADHOC == type)||
9977 (NL80211_IFTYPE_AP == type)||
9978 (NL80211_IFTYPE_P2P_GO == type))
9979 {
9980 pHddCtx->isAmpAllowed = VOS_FALSE;
9981 // stop AMP traffic
9982 status = WLANBAP_StopAmp();
9983 if(VOS_STATUS_SUCCESS != status )
9984 {
9985 pHddCtx->isAmpAllowed = VOS_TRUE;
9986 hddLog(VOS_TRACE_LEVEL_FATAL,
9987 "%s: Failed to stop AMP", __func__);
9988 return -EINVAL;
9989 }
9990 }
9991#endif //WLAN_BTAMP_FEATURE
9992 /* Reset the current device mode bit mask*/
9993 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
9994
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05309995 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
9996 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
9997 (type == NL80211_IFTYPE_P2P_GO)))
9998 {
9999 /* Notify Mode change in case of concurrency.
10000 * Below function invokes TDLS teardown Functionality Since TDLS is
10001 * not Supported in case of concurrency i.e Once P2P session
10002 * is detected disable offchannel and teardown TDLS links
10003 */
10004 hddLog(LOG1,
10005 FL("Device mode = %d Interface type = %d"),
10006 pAdapter->device_mode, type);
10007 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10008 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010009
Jeff Johnson295189b2012-06-20 16:38:30 -070010010 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010011 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010012 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010013 )
10014 {
10015 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010016 if (!pWextState)
10017 {
10018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10019 "%s: pWextState is null", __func__);
10020 return VOS_STATUS_E_FAILURE;
10021 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010022 pRoamProfile = &pWextState->roamProfile;
10023 LastBSSType = pRoamProfile->BSSType;
10024
10025 switch (type)
10026 {
10027 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010029 hddLog(VOS_TRACE_LEVEL_INFO,
10030 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10031 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010032#ifdef WLAN_FEATURE_11AC
10033 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10034 {
10035 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10036 }
10037#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010038 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010039 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010040 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010041 //Check for sub-string p2p to confirm its a p2p interface
10042 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010043 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010044#ifdef FEATURE_WLAN_TDLS
10045 mutex_lock(&pHddCtx->tdls_lock);
10046 wlan_hdd_tdls_exit(pAdapter, TRUE);
10047 mutex_unlock(&pHddCtx->tdls_lock);
10048#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010049 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10050 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10051 }
10052 else
10053 {
10054 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010055 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010056 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010057 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010058
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 case NL80211_IFTYPE_ADHOC:
10060 hddLog(VOS_TRACE_LEVEL_INFO,
10061 "%s: setting interface Type to ADHOC", __func__);
10062 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10063 pRoamProfile->phyMode =
10064 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010065 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010066 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010067 hdd_set_ibss_ops( pAdapter );
10068 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010069
10070 status = hdd_sta_id_hash_attach(pAdapter);
10071 if (VOS_STATUS_SUCCESS != status) {
10072 hddLog(VOS_TRACE_LEVEL_ERROR,
10073 FL("Failed to initialize hash for IBSS"));
10074 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010075 break;
10076
10077 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010078 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 {
10080 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10081 "%s: setting interface Type to %s", __func__,
10082 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10083
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010084 //Cancel any remain on channel for GO mode
10085 if (NL80211_IFTYPE_P2P_GO == type)
10086 {
10087 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10088 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010089 if (NL80211_IFTYPE_AP == type)
10090 {
10091 /* As Loading WLAN Driver one interface being created for p2p device
10092 * address. This will take one HW STA and the max number of clients
10093 * that can connect to softAP will be reduced by one. so while changing
10094 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10095 * interface as it is not required in SoftAP mode.
10096 */
10097
10098 // Get P2P Adapter
10099 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10100
10101 if (pP2pAdapter)
10102 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010103 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010104 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010105 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10106 }
10107 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010108 //Disable IMPS & BMPS for SAP/GO
10109 if(VOS_STATUS_E_FAILURE ==
10110 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10111 {
10112 //Fail to Exit BMPS
10113 VOS_ASSERT(0);
10114 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010115
10116 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10117
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010118#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010119
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010120 /* A Mutex Lock is introduced while changing the mode to
10121 * protect the concurrent access for the Adapters by TDLS
10122 * module.
10123 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010124 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010125#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010127 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010128 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010129 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10130 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010131#ifdef FEATURE_WLAN_TDLS
10132 mutex_unlock(&pHddCtx->tdls_lock);
10133#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010134 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10135 (pConfig->apRandomBssidEnabled))
10136 {
10137 /* To meet Android requirements create a randomized
10138 MAC address of the form 02:1A:11:Fx:xx:xx */
10139 get_random_bytes(&ndev->dev_addr[3], 3);
10140 ndev->dev_addr[0] = 0x02;
10141 ndev->dev_addr[1] = 0x1A;
10142 ndev->dev_addr[2] = 0x11;
10143 ndev->dev_addr[3] |= 0xF0;
10144 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10145 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010146 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10147 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010148 }
10149
Jeff Johnson295189b2012-06-20 16:38:30 -070010150 hdd_set_ap_ops( pAdapter->dev );
10151
Kiet Lam10841362013-11-01 11:36:50 +053010152 /* This is for only SAP mode where users can
10153 * control country through ini.
10154 * P2P GO follows station country code
10155 * acquired during the STA scanning. */
10156 if((NL80211_IFTYPE_AP == type) &&
10157 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10158 {
10159 int status = 0;
10160 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10161 "%s: setting country code from INI ", __func__);
10162 init_completion(&pAdapter->change_country_code);
10163 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10164 (void *)(tSmeChangeCountryCallback)
10165 wlan_hdd_change_country_code_cb,
10166 pConfig->apCntryCode, pAdapter,
10167 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010168 eSIR_FALSE,
10169 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010170 if (eHAL_STATUS_SUCCESS == status)
10171 {
10172 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010173 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010174 &pAdapter->change_country_code,
10175 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010176 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010177 {
10178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010179 FL("SME Timed out while setting country code %ld"),
10180 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010181
10182 if (pHddCtx->isLogpInProgress)
10183 {
10184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10185 "%s: LOGP in Progress. Ignore!!!", __func__);
10186 return -EAGAIN;
10187 }
Kiet Lam10841362013-11-01 11:36:50 +053010188 }
10189 }
10190 else
10191 {
10192 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010193 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010194 return -EINVAL;
10195 }
10196 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010197 status = hdd_init_ap_mode(pAdapter);
10198 if(status != VOS_STATUS_SUCCESS)
10199 {
10200 hddLog(VOS_TRACE_LEVEL_FATAL,
10201 "%s: Error initializing the ap mode", __func__);
10202 return -EINVAL;
10203 }
10204 hdd_set_conparam(1);
10205
Nirav Shah7e3c8132015-06-22 23:51:42 +053010206 status = hdd_sta_id_hash_attach(pAdapter);
10207 if (VOS_STATUS_SUCCESS != status)
10208 {
10209 hddLog(VOS_TRACE_LEVEL_ERROR,
10210 FL("Failed to initialize hash for AP"));
10211 return -EINVAL;
10212 }
10213
Jeff Johnson295189b2012-06-20 16:38:30 -070010214 /*interface type changed update in wiphy structure*/
10215 if(wdev)
10216 {
10217 wdev->iftype = type;
10218 pHddCtx->change_iface = type;
10219 }
10220 else
10221 {
10222 hddLog(VOS_TRACE_LEVEL_ERROR,
10223 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10224 return -EINVAL;
10225 }
10226 goto done;
10227 }
10228
10229 default:
10230 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10231 __func__);
10232 return -EOPNOTSUPP;
10233 }
10234 }
10235 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010236 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010237 )
10238 {
10239 switch(type)
10240 {
10241 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010242 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010243 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010244
10245 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010246#ifdef FEATURE_WLAN_TDLS
10247
10248 /* A Mutex Lock is introduced while changing the mode to
10249 * protect the concurrent access for the Adapters by TDLS
10250 * module.
10251 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010252 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010253#endif
c_hpothu002231a2015-02-05 14:58:51 +053010254 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010255 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010256 //Check for sub-string p2p to confirm its a p2p interface
10257 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010258 {
10259 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10260 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10261 }
10262 else
10263 {
10264 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010265 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010266 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010267 hdd_set_conparam(0);
10268 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010269 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10270 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010271#ifdef FEATURE_WLAN_TDLS
10272 mutex_unlock(&pHddCtx->tdls_lock);
10273#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010274 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010275 if( VOS_STATUS_SUCCESS != status )
10276 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010277 /* In case of JB, for P2P-GO, only change interface will be called,
10278 * This is the right place to enable back bmps_imps()
10279 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010280 if (pHddCtx->hdd_wlan_suspended)
10281 {
10282 hdd_set_pwrparams(pHddCtx);
10283 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010284 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010285 goto done;
10286 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010287 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010289 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10290 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010291 goto done;
10292 default:
10293 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10294 __func__);
10295 return -EOPNOTSUPP;
10296
10297 }
10298
10299 }
10300 else
10301 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010302 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10303 __func__, hdd_device_modetoString(pAdapter->device_mode),
10304 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010305 return -EOPNOTSUPP;
10306 }
10307
10308
10309 if(pRoamProfile)
10310 {
10311 if ( LastBSSType != pRoamProfile->BSSType )
10312 {
10313 /*interface type changed update in wiphy structure*/
10314 wdev->iftype = type;
10315
10316 /*the BSS mode changed, We need to issue disconnect
10317 if connected or in IBSS disconnect state*/
10318 if ( hdd_connGetConnectedBssType(
10319 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10320 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10321 {
10322 /*need to issue a disconnect to CSR.*/
10323 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10324 if( eHAL_STATUS_SUCCESS ==
10325 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10326 pAdapter->sessionId,
10327 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10328 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010329 ret = wait_for_completion_interruptible_timeout(
10330 &pAdapter->disconnect_comp_var,
10331 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10332 if (ret <= 0)
10333 {
10334 hddLog(VOS_TRACE_LEVEL_ERROR,
10335 FL("wait on disconnect_comp_var failed %ld"), ret);
10336 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010337 }
10338 }
10339 }
10340 }
10341
10342done:
10343 /*set bitmask based on updated value*/
10344 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010345
10346 /* Only STA mode support TM now
10347 * all other mode, TM feature should be disabled */
10348 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10349 (~VOS_STA & pHddCtx->concurrency_mode) )
10350 {
10351 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10352 }
10353
Jeff Johnson295189b2012-06-20 16:38:30 -070010354#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010355 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010356 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010357 {
10358 //we are ok to do AMP
10359 pHddCtx->isAmpAllowed = VOS_TRUE;
10360 }
10361#endif //WLAN_BTAMP_FEATURE
10362 EXIT();
10363 return 0;
10364}
10365
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010366/*
10367 * FUNCTION: wlan_hdd_cfg80211_change_iface
10368 * wrapper function to protect the actual implementation from SSR.
10369 */
10370int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10371 struct net_device *ndev,
10372 enum nl80211_iftype type,
10373 u32 *flags,
10374 struct vif_params *params
10375 )
10376{
10377 int ret;
10378
10379 vos_ssr_protect(__func__);
10380 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10381 vos_ssr_unprotect(__func__);
10382
10383 return ret;
10384}
10385
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010386#ifdef FEATURE_WLAN_TDLS
10387static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010388 struct net_device *dev,
10389#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10390 const u8 *mac,
10391#else
10392 u8 *mac,
10393#endif
10394 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010395{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010396 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010397 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010398 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010399 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010400 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010401 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010402
10403 ENTER();
10404
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010405 if (!dev) {
10406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10407 return -EINVAL;
10408 }
10409
10410 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10411 if (!pAdapter) {
10412 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10413 return -EINVAL;
10414 }
10415
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010416 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010417 {
10418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10419 "Invalid arguments");
10420 return -EINVAL;
10421 }
Hoonki Lee27511902013-03-14 18:19:06 -070010422
10423 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10424 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10425 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010426 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010427 "%s: TDLS mode is disabled OR not enabled in FW."
10428 MAC_ADDRESS_STR " Request declined.",
10429 __func__, MAC_ADDR_ARRAY(mac));
10430 return -ENOTSUPP;
10431 }
10432
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010433 if (pHddCtx->isLogpInProgress)
10434 {
10435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10436 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010437 wlan_hdd_tdls_set_link_status(pAdapter,
10438 mac,
10439 eTDLS_LINK_IDLE,
10440 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010441 return -EBUSY;
10442 }
10443
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010444 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010445 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010446
10447 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010449 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10450 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010451 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010452 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010453 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010454
10455 /* in add station, we accept existing valid staId if there is */
10456 if ((0 == update) &&
10457 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10458 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010459 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010461 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010462 " link_status %d. staId %d. add station ignored.",
10463 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010464 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010465 return 0;
10466 }
10467 /* in change station, we accept only when staId is valid */
10468 if ((1 == update) &&
10469 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10470 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10471 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010472 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010473 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010474 "%s: " MAC_ADDRESS_STR
10475 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010476 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10477 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10478 mutex_unlock(&pHddCtx->tdls_lock);
10479 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010480 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010481 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010482
10483 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010484 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010485 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10487 "%s: " MAC_ADDRESS_STR
10488 " TDLS setup is ongoing. Request declined.",
10489 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010490 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010491 }
10492
10493 /* first to check if we reached to maximum supported TDLS peer.
10494 TODO: for now, return -EPERM looks working fine,
10495 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010496 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10497 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010498 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010499 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10500 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010501 " TDLS Max peer already connected. Request declined."
10502 " Num of peers (%d), Max allowed (%d).",
10503 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10504 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010505 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010506 }
10507 else
10508 {
10509 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010510 mutex_lock(&pHddCtx->tdls_lock);
10511 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010512 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010513 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010514 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10516 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10517 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010518 return -EPERM;
10519 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010520 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010521 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010522 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010523 wlan_hdd_tdls_set_link_status(pAdapter,
10524 mac,
10525 eTDLS_LINK_CONNECTING,
10526 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010527
Jeff Johnsond75fe012013-04-06 10:53:06 -070010528 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010529 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010530 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010532 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010533 if(StaParams->htcap_present)
10534 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010536 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010538 "ht_capa->extended_capabilities: %0x",
10539 StaParams->HTCap.extendedHtCapInfo);
10540 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010542 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010544 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010545 if(StaParams->vhtcap_present)
10546 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010548 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10549 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10550 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10551 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010552 {
10553 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010555 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010557 "[%d]: %x ", i, StaParams->supported_rates[i]);
10558 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010559 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010560 else if ((1 == update) && (NULL == StaParams))
10561 {
10562 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10563 "%s : update is true, but staParams is NULL. Error!", __func__);
10564 return -EPERM;
10565 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010566
10567 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10568
10569 if (!update)
10570 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010571 /*Before adding sta make sure that device exited from BMPS*/
10572 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10573 {
10574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10575 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10576 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10577 if (status != VOS_STATUS_SUCCESS) {
10578 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10579 }
10580 }
10581
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010582 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010583 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010584 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010585 hddLog(VOS_TRACE_LEVEL_ERROR,
10586 FL("Failed to add TDLS peer STA. Enable Bmps"));
10587 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010588 return -EPERM;
10589 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010590 }
10591 else
10592 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010593 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010594 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010595 if (ret != eHAL_STATUS_SUCCESS) {
10596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10597 return -EPERM;
10598 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010599 }
10600
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010601 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010602 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10603
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010604 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010605 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010607 "%s: timeout waiting for tdls add station indication %ld",
10608 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010609 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010610 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010611
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010612 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10613 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010615 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010616 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010617 }
10618
10619 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010620
10621error:
Atul Mittal115287b2014-07-08 13:26:33 +053010622 wlan_hdd_tdls_set_link_status(pAdapter,
10623 mac,
10624 eTDLS_LINK_IDLE,
10625 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010626 return -EPERM;
10627
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010628}
10629#endif
10630
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010631static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010632 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010633#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10634 const u8 *mac,
10635#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010636 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010637#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010638 struct station_parameters *params)
10639{
10640 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010641 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010642 hdd_context_t *pHddCtx;
10643 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010644 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010645 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010646#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010647 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010648 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010649 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010650#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010651
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010652 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010653
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010654 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010655 if ((NULL == pAdapter))
10656 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010658 "invalid adapter ");
10659 return -EINVAL;
10660 }
10661
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010662 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10663 TRACE_CODE_HDD_CHANGE_STATION,
10664 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010665 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010666
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010667 ret = wlan_hdd_validate_context(pHddCtx);
10668 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053010669 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010670 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010671 }
10672
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010673 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10674
10675 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010676 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10678 "invalid HDD station context");
10679 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010680 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010681 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
10682
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010683 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10684 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070010685 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010686 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070010687 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010688 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070010689 WLANTL_STA_AUTHENTICATED);
10690
Gopichand Nakkala29149562013-05-10 21:43:41 +053010691 if (status != VOS_STATUS_SUCCESS)
10692 {
10693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10694 "%s: Not able to change TL state to AUTHENTICATED", __func__);
10695 return -EINVAL;
10696 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010697 }
10698 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070010699 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
10700 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010701#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010702 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
10703 StaParams.capability = params->capability;
10704 StaParams.uapsd_queues = params->uapsd_queues;
10705 StaParams.max_sp = params->max_sp;
10706
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010707 /* Convert (first channel , number of channels) tuple to
10708 * the total list of channels. This goes with the assumption
10709 * that if the first channel is < 14, then the next channels
10710 * are an incremental of 1 else an incremental of 4 till the number
10711 * of channels.
10712 */
10713 if (0 != params->supported_channels_len) {
10714 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
10715 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
10716 {
10717 int wifi_chan_index;
10718 StaParams.supported_channels[j] = params->supported_channels[i];
10719 wifi_chan_index =
10720 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
10721 no_of_channels = params->supported_channels[i+1];
10722 for(k=1; k <= no_of_channels; k++)
10723 {
10724 StaParams.supported_channels[j+1] =
10725 StaParams.supported_channels[j] + wifi_chan_index;
10726 j+=1;
10727 }
10728 }
10729 StaParams.supported_channels_len = j;
10730 }
10731 vos_mem_copy(StaParams.supported_oper_classes,
10732 params->supported_oper_classes,
10733 params->supported_oper_classes_len);
10734 StaParams.supported_oper_classes_len =
10735 params->supported_oper_classes_len;
10736
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010737 if (0 != params->ext_capab_len)
10738 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
10739 sizeof(StaParams.extn_capability));
10740
10741 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070010742 {
10743 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010744 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070010745 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010746
10747 StaParams.supported_rates_len = params->supported_rates_len;
10748
10749 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
10750 * The supported_rates array , for all the structures propogating till Add Sta
10751 * to the firmware has to be modified , if the supplicant (ieee80211) is
10752 * modified to send more rates.
10753 */
10754
10755 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
10756 */
10757 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
10758 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
10759
10760 if (0 != StaParams.supported_rates_len) {
10761 int i = 0;
10762 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
10763 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010765 "Supported Rates with Length %d", StaParams.supported_rates_len);
10766 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010768 "[%d]: %0x", i, StaParams.supported_rates[i]);
10769 }
10770
10771 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070010772 {
10773 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010774 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070010775 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010776
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010777 if (0 != params->ext_capab_len ) {
10778 /*Define A Macro : TODO Sunil*/
10779 if ((1<<4) & StaParams.extn_capability[3]) {
10780 isBufSta = 1;
10781 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010782 /* TDLS Channel Switching Support */
10783 if ((1<<6) & StaParams.extn_capability[3]) {
10784 isOffChannelSupported = 1;
10785 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010786 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010787 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
10788 &StaParams, isBufSta,
10789 isOffChannelSupported);
10790
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053010791 if (VOS_STATUS_SUCCESS != status) {
10792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10793 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
10794 return -EINVAL;
10795 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010796 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
10797
10798 if (VOS_STATUS_SUCCESS != status) {
10799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10800 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
10801 return -EINVAL;
10802 }
10803 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010804#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053010805 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010806 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010807 return status;
10808}
10809
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010810#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
10811static int wlan_hdd_change_station(struct wiphy *wiphy,
10812 struct net_device *dev,
10813 const u8 *mac,
10814 struct station_parameters *params)
10815#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010816static int wlan_hdd_change_station(struct wiphy *wiphy,
10817 struct net_device *dev,
10818 u8 *mac,
10819 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010820#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010821{
10822 int ret;
10823
10824 vos_ssr_protect(__func__);
10825 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
10826 vos_ssr_unprotect(__func__);
10827
10828 return ret;
10829}
10830
Jeff Johnson295189b2012-06-20 16:38:30 -070010831/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010832 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010833 * This function is used to initialize the key information
10834 */
10835#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010836static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010837 struct net_device *ndev,
10838 u8 key_index, bool pairwise,
10839 const u8 *mac_addr,
10840 struct key_params *params
10841 )
10842#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010843static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010844 struct net_device *ndev,
10845 u8 key_index, const u8 *mac_addr,
10846 struct key_params *params
10847 )
10848#endif
10849{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010850 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070010851 tCsrRoamSetKey setKey;
10852 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010853 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010854 v_U32_t roamId= 0xFF;
10855 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010856 hdd_hostapd_state_t *pHostapdState;
10857 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010858 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010859 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010860
10861 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010862
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010863 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10864 TRACE_CODE_HDD_CFG80211_ADD_KEY,
10865 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010866 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10867 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010868 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010869 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010870 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010871 }
10872
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010873 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10874 __func__, hdd_device_modetoString(pAdapter->device_mode),
10875 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010876
10877 if (CSR_MAX_NUM_KEY <= key_index)
10878 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010879 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010880 key_index);
10881
10882 return -EINVAL;
10883 }
10884
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010885 if (CSR_MAX_KEY_LEN < params->key_len)
10886 {
10887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
10888 params->key_len);
10889
10890 return -EINVAL;
10891 }
10892
10893 hddLog(VOS_TRACE_LEVEL_INFO,
10894 "%s: called with key index = %d & key length %d",
10895 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070010896
10897 /*extract key idx, key len and key*/
10898 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10899 setKey.keyId = key_index;
10900 setKey.keyLength = params->key_len;
10901 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
10902
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010903 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070010904 {
10905 case WLAN_CIPHER_SUITE_WEP40:
10906 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
10907 break;
10908
10909 case WLAN_CIPHER_SUITE_WEP104:
10910 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
10911 break;
10912
10913 case WLAN_CIPHER_SUITE_TKIP:
10914 {
10915 u8 *pKey = &setKey.Key[0];
10916 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
10917
10918 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
10919
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010920 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070010921
10922 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010923 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070010924 |--------------|----------|----------|
10925 <---16bytes---><--8bytes--><--8bytes-->
10926
10927 */
10928 /*Sme expects the 32 bytes key to be in the below order
10929
10930 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010931 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070010932 |--------------|----------|----------|
10933 <---16bytes---><--8bytes--><--8bytes-->
10934 */
10935 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010936 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070010937
10938 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010939 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070010940
10941 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010942 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070010943
10944
10945 break;
10946 }
10947
10948 case WLAN_CIPHER_SUITE_CCMP:
10949 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
10950 break;
10951
10952#ifdef FEATURE_WLAN_WAPI
10953 case WLAN_CIPHER_SUITE_SMS4:
10954 {
10955 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10956 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
10957 params->key, params->key_len);
10958 return 0;
10959 }
10960#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070010961
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010962#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010963 case WLAN_CIPHER_SUITE_KRK:
10964 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
10965 break;
10966#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070010967
10968#ifdef WLAN_FEATURE_11W
10969 case WLAN_CIPHER_SUITE_AES_CMAC:
10970 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070010971 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070010972#endif
10973
Jeff Johnson295189b2012-06-20 16:38:30 -070010974 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010976 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010977 status = -EOPNOTSUPP;
10978 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 }
10980
10981 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
10982 __func__, setKey.encType);
10983
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010984 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070010985#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10986 (!pairwise)
10987#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010988 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070010989#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010990 )
10991 {
10992 /* set group key*/
10993 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10994 "%s- %d: setting Broadcast key",
10995 __func__, __LINE__);
10996 setKey.keyDirection = eSIR_RX_ONLY;
10997 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
10998 }
10999 else
11000 {
11001 /* set pairwise key*/
11002 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11003 "%s- %d: setting pairwise key",
11004 __func__, __LINE__);
11005 setKey.keyDirection = eSIR_TX_RX;
11006 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11007 }
11008 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11009 {
11010 setKey.keyDirection = eSIR_TX_RX;
11011 /*Set the group key*/
11012 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11013 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011014
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011015 if ( 0 != status )
11016 {
11017 hddLog(VOS_TRACE_LEVEL_ERROR,
11018 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011019 status = -EINVAL;
11020 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011021 }
11022 /*Save the keys here and call sme_RoamSetKey for setting
11023 the PTK after peer joins the IBSS network*/
11024 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11025 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011026 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011027 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011028 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11029 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11030 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011031 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011032 if( pHostapdState->bssState == BSS_START )
11033 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011034 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11035 vos_status = wlan_hdd_check_ula_done(pAdapter);
11036
11037 if ( vos_status != VOS_STATUS_SUCCESS )
11038 {
11039 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11040 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11041 __LINE__, vos_status );
11042
11043 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11044
11045 status = -EINVAL;
11046 goto end;
11047 }
11048
Jeff Johnson295189b2012-06-20 16:38:30 -070011049 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11050
11051 if ( status != eHAL_STATUS_SUCCESS )
11052 {
11053 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11054 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11055 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011056 status = -EINVAL;
11057 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011058 }
11059 }
11060
11061 /* Saving WEP keys */
11062 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11063 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11064 {
11065 //Save the wep key in ap context. Issue setkey after the BSS is started.
11066 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11067 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11068 }
11069 else
11070 {
11071 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011072 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011073 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11074 }
11075 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011076 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11077 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011078 {
11079 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11080 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11081
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011082#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11083 if (!pairwise)
11084#else
11085 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11086#endif
11087 {
11088 /* set group key*/
11089 if (pHddStaCtx->roam_info.deferKeyComplete)
11090 {
11091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11092 "%s- %d: Perform Set key Complete",
11093 __func__, __LINE__);
11094 hdd_PerformRoamSetKeyComplete(pAdapter);
11095 }
11096 }
11097
Jeff Johnson295189b2012-06-20 16:38:30 -070011098 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11099
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011100 pWextState->roamProfile.Keys.defaultIndex = key_index;
11101
11102
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011103 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011104 params->key, params->key_len);
11105
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011106
Jeff Johnson295189b2012-06-20 16:38:30 -070011107 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11108
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011109 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011110 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011111 __func__, setKey.peerMac[0], setKey.peerMac[1],
11112 setKey.peerMac[2], setKey.peerMac[3],
11113 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011114 setKey.keyDirection);
11115
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011116 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011117
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011118 if ( vos_status != VOS_STATUS_SUCCESS )
11119 {
11120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011121 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11122 __LINE__, vos_status );
11123
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011124 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011125
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011126 status = -EINVAL;
11127 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011128
11129 }
11130
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011131#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011132 /* The supplicant may attempt to set the PTK once pre-authentication
11133 is done. Save the key in the UMAC and include it in the ADD BSS
11134 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011135 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011136 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011137 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011138 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11139 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011140 status = 0;
11141 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011142 }
11143 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11144 {
11145 hddLog(VOS_TRACE_LEVEL_ERROR,
11146 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011147 status = -EINVAL;
11148 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011149 }
11150#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011151
11152 /* issue set key request to SME*/
11153 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11154 pAdapter->sessionId, &setKey, &roamId );
11155
11156 if ( 0 != status )
11157 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011158 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11160 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011161 status = -EINVAL;
11162 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 }
11164
11165
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011166 /* in case of IBSS as there was no information available about WEP keys during
11167 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011168 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011169 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11170 !( ( IW_AUTH_KEY_MGMT_802_1X
11171 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11173 )
11174 &&
11175 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11176 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11177 )
11178 )
11179 {
11180 setKey.keyDirection = eSIR_RX_ONLY;
11181 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11182
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011183 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011184 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011185 __func__, setKey.peerMac[0], setKey.peerMac[1],
11186 setKey.peerMac[2], setKey.peerMac[3],
11187 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011188 setKey.keyDirection);
11189
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011190 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011191 pAdapter->sessionId, &setKey, &roamId );
11192
11193 if ( 0 != status )
11194 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011195 hddLog(VOS_TRACE_LEVEL_ERROR,
11196 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011197 __func__, status);
11198 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011199 status = -EINVAL;
11200 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011201 }
11202 }
11203 }
11204
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011205end:
11206 /* Need to clear any trace of key value in the memory.
11207 * Thus zero out the memory even though it is local
11208 * variable.
11209 */
11210 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011211 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011212 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011213}
11214
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11216static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11217 struct net_device *ndev,
11218 u8 key_index, bool pairwise,
11219 const u8 *mac_addr,
11220 struct key_params *params
11221 )
11222#else
11223static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11224 struct net_device *ndev,
11225 u8 key_index, const u8 *mac_addr,
11226 struct key_params *params
11227 )
11228#endif
11229{
11230 int ret;
11231 vos_ssr_protect(__func__);
11232#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11233 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11234 mac_addr, params);
11235#else
11236 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11237 params);
11238#endif
11239 vos_ssr_unprotect(__func__);
11240
11241 return ret;
11242}
11243
Jeff Johnson295189b2012-06-20 16:38:30 -070011244/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011245 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011246 * This function is used to get the key information
11247 */
11248#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011249static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011250 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011252 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 const u8 *mac_addr, void *cookie,
11254 void (*callback)(void *cookie, struct key_params*)
11255 )
11256#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011257static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011258 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011259 struct net_device *ndev,
11260 u8 key_index, const u8 *mac_addr, void *cookie,
11261 void (*callback)(void *cookie, struct key_params*)
11262 )
11263#endif
11264{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011265 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011266 hdd_wext_state_t *pWextState = NULL;
11267 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011268 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011269 hdd_context_t *pHddCtx;
11270 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011271
11272 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011273
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011274 if (NULL == pAdapter)
11275 {
11276 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11277 "%s: HDD adapter is Null", __func__);
11278 return -ENODEV;
11279 }
11280
11281 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11282 ret = wlan_hdd_validate_context(pHddCtx);
11283 if (0 != ret)
11284 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011285 return ret;
11286 }
11287
11288 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11289 pRoamProfile = &(pWextState->roamProfile);
11290
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011291 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11292 __func__, hdd_device_modetoString(pAdapter->device_mode),
11293 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011294
Jeff Johnson295189b2012-06-20 16:38:30 -070011295 memset(&params, 0, sizeof(params));
11296
11297 if (CSR_MAX_NUM_KEY <= key_index)
11298 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011299 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011300 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011301 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011302
11303 switch(pRoamProfile->EncryptionType.encryptionType[0])
11304 {
11305 case eCSR_ENCRYPT_TYPE_NONE:
11306 params.cipher = IW_AUTH_CIPHER_NONE;
11307 break;
11308
11309 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11310 case eCSR_ENCRYPT_TYPE_WEP40:
11311 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11312 break;
11313
11314 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11315 case eCSR_ENCRYPT_TYPE_WEP104:
11316 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11317 break;
11318
11319 case eCSR_ENCRYPT_TYPE_TKIP:
11320 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11321 break;
11322
11323 case eCSR_ENCRYPT_TYPE_AES:
11324 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11325 break;
11326
11327 default:
11328 params.cipher = IW_AUTH_CIPHER_NONE;
11329 break;
11330 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011331
c_hpothuaaf19692014-05-17 17:01:48 +053011332 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11333 TRACE_CODE_HDD_CFG80211_GET_KEY,
11334 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011335
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11337 params.seq_len = 0;
11338 params.seq = NULL;
11339 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11340 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011341 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011342 return 0;
11343}
11344
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011345#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11346static int wlan_hdd_cfg80211_get_key(
11347 struct wiphy *wiphy,
11348 struct net_device *ndev,
11349 u8 key_index, bool pairwise,
11350 const u8 *mac_addr, void *cookie,
11351 void (*callback)(void *cookie, struct key_params*)
11352 )
11353#else
11354static int wlan_hdd_cfg80211_get_key(
11355 struct wiphy *wiphy,
11356 struct net_device *ndev,
11357 u8 key_index, const u8 *mac_addr, void *cookie,
11358 void (*callback)(void *cookie, struct key_params*)
11359 )
11360#endif
11361{
11362 int ret;
11363
11364 vos_ssr_protect(__func__);
11365#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11366 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11367 mac_addr, cookie, callback);
11368#else
11369 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11370 callback);
11371#endif
11372 vos_ssr_unprotect(__func__);
11373
11374 return ret;
11375}
11376
Jeff Johnson295189b2012-06-20 16:38:30 -070011377/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011378 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011379 * This function is used to delete the key information
11380 */
11381#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011382static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011383 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011384 u8 key_index,
11385 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011386 const u8 *mac_addr
11387 )
11388#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011389static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011390 struct net_device *ndev,
11391 u8 key_index,
11392 const u8 *mac_addr
11393 )
11394#endif
11395{
11396 int status = 0;
11397
11398 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011399 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 //it is observed that this is invalidating peer
11401 //key index whenever re-key is done. This is affecting data link.
11402 //It should be ok to ignore del_key.
11403#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011404 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11405 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11407 tCsrRoamSetKey setKey;
11408 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011409
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 ENTER();
11411
11412 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11413 __func__,pAdapter->device_mode);
11414
11415 if (CSR_MAX_NUM_KEY <= key_index)
11416 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011417 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011418 key_index);
11419
11420 return -EINVAL;
11421 }
11422
11423 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11424 setKey.keyId = key_index;
11425
11426 if (mac_addr)
11427 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11428 else
11429 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11430
11431 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11432
11433 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011434 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011435 )
11436 {
11437
11438 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011439 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11440 if( pHostapdState->bssState == BSS_START)
11441 {
11442 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011443
Jeff Johnson295189b2012-06-20 16:38:30 -070011444 if ( status != eHAL_STATUS_SUCCESS )
11445 {
11446 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11447 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11448 __LINE__, status );
11449 }
11450 }
11451 }
11452 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011453 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011454 )
11455 {
11456 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11457
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011458 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11459
11460 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011461 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011462 __func__, setKey.peerMac[0], setKey.peerMac[1],
11463 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011464 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011465 if(pAdapter->sessionCtx.station.conn_info.connState ==
11466 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011468 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011470
Jeff Johnson295189b2012-06-20 16:38:30 -070011471 if ( 0 != status )
11472 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011473 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 "%s: sme_RoamSetKey failure, returned %d",
11475 __func__, status);
11476 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11477 return -EINVAL;
11478 }
11479 }
11480 }
11481#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011482 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011483 return status;
11484}
11485
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011486#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11487static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11488 struct net_device *ndev,
11489 u8 key_index,
11490 bool pairwise,
11491 const u8 *mac_addr
11492 )
11493#else
11494static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11495 struct net_device *ndev,
11496 u8 key_index,
11497 const u8 *mac_addr
11498 )
11499#endif
11500{
11501 int ret;
11502
11503 vos_ssr_protect(__func__);
11504#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11505 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11506 mac_addr);
11507#else
11508 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11509#endif
11510 vos_ssr_unprotect(__func__);
11511
11512 return ret;
11513}
11514
Jeff Johnson295189b2012-06-20 16:38:30 -070011515/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011516 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011517 * This function is used to set the default tx key index
11518 */
11519#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011520static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011521 struct net_device *ndev,
11522 u8 key_index,
11523 bool unicast, bool multicast)
11524#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011525static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011526 struct net_device *ndev,
11527 u8 key_index)
11528#endif
11529{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011530 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011531 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011532 hdd_wext_state_t *pWextState;
11533 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011534 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011535
11536 ENTER();
11537
Gopichand Nakkala29149562013-05-10 21:43:41 +053011538 if ((NULL == pAdapter))
11539 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011541 "invalid adapter");
11542 return -EINVAL;
11543 }
11544
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011545 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11546 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11547 pAdapter->sessionId, key_index));
11548
Gopichand Nakkala29149562013-05-10 21:43:41 +053011549 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11550 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11551
11552 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11553 {
11554 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11555 "invalid Wext state or HDD context");
11556 return -EINVAL;
11557 }
11558
Arif Hussain6d2a3322013-11-17 19:50:10 -080011559 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011560 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011561
Jeff Johnson295189b2012-06-20 16:38:30 -070011562 if (CSR_MAX_NUM_KEY <= key_index)
11563 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011564 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011565 key_index);
11566
11567 return -EINVAL;
11568 }
11569
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011570 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11571 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011572 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011573 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011574 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011575 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011576
Jeff Johnson295189b2012-06-20 16:38:30 -070011577 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011579 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011580 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011581 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011582 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011583 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011584 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011585 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011586 {
11587 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011588 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011589
Jeff Johnson295189b2012-06-20 16:38:30 -070011590 tCsrRoamSetKey setKey;
11591 v_U32_t roamId= 0xFF;
11592 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011593
11594 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011595 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011596
Jeff Johnson295189b2012-06-20 16:38:30 -070011597 Keys->defaultIndex = (u8)key_index;
11598 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11599 setKey.keyId = key_index;
11600 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011601
11602 vos_mem_copy(&setKey.Key[0],
11603 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011604 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011605
Gopichand Nakkala29149562013-05-10 21:43:41 +053011606 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011607
11608 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011609 &pHddStaCtx->conn_info.bssId[0],
11610 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011611
Gopichand Nakkala29149562013-05-10 21:43:41 +053011612 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11613 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11614 eCSR_ENCRYPT_TYPE_WEP104)
11615 {
11616 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11617 even though ap is configured for WEP-40 encryption. In this canse the key length
11618 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11619 type(104) and switching encryption type to 40*/
11620 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11621 eCSR_ENCRYPT_TYPE_WEP40;
11622 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11623 eCSR_ENCRYPT_TYPE_WEP40;
11624 }
11625
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011626 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011627 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011628
Jeff Johnson295189b2012-06-20 16:38:30 -070011629 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011630 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011631 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011632
Jeff Johnson295189b2012-06-20 16:38:30 -070011633 if ( 0 != status )
11634 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011635 hddLog(VOS_TRACE_LEVEL_ERROR,
11636 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011637 status);
11638 return -EINVAL;
11639 }
11640 }
11641 }
11642
11643 /* In SoftAp mode setting key direction for default mode */
11644 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11645 {
11646 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11647 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11648 (eCSR_ENCRYPT_TYPE_AES !=
11649 pWextState->roamProfile.EncryptionType.encryptionType[0])
11650 )
11651 {
11652 /* Saving key direction for default key index to TX default */
11653 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11654 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11655 }
11656 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011657 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011658 return status;
11659}
11660
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011661#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11662static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11663 struct net_device *ndev,
11664 u8 key_index,
11665 bool unicast, bool multicast)
11666#else
11667static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11668 struct net_device *ndev,
11669 u8 key_index)
11670#endif
11671{
11672 int ret;
11673 vos_ssr_protect(__func__);
11674#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11675 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
11676 multicast);
11677#else
11678 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
11679#endif
11680 vos_ssr_unprotect(__func__);
11681
11682 return ret;
11683}
11684
Jeff Johnson295189b2012-06-20 16:38:30 -070011685/*
11686 * FUNCTION: wlan_hdd_cfg80211_inform_bss
11687 * This function is used to inform the BSS details to nl80211 interface.
11688 */
11689static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
11690 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
11691{
11692 struct net_device *dev = pAdapter->dev;
11693 struct wireless_dev *wdev = dev->ieee80211_ptr;
11694 struct wiphy *wiphy = wdev->wiphy;
11695 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
11696 int chan_no;
11697 int ie_length;
11698 const char *ie;
11699 unsigned int freq;
11700 struct ieee80211_channel *chan;
11701 int rssi = 0;
11702 struct cfg80211_bss *bss = NULL;
11703
Jeff Johnson295189b2012-06-20 16:38:30 -070011704 if( NULL == pBssDesc )
11705 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011706 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 return bss;
11708 }
11709
11710 chan_no = pBssDesc->channelId;
11711 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
11712 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
11713
11714 if( NULL == ie )
11715 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011716 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 return bss;
11718 }
11719
11720#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
11721 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
11722 {
11723 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
11724 }
11725 else
11726 {
11727 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
11728 }
11729#else
11730 freq = ieee80211_channel_to_frequency(chan_no);
11731#endif
11732
11733 chan = __ieee80211_get_channel(wiphy, freq);
11734
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053011735 if (!chan) {
11736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
11737 return NULL;
11738 }
11739
Abhishek Singhaee43942014-06-16 18:55:47 +053011740 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070011741
Anand N Sunkad9f80b742015-07-30 20:05:51 +053011742 return cfg80211_inform_bss(wiphy, chan,
11743#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11744 CFG80211_BSS_FTYPE_UNKNOWN,
11745#endif
11746 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011747 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070011748 pBssDesc->capabilityInfo,
11749 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053011750 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070011751}
11752
11753
11754
11755/*
11756 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
11757 * This function is used to inform the BSS details to nl80211 interface.
11758 */
11759struct cfg80211_bss*
11760wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
11761 tSirBssDescription *bss_desc
11762 )
11763{
11764 /*
11765 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
11766 already exists in bss data base of cfg80211 for that particular BSS ID.
11767 Using cfg80211_inform_bss_frame to update the bss entry instead of
11768 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
11769 now there is no possibility to get the mgmt(probe response) frame from PE,
11770 converting bss_desc to ieee80211_mgmt(probe response) and passing to
11771 cfg80211_inform_bss_frame.
11772 */
11773 struct net_device *dev = pAdapter->dev;
11774 struct wireless_dev *wdev = dev->ieee80211_ptr;
11775 struct wiphy *wiphy = wdev->wiphy;
11776 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080011777#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
11778 qcom_ie_age *qie_age = NULL;
11779 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
11780#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011781 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080011782#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011783 const char *ie =
11784 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
11785 unsigned int freq;
11786 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053011787 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 struct cfg80211_bss *bss_status = NULL;
11789 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
11790 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070011791 hdd_context_t *pHddCtx;
11792 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070011793#ifdef WLAN_OPEN_SOURCE
11794 struct timespec ts;
11795#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011796
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011797
Wilson Yangf80a0542013-10-07 13:02:37 -070011798 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11799 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070011800 if (0 != status)
11801 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070011802 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070011803 }
11804
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053011805 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070011806 if (!mgmt)
11807 {
11808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11809 "%s: memory allocation failed ", __func__);
11810 return NULL;
11811 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070011812
Jeff Johnson295189b2012-06-20 16:38:30 -070011813 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011814
11815#ifdef WLAN_OPEN_SOURCE
11816 /* Android does not want the timestamp from the frame.
11817 Instead it wants a monotonic increasing value */
11818 get_monotonic_boottime(&ts);
11819 mgmt->u.probe_resp.timestamp =
11820 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
11821#else
11822 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011823 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
11824 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070011825
11826#endif
11827
Jeff Johnson295189b2012-06-20 16:38:30 -070011828 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
11829 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080011830
11831#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
11832 /* GPS Requirement: need age ie per entry. Using vendor specific. */
11833 /* Assuming this is the last IE, copy at the end */
11834 ie_length -=sizeof(qcom_ie_age);
11835 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
11836 qie_age->element_id = QCOM_VENDOR_IE_ID;
11837 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
11838 qie_age->oui_1 = QCOM_OUI1;
11839 qie_age->oui_2 = QCOM_OUI2;
11840 qie_age->oui_3 = QCOM_OUI3;
11841 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
11842 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
11843#endif
11844
Jeff Johnson295189b2012-06-20 16:38:30 -070011845 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053011846 if (bss_desc->fProbeRsp)
11847 {
11848 mgmt->frame_control |=
11849 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
11850 }
11851 else
11852 {
11853 mgmt->frame_control |=
11854 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
11855 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011856
11857#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011858 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070011859 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
11860 {
11861 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
11862 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011863 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070011864 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
11865
11866 {
11867 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
11868 }
11869 else
11870 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011871 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
11872 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070011873 kfree(mgmt);
11874 return NULL;
11875 }
11876#else
11877 freq = ieee80211_channel_to_frequency(chan_no);
11878#endif
11879 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080011880 /*when the band is changed on the fly using the GUI, three things are done
11881 * 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)
11882 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
11883 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
11884 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
11885 * and discards the channels correponding to previous band and calls back with zero bss results.
11886 * 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
11887 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
11888 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
11889 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
11890 * So drop the bss and continue to next bss.
11891 */
11892 if(chan == NULL)
11893 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011894 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070011895 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080011896 return NULL;
11897 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053011898 /*To keep the rssi icon of the connected AP in the scan window
11899 *and the rssi icon of the wireless networks in sync
11900 * */
11901 if (( eConnectionState_Associated ==
11902 pAdapter->sessionCtx.station.conn_info.connState ) &&
11903 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
11904 pAdapter->sessionCtx.station.conn_info.bssId,
11905 WNI_CFG_BSSID_LEN)) &&
11906 (pHddCtx->hdd_wlan_suspended == FALSE))
11907 {
11908 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
11909 rssi = (pAdapter->rssi * 100);
11910 }
11911 else
11912 {
11913 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
11914 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011915
Nirav Shah20ac06f2013-12-12 18:14:06 +053011916 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053011917 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
11918 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053011919
Jeff Johnson295189b2012-06-20 16:38:30 -070011920 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
11921 frame_len, rssi, GFP_KERNEL);
11922 kfree(mgmt);
11923 return bss_status;
11924}
11925
11926/*
11927 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
11928 * This function is used to update the BSS data base of CFG8011
11929 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011930struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011931 tCsrRoamInfo *pRoamInfo
11932 )
11933{
11934 tCsrRoamConnectedProfile roamProfile;
11935 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11936 struct cfg80211_bss *bss = NULL;
11937
11938 ENTER();
11939
11940 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
11941 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
11942
11943 if (NULL != roamProfile.pBssDesc)
11944 {
Girish Gowlif4b68022014-08-28 23:18:57 +053011945 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
11946 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070011947
11948 if (NULL == bss)
11949 {
11950 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
11951 __func__);
11952 }
11953
11954 sme_RoamFreeConnectProfile(hHal, &roamProfile);
11955 }
11956 else
11957 {
11958 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
11959 __func__);
11960 }
11961 return bss;
11962}
11963
11964/*
11965 * FUNCTION: wlan_hdd_cfg80211_update_bss
11966 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011967static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
11968 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070011969 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011970{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011971 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011972 tCsrScanResultInfo *pScanResult;
11973 eHalStatus status = 0;
11974 tScanResultHandle pResult;
11975 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070011976 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011977 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070011978 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011979
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011980 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11981 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
11982 NO_SESSION, pAdapter->sessionId));
11983
Wilson Yangf80a0542013-10-07 13:02:37 -070011984 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11985
11986 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070011987 {
Wilson Yangf80a0542013-10-07 13:02:37 -070011988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11989 "%s:LOGP in Progress. Ignore!!!",__func__);
11990 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011991 }
11992
Wilson Yangf80a0542013-10-07 13:02:37 -070011993
11994 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053011995 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070011996 {
11997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11998 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
11999 return VOS_STATUS_E_PERM;
12000 }
12001
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012002 if (pAdapter->request != NULL)
12003 {
12004 if ((pAdapter->request->n_ssids == 1)
12005 && (pAdapter->request->ssids != NULL)
12006 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12007 is_p2p_scan = true;
12008 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012009 /*
12010 * start getting scan results and populate cgf80211 BSS database
12011 */
12012 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12013
12014 /* no scan results */
12015 if (NULL == pResult)
12016 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012017 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12018 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012019 wlan_hdd_get_frame_logs(pAdapter,
12020 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012021 return status;
12022 }
12023
12024 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12025
12026 while (pScanResult)
12027 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012028 /*
12029 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12030 * entry already exists in bss data base of cfg80211 for that
12031 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12032 * bss entry instead of cfg80211_inform_bss, But this call expects
12033 * mgmt packet as input. As of now there is no possibility to get
12034 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012035 * ieee80211_mgmt(probe response) and passing to c
12036 * fg80211_inform_bss_frame.
12037 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012038 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12039 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12040 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012041 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12042 continue; //Skip the non p2p bss entries
12043 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012044 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12045 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012046
Jeff Johnson295189b2012-06-20 16:38:30 -070012047
12048 if (NULL == bss_status)
12049 {
12050 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012051 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012052 }
12053 else
12054 {
Yue Maf49ba872013-08-19 12:04:25 -070012055 cfg80211_put_bss(
12056#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12057 wiphy,
12058#endif
12059 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012060 }
12061
12062 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12063 }
12064
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012065 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012066 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012067 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012068}
12069
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012070void
12071hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12072{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012073 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012074 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012075} /****** end hddPrintMacAddr() ******/
12076
12077void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012078hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012079{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012080 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012081 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012082 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12083 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12084 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012085} /****** end hddPrintPmkId() ******/
12086
12087//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12088//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12089
12090//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12091//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12092
12093#define dump_bssid(bssid) \
12094 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012095 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12096 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012097 }
12098
12099#define dump_pmkid(pMac, pmkid) \
12100 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012101 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12102 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012103 }
12104
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012105#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012106/*
12107 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12108 * This function is used to notify the supplicant of a new PMKSA candidate.
12109 */
12110int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012111 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012112 int index, bool preauth )
12113{
Jeff Johnsone7245742012-09-05 17:12:55 -070012114#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012115 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012116 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012117
12118 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012119 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012120
12121 if( NULL == pRoamInfo )
12122 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012123 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012124 return -EINVAL;
12125 }
12126
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012127 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12128 {
12129 dump_bssid(pRoamInfo->bssid);
12130 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012131 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012132 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012133#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012134 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012135}
12136#endif //FEATURE_WLAN_LFR
12137
Yue Maef608272013-04-08 23:09:17 -070012138#ifdef FEATURE_WLAN_LFR_METRICS
12139/*
12140 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12141 * 802.11r/LFR metrics reporting function to report preauth initiation
12142 *
12143 */
12144#define MAX_LFR_METRICS_EVENT_LENGTH 100
12145VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12146 tCsrRoamInfo *pRoamInfo)
12147{
12148 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12149 union iwreq_data wrqu;
12150
12151 ENTER();
12152
12153 if (NULL == pAdapter)
12154 {
12155 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12156 return VOS_STATUS_E_FAILURE;
12157 }
12158
12159 /* create the event */
12160 memset(&wrqu, 0, sizeof(wrqu));
12161 memset(metrics_notification, 0, sizeof(metrics_notification));
12162
12163 wrqu.data.pointer = metrics_notification;
12164 wrqu.data.length = scnprintf(metrics_notification,
12165 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12166 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12167
12168 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12169
12170 EXIT();
12171
12172 return VOS_STATUS_SUCCESS;
12173}
12174
12175/*
12176 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12177 * 802.11r/LFR metrics reporting function to report preauth completion
12178 * or failure
12179 */
12180VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12181 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12182{
12183 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12184 union iwreq_data wrqu;
12185
12186 ENTER();
12187
12188 if (NULL == pAdapter)
12189 {
12190 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12191 return VOS_STATUS_E_FAILURE;
12192 }
12193
12194 /* create the event */
12195 memset(&wrqu, 0, sizeof(wrqu));
12196 memset(metrics_notification, 0, sizeof(metrics_notification));
12197
12198 scnprintf(metrics_notification, sizeof(metrics_notification),
12199 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12200 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12201
12202 if (1 == preauth_status)
12203 strncat(metrics_notification, " TRUE", 5);
12204 else
12205 strncat(metrics_notification, " FALSE", 6);
12206
12207 wrqu.data.pointer = metrics_notification;
12208 wrqu.data.length = strlen(metrics_notification);
12209
12210 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12211
12212 EXIT();
12213
12214 return VOS_STATUS_SUCCESS;
12215}
12216
12217/*
12218 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12219 * 802.11r/LFR metrics reporting function to report handover initiation
12220 *
12221 */
12222VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12223 tCsrRoamInfo *pRoamInfo)
12224{
12225 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12226 union iwreq_data wrqu;
12227
12228 ENTER();
12229
12230 if (NULL == pAdapter)
12231 {
12232 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12233 return VOS_STATUS_E_FAILURE;
12234 }
12235
12236 /* create the event */
12237 memset(&wrqu, 0, sizeof(wrqu));
12238 memset(metrics_notification, 0, sizeof(metrics_notification));
12239
12240 wrqu.data.pointer = metrics_notification;
12241 wrqu.data.length = scnprintf(metrics_notification,
12242 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12243 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12244
12245 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12246
12247 EXIT();
12248
12249 return VOS_STATUS_SUCCESS;
12250}
12251#endif
12252
Jeff Johnson295189b2012-06-20 16:38:30 -070012253/*
12254 * FUNCTION: hdd_cfg80211_scan_done_callback
12255 * scanning callback function, called after finishing scan
12256 *
12257 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012258static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012259 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12260{
12261 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012262 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012263 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012264 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012265 struct cfg80211_scan_request *req = NULL;
12266 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012267 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012268 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012269 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012270 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012271
12272 ENTER();
12273
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012274 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012275 if (NULL == pHddCtx) {
12276 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012277 goto allow_suspend;
12278 }
12279
12280 pScanInfo = &pHddCtx->scan_info;
12281
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 hddLog(VOS_TRACE_LEVEL_INFO,
12283 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012284 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012285 __func__, halHandle, pContext, (int) scanId, (int) status);
12286
Kiet Lamac06e2c2013-10-23 16:25:07 +053012287 pScanInfo->mScanPendingCounter = 0;
12288
Jeff Johnson295189b2012-06-20 16:38:30 -070012289 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012290 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012291 &pScanInfo->scan_req_completion_event,
12292 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012293 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012294 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012295 hddLog(VOS_TRACE_LEVEL_ERROR,
12296 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012297 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012298 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012299 }
12300
Yue Maef608272013-04-08 23:09:17 -070012301 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012302 {
12303 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012304 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012305 }
12306
12307 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012308 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012309 {
12310 hddLog(VOS_TRACE_LEVEL_INFO,
12311 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012312 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012313 (int) scanId);
12314 }
12315
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012316 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012317 pAdapter);
12318
12319 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012320 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012321
12322
12323 /* If any client wait scan result through WEXT
12324 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012325 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012326 {
12327 /* The other scan request waiting for current scan finish
12328 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012329 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012330 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012331 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012332 }
12333 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012334 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012335 {
12336 struct net_device *dev = pAdapter->dev;
12337 union iwreq_data wrqu;
12338 int we_event;
12339 char *msg;
12340
12341 memset(&wrqu, '\0', sizeof(wrqu));
12342 we_event = SIOCGIWSCAN;
12343 msg = NULL;
12344 wireless_send_event(dev, we_event, &wrqu, msg);
12345 }
12346 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012347 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012348
12349 /* Get the Scan Req */
12350 req = pAdapter->request;
12351
12352 if (!req)
12353 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012354 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012355 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012356 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012357 }
12358
Jeff Johnson295189b2012-06-20 16:38:30 -070012359 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012360 /* Scan is no longer pending */
12361 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012362
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012363 /* last_scan_timestamp is used to decide if new scan
12364 * is needed or not on station interface. If last station
12365 * scan time and new station scan time is less then
12366 * last_scan_timestamp ; driver will return cached scan.
12367 */
12368 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12369 {
12370 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12371
12372 if ( req->n_channels )
12373 {
12374 for (i = 0; i < req->n_channels ; i++ )
12375 {
12376 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12377 }
12378 /* store no of channel scanned */
12379 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12380 }
12381
12382 }
12383
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012384 /*
12385 * cfg80211_scan_done informing NL80211 about completion
12386 * of scanning
12387 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012388 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12389 {
12390 aborted = true;
12391 }
12392 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012393 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012394
Siddharth Bhal76972212014-10-15 16:22:51 +053012395 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
12396 /* Generate new random mac addr for next scan */
12397 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
12398 hdd_processSpoofMacAddrRequest(pHddCtx);
12399 }
12400
Jeff Johnsone7245742012-09-05 17:12:55 -070012401allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012402 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012403 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012404
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012405 /* Acquire wakelock to handle the case where APP's tries to suspend
12406 * immediatly after the driver gets connect request(i.e after scan)
12407 * from supplicant, this result in app's is suspending and not able
12408 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012409 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012410
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012411#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012412 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012413#endif
12414
Jeff Johnson295189b2012-06-20 16:38:30 -070012415 EXIT();
12416 return 0;
12417}
12418
12419/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012420 * FUNCTION: hdd_isConnectionInProgress
12421 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012422 *
12423 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012424v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012425{
12426 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12427 hdd_station_ctx_t *pHddStaCtx = NULL;
12428 hdd_adapter_t *pAdapter = NULL;
12429 VOS_STATUS status = 0;
12430 v_U8_t staId = 0;
12431 v_U8_t *staMac = NULL;
12432
c_hpothu9b781ba2013-12-30 20:57:45 +053012433 if (TRUE == pHddCtx->btCoexModeSet)
12434 {
12435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012436 FL("BTCoex Mode operation in progress"));
12437 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012438 }
12439
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012440 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12441
12442 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12443 {
12444 pAdapter = pAdapterNode->pAdapter;
12445
12446 if( pAdapter )
12447 {
12448 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012449 "%s: Adapter with device mode %s (%d) exists",
12450 __func__, hdd_device_modetoString(pAdapter->device_mode),
12451 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012452 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012453 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12454 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12455 (eConnectionState_Connecting ==
12456 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12457 {
12458 hddLog(VOS_TRACE_LEVEL_ERROR,
12459 "%s: %p(%d) Connection is in progress", __func__,
12460 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12461 return VOS_TRUE;
12462 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012463 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012464 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012465 {
12466 hddLog(VOS_TRACE_LEVEL_ERROR,
12467 "%s: %p(%d) Reassociation is in progress", __func__,
12468 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12469 return VOS_TRUE;
12470 }
12471 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012472 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12473 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012474 {
12475 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12476 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012477 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012478 {
12479 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12480 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012481 "%s: client " MAC_ADDRESS_STR
12482 " is in the middle of WPS/EAPOL exchange.", __func__,
12483 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012484 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012485 }
12486 }
12487 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12488 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12489 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012490 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12491 ptSapContext pSapCtx = NULL;
12492 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12493 if(pSapCtx == NULL){
12494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12495 FL("psapCtx is NULL"));
12496 return VOS_FALSE;
12497 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012498 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12499 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012500 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12501 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012502 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012503 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012504
12505 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012506 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12507 "middle of WPS/EAPOL exchange.", __func__,
12508 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012509 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012510 }
12511 }
12512 }
12513 }
12514 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12515 pAdapterNode = pNext;
12516 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012517 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012518}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012519
12520/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012521 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 * this scan respond to scan trigger and update cfg80211 scan database
12523 * later, scan dump command can be used to recieve scan results
12524 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012525int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012526#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12527 struct net_device *dev,
12528#endif
12529 struct cfg80211_scan_request *request)
12530{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012531 hdd_adapter_t *pAdapter = NULL;
12532 hdd_context_t *pHddCtx = NULL;
12533 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012534 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 tCsrScanRequest scanRequest;
12536 tANI_U8 *channelList = NULL, i;
12537 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012538 int status;
12539 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012540 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012541 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012542 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012543 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012544 v_S7_t rssi=0;
12545 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012546
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012547#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12548 struct net_device *dev = NULL;
12549 if (NULL == request)
12550 {
12551 hddLog(VOS_TRACE_LEVEL_ERROR,
12552 "%s: scan req param null", __func__);
12553 return -EINVAL;
12554 }
12555 dev = request->wdev->netdev;
12556#endif
12557
12558 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12559 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12560 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12561
Jeff Johnson295189b2012-06-20 16:38:30 -070012562 ENTER();
12563
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012564 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12565 __func__, hdd_device_modetoString(pAdapter->device_mode),
12566 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012567
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012568 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012569 if (0 != status)
12570 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012571 return status;
12572 }
12573
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012574 if (NULL == pwextBuf)
12575 {
12576 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12577 __func__);
12578 return -EIO;
12579 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012580 cfg_param = pHddCtx->cfg_ini;
12581 pScanInfo = &pHddCtx->scan_info;
12582
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012583 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12584 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
12585 {
12586 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
12587 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
12588 }
12589
Jeff Johnson295189b2012-06-20 16:38:30 -070012590#ifdef WLAN_BTAMP_FEATURE
12591 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012592 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070012593 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012594 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012595 "%s: No scanning when AMP is on", __func__);
12596 return -EOPNOTSUPP;
12597 }
12598#endif
12599 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012600 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012602 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012603 "%s: Not scanning on device_mode = %s (%d)",
12604 __func__, hdd_device_modetoString(pAdapter->device_mode),
12605 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012606 return -EOPNOTSUPP;
12607 }
12608
12609 if (TRUE == pScanInfo->mScanPending)
12610 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012611 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
12612 {
12613 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
12614 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012615 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012616 }
12617
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053012618 // Don't allow scan if PNO scan is going on.
12619 if (pHddCtx->isPnoEnable)
12620 {
12621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12622 FL("pno scan in progress"));
12623 return -EBUSY;
12624 }
12625
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012626 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070012627 //Channel and action frame is pending
12628 //Otherwise Cancel Remain On Channel and allow Scan
12629 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012630 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070012631 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012633 return -EBUSY;
12634 }
12635
Jeff Johnson295189b2012-06-20 16:38:30 -070012636 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
12637 {
12638 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080012639 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012640 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012641 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012642 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
12643 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012644 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012645 "%s: MAX TM Level Scan not allowed", __func__);
12646 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012647 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012648 }
12649 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
12650
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012651 /* Check if scan is allowed at this point of time.
12652 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012653 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012654 {
12655 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
12656 return -EBUSY;
12657 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012658
Jeff Johnson295189b2012-06-20 16:38:30 -070012659 vos_mem_zero( &scanRequest, sizeof(scanRequest));
12660
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012661 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
12662 * Becasue of this, driver is assuming that this is not wildcard scan and so
12663 * is not aging out the scan results.
12664 */
12665 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012667 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012668 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012669
12670 if ((request->ssids) && (0 < request->n_ssids))
12671 {
12672 tCsrSSIDInfo *SsidInfo;
12673 int j;
12674 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
12675 /* Allocate num_ssid tCsrSSIDInfo structure */
12676 SsidInfo = scanRequest.SSIDs.SSIDList =
12677 ( tCsrSSIDInfo *)vos_mem_malloc(
12678 request->n_ssids*sizeof(tCsrSSIDInfo));
12679
12680 if(NULL == scanRequest.SSIDs.SSIDList)
12681 {
12682 hddLog(VOS_TRACE_LEVEL_ERROR,
12683 "%s: memory alloc failed SSIDInfo buffer", __func__);
12684 return -ENOMEM;
12685 }
12686
12687 /* copy all the ssid's and their length */
12688 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
12689 {
12690 /* get the ssid length */
12691 SsidInfo->SSID.length = request->ssids[j].ssid_len;
12692 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
12693 SsidInfo->SSID.length);
12694 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
12695 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
12696 j, SsidInfo->SSID.ssId);
12697 }
12698 /* set the scan type to active */
12699 scanRequest.scanType = eSIR_ACTIVE_SCAN;
12700 }
12701 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012702 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012703 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12704 TRACE_CODE_HDD_CFG80211_SCAN,
12705 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070012706 /* set the scan type to active */
12707 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012708 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012709 else
12710 {
12711 /*Set the scan type to default type, in this case it is ACTIVE*/
12712 scanRequest.scanType = pScanInfo->scan_mode;
12713 }
12714 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
12715 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070012716
12717 /* set BSSType to default type */
12718 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
12719
12720 /*TODO: scan the requested channels only*/
12721
12722 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012723 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070012724 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012725 hddLog(VOS_TRACE_LEVEL_WARN,
12726 "No of Scan Channels exceeded limit: %d", request->n_channels);
12727 request->n_channels = MAX_CHANNEL;
12728 }
12729
12730 hddLog(VOS_TRACE_LEVEL_INFO,
12731 "No of Scan Channels: %d", request->n_channels);
12732
12733
12734 if( request->n_channels )
12735 {
12736 char chList [(request->n_channels*5)+1];
12737 int len;
12738 channelList = vos_mem_malloc( request->n_channels );
12739 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053012740 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012741 hddLog(VOS_TRACE_LEVEL_ERROR,
12742 "%s: memory alloc failed channelList", __func__);
12743 status = -ENOMEM;
12744 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053012745 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012746
12747 for( i = 0, len = 0; i < request->n_channels ; i++ )
12748 {
12749 channelList[i] = request->channels[i]->hw_value;
12750 len += snprintf(chList+len, 5, "%d ", channelList[i]);
12751 }
12752
Nirav Shah20ac06f2013-12-12 18:14:06 +053012753 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012754 "Channel-List: %s ", chList);
12755 }
c_hpothu53512302014-04-15 18:49:53 +053012756
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012757 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
12758 scanRequest.ChannelInfo.ChannelList = channelList;
12759
12760 /* set requestType to full scan */
12761 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
12762
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012763 /* if there is back to back scan happening in driver with in
12764 * nDeferScanTimeInterval interval driver should defer new scan request
12765 * and should provide last cached scan results instead of new channel list.
12766 * This rule is not applicable if scan is p2p scan.
12767 * This condition will work only in case when last request no of channels
12768 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053012769 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053012770 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012771 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012772
Sushant Kaushik86592172015-04-27 16:35:03 +053012773 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
12774 /* if wps ie is NULL , then only defer scan */
12775 if ( pWpsIe == NULL &&
12776 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053012777 {
12778 if ( pScanInfo->last_scan_timestamp !=0 &&
12779 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
12780 {
12781 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
12782 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
12783 vos_mem_compare(pScanInfo->last_scan_channelList,
12784 channelList, pScanInfo->last_scan_numChannels))
12785 {
12786 hddLog(VOS_TRACE_LEVEL_WARN,
12787 " New and old station scan time differ is less then %u",
12788 pHddCtx->cfg_ini->nDeferScanTimeInterval);
12789
12790 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012791 pAdapter);
12792
Agarwal Ashish57e84372014-12-05 18:26:53 +053012793 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053012794 "Return old cached scan as all channels and no of channels are same");
12795
Agarwal Ashish57e84372014-12-05 18:26:53 +053012796 if (0 > ret)
12797 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012798
Agarwal Ashish57e84372014-12-05 18:26:53 +053012799 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053012800
12801 status = eHAL_STATUS_SUCCESS;
12802 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053012803 }
12804 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012805 }
12806
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012807 /* Flush the scan results(only p2p beacons) for STA scan and P2P
12808 * search (Flush on both full scan and social scan but not on single
12809 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
12810 */
12811
12812 /* Supplicant does single channel scan after 8-way handshake
12813 * and in that case driver shoudnt flush scan results. If
12814 * driver flushes the scan results here and unfortunately if
12815 * the AP doesnt respond to our probe req then association
12816 * fails which is not desired
12817 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012818 if ((request->n_ssids == 1)
12819 && (request->ssids != NULL)
12820 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
12821 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012822
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012823 if( is_p2p_scan ||
12824 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012825 {
12826 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
12827 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
12828 pAdapter->sessionId );
12829 }
12830
12831 if( request->ie_len )
12832 {
12833 /* save this for future association (join requires this) */
12834 /*TODO: Array needs to be converted to dynamic allocation,
12835 * as multiple ie.s can be sent in cfg80211_scan_request structure
12836 * CR 597966
12837 */
12838 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
12839 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
12840 pScanInfo->scanAddIE.length = request->ie_len;
12841
12842 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
12843 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12844 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070012845 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012846 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070012847 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012848 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
12849 memcpy( pwextBuf->roamProfile.addIEScan,
12850 request->ie, request->ie_len);
12851 }
12852 else
12853 {
12854 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
12855 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012856 }
12857
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012858 }
12859 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
12860 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
12861
12862 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
12863 request->ie_len);
12864 if (pP2pIe != NULL)
12865 {
12866#ifdef WLAN_FEATURE_P2P_DEBUG
12867 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
12868 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
12869 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053012870 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012871 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
12872 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
12873 "Go nego completed to Connection is started");
12874 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
12875 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053012876 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012877 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
12878 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070012879 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012880 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
12881 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
12882 "Disconnected state to Connection is started");
12883 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
12884 "for 4way Handshake");
12885 }
12886#endif
12887
12888 /* no_cck will be set during p2p find to disable 11b rates */
12889 if(TRUE == request->no_cck)
12890 {
12891 hddLog(VOS_TRACE_LEVEL_INFO,
12892 "%s: This is a P2P Search", __func__);
12893 scanRequest.p2pSearch = 1;
12894
12895 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053012896 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012897 /* set requestType to P2P Discovery */
12898 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
12899 }
12900
12901 /*
12902 Skip Dfs Channel in case of P2P Search
12903 if it is set in ini file
12904 */
12905 if(cfg_param->skipDfsChnlInP2pSearch)
12906 {
12907 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053012908 }
12909 else
12910 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012911 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053012912 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012913
Agarwal Ashish4f616132013-12-30 23:32:50 +053012914 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012915 }
12916 }
12917
12918 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
12919
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012920#ifdef FEATURE_WLAN_TDLS
12921 /* if tdls disagree scan right now, return immediately.
12922 tdls will schedule the scan when scan is allowed. (return SUCCESS)
12923 or will reject the scan if any TDLS is in progress. (return -EBUSY)
12924 */
12925 status = wlan_hdd_tdls_scan_callback (pAdapter,
12926 wiphy,
12927#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12928 dev,
12929#endif
12930 request);
12931 if(status <= 0)
12932 {
12933 if(!status)
12934 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
12935 "scan rejected %d", __func__, status);
12936 else
12937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
12938 __func__, status);
12939
12940 return status;
12941 }
12942#endif
12943
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012944 /* acquire the wakelock to avoid the apps suspend during the scan. To
12945 * address the following issues.
12946 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
12947 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
12948 * for long time, this result in apps running at full power for long time.
12949 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
12950 * be stuck in full power because of resume BMPS
12951 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012952 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012953
Nirav Shah20ac06f2013-12-12 18:14:06 +053012954 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12955 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012956 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
12957 scanRequest.requestType, scanRequest.scanType,
12958 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053012959 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
12960
Siddharth Bhal76972212014-10-15 16:22:51 +053012961 if (pHddCtx->spoofMacAddr.isEnabled)
12962 {
12963 hddLog(VOS_TRACE_LEVEL_INFO,
12964 "%s: MAC Spoofing enabled for current scan", __func__);
12965 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
12966 * to fill TxBds for probe request during current scan
12967 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053012968 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053012969 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053012970
12971 if(status != VOS_STATUS_SUCCESS)
12972 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012973 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053012974 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053012975#ifdef FEATURE_WLAN_TDLS
12976 wlan_hdd_tdls_scan_done_callback(pAdapter);
12977#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053012978 goto free_mem;
12979 }
Siddharth Bhal76972212014-10-15 16:22:51 +053012980 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012981 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070012982 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012983 pAdapter->sessionId, &scanRequest, &scanId,
12984 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070012985
Jeff Johnson295189b2012-06-20 16:38:30 -070012986 if (eHAL_STATUS_SUCCESS != status)
12987 {
12988 hddLog(VOS_TRACE_LEVEL_ERROR,
12989 "%s: sme_ScanRequest returned error %d", __func__, status);
12990 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070012991 if(eHAL_STATUS_RESOURCES == status)
12992 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012993 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
12994 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070012995 status = -EBUSY;
12996 } else {
12997 status = -EIO;
12998 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012999 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013000
13001#ifdef FEATURE_WLAN_TDLS
13002 wlan_hdd_tdls_scan_done_callback(pAdapter);
13003#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013004 goto free_mem;
13005 }
13006
13007 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013008 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013009 pAdapter->request = request;
13010 pScanInfo->scanId = scanId;
13011
13012 complete(&pScanInfo->scan_req_completion_event);
13013
13014free_mem:
13015 if( scanRequest.SSIDs.SSIDList )
13016 {
13017 vos_mem_free(scanRequest.SSIDs.SSIDList);
13018 }
13019
13020 if( channelList )
13021 vos_mem_free( channelList );
13022
13023 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013024 return status;
13025}
13026
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013027int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13028#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13029 struct net_device *dev,
13030#endif
13031 struct cfg80211_scan_request *request)
13032{
13033 int ret;
13034
13035 vos_ssr_protect(__func__);
13036 ret = __wlan_hdd_cfg80211_scan(wiphy,
13037#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13038 dev,
13039#endif
13040 request);
13041 vos_ssr_unprotect(__func__);
13042
13043 return ret;
13044}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013045
13046void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13047{
13048 v_U8_t iniDot11Mode =
13049 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13050 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13051
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013052 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13053 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013054 switch ( iniDot11Mode )
13055 {
13056 case eHDD_DOT11_MODE_AUTO:
13057 case eHDD_DOT11_MODE_11ac:
13058 case eHDD_DOT11_MODE_11ac_ONLY:
13059#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013060 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13061 sme_IsFeatureSupportedByFW(DOT11AC) )
13062 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13063 else
13064 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013065#else
13066 hddDot11Mode = eHDD_DOT11_MODE_11n;
13067#endif
13068 break;
13069 case eHDD_DOT11_MODE_11n:
13070 case eHDD_DOT11_MODE_11n_ONLY:
13071 hddDot11Mode = eHDD_DOT11_MODE_11n;
13072 break;
13073 default:
13074 hddDot11Mode = iniDot11Mode;
13075 break;
13076 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013077#ifdef WLAN_FEATURE_AP_HT40_24G
13078 if (operationChannel > SIR_11B_CHANNEL_END)
13079#endif
13080 {
13081 /* This call decides required channel bonding mode */
13082 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013083 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13084 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013085 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013086}
13087
Jeff Johnson295189b2012-06-20 16:38:30 -070013088/*
13089 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013090 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013092int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013093 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13094 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013095{
13096 int status = 0;
13097 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013098 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013099 v_U32_t roamId;
13100 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013101 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013102 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013103
13104 ENTER();
13105
13106 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013107 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13108
13109 status = wlan_hdd_validate_context(pHddCtx);
13110 if (status)
13111 {
Yue Mae36e3552014-03-05 17:06:20 -080013112 return status;
13113 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013114
Jeff Johnson295189b2012-06-20 16:38:30 -070013115 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13116 {
13117 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13118 return -EINVAL;
13119 }
13120
13121 pRoamProfile = &pWextState->roamProfile;
13122
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013123 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013124 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013125 hdd_station_ctx_t *pHddStaCtx;
13126 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013127
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013128 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13129
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013130 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013131 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13132 {
13133 /*QoS not enabled in cfg file*/
13134 pRoamProfile->uapsd_mask = 0;
13135 }
13136 else
13137 {
13138 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013139 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013140 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13141 }
13142
13143 pRoamProfile->SSIDs.numOfSSIDs = 1;
13144 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13145 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013146 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013147 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13148 ssid, ssid_len);
13149
13150 if (bssid)
13151 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013152 pValidBssid = bssid;
13153 }
13154 else if (bssid_hint)
13155 {
13156 pValidBssid = bssid_hint;
13157 }
13158 if (pValidBssid)
13159 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013160 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013161 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013162 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013163 /* Save BSSID in seperate variable as well, as RoamProfile
13164 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013165 case of join failure we should send valid BSSID to supplicant
13166 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013167 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013168 WNI_CFG_BSSID_LEN);
13169 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013170 else
13171 {
13172 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13173 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013174
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013175 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13176 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013177 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13178 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013179 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013180 /*set gen ie*/
13181 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13182 /*set auth*/
13183 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13184 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013185#ifdef FEATURE_WLAN_WAPI
13186 if (pAdapter->wapi_info.nWapiMode)
13187 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013188 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013189 switch (pAdapter->wapi_info.wapiAuthMode)
13190 {
13191 case WAPI_AUTH_MODE_PSK:
13192 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013193 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013194 pAdapter->wapi_info.wapiAuthMode);
13195 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13196 break;
13197 }
13198 case WAPI_AUTH_MODE_CERT:
13199 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013200 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013201 pAdapter->wapi_info.wapiAuthMode);
13202 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13203 break;
13204 }
13205 } // End of switch
13206 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13207 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13208 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013209 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013210 pRoamProfile->AuthType.numEntries = 1;
13211 pRoamProfile->EncryptionType.numEntries = 1;
13212 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13213 pRoamProfile->mcEncryptionType.numEntries = 1;
13214 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13215 }
13216 }
13217#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013218#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013219 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013220 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13221 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13222 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013223 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13224 sizeof (tSirGtkOffloadParams));
13225 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013226 }
13227#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013228 pRoamProfile->csrPersona = pAdapter->device_mode;
13229
Jeff Johnson32d95a32012-09-10 13:15:23 -070013230 if( operatingChannel )
13231 {
13232 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13233 pRoamProfile->ChannelInfo.numOfChannels = 1;
13234 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013235 else
13236 {
13237 pRoamProfile->ChannelInfo.ChannelList = NULL;
13238 pRoamProfile->ChannelInfo.numOfChannels = 0;
13239 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013240 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13241 {
13242 hdd_select_cbmode(pAdapter,operatingChannel);
13243 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013244
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013245 /*
13246 * Change conn_state to connecting before sme_RoamConnect(),
13247 * because sme_RoamConnect() has a direct path to call
13248 * hdd_smeRoamCallback(), which will change the conn_state
13249 * If direct path, conn_state will be accordingly changed
13250 * to NotConnected or Associated by either
13251 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13252 * in sme_RoamCallback()
13253 * if sme_RomConnect is to be queued,
13254 * Connecting state will remain until it is completed.
13255 * If connection state is not changed,
13256 * connection state will remain in eConnectionState_NotConnected state.
13257 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13258 * if conn state is eConnectionState_NotConnected.
13259 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13260 * informed of connect result indication which is an issue.
13261 */
13262
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013263 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13264 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013265 {
13266 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013267 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013268 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13269 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013270 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013271 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013272 pAdapter->sessionId, pRoamProfile, &roamId);
13273
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013274 if ((eHAL_STATUS_SUCCESS != status) &&
13275 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13276 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013277
13278 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013279 hddLog(VOS_TRACE_LEVEL_ERROR,
13280 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13281 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013282 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013283 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013284 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013285 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013286
13287 pRoamProfile->ChannelInfo.ChannelList = NULL;
13288 pRoamProfile->ChannelInfo.numOfChannels = 0;
13289
Jeff Johnson295189b2012-06-20 16:38:30 -070013290 }
13291 else
13292 {
13293 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13294 return -EINVAL;
13295 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013296 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013297 return status;
13298}
13299
13300/*
13301 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13302 * This function is used to set the authentication type (OPEN/SHARED).
13303 *
13304 */
13305static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13306 enum nl80211_auth_type auth_type)
13307{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013308 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013309 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13310
13311 ENTER();
13312
13313 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013314 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013315 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013316 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013317 hddLog(VOS_TRACE_LEVEL_INFO,
13318 "%s: set authentication type to AUTOSWITCH", __func__);
13319 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13320 break;
13321
13322 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013323#ifdef WLAN_FEATURE_VOWIFI_11R
13324 case NL80211_AUTHTYPE_FT:
13325#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013326 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013327 "%s: set authentication type to OPEN", __func__);
13328 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13329 break;
13330
13331 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013332 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013333 "%s: set authentication type to SHARED", __func__);
13334 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13335 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013336#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013337 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013338 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013339 "%s: set authentication type to CCKM WPA", __func__);
13340 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13341 break;
13342#endif
13343
13344
13345 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013346 hddLog(VOS_TRACE_LEVEL_ERROR,
13347 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013348 auth_type);
13349 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13350 return -EINVAL;
13351 }
13352
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013353 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013354 pHddStaCtx->conn_info.authType;
13355 return 0;
13356}
13357
13358/*
13359 * FUNCTION: wlan_hdd_set_akm_suite
13360 * This function is used to set the key mgmt type(PSK/8021x).
13361 *
13362 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013363static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013364 u32 key_mgmt
13365 )
13366{
13367 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13368 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013369 /* Should be in ieee802_11_defs.h */
13370#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13371#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013372 /*set key mgmt type*/
13373 switch(key_mgmt)
13374 {
13375 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013376 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013377#ifdef WLAN_FEATURE_VOWIFI_11R
13378 case WLAN_AKM_SUITE_FT_PSK:
13379#endif
13380 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013381 __func__);
13382 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13383 break;
13384
13385 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013386 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013387#ifdef WLAN_FEATURE_VOWIFI_11R
13388 case WLAN_AKM_SUITE_FT_8021X:
13389#endif
13390 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013391 __func__);
13392 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13393 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013394#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013395#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13396#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13397 case WLAN_AKM_SUITE_CCKM:
13398 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13399 __func__);
13400 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13401 break;
13402#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013403#ifndef WLAN_AKM_SUITE_OSEN
13404#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13405 case WLAN_AKM_SUITE_OSEN:
13406 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13407 __func__);
13408 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13409 break;
13410#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013411
13412 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013413 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013414 __func__, key_mgmt);
13415 return -EINVAL;
13416
13417 }
13418 return 0;
13419}
13420
13421/*
13422 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013423 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013424 * (NONE/WEP40/WEP104/TKIP/CCMP).
13425 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013426static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13427 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013428 bool ucast
13429 )
13430{
13431 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013432 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013433 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13434
13435 ENTER();
13436
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013437 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013438 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013439 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013440 __func__, cipher);
13441 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13442 }
13443 else
13444 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013445
Jeff Johnson295189b2012-06-20 16:38:30 -070013446 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013447 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013448 {
13449 case IW_AUTH_CIPHER_NONE:
13450 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13451 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013452
Jeff Johnson295189b2012-06-20 16:38:30 -070013453 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013454 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013455 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013456
Jeff Johnson295189b2012-06-20 16:38:30 -070013457 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013458 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013459 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013460
Jeff Johnson295189b2012-06-20 16:38:30 -070013461 case WLAN_CIPHER_SUITE_TKIP:
13462 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13463 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013464
Jeff Johnson295189b2012-06-20 16:38:30 -070013465 case WLAN_CIPHER_SUITE_CCMP:
13466 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13467 break;
13468#ifdef FEATURE_WLAN_WAPI
13469 case WLAN_CIPHER_SUITE_SMS4:
13470 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13471 break;
13472#endif
13473
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013474#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013475 case WLAN_CIPHER_SUITE_KRK:
13476 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13477 break;
13478#endif
13479 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013481 __func__, cipher);
13482 return -EOPNOTSUPP;
13483 }
13484 }
13485
13486 if (ucast)
13487 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013488 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013489 __func__, encryptionType);
13490 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13491 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013492 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 encryptionType;
13494 }
13495 else
13496 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013497 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013498 __func__, encryptionType);
13499 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13500 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13501 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13502 }
13503
13504 return 0;
13505}
13506
13507
13508/*
13509 * FUNCTION: wlan_hdd_cfg80211_set_ie
13510 * This function is used to parse WPA/RSN IE's.
13511 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013512int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013513#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13514 const u8 *ie,
13515#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013516 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013517#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013518 size_t ie_len
13519 )
13520{
13521 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013522#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13523 const u8 *genie = ie;
13524#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013525 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013526#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013527 v_U16_t remLen = ie_len;
13528#ifdef FEATURE_WLAN_WAPI
13529 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13530 u16 *tmp;
13531 v_U16_t akmsuiteCount;
13532 int *akmlist;
13533#endif
13534 ENTER();
13535
13536 /* clear previous assocAddIE */
13537 pWextState->assocAddIE.length = 0;
13538 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013539 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013540
13541 while (remLen >= 2)
13542 {
13543 v_U16_t eLen = 0;
13544 v_U8_t elementId;
13545 elementId = *genie++;
13546 eLen = *genie++;
13547 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013548
Arif Hussain6d2a3322013-11-17 19:50:10 -080013549 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013550 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013551
13552 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013553 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013554 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013555 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 -070013556 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013557 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013558 "%s: Invalid WPA IE", __func__);
13559 return -EINVAL;
13560 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013561 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 {
13563 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013564 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013565 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013566
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013567 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013568 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013569 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13570 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013571 VOS_ASSERT(0);
13572 return -ENOMEM;
13573 }
13574 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13575 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13576 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013577
Jeff Johnson295189b2012-06-20 16:38:30 -070013578 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
13579 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13580 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13581 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013582 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
13583 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013584 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
13585 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13586 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
13587 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
13588 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
13589 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013590 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053013591 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013592 {
13593 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013594 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013595 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013596
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013597 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013598 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013599 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13600 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013601 VOS_ASSERT(0);
13602 return -ENOMEM;
13603 }
13604 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13605 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13606 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013607
Jeff Johnson295189b2012-06-20 16:38:30 -070013608 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13609 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13610 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013611#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013612 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
13613 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013614 /*Consider WFD IE, only for P2P Client */
13615 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13616 {
13617 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013618 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013619 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013620
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013621 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013622 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013623 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13624 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013625 VOS_ASSERT(0);
13626 return -ENOMEM;
13627 }
13628 // WFD IE is saved to Additional IE ; it should be accumulated to handle
13629 // WPS IE + P2P IE + WFD IE
13630 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13631 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013632
Jeff Johnson295189b2012-06-20 16:38:30 -070013633 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13634 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13635 }
13636#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013637 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013638 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013639 HS20_OUI_TYPE_SIZE)) )
13640 {
13641 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013642 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013643 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013644
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013645 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013646 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013647 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13648 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013649 VOS_ASSERT(0);
13650 return -ENOMEM;
13651 }
13652 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13653 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013654
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013655 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13656 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13657 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013658 /* Appending OSEN Information Element in Assiciation Request */
13659 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
13660 OSEN_OUI_TYPE_SIZE)) )
13661 {
13662 v_U16_t curAddIELen = pWextState->assocAddIE.length;
13663 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
13664 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013665
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013666 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013667 {
13668 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13669 "Need bigger buffer space");
13670 VOS_ASSERT(0);
13671 return -ENOMEM;
13672 }
13673 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13674 pWextState->assocAddIE.length += eLen + 2;
13675
13676 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
13677 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13678 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13679 }
13680
Abhishek Singh4322e622015-06-10 15:42:54 +053013681 /* Update only for WPA IE */
13682 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
13683 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013684
13685 /* populating as ADDIE in beacon frames */
13686 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013687 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013688 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
13689 {
13690 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
13691 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
13692 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
13693 {
13694 hddLog(LOGE,
13695 "Coldn't pass "
13696 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
13697 }
13698 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
13699 else
13700 hddLog(LOGE,
13701 "Could not pass on "
13702 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
13703
13704 /* IBSS mode doesn't contain params->proberesp_ies still
13705 beaconIE's need to be populated in probe response frames */
13706 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
13707 {
13708 u16 rem_probe_resp_ie_len = eLen + 2;
13709 u8 probe_rsp_ie_len[3] = {0};
13710 u8 counter = 0;
13711
13712 /* Check Probe Resp Length if it is greater then 255 then
13713 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
13714 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
13715 not able Store More then 255 bytes into One Variable */
13716
13717 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
13718 {
13719 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
13720 {
13721 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
13722 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
13723 }
13724 else
13725 {
13726 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
13727 rem_probe_resp_ie_len = 0;
13728 }
13729 }
13730
13731 rem_probe_resp_ie_len = 0;
13732
13733 if (probe_rsp_ie_len[0] > 0)
13734 {
13735 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13736 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
13737 (tANI_U8*)(genie - 2),
13738 probe_rsp_ie_len[0], NULL,
13739 eANI_BOOLEAN_FALSE)
13740 == eHAL_STATUS_FAILURE)
13741 {
13742 hddLog(LOGE,
13743 "Could not pass"
13744 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
13745 }
13746 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
13747 }
13748
13749 if (probe_rsp_ie_len[1] > 0)
13750 {
13751 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13752 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
13753 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
13754 probe_rsp_ie_len[1], NULL,
13755 eANI_BOOLEAN_FALSE)
13756 == eHAL_STATUS_FAILURE)
13757 {
13758 hddLog(LOGE,
13759 "Could not pass"
13760 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
13761 }
13762 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
13763 }
13764
13765 if (probe_rsp_ie_len[2] > 0)
13766 {
13767 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13768 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
13769 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
13770 probe_rsp_ie_len[2], NULL,
13771 eANI_BOOLEAN_FALSE)
13772 == eHAL_STATUS_FAILURE)
13773 {
13774 hddLog(LOGE,
13775 "Could not pass"
13776 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
13777 }
13778 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
13779 }
13780
13781 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
13782 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
13783 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
13784 {
13785 hddLog(LOGE,
13786 "Could not pass"
13787 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
13788 }
13789 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013790 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013791 break;
13792 case DOT11F_EID_RSN:
13793 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
13794 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13795 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
13796 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
13797 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
13798 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053013799
13800 /* Appending Extended Capabilities with Interworking bit set
13801 * in Assoc Req.
13802 *
13803 * In assoc req this EXT Cap will only be taken into account if
13804 * interworkingService bit is set to 1. Currently
13805 * driver is only interested in interworkingService capability
13806 * from supplicant. If in future any other EXT Cap info is
13807 * required from supplicat, it needs to be handled while
13808 * sending Assoc Req in LIM.
13809 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013810 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013811 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013812 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013813 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013814 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013815
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013816 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013817 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013818 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13819 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013820 VOS_ASSERT(0);
13821 return -ENOMEM;
13822 }
13823 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13824 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013825
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013826 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13827 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13828 break;
13829 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013830#ifdef FEATURE_WLAN_WAPI
13831 case WLAN_EID_WAPI:
13832 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013833 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013834 pAdapter->wapi_info.nWapiMode);
13835 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013836 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070013837 akmsuiteCount = WPA_GET_LE16(tmp);
13838 tmp = tmp + 1;
13839 akmlist = (int *)(tmp);
13840 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
13841 {
13842 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
13843 }
13844 else
13845 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013846 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070013847 VOS_ASSERT(0);
13848 return -EINVAL;
13849 }
13850
13851 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
13852 {
13853 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013854 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013855 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013856 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013857 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013858 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013859 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013860 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013861 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
13862 }
13863 break;
13864#endif
13865 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013866 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013867 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013868 /* when Unknown IE is received we should break and continue
13869 * to the next IE in the buffer instead we were returning
13870 * so changing this to break */
13871 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070013872 }
13873 genie += eLen;
13874 remLen -= eLen;
13875 }
13876 EXIT();
13877 return 0;
13878}
13879
13880/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053013881 * FUNCTION: hdd_isWPAIEPresent
13882 * Parse the received IE to find the WPA IE
13883 *
13884 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013885static bool hdd_isWPAIEPresent(
13886#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
13887 const u8 *ie,
13888#else
13889 u8 *ie,
13890#endif
13891 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053013892{
13893 v_U8_t eLen = 0;
13894 v_U16_t remLen = ie_len;
13895 v_U8_t elementId = 0;
13896
13897 while (remLen >= 2)
13898 {
13899 elementId = *ie++;
13900 eLen = *ie++;
13901 remLen -= 2;
13902 if (eLen > remLen)
13903 {
13904 hddLog(VOS_TRACE_LEVEL_ERROR,
13905 "%s: IE length is wrong %d", __func__, eLen);
13906 return FALSE;
13907 }
13908 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
13909 {
13910 /* OUI - 0x00 0X50 0XF2
13911 WPA Information Element - 0x01
13912 WPA version - 0x01*/
13913 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
13914 return TRUE;
13915 }
13916 ie += eLen;
13917 remLen -= eLen;
13918 }
13919 return FALSE;
13920}
13921
13922/*
Jeff Johnson295189b2012-06-20 16:38:30 -070013923 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013924 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013925 * parameters during connect operation.
13926 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013927int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013928 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013929 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013930{
13931 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013932 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013933 ENTER();
13934
13935 /*set wpa version*/
13936 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
13937
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013938 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070013939 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053013940 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 {
13942 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13943 }
13944 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
13945 {
13946 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13947 }
13948 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013949
13950 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013951 pWextState->wpaVersion);
13952
13953 /*set authentication type*/
13954 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
13955
13956 if (0 > status)
13957 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013958 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013959 "%s: failed to set authentication type ", __func__);
13960 return status;
13961 }
13962
13963 /*set key mgmt type*/
13964 if (req->crypto.n_akm_suites)
13965 {
13966 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
13967 if (0 > status)
13968 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013969 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 __func__);
13971 return status;
13972 }
13973 }
13974
13975 /*set pairwise cipher type*/
13976 if (req->crypto.n_ciphers_pairwise)
13977 {
13978 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
13979 req->crypto.ciphers_pairwise[0], true);
13980 if (0 > status)
13981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013982 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013983 "%s: failed to set unicast cipher type", __func__);
13984 return status;
13985 }
13986 }
13987 else
13988 {
13989 /*Reset previous cipher suite to none*/
13990 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
13991 if (0 > status)
13992 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013993 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013994 "%s: failed to set unicast cipher type", __func__);
13995 return status;
13996 }
13997 }
13998
13999 /*set group cipher type*/
14000 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14001 false);
14002
14003 if (0 > status)
14004 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014005 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014006 __func__);
14007 return status;
14008 }
14009
Chet Lanctot186b5732013-03-18 10:26:30 -070014010#ifdef WLAN_FEATURE_11W
14011 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14012#endif
14013
Jeff Johnson295189b2012-06-20 16:38:30 -070014014 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14015 if (req->ie_len)
14016 {
14017 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14018 if ( 0 > status)
14019 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014021 __func__);
14022 return status;
14023 }
14024 }
14025
14026 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014027 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014028 {
14029 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14030 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14031 )
14032 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014033 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014034 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14035 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014036 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014037 __func__);
14038 return -EOPNOTSUPP;
14039 }
14040 else
14041 {
14042 u8 key_len = req->key_len;
14043 u8 key_idx = req->key_idx;
14044
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014045 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014046 && (CSR_MAX_NUM_KEY > key_idx)
14047 )
14048 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014049 hddLog(VOS_TRACE_LEVEL_INFO,
14050 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014051 __func__, key_idx, key_len);
14052 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014053 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014054 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014055 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014056 (u8)key_len;
14057 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14058 }
14059 }
14060 }
14061 }
14062
14063 return status;
14064}
14065
14066/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014067 * FUNCTION: wlan_hdd_try_disconnect
14068 * This function is used to disconnect from previous
14069 * connection
14070 */
14071static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14072{
14073 long ret = 0;
14074 hdd_station_ctx_t *pHddStaCtx;
14075 eMib_dot11DesiredBssType connectedBssType;
14076
14077 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14078
14079 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14080
14081 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14082 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
14083 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14084 {
14085 /* Issue disconnect to CSR */
14086 INIT_COMPLETION(pAdapter->disconnect_comp_var);
14087 if( eHAL_STATUS_SUCCESS ==
14088 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14089 pAdapter->sessionId,
14090 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
14091 {
14092 ret = wait_for_completion_interruptible_timeout(
14093 &pAdapter->disconnect_comp_var,
14094 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14095 if (0 >= ret)
14096 {
14097 hddLog(LOGE, FL("Failed to receive disconnect event"));
14098 return -EALREADY;
14099 }
14100 }
14101 }
14102 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14103 {
14104 ret = wait_for_completion_interruptible_timeout(
14105 &pAdapter->disconnect_comp_var,
14106 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14107 if (0 >= ret)
14108 {
14109 hddLog(LOGE, FL("Failed to receive disconnect event"));
14110 return -EALREADY;
14111 }
14112 }
14113
14114 return 0;
14115}
14116
14117/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014118 * FUNCTION: __wlan_hdd_cfg80211_connect
14119 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014120 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014121static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014122 struct net_device *ndev,
14123 struct cfg80211_connect_params *req
14124 )
14125{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014126 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014127 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014128 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014129 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014130
14131 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014132
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014133 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14134 TRACE_CODE_HDD_CFG80211_CONNECT,
14135 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014136 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014137 "%s: device_mode = %s (%d)", __func__,
14138 hdd_device_modetoString(pAdapter->device_mode),
14139 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014140
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014141 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014142 if (!pHddCtx)
14143 {
14144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14145 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014146 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014147 }
14148
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014149 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014150 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014151 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014152 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014153 }
14154
Agarwal Ashish51325b52014-06-16 16:50:49 +053014155 if (vos_max_concurrent_connections_reached()) {
14156 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14157 return -ECONNREFUSED;
14158 }
14159
Jeff Johnson295189b2012-06-20 16:38:30 -070014160#ifdef WLAN_BTAMP_FEATURE
14161 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014162 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014163 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014164 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014165 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014166 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014167 }
14168#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014169
14170 //If Device Mode is Station Concurrent Sessions Exit BMps
14171 //P2P Mode will be taken care in Open/close adapter
14172 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014173 (vos_concurrent_open_sessions_running())) {
14174 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14175 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014176 }
14177
14178 /*Try disconnecting if already in connected state*/
14179 status = wlan_hdd_try_disconnect(pAdapter);
14180 if ( 0 > status)
14181 {
14182 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14183 " connection"));
14184 return -EALREADY;
14185 }
14186
Jeff Johnson295189b2012-06-20 16:38:30 -070014187 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014188 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014189
14190 if ( 0 > status)
14191 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014192 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014193 __func__);
14194 return status;
14195 }
Mohit Khanna765234a2012-09-11 15:08:35 -070014196 if ( req->channel )
14197 {
14198 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14199 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014200 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070014201 req->channel->hw_value);
14202 }
14203 else
14204 {
14205 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014206 req->ssid_len, req->bssid,
14207 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070014208 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014209
Sushant Kaushikd7083982015-03-18 14:33:24 +053014210 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014211 {
14212 //ReEnable BMPS if disabled
14213 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14214 (NULL != pHddCtx))
14215 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014216 if (pHddCtx->hdd_wlan_suspended)
14217 {
14218 hdd_set_pwrparams(pHddCtx);
14219 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014220 //ReEnable Bmps and Imps back
14221 hdd_enable_bmps_imps(pHddCtx);
14222 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014223 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014224 return status;
14225 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014226 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014227 EXIT();
14228 return status;
14229}
14230
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014231static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14232 struct net_device *ndev,
14233 struct cfg80211_connect_params *req)
14234{
14235 int ret;
14236 vos_ssr_protect(__func__);
14237 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14238 vos_ssr_unprotect(__func__);
14239
14240 return ret;
14241}
Jeff Johnson295189b2012-06-20 16:38:30 -070014242
14243/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014244 * FUNCTION: wlan_hdd_disconnect
14245 * This function is used to issue a disconnect request to SME
14246 */
14247int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14248{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014249 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014250 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014251 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014252 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014253
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014254 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014255
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014256 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014257 if (0 != status)
14258 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014259 return status;
14260 }
14261
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014262 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
14263 {
14264 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
14265 pAdapter->sessionId);
14266 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014267 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014268
Agarwal Ashish47d18112014-08-04 19:55:07 +053014269 /* Need to apply spin lock before decreasing active sessions
14270 * as there can be chance for double decrement if context switch
14271 * Calls hdd_DisConnectHandler.
14272 */
14273
14274 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014275 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14276 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014277 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14278 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014279 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14280 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014281
Abhishek Singhf4669da2014-05-26 15:07:49 +053014282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014283 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14284
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014285 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014286
Mihir Shete182a0b22014-08-18 16:08:48 +053014287 /*
14288 * stop tx queues before deleting STA/BSS context from the firmware.
14289 * tx has to be disabled because the firmware can get busy dropping
14290 * the tx frames after BSS/STA has been deleted and will not send
14291 * back a response resulting in WDI timeout
14292 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014293 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014294 netif_tx_disable(pAdapter->dev);
14295 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014296
Mihir Shete182a0b22014-08-18 16:08:48 +053014297 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014298 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14299 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014300 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14301 {
14302 hddLog(VOS_TRACE_LEVEL_INFO,
14303 FL("status = %d, already disconnected"),
14304 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014305
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014306 }
14307 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014308 {
14309 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014310 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014311 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014312 result = -EINVAL;
14313 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014314 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014315 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014316 &pAdapter->disconnect_comp_var,
14317 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014318 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014319 {
14320 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014321 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014322 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014323 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014324 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014325 {
14326 hddLog(VOS_TRACE_LEVEL_ERROR,
14327 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014328 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014329 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014330disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14332 FL("Set HDD connState to eConnectionState_NotConnected"));
14333 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14334
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014335 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014336 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014337}
14338
14339
14340/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014341 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014342 * This function is used to issue a disconnect request to SME
14343 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014344static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014345 struct net_device *dev,
14346 u16 reason
14347 )
14348{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014349 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014350 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014351 tCsrRoamProfile *pRoamProfile;
14352 hdd_station_ctx_t *pHddStaCtx;
14353 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014354#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014355 tANI_U8 staIdx;
14356#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014357
Jeff Johnson295189b2012-06-20 16:38:30 -070014358 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014359
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014360 if (!pAdapter) {
14361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14362 return -EINVAL;
14363 }
14364
14365 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14366 if (!pHddStaCtx) {
14367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14368 return -EINVAL;
14369 }
14370
14371 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14372 status = wlan_hdd_validate_context(pHddCtx);
14373 if (0 != status)
14374 {
14375 return status;
14376 }
14377
14378 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14379
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014380 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14381 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14382 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014383 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14384 __func__, hdd_device_modetoString(pAdapter->device_mode),
14385 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014386
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014387 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14388 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014389
Jeff Johnson295189b2012-06-20 16:38:30 -070014390 if (NULL != pRoamProfile)
14391 {
14392 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014393 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14394 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014395 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014396 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014397 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014398 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014399 switch(reason)
14400 {
14401 case WLAN_REASON_MIC_FAILURE:
14402 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14403 break;
14404
14405 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14406 case WLAN_REASON_DISASSOC_AP_BUSY:
14407 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14408 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14409 break;
14410
14411 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14412 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014413 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014414 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14415 break;
14416
Jeff Johnson295189b2012-06-20 16:38:30 -070014417 default:
14418 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14419 break;
14420 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014421 pScanInfo = &pHddCtx->scan_info;
14422 if (pScanInfo->mScanPending)
14423 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014424 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014425 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014426 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014427 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014428 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014429 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014430#ifdef FEATURE_WLAN_TDLS
14431 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014432 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014433 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014434 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14435 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014436 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014437 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014438 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014440 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014441 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014442 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014443 status = sme_DeleteTdlsPeerSta(
14444 WLAN_HDD_GET_HAL_CTX(pAdapter),
14445 pAdapter->sessionId,
14446 mac);
14447 if (status != eHAL_STATUS_SUCCESS) {
14448 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14449 return -EPERM;
14450 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014451 }
14452 }
14453#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014454 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014455 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14456 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014457 {
14458 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014459 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014460 __func__, (int)status );
14461 return -EINVAL;
14462 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014463 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014464 else
14465 {
14466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14467 "called while in %d state", __func__,
14468 pHddStaCtx->conn_info.connState);
14469 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014470 }
14471 else
14472 {
14473 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14474 }
14475
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014476 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014477 return status;
14478}
14479
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014480static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14481 struct net_device *dev,
14482 u16 reason
14483 )
14484{
14485 int ret;
14486 vos_ssr_protect(__func__);
14487 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14488 vos_ssr_unprotect(__func__);
14489
14490 return ret;
14491}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014492
Jeff Johnson295189b2012-06-20 16:38:30 -070014493/*
14494 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014495 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014496 * settings in IBSS mode.
14497 */
14498static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014499 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014500 struct cfg80211_ibss_params *params
14501 )
14502{
14503 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014504 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014505 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14506 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014507
Jeff Johnson295189b2012-06-20 16:38:30 -070014508 ENTER();
14509
14510 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070014511 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070014512
14513 if (params->ie_len && ( NULL != params->ie) )
14514 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014515 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14516 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014517 {
14518 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14519 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14520 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014521 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014522 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014523 tDot11fIEWPA dot11WPAIE;
14524 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014525 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014526
Wilson Yang00256342013-10-10 23:13:38 -070014527 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014528 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14529 params->ie_len, DOT11F_EID_WPA);
14530 if ( NULL != ie )
14531 {
14532 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14533 // Unpack the WPA IE
14534 //Skip past the EID byte and length byte - and four byte WiFi OUI
14535 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
14536 &ie[2+4],
14537 ie[1] - 4,
14538 &dot11WPAIE);
14539 /*Extract the multicast cipher, the encType for unicast
14540 cipher for wpa-none is none*/
14541 encryptionType =
14542 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
14543 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014544 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014545
Jeff Johnson295189b2012-06-20 16:38:30 -070014546 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
14547
14548 if (0 > status)
14549 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014550 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014551 __func__);
14552 return status;
14553 }
14554 }
14555
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014556 pWextState->roamProfile.AuthType.authType[0] =
14557 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014558 eCSR_AUTH_TYPE_OPEN_SYSTEM;
14559
14560 if (params->privacy)
14561 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014562 /* Security enabled IBSS, At this time there is no information available
14563 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070014564 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014565 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070014566 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014567 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070014568 *enable privacy bit in beacons */
14569
14570 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
14571 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014572 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
14573 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070014574 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14575 pWextState->roamProfile.EncryptionType.numEntries = 1;
14576 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070014577 return status;
14578}
14579
14580/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014581 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014582 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014583 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014584static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014585 struct net_device *dev,
14586 struct cfg80211_ibss_params *params
14587 )
14588{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014589 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014590 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14591 tCsrRoamProfile *pRoamProfile;
14592 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014593 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14594 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014595 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070014596
14597 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014598
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014599 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14600 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
14601 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014602 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014603 "%s: device_mode = %s (%d)", __func__,
14604 hdd_device_modetoString(pAdapter->device_mode),
14605 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014606
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014607 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014608 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014609 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014610 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014611 }
14612
14613 if (NULL == pWextState)
14614 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014615 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014616 __func__);
14617 return -EIO;
14618 }
14619
Agarwal Ashish51325b52014-06-16 16:50:49 +053014620 if (vos_max_concurrent_connections_reached()) {
14621 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14622 return -ECONNREFUSED;
14623 }
14624
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014625 /*Try disconnecting if already in connected state*/
14626 status = wlan_hdd_try_disconnect(pAdapter);
14627 if ( 0 > status)
14628 {
14629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14630 " IBSS connection"));
14631 return -EALREADY;
14632 }
14633
Jeff Johnson295189b2012-06-20 16:38:30 -070014634 pRoamProfile = &pWextState->roamProfile;
14635
14636 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
14637 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014638 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014639 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014640 return -EINVAL;
14641 }
14642
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014643 /* BSSID is provided by upper layers hence no need to AUTO generate */
14644 if (NULL != params->bssid) {
14645 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14646 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
14647 hddLog (VOS_TRACE_LEVEL_ERROR,
14648 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14649 return -EIO;
14650 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014651 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014652 }
krunal sonie9002db2013-11-25 14:24:17 -080014653 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
14654 {
14655 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14656 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
14657 {
14658 hddLog (VOS_TRACE_LEVEL_ERROR,
14659 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14660 return -EIO;
14661 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014662
14663 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080014664 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014665 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080014666 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014667
Jeff Johnson295189b2012-06-20 16:38:30 -070014668 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070014669 if (NULL !=
14670#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14671 params->chandef.chan)
14672#else
14673 params->channel)
14674#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014675 {
14676 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014677 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14678 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
14679 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14680 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014681
14682 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014683 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070014684 ieee80211_frequency_to_channel(
14685#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14686 params->chandef.chan->center_freq);
14687#else
14688 params->channel->center_freq);
14689#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014690
14691 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14692 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070014693 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014694 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
14695 __func__);
14696 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014697 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014698
14699 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014700 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014701 if (channelNum == validChan[indx])
14702 {
14703 break;
14704 }
14705 }
14706 if (indx >= numChans)
14707 {
14708 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014709 __func__, channelNum);
14710 return -EINVAL;
14711 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014712 /* Set the Operational Channel */
14713 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
14714 channelNum);
14715 pRoamProfile->ChannelInfo.numOfChannels = 1;
14716 pHddStaCtx->conn_info.operationChannel = channelNum;
14717 pRoamProfile->ChannelInfo.ChannelList =
14718 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070014719 }
14720
14721 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014722 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070014723 if (status < 0)
14724 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014725 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070014726 __func__);
14727 return status;
14728 }
14729
14730 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014731 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014732 params->ssid_len, params->bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014733 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014734
14735 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014736 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014737
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014738 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014739 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014740}
14741
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014742static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
14743 struct net_device *dev,
14744 struct cfg80211_ibss_params *params
14745 )
14746{
14747 int ret = 0;
14748
14749 vos_ssr_protect(__func__);
14750 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
14751 vos_ssr_unprotect(__func__);
14752
14753 return ret;
14754}
14755
Jeff Johnson295189b2012-06-20 16:38:30 -070014756/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014757 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014758 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014759 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014760static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014761 struct net_device *dev
14762 )
14763{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014764 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014765 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14766 tCsrRoamProfile *pRoamProfile;
14767 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014768 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014769
14770 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014771
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014772 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14773 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
14774 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014775 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014776 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014777 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014778 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014779 }
14780
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014781 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
14782 hdd_device_modetoString(pAdapter->device_mode),
14783 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014784 if (NULL == pWextState)
14785 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014786 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014787 __func__);
14788 return -EIO;
14789 }
14790
14791 pRoamProfile = &pWextState->roamProfile;
14792
14793 /* Issue disconnect only if interface type is set to IBSS */
14794 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
14795 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014796 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070014797 __func__);
14798 return -EINVAL;
14799 }
14800
14801 /* Issue Disconnect request */
14802 INIT_COMPLETION(pAdapter->disconnect_comp_var);
14803 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14804 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
14805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014806 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014807 return 0;
14808}
14809
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014810static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
14811 struct net_device *dev
14812 )
14813{
14814 int ret = 0;
14815
14816 vos_ssr_protect(__func__);
14817 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
14818 vos_ssr_unprotect(__func__);
14819
14820 return ret;
14821}
14822
Jeff Johnson295189b2012-06-20 16:38:30 -070014823/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014824 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070014825 * This function is used to set the phy parameters
14826 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
14827 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014828static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014829 u32 changed)
14830{
14831 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
14832 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014833 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014834
14835 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014836
14837 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014838 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
14839 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014840
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014841 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014842 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014843 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014844 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014845 }
14846
Jeff Johnson295189b2012-06-20 16:38:30 -070014847 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
14848 {
14849 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
14850 WNI_CFG_RTS_THRESHOLD_STAMAX :
14851 wiphy->rts_threshold;
14852
14853 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014854 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070014855 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014856 hddLog(VOS_TRACE_LEVEL_ERROR,
14857 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014858 __func__, rts_threshold);
14859 return -EINVAL;
14860 }
14861
14862 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
14863 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014864 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014865 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014866 hddLog(VOS_TRACE_LEVEL_ERROR,
14867 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014868 __func__, rts_threshold);
14869 return -EIO;
14870 }
14871
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014872 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014873 rts_threshold);
14874 }
14875
14876 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
14877 {
14878 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
14879 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
14880 wiphy->frag_threshold;
14881
14882 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014883 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070014884 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014885 hddLog(VOS_TRACE_LEVEL_ERROR,
14886 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014887 frag_threshold);
14888 return -EINVAL;
14889 }
14890
14891 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
14892 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014893 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014894 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014895 hddLog(VOS_TRACE_LEVEL_ERROR,
14896 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014897 __func__, frag_threshold);
14898 return -EIO;
14899 }
14900
14901 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
14902 frag_threshold);
14903 }
14904
14905 if ((changed & WIPHY_PARAM_RETRY_SHORT)
14906 || (changed & WIPHY_PARAM_RETRY_LONG))
14907 {
14908 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
14909 wiphy->retry_short :
14910 wiphy->retry_long;
14911
14912 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
14913 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
14914 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014915 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014916 __func__, retry_value);
14917 return -EINVAL;
14918 }
14919
14920 if (changed & WIPHY_PARAM_RETRY_SHORT)
14921 {
14922 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
14923 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014924 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014925 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014926 hddLog(VOS_TRACE_LEVEL_ERROR,
14927 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014928 __func__, retry_value);
14929 return -EIO;
14930 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014931 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014932 __func__, retry_value);
14933 }
14934 else if (changed & WIPHY_PARAM_RETRY_SHORT)
14935 {
14936 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
14937 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014938 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014939 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014940 hddLog(VOS_TRACE_LEVEL_ERROR,
14941 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014942 __func__, retry_value);
14943 return -EIO;
14944 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014945 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014946 __func__, retry_value);
14947 }
14948 }
14949
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014950 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014951 return 0;
14952}
14953
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014954static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
14955 u32 changed)
14956{
14957 int ret;
14958
14959 vos_ssr_protect(__func__);
14960 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
14961 vos_ssr_unprotect(__func__);
14962
14963 return ret;
14964}
14965
Jeff Johnson295189b2012-06-20 16:38:30 -070014966/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014967 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070014968 * This function is used to set the txpower
14969 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014970static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070014971#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14972 struct wireless_dev *wdev,
14973#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014974#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014975 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070014976#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014977 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070014978#endif
14979 int dbm)
14980{
14981 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014982 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014983 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
14984 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014985 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014986
14987 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014988
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014989 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14990 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
14991 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014992 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014993 if (0 != status)
14994 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014995 return status;
14996 }
14997
14998 hHal = pHddCtx->hHal;
14999
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015000 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15001 dbm, ccmCfgSetCallback,
15002 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015003 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015004 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015005 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15006 return -EIO;
15007 }
15008
15009 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15010 dbm);
15011
15012 switch(type)
15013 {
15014 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15015 /* Fall through */
15016 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15017 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15018 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015019 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15020 __func__);
15021 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015022 }
15023 break;
15024 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015026 __func__);
15027 return -EOPNOTSUPP;
15028 break;
15029 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15031 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015032 return -EIO;
15033 }
15034
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015035 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015036 return 0;
15037}
15038
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015039static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15040#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15041 struct wireless_dev *wdev,
15042#endif
15043#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15044 enum tx_power_setting type,
15045#else
15046 enum nl80211_tx_power_setting type,
15047#endif
15048 int dbm)
15049{
15050 int ret;
15051 vos_ssr_protect(__func__);
15052 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15053#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15054 wdev,
15055#endif
15056#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15057 type,
15058#else
15059 type,
15060#endif
15061 dbm);
15062 vos_ssr_unprotect(__func__);
15063
15064 return ret;
15065}
15066
Jeff Johnson295189b2012-06-20 16:38:30 -070015067/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015068 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015069 * This function is used to read the txpower
15070 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015071static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015072#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15073 struct wireless_dev *wdev,
15074#endif
15075 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015076{
15077
15078 hdd_adapter_t *pAdapter;
15079 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015080 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015081
Jeff Johnsone7245742012-09-05 17:12:55 -070015082 ENTER();
15083
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015084 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015085 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015086 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015087 *dbm = 0;
15088 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015089 }
15090
Jeff Johnson295189b2012-06-20 16:38:30 -070015091 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15092 if (NULL == pAdapter)
15093 {
15094 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15095 return -ENOENT;
15096 }
15097
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015098 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15099 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15100 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015101 wlan_hdd_get_classAstats(pAdapter);
15102 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15103
Jeff Johnsone7245742012-09-05 17:12:55 -070015104 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015105 return 0;
15106}
15107
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015108static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15109#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15110 struct wireless_dev *wdev,
15111#endif
15112 int *dbm)
15113{
15114 int ret;
15115
15116 vos_ssr_protect(__func__);
15117 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15118#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15119 wdev,
15120#endif
15121 dbm);
15122 vos_ssr_unprotect(__func__);
15123
15124 return ret;
15125}
15126
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015127static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015128#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15129 const u8* mac,
15130#else
15131 u8* mac,
15132#endif
15133 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015134{
15135 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15136 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15137 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015138 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015139
15140 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15141 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015142
15143 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15144 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15145 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15146 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15147 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15148 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15149 tANI_U16 maxRate = 0;
15150 tANI_U16 myRate;
15151 tANI_U16 currentRate = 0;
15152 tANI_U8 maxSpeedMCS = 0;
15153 tANI_U8 maxMCSIdx = 0;
15154 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015155 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015156 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015157 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015158
Leo Chang6f8870f2013-03-26 18:11:36 -070015159#ifdef WLAN_FEATURE_11AC
15160 tANI_U32 vht_mcs_map;
15161 eDataRate11ACMaxMcs vhtMaxMcs;
15162#endif /* WLAN_FEATURE_11AC */
15163
Jeff Johnsone7245742012-09-05 17:12:55 -070015164 ENTER();
15165
Jeff Johnson295189b2012-06-20 16:38:30 -070015166 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15167 (0 == ssidlen))
15168 {
15169 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15170 " Invalid ssidlen, %d", __func__, ssidlen);
15171 /*To keep GUI happy*/
15172 return 0;
15173 }
15174
Mukul Sharma811205f2014-07-09 21:07:30 +053015175 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15176 {
15177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15178 "%s: Roaming in progress, so unable to proceed this request", __func__);
15179 return 0;
15180 }
15181
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015182 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015183 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015184 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015185 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015186 }
15187
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015188 wlan_hdd_get_station_stats(pAdapter);
15189 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015190
Kiet Lam3b17fc82013-09-27 05:24:08 +053015191 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15192 sinfo->filled |= STATION_INFO_SIGNAL;
15193
c_hpothu09f19542014-05-30 21:53:31 +053015194 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015195 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15196 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015197 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015198 {
15199 rate_flags = pAdapter->maxRateFlags;
15200 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015201
Jeff Johnson295189b2012-06-20 16:38:30 -070015202 //convert to the UI units of 100kbps
15203 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15204
15205#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015206 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 -070015207 sinfo->signal,
15208 pCfg->reportMaxLinkSpeed,
15209 myRate,
15210 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015211 (int) pCfg->linkSpeedRssiMid,
15212 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015213 (int) rate_flags,
15214 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015215#endif //LINKSPEED_DEBUG_ENABLED
15216
15217 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15218 {
15219 // we do not want to necessarily report the current speed
15220 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15221 {
15222 // report the max possible speed
15223 rssidx = 0;
15224 }
15225 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15226 {
15227 // report the max possible speed with RSSI scaling
15228 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15229 {
15230 // report the max possible speed
15231 rssidx = 0;
15232 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015233 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015234 {
15235 // report middle speed
15236 rssidx = 1;
15237 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015238 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15239 {
15240 // report middle speed
15241 rssidx = 2;
15242 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015243 else
15244 {
15245 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015246 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015247 }
15248 }
15249 else
15250 {
15251 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15252 hddLog(VOS_TRACE_LEVEL_ERROR,
15253 "%s: Invalid value for reportMaxLinkSpeed: %u",
15254 __func__, pCfg->reportMaxLinkSpeed);
15255 rssidx = 0;
15256 }
15257
15258 maxRate = 0;
15259
15260 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015261 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15262 OperationalRates, &ORLeng))
15263 {
15264 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15265 /*To keep GUI happy*/
15266 return 0;
15267 }
15268
Jeff Johnson295189b2012-06-20 16:38:30 -070015269 for (i = 0; i < ORLeng; i++)
15270 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015271 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015272 {
15273 /* Validate Rate Set */
15274 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15275 {
15276 currentRate = supported_data_rate[j].supported_rate[rssidx];
15277 break;
15278 }
15279 }
15280 /* Update MAX rate */
15281 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15282 }
15283
15284 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015285 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15286 ExtendedRates, &ERLeng))
15287 {
15288 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15289 /*To keep GUI happy*/
15290 return 0;
15291 }
15292
Jeff Johnson295189b2012-06-20 16:38:30 -070015293 for (i = 0; i < ERLeng; i++)
15294 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015295 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015296 {
15297 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15298 {
15299 currentRate = supported_data_rate[j].supported_rate[rssidx];
15300 break;
15301 }
15302 }
15303 /* Update MAX rate */
15304 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15305 }
c_hpothu79aab322014-07-14 21:11:01 +053015306
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015307 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015308 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015309 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015310 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015311 {
c_hpothu79aab322014-07-14 21:11:01 +053015312 if (rate_flags & eHAL_TX_RATE_VHT80)
15313 mode = 2;
15314 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15315 mode = 1;
15316 else
15317 mode = 0;
15318
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015319 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15320 MCSRates, &MCSLeng))
15321 {
15322 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15323 /*To keep GUI happy*/
15324 return 0;
15325 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015326 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015327#ifdef WLAN_FEATURE_11AC
15328 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015329 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015330 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015331 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015332 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015333 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015334 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015335 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015336 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015337 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015338 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015339 maxMCSIdx = 7;
15340 }
15341 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15342 {
15343 maxMCSIdx = 8;
15344 }
15345 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15346 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015347 //VHT20 is supporting 0~8
15348 if (rate_flags & eHAL_TX_RATE_VHT20)
15349 maxMCSIdx = 8;
15350 else
15351 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015352 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015353
c_hpothu79aab322014-07-14 21:11:01 +053015354 if (0 != rssidx)/*check for scaled */
15355 {
15356 //get middle rate MCS index if rssi=1/2
15357 for (i=0; i <= maxMCSIdx; i++)
15358 {
15359 if (sinfo->signal <= rssiMcsTbl[mode][i])
15360 {
15361 maxMCSIdx = i;
15362 break;
15363 }
15364 }
15365 }
15366
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015367 if (rate_flags & eHAL_TX_RATE_VHT80)
15368 {
15369 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15370 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15371 }
15372 else if (rate_flags & eHAL_TX_RATE_VHT40)
15373 {
15374 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15375 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15376 }
15377 else if (rate_flags & eHAL_TX_RATE_VHT20)
15378 {
15379 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15380 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15381 }
15382
Leo Chang6f8870f2013-03-26 18:11:36 -070015383 maxSpeedMCS = 1;
15384 if (currentRate > maxRate)
15385 {
15386 maxRate = currentRate;
15387 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015388
Leo Chang6f8870f2013-03-26 18:11:36 -070015389 }
15390 else
15391#endif /* WLAN_FEATURE_11AC */
15392 {
15393 if (rate_flags & eHAL_TX_RATE_HT40)
15394 {
15395 rateFlag |= 1;
15396 }
15397 if (rate_flags & eHAL_TX_RATE_SGI)
15398 {
15399 rateFlag |= 2;
15400 }
15401
Girish Gowli01abcee2014-07-31 20:18:55 +053015402 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015403 if (rssidx == 1 || rssidx == 2)
15404 {
15405 //get middle rate MCS index if rssi=1/2
15406 for (i=0; i <= 7; i++)
15407 {
15408 if (sinfo->signal <= rssiMcsTbl[mode][i])
15409 {
15410 temp = i+1;
15411 break;
15412 }
15413 }
15414 }
c_hpothu79aab322014-07-14 21:11:01 +053015415
15416 for (i = 0; i < MCSLeng; i++)
15417 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015418 for (j = 0; j < temp; j++)
15419 {
15420 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15421 {
15422 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015423 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015424 break;
15425 }
15426 }
15427 if ((j < temp) && (currentRate > maxRate))
15428 {
15429 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015430 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015431 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015432 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015433 }
15434 }
15435
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015436 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15437 {
15438 maxRate = myRate;
15439 maxSpeedMCS = 1;
15440 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15441 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015442 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015443 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015444 {
15445 maxRate = myRate;
15446 if (rate_flags & eHAL_TX_RATE_LEGACY)
15447 {
15448 maxSpeedMCS = 0;
15449 }
15450 else
15451 {
15452 maxSpeedMCS = 1;
15453 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15454 }
15455 }
15456
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015457 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070015458 {
15459 sinfo->txrate.legacy = maxRate;
15460#ifdef LINKSPEED_DEBUG_ENABLED
15461 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
15462#endif //LINKSPEED_DEBUG_ENABLED
15463 }
15464 else
15465 {
15466 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070015467#ifdef WLAN_FEATURE_11AC
15468 sinfo->txrate.nss = 1;
15469 if (rate_flags & eHAL_TX_RATE_VHT80)
15470 {
15471 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015472 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070015473 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015474 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070015475 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015476 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15477 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15478 }
15479 else if (rate_flags & eHAL_TX_RATE_VHT20)
15480 {
15481 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15482 }
15483#endif /* WLAN_FEATURE_11AC */
15484 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
15485 {
15486 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15487 if (rate_flags & eHAL_TX_RATE_HT40)
15488 {
15489 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15490 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015491 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015492 if (rate_flags & eHAL_TX_RATE_SGI)
15493 {
15494 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15495 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015496
Jeff Johnson295189b2012-06-20 16:38:30 -070015497#ifdef LINKSPEED_DEBUG_ENABLED
15498 pr_info("Reporting MCS rate %d flags %x\n",
15499 sinfo->txrate.mcs,
15500 sinfo->txrate.flags );
15501#endif //LINKSPEED_DEBUG_ENABLED
15502 }
15503 }
15504 else
15505 {
15506 // report current rate instead of max rate
15507
15508 if (rate_flags & eHAL_TX_RATE_LEGACY)
15509 {
15510 //provide to the UI in units of 100kbps
15511 sinfo->txrate.legacy = myRate;
15512#ifdef LINKSPEED_DEBUG_ENABLED
15513 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
15514#endif //LINKSPEED_DEBUG_ENABLED
15515 }
15516 else
15517 {
15518 //must be MCS
15519 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015520#ifdef WLAN_FEATURE_11AC
15521 sinfo->txrate.nss = 1;
15522 if (rate_flags & eHAL_TX_RATE_VHT80)
15523 {
15524 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15525 }
15526 else
15527#endif /* WLAN_FEATURE_11AC */
15528 {
15529 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15530 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015531 if (rate_flags & eHAL_TX_RATE_SGI)
15532 {
15533 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15534 }
15535 if (rate_flags & eHAL_TX_RATE_HT40)
15536 {
15537 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15538 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015539#ifdef WLAN_FEATURE_11AC
15540 else if (rate_flags & eHAL_TX_RATE_VHT80)
15541 {
15542 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
15543 }
15544#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070015545#ifdef LINKSPEED_DEBUG_ENABLED
15546 pr_info("Reporting actual MCS rate %d flags %x\n",
15547 sinfo->txrate.mcs,
15548 sinfo->txrate.flags );
15549#endif //LINKSPEED_DEBUG_ENABLED
15550 }
15551 }
15552 sinfo->filled |= STATION_INFO_TX_BITRATE;
15553
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015554 sinfo->tx_packets =
15555 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
15556 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
15557 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
15558 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
15559
15560 sinfo->tx_retries =
15561 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
15562 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
15563 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
15564 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
15565
15566 sinfo->tx_failed =
15567 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
15568 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
15569 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
15570 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
15571
15572 sinfo->filled |=
15573 STATION_INFO_TX_PACKETS |
15574 STATION_INFO_TX_RETRIES |
15575 STATION_INFO_TX_FAILED;
15576
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015577 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15578 TRACE_CODE_HDD_CFG80211_GET_STA,
15579 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015580 EXIT();
15581 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015582}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015583#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15584static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15585 const u8* mac, struct station_info *sinfo)
15586#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015587static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15588 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015589#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015590{
15591 int ret;
15592
15593 vos_ssr_protect(__func__);
15594 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
15595 vos_ssr_unprotect(__func__);
15596
15597 return ret;
15598}
15599
15600static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070015601 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070015602{
15603 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015604 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015605 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015606 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015607
Jeff Johnsone7245742012-09-05 17:12:55 -070015608 ENTER();
15609
Jeff Johnson295189b2012-06-20 16:38:30 -070015610 if (NULL == pAdapter)
15611 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015612 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015613 return -ENODEV;
15614 }
15615
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015616 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15617 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
15618 pAdapter->sessionId, timeout));
15619
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015620 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015621 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015622 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015623 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015624 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015625 }
15626
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015627 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
15628 (TRUE == pHddCtx->hdd_wlan_suspended) &&
15629 (pHddCtx->cfg_ini->fhostArpOffload) &&
15630 (eConnectionState_Associated ==
15631 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15632 {
Amar Singhald53568e2013-09-26 11:03:45 -070015633
15634 hddLog(VOS_TRACE_LEVEL_INFO,
15635 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053015636 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015637 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15638 {
15639 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015640 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015641 __func__, vos_status);
15642 }
15643 }
15644
Jeff Johnson295189b2012-06-20 16:38:30 -070015645 /**The get power cmd from the supplicant gets updated by the nl only
15646 *on successful execution of the function call
15647 *we are oppositely mapped w.r.t mode in the driver
15648 **/
15649 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
15650
15651 if (VOS_STATUS_E_FAILURE == vos_status)
15652 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15654 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015655 return -EINVAL;
15656 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015657 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015658 return 0;
15659}
15660
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015661static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
15662 struct net_device *dev, bool mode, int timeout)
15663{
15664 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015665
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015666 vos_ssr_protect(__func__);
15667 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
15668 vos_ssr_unprotect(__func__);
15669
15670 return ret;
15671}
Sushant Kaushik084f6592015-09-10 13:11:56 +053015672
Jeff Johnson295189b2012-06-20 16:38:30 -070015673#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015674static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
15675 struct net_device *netdev,
15676 u8 key_index)
15677{
15678 ENTER();
15679 return 0;
15680}
15681
Jeff Johnson295189b2012-06-20 16:38:30 -070015682static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015683 struct net_device *netdev,
15684 u8 key_index)
15685{
15686 int ret;
15687 vos_ssr_protect(__func__);
15688 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
15689 vos_ssr_unprotect(__func__);
15690 return ret;
15691}
15692#endif //LINUX_VERSION_CODE
15693
15694#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15695static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15696 struct net_device *dev,
15697 struct ieee80211_txq_params *params)
15698{
15699 ENTER();
15700 return 0;
15701}
15702#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15703static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15704 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015705{
Jeff Johnsone7245742012-09-05 17:12:55 -070015706 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070015707 return 0;
15708}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015709#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070015710
15711#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15712static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015713 struct net_device *dev,
15714 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015715{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015716 int ret;
15717
15718 vos_ssr_protect(__func__);
15719 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
15720 vos_ssr_unprotect(__func__);
15721 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015722}
15723#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15724static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
15725 struct ieee80211_txq_params *params)
15726{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015727 int ret;
15728
15729 vos_ssr_protect(__func__);
15730 ret = __wlan_hdd_set_txq_params(wiphy, params);
15731 vos_ssr_unprotect(__func__);
15732 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015733}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015734#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015735
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015736static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015737 struct net_device *dev,
15738 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070015739{
15740 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015741 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015742 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015743 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015744 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015745 v_CONTEXT_t pVosContext = NULL;
15746 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015747
Jeff Johnsone7245742012-09-05 17:12:55 -070015748 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015749
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015750 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070015751 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015752 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015753 return -EINVAL;
15754 }
15755
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015756 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15757 TRACE_CODE_HDD_CFG80211_DEL_STA,
15758 pAdapter->sessionId, pAdapter->device_mode));
15759
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015760 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15761 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015762 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015763 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015764 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015765 }
15766
Jeff Johnson295189b2012-06-20 16:38:30 -070015767 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015768 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015769 )
15770 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015771 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15772 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15773 if(pSapCtx == NULL){
15774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15775 FL("psapCtx is NULL"));
15776 return -ENOENT;
15777 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015778 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070015779 {
15780 v_U16_t i;
15781 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
15782 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015783 if ((pSapCtx->aStaInfo[i].isUsed) &&
15784 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070015785 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015786 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015787 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015788 ETHER_ADDR_LEN);
15789
Jeff Johnson295189b2012-06-20 16:38:30 -070015790 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080015791 "%s: Delete STA with MAC::"
15792 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015793 __func__,
15794 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
15795 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070015796 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015797 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015798 }
15799 }
15800 }
15801 else
15802 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015803
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015804 vos_status = hdd_softap_GetStaId(pAdapter,
15805 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015806 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15807 {
15808 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080015809 "%s: Skip this DEL STA as this is not used::"
15810 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015811 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015812 return -ENOENT;
15813 }
15814
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015815 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015816 {
15817 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080015818 "%s: Skip this DEL STA as deauth is in progress::"
15819 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015820 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015821 return -ENOENT;
15822 }
15823
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015824 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015825
Jeff Johnson295189b2012-06-20 16:38:30 -070015826 hddLog(VOS_TRACE_LEVEL_INFO,
15827 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080015828 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015829 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015830 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015831
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015832 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015833 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15834 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015835 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015836 hddLog(VOS_TRACE_LEVEL_INFO,
15837 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080015838 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015839 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015840 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015841 return -ENOENT;
15842 }
15843
Jeff Johnson295189b2012-06-20 16:38:30 -070015844 }
15845 }
15846
15847 EXIT();
15848
15849 return 0;
15850}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015851
15852#ifdef CFG80211_DEL_STA_V2
15853static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
15854 struct net_device *dev,
15855 struct station_del_parameters *param)
15856#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015857#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15858static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
15859 struct net_device *dev, const u8 *mac)
15860#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015861static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
15862 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015863#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015864#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015865{
15866 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015867 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070015868
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015869 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015870
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015871#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015872 if (NULL == param) {
15873 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015874 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015875 return -EINVAL;
15876 }
15877
15878 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
15879 param->subtype, &delStaParams);
15880
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015881#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053015882 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015883 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015884#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015885 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
15886
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015887 vos_ssr_unprotect(__func__);
15888
15889 return ret;
15890}
15891
15892static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015893 struct net_device *dev,
15894#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15895 const u8 *mac,
15896#else
15897 u8 *mac,
15898#endif
15899 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015900{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015901 hdd_adapter_t *pAdapter;
15902 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015903 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015904#ifdef FEATURE_WLAN_TDLS
15905 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015906
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015907 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015908
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015909 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15910 if (NULL == pAdapter)
15911 {
15912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15913 "%s: Adapter is NULL",__func__);
15914 return -EINVAL;
15915 }
15916 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15917 status = wlan_hdd_validate_context(pHddCtx);
15918 if (0 != status)
15919 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015920 return status;
15921 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015922
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015923 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15924 TRACE_CODE_HDD_CFG80211_ADD_STA,
15925 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015926 mask = params->sta_flags_mask;
15927
15928 set = params->sta_flags_set;
15929
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015930 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015931 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
15932 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015933
15934 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
15935 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015936 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015937 }
15938 }
15939#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015940 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015941 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015942}
15943
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015944#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15945static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
15946 struct net_device *dev, const u8 *mac,
15947 struct station_parameters *params)
15948#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015949static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
15950 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015951#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015952{
15953 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015954
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015955 vos_ssr_protect(__func__);
15956 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
15957 vos_ssr_unprotect(__func__);
15958
15959 return ret;
15960}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015961#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070015962
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015963static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070015964 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015965{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015966 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15967 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015968 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015969 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015970 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015971 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070015972
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015973 ENTER();
15974
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015975 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015976 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015977 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015978 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015979 return -EINVAL;
15980 }
15981
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015982 if (!pmksa) {
15983 hddLog(LOGE, FL("pmksa is NULL"));
15984 return -EINVAL;
15985 }
15986
15987 if (!pmksa->bssid || !pmksa->pmkid) {
15988 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
15989 pmksa->bssid, pmksa->pmkid);
15990 return -EINVAL;
15991 }
15992
15993 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
15994 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
15995
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015996 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15997 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015998 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015999 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016000 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016001 }
16002
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016003 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016004 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16005
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016006 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16007 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016008
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016009 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016010 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016011 &pmk_id, 1, FALSE);
16012
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016013 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16014 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16015 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016016
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016017 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016018 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016019}
16020
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016021static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16022 struct cfg80211_pmksa *pmksa)
16023{
16024 int ret;
16025
16026 vos_ssr_protect(__func__);
16027 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16028 vos_ssr_unprotect(__func__);
16029
16030 return ret;
16031}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016032
Wilson Yang6507c4e2013-10-01 20:11:19 -070016033
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016034static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016035 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016036{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016037 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16038 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016039 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016040 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016041
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016042 ENTER();
16043
Wilson Yang6507c4e2013-10-01 20:11:19 -070016044 /* Validate pAdapter */
16045 if (NULL == pAdapter)
16046 {
16047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16048 return -EINVAL;
16049 }
16050
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016051 if (!pmksa) {
16052 hddLog(LOGE, FL("pmksa is NULL"));
16053 return -EINVAL;
16054 }
16055
16056 if (!pmksa->bssid) {
16057 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16058 return -EINVAL;
16059 }
16060
Kiet Lam98c46a12014-10-31 15:34:57 -070016061 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16062 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16063
Wilson Yang6507c4e2013-10-01 20:11:19 -070016064 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16065 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016066 if (0 != status)
16067 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016068 return status;
16069 }
16070
16071 /*Retrieve halHandle*/
16072 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16073
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016074 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16075 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16076 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016077 /* Delete the PMKID CSR cache */
16078 if (eHAL_STATUS_SUCCESS !=
16079 sme_RoamDelPMKIDfromCache(halHandle,
16080 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16081 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16082 MAC_ADDR_ARRAY(pmksa->bssid));
16083 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016084 }
16085
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016086 EXIT();
16087 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016088}
16089
Wilson Yang6507c4e2013-10-01 20:11:19 -070016090
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016091static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16092 struct cfg80211_pmksa *pmksa)
16093{
16094 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016095
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016096 vos_ssr_protect(__func__);
16097 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16098 vos_ssr_unprotect(__func__);
16099
16100 return ret;
16101
16102}
16103
16104static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016105{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016106 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16107 tHalHandle halHandle;
16108 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016109 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016110
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016111 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016112
16113 /* Validate pAdapter */
16114 if (NULL == pAdapter)
16115 {
16116 hddLog(VOS_TRACE_LEVEL_ERROR,
16117 "%s: Invalid Adapter" ,__func__);
16118 return -EINVAL;
16119 }
16120
16121 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16122 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016123 if (0 != status)
16124 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016125 return status;
16126 }
16127
16128 /*Retrieve halHandle*/
16129 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16130
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016131 /* Flush the PMKID cache in CSR */
16132 if (eHAL_STATUS_SUCCESS !=
16133 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16134 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16135 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016136 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016137 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016138 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016139}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016140
16141static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16142{
16143 int ret;
16144
16145 vos_ssr_protect(__func__);
16146 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16147 vos_ssr_unprotect(__func__);
16148
16149 return ret;
16150}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016151#endif
16152
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016153#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016154static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16155 struct net_device *dev,
16156 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016157{
16158 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16159 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016160 hdd_context_t *pHddCtx;
16161 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016162
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016163 ENTER();
16164
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016165 if (NULL == pAdapter)
16166 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016168 return -ENODEV;
16169 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016170 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16171 ret = wlan_hdd_validate_context(pHddCtx);
16172 if (0 != ret)
16173 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016174 return ret;
16175 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016176 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016177 if (NULL == pHddStaCtx)
16178 {
16179 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16180 return -EINVAL;
16181 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016182
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016183 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16184 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16185 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016186 // Added for debug on reception of Re-assoc Req.
16187 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16188 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016189 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016190 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016191 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016192 }
16193
16194#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016195 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016196 ftie->ie_len);
16197#endif
16198
16199 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016200 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16201 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016202 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016203
16204 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016205 return 0;
16206}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016207
16208static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16209 struct net_device *dev,
16210 struct cfg80211_update_ft_ies_params *ftie)
16211{
16212 int ret;
16213
16214 vos_ssr_protect(__func__);
16215 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16216 vos_ssr_unprotect(__func__);
16217
16218 return ret;
16219}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016220#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016221
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016222#ifdef FEATURE_WLAN_SCAN_PNO
16223
16224void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16225 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16226{
16227 int ret;
16228 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16229 hdd_context_t *pHddCtx;
16230
Nirav Shah80830bf2013-12-31 16:35:12 +053016231 ENTER();
16232
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016233 if (NULL == pAdapter)
16234 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016236 "%s: HDD adapter is Null", __func__);
16237 return ;
16238 }
16239
16240 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16241 if (NULL == pHddCtx)
16242 {
16243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16244 "%s: HDD context is Null!!!", __func__);
16245 return ;
16246 }
16247
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016248 spin_lock(&pHddCtx->schedScan_lock);
16249 if (TRUE == pHddCtx->isWiphySuspended)
16250 {
16251 pHddCtx->isSchedScanUpdatePending = TRUE;
16252 spin_unlock(&pHddCtx->schedScan_lock);
16253 hddLog(VOS_TRACE_LEVEL_INFO,
16254 "%s: Update cfg80211 scan database after it resume", __func__);
16255 return ;
16256 }
16257 spin_unlock(&pHddCtx->schedScan_lock);
16258
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016259 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16260
16261 if (0 > ret)
16262 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
16263
16264 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16266 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016267}
16268
16269/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016270 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016271 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016272 */
16273static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16274{
16275 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16276 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016277 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016278 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16279 int status = 0;
16280 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16281
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016282 /* The current firmware design does not allow PNO during any
16283 * active sessions. Hence, determine the active sessions
16284 * and return a failure.
16285 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016286 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16287 {
16288 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016289 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016290
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016291 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16292 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16293 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16294 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16295 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016296 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016297 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016298 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016299 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016300 }
16301 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16302 pAdapterNode = pNext;
16303 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016304 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016305}
16306
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016307void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16308{
16309 hdd_adapter_t *pAdapter = callbackContext;
16310 hdd_context_t *pHddCtx;
16311
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016312 ENTER();
16313
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016314 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16315 {
16316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16317 FL("Invalid adapter or adapter has invalid magic"));
16318 return;
16319 }
16320
16321 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16322 if (0 != wlan_hdd_validate_context(pHddCtx))
16323 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016324 return;
16325 }
16326
c_hpothub53c45d2014-08-18 16:53:14 +053016327 if (VOS_STATUS_SUCCESS != status)
16328 {
16329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016330 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016331 pHddCtx->isPnoEnable = FALSE;
16332 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016333
16334 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16335 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016336 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016337}
16338
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016339/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016340 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16341 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016342 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016343static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016344 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16345{
16346 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016347 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016348 hdd_context_t *pHddCtx;
16349 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016350 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016351 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16352 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016353 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16354 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016355 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016356 hdd_config_t *pConfig = NULL;
16357 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016358
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016359 ENTER();
16360
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016361 if (NULL == pAdapter)
16362 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016364 "%s: HDD adapter is Null", __func__);
16365 return -ENODEV;
16366 }
16367
16368 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016369 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016370
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016371 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016372 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016373 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016374 }
16375
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016376 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016377 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16378 if (NULL == hHal)
16379 {
16380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16381 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016382 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016383 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016384 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16385 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16386 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016387 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016388 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016389 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016390 {
16391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16392 "%s: aborting the existing scan is unsuccessfull", __func__);
16393 return -EBUSY;
16394 }
16395
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016396 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016397 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016399 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016400 return -EBUSY;
16401 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016402
c_hpothu37f21312014-04-09 21:49:54 +053016403 if (TRUE == pHddCtx->isPnoEnable)
16404 {
16405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16406 FL("already PNO is enabled"));
16407 return -EBUSY;
16408 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016409
16410 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16411 {
16412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16413 "%s: abort ROC failed ", __func__);
16414 return -EBUSY;
16415 }
16416
c_hpothu37f21312014-04-09 21:49:54 +053016417 pHddCtx->isPnoEnable = TRUE;
16418
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016419 pnoRequest.enable = 1; /*Enable PNO */
16420 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016421
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016422 if (( !pnoRequest.ucNetworksCount ) ||
16423 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016424 {
16425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016426 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016427 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016428 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016429 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016430 goto error;
16431 }
16432
16433 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
16434 {
16435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016436 "%s: Incorrect number of channels %d",
16437 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016438 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016439 goto error;
16440 }
16441
16442 /* Framework provides one set of channels(all)
16443 * common for all saved profile */
16444 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16445 channels_allowed, &num_channels_allowed))
16446 {
16447 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16448 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016449 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016450 goto error;
16451 }
16452 /* Checking each channel against allowed channel list */
16453 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053016454 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016455 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016456 char chList [(request->n_channels*5)+1];
16457 int len;
16458 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016459 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016460 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016461 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016462 if (request->channels[i]->hw_value == channels_allowed[indx])
16463 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016464 if ((!pConfig->enableDFSPnoChnlScan) &&
16465 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
16466 {
16467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16468 "%s : Dropping DFS channel : %d",
16469 __func__,channels_allowed[indx]);
16470 num_ignore_dfs_ch++;
16471 break;
16472 }
16473
Nirav Shah80830bf2013-12-31 16:35:12 +053016474 valid_ch[num_ch++] = request->channels[i]->hw_value;
16475 len += snprintf(chList+len, 5, "%d ",
16476 request->channels[i]->hw_value);
16477 break ;
16478 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016479 }
16480 }
Nirav Shah80830bf2013-12-31 16:35:12 +053016481 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016482
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016483 /*If all channels are DFS and dropped, then ignore the PNO request*/
16484 if (num_ignore_dfs_ch == request->n_channels)
16485 {
16486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16487 "%s : All requested channels are DFS channels", __func__);
16488 ret = -EINVAL;
16489 goto error;
16490 }
16491 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016492
16493 pnoRequest.aNetworks =
16494 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16495 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016496 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016497 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16498 FL("failed to allocate memory aNetworks %u"),
16499 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16500 goto error;
16501 }
16502 vos_mem_zero(pnoRequest.aNetworks,
16503 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16504
16505 /* Filling per profile params */
16506 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
16507 {
16508 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016509 request->match_sets[i].ssid.ssid_len;
16510
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016511 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
16512 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016513 {
16514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016515 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016516 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016517 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016518 goto error;
16519 }
16520
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016521 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016522 request->match_sets[i].ssid.ssid,
16523 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16525 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016526 i, pnoRequest.aNetworks[i].ssId.ssId);
16527 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
16528 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
16529 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016530
16531 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016532 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
16533 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016534
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016535 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016536 }
16537
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016538 for (i = 0; i < request->n_ssids; i++)
16539 {
16540 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016541 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016542 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016543 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016544 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016545 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016546 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016547 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016548 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016549 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016550 break;
16551 }
16552 j++;
16553 }
16554 }
16555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16556 "Number of hidden networks being Configured = %d",
16557 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080016559 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016560
16561 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16562 if (pnoRequest.p24GProbeTemplate == NULL)
16563 {
16564 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16565 FL("failed to allocate memory p24GProbeTemplate %u"),
16566 SIR_PNO_MAX_PB_REQ_SIZE);
16567 goto error;
16568 }
16569
16570 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16571 if (pnoRequest.p5GProbeTemplate == NULL)
16572 {
16573 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16574 FL("failed to allocate memory p5GProbeTemplate %u"),
16575 SIR_PNO_MAX_PB_REQ_SIZE);
16576 goto error;
16577 }
16578
16579 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16580 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16581
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053016582 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
16583 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016584 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016585 pnoRequest.us24GProbeTemplateLen = request->ie_len;
16586 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
16587 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016588
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016589 pnoRequest.us5GProbeTemplateLen = request->ie_len;
16590 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
16591 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016592 }
16593
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016594 /* Driver gets only one time interval which is hardcoded in
16595 * supplicant for 10000ms. Taking power consumption into account 6 timers
16596 * will be used, Timervalue is increased exponentially i.e 10,20,40,
16597 * 80,160,320 secs. And number of scan cycle for each timer
16598 * is configurable through INI param gPNOScanTimerRepeatValue.
16599 * If it is set to 0 only one timer will be used and PNO scan cycle
16600 * will be repeated after each interval specified by supplicant
16601 * till PNO is disabled.
16602 */
16603 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016604 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016605 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016606 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016607 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
16608
16609 tempInterval = (request->interval)/1000;
16610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16611 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
16612 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016613 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016614 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016615 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016616 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016617 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016618 tempInterval *= 2;
16619 }
16620 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016621 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016622
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016623 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016624
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016625 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016626 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
16627 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016628 pAdapter->pno_req_status = 0;
16629
Nirav Shah80830bf2013-12-31 16:35:12 +053016630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16631 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016632 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
16633 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053016634
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016635 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016636 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016637 hdd_cfg80211_sched_scan_done_callback, pAdapter);
16638 if (eHAL_STATUS_SUCCESS != status)
16639 {
16640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016641 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016642 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016643 goto error;
16644 }
16645
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016646 ret = wait_for_completion_timeout(
16647 &pAdapter->pno_comp_var,
16648 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
16649 if (0 >= ret)
16650 {
16651 // Did not receive the response for PNO enable in time.
16652 // Assuming the PNO enable was success.
16653 // Returning error from here, because we timeout, results
16654 // in side effect of Wifi (Wifi Setting) not to work.
16655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16656 FL("Timed out waiting for PNO to be Enabled"));
16657 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016658 }
16659
16660 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053016661 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016662
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016663error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16665 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053016666 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016667 if (pnoRequest.aNetworks)
16668 vos_mem_free(pnoRequest.aNetworks);
16669 if (pnoRequest.p24GProbeTemplate)
16670 vos_mem_free(pnoRequest.p24GProbeTemplate);
16671 if (pnoRequest.p5GProbeTemplate)
16672 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016673
16674 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016675 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016676}
16677
16678/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016679 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
16680 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016681 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016682static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
16683 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16684{
16685 int ret;
16686
16687 vos_ssr_protect(__func__);
16688 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
16689 vos_ssr_unprotect(__func__);
16690
16691 return ret;
16692}
16693
16694/*
16695 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
16696 * Function to disable PNO
16697 */
16698static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016699 struct net_device *dev)
16700{
16701 eHalStatus status = eHAL_STATUS_FAILURE;
16702 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16703 hdd_context_t *pHddCtx;
16704 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016705 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016706 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016707
16708 ENTER();
16709
16710 if (NULL == pAdapter)
16711 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016712 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016713 "%s: HDD adapter is Null", __func__);
16714 return -ENODEV;
16715 }
16716
16717 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016718
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016719 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016720 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016721 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016722 "%s: HDD context is Null", __func__);
16723 return -ENODEV;
16724 }
16725
16726 /* The return 0 is intentional when isLogpInProgress and
16727 * isLoadUnloadInProgress. We did observe a crash due to a return of
16728 * failure in sched_scan_stop , especially for a case where the unload
16729 * of the happens at the same time. The function __cfg80211_stop_sched_scan
16730 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
16731 * success. If it returns a failure , then its next invocation due to the
16732 * clean up of the second interface will have the dev pointer corresponding
16733 * to the first one leading to a crash.
16734 */
16735 if (pHddCtx->isLogpInProgress)
16736 {
16737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16738 "%s: LOGP in Progress. Ignore!!!", __func__);
16739 return ret;
16740 }
16741
Mihir Shete18156292014-03-11 15:38:30 +053016742 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016743 {
16744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16745 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
16746 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016747 }
16748
16749 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16750 if (NULL == hHal)
16751 {
16752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16753 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016754 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016755 }
16756
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016757 pnoRequest.enable = 0; /* Disable PNO */
16758 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016759
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016760 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16761 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
16762 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016763 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016764 pAdapter->sessionId,
16765 NULL, pAdapter);
16766 if (eHAL_STATUS_SUCCESS != status)
16767 {
16768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16769 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016770 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016771 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016772 }
c_hpothu37f21312014-04-09 21:49:54 +053016773 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016774
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016775error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016777 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016778
16779 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016780 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016781}
16782
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016783/*
16784 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
16785 * NL interface to disable PNO
16786 */
16787static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
16788 struct net_device *dev)
16789{
16790 int ret;
16791
16792 vos_ssr_protect(__func__);
16793 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
16794 vos_ssr_unprotect(__func__);
16795
16796 return ret;
16797}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016798#endif /*FEATURE_WLAN_SCAN_PNO*/
16799
16800
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016801#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016802#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016803static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16804 struct net_device *dev,
16805 u8 *peer, u8 action_code,
16806 u8 dialog_token,
16807 u16 status_code, u32 peer_capability,
16808 const u8 *buf, size_t len)
16809#else /* TDLS_MGMT_VERSION2 */
16810#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
16811static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16812 struct net_device *dev,
16813 const u8 *peer, u8 action_code,
16814 u8 dialog_token, u16 status_code,
16815 u32 peer_capability, bool initiator,
16816 const u8 *buf, size_t len)
16817#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
16818static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16819 struct net_device *dev,
16820 const u8 *peer, u8 action_code,
16821 u8 dialog_token, u16 status_code,
16822 u32 peer_capability, const u8 *buf,
16823 size_t len)
16824#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
16825static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16826 struct net_device *dev,
16827 u8 *peer, u8 action_code,
16828 u8 dialog_token,
16829 u16 status_code, u32 peer_capability,
16830 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016831#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016832static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16833 struct net_device *dev,
16834 u8 *peer, u8 action_code,
16835 u8 dialog_token,
16836 u16 status_code, const u8 *buf,
16837 size_t len)
16838#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016839#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016840{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016841 hdd_adapter_t *pAdapter;
16842 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016843 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070016844 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080016845 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070016846 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016847 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016848#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016849 u32 peer_capability = 0;
16850#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053016851 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016852 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016853
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016854 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16855 if (NULL == pAdapter)
16856 {
16857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16858 "%s: Adapter is NULL",__func__);
16859 return -EINVAL;
16860 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016861 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16862 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
16863 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016864
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016865 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016866 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016867 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016869 "Invalid arguments");
16870 return -EINVAL;
16871 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016872
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016873 if (pHddCtx->isLogpInProgress)
16874 {
16875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16876 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053016877 wlan_hdd_tdls_set_link_status(pAdapter,
16878 peer,
16879 eTDLS_LINK_IDLE,
16880 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016881 return -EBUSY;
16882 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016883
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016884 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
16885 {
16886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16887 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
16888 return -EAGAIN;
16889 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016890
Hoonki Lee27511902013-03-14 18:19:06 -070016891 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016892 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016893 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070016894 "%s: TDLS mode is disabled OR not enabled in FW."
16895 MAC_ADDRESS_STR " action %d declined.",
16896 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016897 return -ENOTSUPP;
16898 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016899
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016900 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16901
16902 if( NULL == pHddStaCtx )
16903 {
16904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16905 "%s: HDD station context NULL ",__func__);
16906 return -EINVAL;
16907 }
16908
16909 /* STA should be connected and authenticated
16910 * before sending any TDLS frames
16911 */
16912 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
16913 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
16914 {
16915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16916 "STA is not connected or unauthenticated. "
16917 "connState %u, uIsAuthenticated %u",
16918 pHddStaCtx->conn_info.connState,
16919 pHddStaCtx->conn_info.uIsAuthenticated);
16920 return -EAGAIN;
16921 }
16922
Hoonki Lee27511902013-03-14 18:19:06 -070016923 /* other than teardown frame, other mgmt frames are not sent if disabled */
16924 if (SIR_MAC_TDLS_TEARDOWN != action_code)
16925 {
16926 /* if tdls_mode is disabled to respond to peer's request */
16927 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
16928 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070016930 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070016931 " TDLS mode is disabled. action %d declined.",
16932 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070016933
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016934 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070016935 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053016936
16937 if (vos_max_concurrent_connections_reached())
16938 {
16939 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16940 return -EINVAL;
16941 }
Hoonki Lee27511902013-03-14 18:19:06 -070016942 }
16943
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016944 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
16945 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053016946 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016947 {
16948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016949 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070016950 " TDLS setup is ongoing. action %d declined.",
16951 __func__, MAC_ADDR_ARRAY(peer), action_code);
16952 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016953 }
16954 }
16955
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016956 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
16957 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080016958 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053016959 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16960 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080016961 {
16962 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
16963 we return error code at 'add_station()'. Hence we have this
16964 check again in addtion to add_station().
16965 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016966 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080016967 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016968 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16969 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053016970 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
16971 __func__, MAC_ADDR_ARRAY(peer), action_code,
16972 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053016973 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080016974 }
16975 else
16976 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016977 /* maximum reached. tweak to send error code to peer and return
16978 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080016979 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016980 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16981 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053016982 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
16983 __func__, MAC_ADDR_ARRAY(peer), status_code,
16984 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070016985 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016986 /* fall through to send setup resp with failure status
16987 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080016988 }
16989 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016990 else
16991 {
16992 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053016993 mutex_lock(&pHddCtx->tdls_lock);
16994 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016995 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016996 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053016997 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070016999 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17000 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017001 return -EPERM;
17002 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017003 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017004 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017005 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017006
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017008 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017009 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17010 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017011
Hoonki Leea34dd892013-02-05 22:56:02 -080017012 /*Except teardown responder will not be used so just make 0*/
17013 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017014 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017015 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017016
17017 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017018
17019 mutex_lock(&pHddCtx->tdls_lock);
17020 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017021
17022 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17023 responder = pTdlsPeer->is_responder;
17024 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017025 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017026 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017027 "%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 -070017028 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17029 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017030 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017031 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017032 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017033 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017034 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017035
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017036 /* For explicit trigger of DIS_REQ come out of BMPS for
17037 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017038 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017039 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17040 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017041 {
17042 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17043 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017044 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017045 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017046 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17047 if (status != VOS_STATUS_SUCCESS) {
17048 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17049 }
Hoonki Lee14621352013-04-16 17:51:19 -070017050 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017051 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017052 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17054 }
17055 }
Hoonki Lee14621352013-04-16 17:51:19 -070017056 }
17057
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017058 /* make sure doesn't call send_mgmt() while it is pending */
17059 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17060 {
17061 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017062 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017063 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017064 ret = -EBUSY;
17065 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017066 }
17067
17068 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017069 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17070
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017071 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17072 pAdapter->sessionId, peer, action_code, dialog_token,
17073 status_code, peer_capability, (tANI_U8 *)buf, len,
17074 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017075
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017076 if (VOS_STATUS_SUCCESS != status)
17077 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17079 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017080 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017081 ret = -EINVAL;
17082 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017083 }
17084
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017085 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
17086 (SIR_MAC_TDLS_DIS_RSP == action_code))
17087 {
17088 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
17089 * So we no need to wait for tdls_mgmt_comp for sending ack status.
17090 */
17091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17092 "%s: tx done for frm %u", __func__, action_code);
17093 return 0;
17094 }
17095
17096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17097 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17098 WAIT_TIME_TDLS_MGMT);
17099
Hoonki Leed37cbb32013-04-20 00:31:14 -070017100 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17101 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17102
17103 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017104 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017106 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017107 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017108 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017109
17110 if (pHddCtx->isLogpInProgress)
17111 {
17112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17113 "%s: LOGP in Progress. Ignore!!!", __func__);
17114 return -EAGAIN;
17115 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017116 if (rc <= 0)
17117 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17118 WLAN_LOG_INDICATOR_HOST_DRIVER,
17119 WLAN_LOG_REASON_HDD_TIME_OUT,
17120 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017121
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017122 ret = -EINVAL;
17123 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017124 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017125 else
17126 {
17127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17128 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17129 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17130 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017131
Gopichand Nakkala05922802013-03-14 12:23:19 -070017132 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017133 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017134 ret = max_sta_failed;
17135 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017136 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017137
Hoonki Leea34dd892013-02-05 22:56:02 -080017138 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17139 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017140 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17142 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017143 }
17144 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17145 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017146 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17148 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017149 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017150
17151 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017152
17153tx_failed:
17154 /* add_station will be called before sending TDLS_SETUP_REQ and
17155 * TDLS_SETUP_RSP and as part of add_station driver will enable
17156 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17157 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17158 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17159 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17160 */
17161
17162 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17163 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17164 wlan_hdd_tdls_check_bmps(pAdapter);
17165 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017166}
17167
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017168#if TDLS_MGMT_VERSION2
17169static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17170 u8 *peer, u8 action_code, u8 dialog_token,
17171 u16 status_code, u32 peer_capability,
17172 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017173#else /* TDLS_MGMT_VERSION2 */
17174#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17175static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17176 struct net_device *dev,
17177 const u8 *peer, u8 action_code,
17178 u8 dialog_token, u16 status_code,
17179 u32 peer_capability, bool initiator,
17180 const u8 *buf, size_t len)
17181#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17182static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17183 struct net_device *dev,
17184 const u8 *peer, u8 action_code,
17185 u8 dialog_token, u16 status_code,
17186 u32 peer_capability, const u8 *buf,
17187 size_t len)
17188#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17189static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17190 struct net_device *dev,
17191 u8 *peer, u8 action_code,
17192 u8 dialog_token,
17193 u16 status_code, u32 peer_capability,
17194 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017195#else
17196static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17197 u8 *peer, u8 action_code, u8 dialog_token,
17198 u16 status_code, const u8 *buf, size_t len)
17199#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017200#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017201{
17202 int ret;
17203
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017204 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017205#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017206 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17207 dialog_token, status_code,
17208 peer_capability, buf, len);
17209#else /* TDLS_MGMT_VERSION2 */
17210#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17211 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17212 dialog_token, status_code,
17213 peer_capability, initiator,
17214 buf, len);
17215#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17216 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17217 dialog_token, status_code,
17218 peer_capability, buf, len);
17219#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17220 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17221 dialog_token, status_code,
17222 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017223#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017224 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17225 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017226#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017227#endif
17228 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017229
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017230 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017231}
Atul Mittal115287b2014-07-08 13:26:33 +053017232
17233int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017234#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17235 const u8 *peer,
17236#else
Atul Mittal115287b2014-07-08 13:26:33 +053017237 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017238#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017239 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017240 cfg80211_exttdls_callback callback)
17241{
17242
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017243 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017244 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017245 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17247 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17248 __func__, MAC_ADDR_ARRAY(peer));
17249
17250 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17251 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17252
17253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017254 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17255 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17256 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017257 return -ENOTSUPP;
17258 }
17259
17260 /* To cater the requirement of establishing the TDLS link
17261 * irrespective of the data traffic , get an entry of TDLS peer.
17262 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017263 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017264 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17265 if (pTdlsPeer == NULL) {
17266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17267 "%s: peer " MAC_ADDRESS_STR " not existing",
17268 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017269 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017270 return -EINVAL;
17271 }
17272
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017273 /* check FW TDLS Off Channel capability */
17274 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017275 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017276 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017277 {
17278 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17279 pTdlsPeer->peerParams.global_operating_class =
17280 tdls_peer_params->global_operating_class;
17281 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17282 pTdlsPeer->peerParams.min_bandwidth_kbps =
17283 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017284 /* check configured channel is valid, non dfs and
17285 * not current operating channel */
17286 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17287 tdls_peer_params->channel)) &&
17288 (pHddStaCtx) &&
17289 (tdls_peer_params->channel !=
17290 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017291 {
17292 pTdlsPeer->isOffChannelConfigured = TRUE;
17293 }
17294 else
17295 {
17296 pTdlsPeer->isOffChannelConfigured = FALSE;
17297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17298 "%s: Configured Tdls Off Channel is not valid", __func__);
17299
17300 }
17301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017302 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17303 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017304 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017305 pTdlsPeer->isOffChannelConfigured,
17306 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017307 }
17308 else
17309 {
17310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017311 "%s: TDLS off channel FW capability %d, "
17312 "host capab %d or Invalid TDLS Peer Params", __func__,
17313 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17314 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017315 }
17316
Atul Mittal115287b2014-07-08 13:26:33 +053017317 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17318
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017319 mutex_unlock(&pHddCtx->tdls_lock);
17320
Atul Mittal115287b2014-07-08 13:26:33 +053017321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17322 " %s TDLS Add Force Peer Failed",
17323 __func__);
17324 return -EINVAL;
17325 }
17326 /*EXT TDLS*/
17327
17328 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017329 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017330 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17331 " %s TDLS set callback Failed",
17332 __func__);
17333 return -EINVAL;
17334 }
17335
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017336 mutex_unlock(&pHddCtx->tdls_lock);
17337
Atul Mittal115287b2014-07-08 13:26:33 +053017338 return(0);
17339
17340}
17341
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017342int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17343#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17344 const u8 *peer
17345#else
17346 u8 *peer
17347#endif
17348)
Atul Mittal115287b2014-07-08 13:26:33 +053017349{
17350
17351 hddTdlsPeer_t *pTdlsPeer;
17352 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17354 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17355 __func__, MAC_ADDR_ARRAY(peer));
17356
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017357 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17358 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17359 return -EINVAL;
17360 }
17361
Atul Mittal115287b2014-07-08 13:26:33 +053017362 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17363 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17364
17365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017366 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17367 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17368 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017369 return -ENOTSUPP;
17370 }
17371
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017372 mutex_lock(&pHddCtx->tdls_lock);
17373 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017374
17375 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017376 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017377 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017378 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017379 __func__, MAC_ADDR_ARRAY(peer));
17380 return -EINVAL;
17381 }
17382 else {
17383 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17384 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017385 /* if channel switch is configured, reset
17386 the channel for this peer */
17387 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17388 {
17389 pTdlsPeer->peerParams.channel = 0;
17390 pTdlsPeer->isOffChannelConfigured = FALSE;
17391 }
Atul Mittal115287b2014-07-08 13:26:33 +053017392 }
17393
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017394 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017395 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017396 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017397 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017398 }
Atul Mittal115287b2014-07-08 13:26:33 +053017399
17400 /*EXT TDLS*/
17401
17402 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017403 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17405 " %s TDLS set callback Failed",
17406 __func__);
17407 return -EINVAL;
17408 }
Atul Mittal115287b2014-07-08 13:26:33 +053017409
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017410 mutex_unlock(&pHddCtx->tdls_lock);
17411
17412 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053017413}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017414static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017415#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17416 const u8 *peer,
17417#else
17418 u8 *peer,
17419#endif
17420 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017421{
17422 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17423 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017424 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017425 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017426
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017427 ENTER();
17428
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017429 if (!pAdapter) {
17430 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17431 return -EINVAL;
17432 }
17433
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017434 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17435 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
17436 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017437 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017438 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017439 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070017440 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017441 return -EINVAL;
17442 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017443
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017444 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017445 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017446 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017447 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017448 }
17449
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017450
17451 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017452 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017453 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017454 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017455 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
17456 "Cannot process TDLS commands",
17457 pHddCtx->cfg_ini->fEnableTDLSSupport,
17458 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017459 return -ENOTSUPP;
17460 }
17461
17462 switch (oper) {
17463 case NL80211_TDLS_ENABLE_LINK:
17464 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017465 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017466 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017467 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053017468 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017469 tANI_U16 numCurrTdlsPeers = 0;
17470 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017471 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017472
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17474 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
17475 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017476
Sunil Dutt41de4e22013-11-14 18:09:02 +053017477 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017478 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053017479 if ( NULL == pTdlsPeer ) {
17480 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17481 " (oper %d) not exsting. ignored",
17482 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17483 return -EINVAL;
17484 }
17485
17486 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17487 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
17488 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
17489 "NL80211_TDLS_ENABLE_LINK");
17490
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070017491 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
17492 {
17493 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
17494 MAC_ADDRESS_STR " failed",
17495 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
17496 return -EINVAL;
17497 }
17498
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053017499 /* before starting tdls connection, set tdls
17500 * off channel established status to default value */
17501 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017502 /* TDLS Off Channel, Disable tdls channel switch,
17503 when there are more than one tdls link */
17504 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053017505 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017506 {
17507 /* get connected peer and send disable tdls off chan */
17508 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017509 if ((connPeer) &&
17510 (connPeer->isOffChannelSupported == TRUE) &&
17511 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017512 {
17513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17514 "%s: More then one peer connected, Disable "
17515 "TDLS channel switch", __func__);
17516
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017517 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017518
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017519 ret = sme_SendTdlsChanSwitchReq(
17520 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017521 pAdapter->sessionId,
17522 connPeer->peerMac,
17523 connPeer->peerParams.channel,
17524 TDLS_OFF_CHANNEL_BW_OFFSET,
17525 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017526 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017527 hddLog(VOS_TRACE_LEVEL_ERROR,
17528 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017529 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017530 }
17531 else
17532 {
17533 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17534 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017535 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017536 "isOffChannelConfigured %d",
17537 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017538 (connPeer ? (connPeer->isOffChannelSupported)
17539 : -1),
17540 (connPeer ? (connPeer->isOffChannelConfigured)
17541 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017542 }
17543 }
17544
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017545 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017546 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017547 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053017548
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017549 if (0 != wlan_hdd_tdls_get_link_establish_params(
17550 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017551 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017552 return -EINVAL;
17553 }
17554 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017555
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017556 ret = sme_SendTdlsLinkEstablishParams(
17557 WLAN_HDD_GET_HAL_CTX(pAdapter),
17558 pAdapter->sessionId, peer,
17559 &tdlsLinkEstablishParams);
17560 if (ret != VOS_STATUS_SUCCESS) {
17561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
17562 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017563 /* Send TDLS peer UAPSD capabilities to the firmware and
17564 * register with the TL on after the response for this operation
17565 * is received .
17566 */
17567 ret = wait_for_completion_interruptible_timeout(
17568 &pAdapter->tdls_link_establish_req_comp,
17569 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
17570 if (ret <= 0)
17571 {
17572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017573 FL("Link Establish Request Failed Status %ld"),
17574 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017575 return -EINVAL;
17576 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017577 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017578
Atul Mittal115287b2014-07-08 13:26:33 +053017579 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
17580 eTDLS_LINK_CONNECTED,
17581 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017582 staDesc.ucSTAId = pTdlsPeer->staId;
17583 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017584 ret = WLANTL_UpdateTdlsSTAClient(
17585 pHddCtx->pvosContext,
17586 &staDesc);
17587 if (ret != VOS_STATUS_SUCCESS) {
17588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
17589 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053017590
Gopichand Nakkala471708b2013-06-04 20:03:01 +053017591 /* Mark TDLS client Authenticated .*/
17592 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
17593 pTdlsPeer->staId,
17594 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017595 if (VOS_STATUS_SUCCESS == status)
17596 {
Hoonki Lee14621352013-04-16 17:51:19 -070017597 if (pTdlsPeer->is_responder == 0)
17598 {
17599 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053017600 tdlsConnInfo_t *tdlsInfo;
17601
17602 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
17603
17604 /* Initialize initiator wait callback */
17605 vos_timer_init(
17606 &pTdlsPeer->initiatorWaitTimeoutTimer,
17607 VOS_TIMER_TYPE_SW,
17608 wlan_hdd_tdls_initiator_wait_cb,
17609 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070017610
17611 wlan_hdd_tdls_timer_restart(pAdapter,
17612 &pTdlsPeer->initiatorWaitTimeoutTimer,
17613 WAIT_TIME_TDLS_INITIATOR);
17614 /* suspend initiator TX until it receives direct packet from the
17615 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017616 ret = WLANTL_SuspendDataTx(
17617 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
17618 &staId, NULL);
17619 if (ret != VOS_STATUS_SUCCESS) {
17620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
17621 }
Hoonki Lee14621352013-04-16 17:51:19 -070017622 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017623
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017624 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017625 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017626 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017627 suppChannelLen =
17628 tdlsLinkEstablishParams.supportedChannelsLen;
17629
17630 if ((suppChannelLen > 0) &&
17631 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
17632 {
17633 tANI_U8 suppPeerChannel = 0;
17634 int i = 0;
17635 for (i = 0U; i < suppChannelLen; i++)
17636 {
17637 suppPeerChannel =
17638 tdlsLinkEstablishParams.supportedChannels[i];
17639
17640 pTdlsPeer->isOffChannelSupported = FALSE;
17641 if (suppPeerChannel ==
17642 pTdlsPeer->peerParams.channel)
17643 {
17644 pTdlsPeer->isOffChannelSupported = TRUE;
17645 break;
17646 }
17647 }
17648 }
17649 else
17650 {
17651 pTdlsPeer->isOffChannelSupported = FALSE;
17652 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017653 }
17654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17655 "%s: TDLS channel switch request for channel "
17656 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017657 "%d isOffChannelSupported %d", __func__,
17658 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017659 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017660 suppChannelLen,
17661 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017662
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017663 /* TDLS Off Channel, Enable tdls channel switch,
17664 when their is only one tdls link and it supports */
17665 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17666 if ((numCurrTdlsPeers == 1) &&
17667 (TRUE == pTdlsPeer->isOffChannelSupported) &&
17668 (TRUE == pTdlsPeer->isOffChannelConfigured))
17669 {
17670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17671 "%s: Send TDLS channel switch request for channel %d",
17672 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017673
17674 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017675 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
17676 pAdapter->sessionId,
17677 pTdlsPeer->peerMac,
17678 pTdlsPeer->peerParams.channel,
17679 TDLS_OFF_CHANNEL_BW_OFFSET,
17680 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017681 if (ret != VOS_STATUS_SUCCESS) {
17682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
17683 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017684 }
17685 else
17686 {
17687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17688 "%s: TDLS channel switch request not sent"
17689 " numCurrTdlsPeers %d "
17690 "isOffChannelSupported %d "
17691 "isOffChannelConfigured %d",
17692 __func__, numCurrTdlsPeers,
17693 pTdlsPeer->isOffChannelSupported,
17694 pTdlsPeer->isOffChannelConfigured);
17695 }
17696
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017697 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017698 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017699
17700 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017701 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
17702 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017703 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017704 int ac;
17705 uint8 ucAc[4] = { WLANTL_AC_VO,
17706 WLANTL_AC_VI,
17707 WLANTL_AC_BK,
17708 WLANTL_AC_BE };
17709 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
17710 for(ac=0; ac < 4; ac++)
17711 {
17712 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
17713 pTdlsPeer->staId, ucAc[ac],
17714 tlTid[ac], tlTid[ac], 0, 0,
17715 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017716 if (status != VOS_STATUS_SUCCESS) {
17717 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
17718 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017719 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017720 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017721 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017722 }
17723 break;
17724 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080017725 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017726 tANI_U16 numCurrTdlsPeers = 0;
17727 hddTdlsPeer_t *connPeer = NULL;
17728
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17730 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
17731 __func__, MAC_ADDR_ARRAY(peer));
17732
Sunil Dutt41de4e22013-11-14 18:09:02 +053017733 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
17734
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017735
Sunil Dutt41de4e22013-11-14 18:09:02 +053017736 if ( NULL == pTdlsPeer ) {
17737 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17738 " (oper %d) not exsting. ignored",
17739 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17740 return -EINVAL;
17741 }
17742
17743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17744 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
17745 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
17746 "NL80211_TDLS_DISABLE_LINK");
17747
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017748 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080017749 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017750 long status;
17751
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053017752 /* set tdls off channel status to false for this peer */
17753 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053017754 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
17755 eTDLS_LINK_TEARING,
17756 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
17757 eTDLS_LINK_UNSPECIFIED:
17758 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017759 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
17760
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017761 status = sme_DeleteTdlsPeerSta(
17762 WLAN_HDD_GET_HAL_CTX(pAdapter),
17763 pAdapter->sessionId, peer );
17764 if (status != VOS_STATUS_SUCCESS) {
17765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17766 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017767
17768 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
17769 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053017770 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053017771 eTDLS_LINK_IDLE,
17772 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017773 if (status <= 0)
17774 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17776 "%s: Del station failed status %ld",
17777 __func__, status);
17778 return -EPERM;
17779 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017780
17781 /* TDLS Off Channel, Enable tdls channel switch,
17782 when their is only one tdls link and it supports */
17783 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17784 if (numCurrTdlsPeers == 1)
17785 {
17786 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
17787 if ((connPeer) &&
17788 (connPeer->isOffChannelSupported == TRUE) &&
17789 (connPeer->isOffChannelConfigured == TRUE))
17790 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017791 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017792 status = sme_SendTdlsChanSwitchReq(
17793 WLAN_HDD_GET_HAL_CTX(pAdapter),
17794 pAdapter->sessionId,
17795 connPeer->peerMac,
17796 connPeer->peerParams.channel,
17797 TDLS_OFF_CHANNEL_BW_OFFSET,
17798 TDLS_CHANNEL_SWITCH_ENABLE);
17799 if (status != VOS_STATUS_SUCCESS) {
17800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
17801 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017802 }
17803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17804 "%s: TDLS channel switch "
17805 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017806 "isOffChannelConfigured %d "
17807 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017808 __func__,
17809 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017810 (connPeer ? connPeer->isOffChannelConfigured : -1),
17811 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017812 }
17813 else
17814 {
17815 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17816 "%s: TDLS channel switch request not sent "
17817 "numCurrTdlsPeers %d ",
17818 __func__, numCurrTdlsPeers);
17819 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017820 }
17821 else
17822 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17824 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080017825 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017826 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017827 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017828 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053017829 {
Atul Mittal115287b2014-07-08 13:26:33 +053017830 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053017831
Atul Mittal115287b2014-07-08 13:26:33 +053017832 if (0 != status)
17833 {
17834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017835 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053017836 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053017837 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053017838 break;
17839 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017840 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053017841 {
Atul Mittal115287b2014-07-08 13:26:33 +053017842 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
17843 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017844 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053017845 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053017846
Atul Mittal115287b2014-07-08 13:26:33 +053017847 if (0 != status)
17848 {
17849 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017850 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053017851 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053017852 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053017853 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053017854 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017855 case NL80211_TDLS_DISCOVERY_REQ:
17856 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017858 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017859 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017860 return -ENOTSUPP;
17861 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017862 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17863 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017864 return -ENOTSUPP;
17865 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017866
17867 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017868 return 0;
17869}
Chilam NG571c65a2013-01-19 12:27:36 +053017870
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017871static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017872#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17873 const u8 *peer,
17874#else
17875 u8 *peer,
17876#endif
17877 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017878{
17879 int ret;
17880
17881 vos_ssr_protect(__func__);
17882 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
17883 vos_ssr_unprotect(__func__);
17884
17885 return ret;
17886}
17887
Chilam NG571c65a2013-01-19 12:27:36 +053017888int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
17889 struct net_device *dev, u8 *peer)
17890{
Arif Hussaina7c8e412013-11-20 11:06:42 -080017891 hddLog(VOS_TRACE_LEVEL_INFO,
17892 "tdls send discover req: "MAC_ADDRESS_STR,
17893 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053017894
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017895#if TDLS_MGMT_VERSION2
17896 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
17897 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
17898#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17900 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
17901 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
17902#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17903 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
17904 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
17905#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17906 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
17907 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
17908#else
Chilam NG571c65a2013-01-19 12:27:36 +053017909 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
17910 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017911#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017912#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053017913}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017914#endif
17915
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017916#ifdef WLAN_FEATURE_GTK_OFFLOAD
17917/*
17918 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
17919 * Callback rountine called upon receiving response for
17920 * get offload info
17921 */
17922void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
17923 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
17924{
17925
17926 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017927 tANI_U8 tempReplayCounter[8];
17928 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017929
17930 ENTER();
17931
17932 if (NULL == pAdapter)
17933 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017935 "%s: HDD adapter is Null", __func__);
17936 return ;
17937 }
17938
17939 if (NULL == pGtkOffloadGetInfoRsp)
17940 {
17941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17942 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
17943 return ;
17944 }
17945
17946 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
17947 {
17948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17949 "%s: wlan Failed to get replay counter value",
17950 __func__);
17951 return ;
17952 }
17953
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017954 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17955 /* Update replay counter */
17956 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
17957 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
17958
17959 {
17960 /* changing from little to big endian since supplicant
17961 * works on big endian format
17962 */
17963 int i;
17964 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
17965
17966 for (i = 0; i < 8; i++)
17967 {
17968 tempReplayCounter[7-i] = (tANI_U8)p[i];
17969 }
17970 }
17971
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017972 /* Update replay counter to NL */
17973 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017974 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017975}
17976
17977/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017978 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017979 * This function is used to offload GTK rekeying job to the firmware.
17980 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017981int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017982 struct cfg80211_gtk_rekey_data *data)
17983{
17984 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17985 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17986 hdd_station_ctx_t *pHddStaCtx;
17987 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017988 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017989 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017990 eHalStatus status = eHAL_STATUS_FAILURE;
17991
17992 ENTER();
17993
17994 if (NULL == pAdapter)
17995 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017997 "%s: HDD adapter is Null", __func__);
17998 return -ENODEV;
17999 }
18000
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018001 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18002 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18003 pAdapter->sessionId, pAdapter->device_mode));
18004
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018005 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018006 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018007 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018008 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018009 }
18010
18011 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18012 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18013 if (NULL == hHal)
18014 {
18015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18016 "%s: HAL context is Null!!!", __func__);
18017 return -EAGAIN;
18018 }
18019
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018020 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18021 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18022 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18023 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018024 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018025 {
18026 /* changing from big to little endian since driver
18027 * works on little endian format
18028 */
18029 tANI_U8 *p =
18030 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18031 int i;
18032
18033 for (i = 0; i < 8; i++)
18034 {
18035 p[7-i] = data->replay_ctr[i];
18036 }
18037 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018038
18039 if (TRUE == pHddCtx->hdd_wlan_suspended)
18040 {
18041 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018042 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18043 sizeof (tSirGtkOffloadParams));
18044 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018045 pAdapter->sessionId);
18046
18047 if (eHAL_STATUS_SUCCESS != status)
18048 {
18049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18050 "%s: sme_SetGTKOffload failed, returned %d",
18051 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018052
18053 /* Need to clear any trace of key value in the memory.
18054 * Thus zero out the memory even though it is local
18055 * variable.
18056 */
18057 vos_mem_zero(&hddGtkOffloadReqParams,
18058 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018059 return status;
18060 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18062 "%s: sme_SetGTKOffload successfull", __func__);
18063 }
18064 else
18065 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18067 "%s: wlan not suspended GTKOffload request is stored",
18068 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018069 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018070
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018071 /* Need to clear any trace of key value in the memory.
18072 * Thus zero out the memory even though it is local
18073 * variable.
18074 */
18075 vos_mem_zero(&hddGtkOffloadReqParams,
18076 sizeof(hddGtkOffloadReqParams));
18077
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018078 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018079 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018080}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018081
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018082int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18083 struct cfg80211_gtk_rekey_data *data)
18084{
18085 int ret;
18086
18087 vos_ssr_protect(__func__);
18088 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18089 vos_ssr_unprotect(__func__);
18090
18091 return ret;
18092}
18093#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018094/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018095 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018096 * This function is used to set access control policy
18097 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018098static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18099 struct net_device *dev,
18100 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018101{
18102 int i;
18103 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18104 hdd_hostapd_state_t *pHostapdState;
18105 tsap_Config_t *pConfig;
18106 v_CONTEXT_t pVosContext = NULL;
18107 hdd_context_t *pHddCtx;
18108 int status;
18109
18110 ENTER();
18111
18112 if (NULL == pAdapter)
18113 {
18114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18115 "%s: HDD adapter is Null", __func__);
18116 return -ENODEV;
18117 }
18118
18119 if (NULL == params)
18120 {
18121 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18122 "%s: params is Null", __func__);
18123 return -EINVAL;
18124 }
18125
18126 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18127 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018128 if (0 != status)
18129 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018130 return status;
18131 }
18132
18133 pVosContext = pHddCtx->pvosContext;
18134 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18135
18136 if (NULL == pHostapdState)
18137 {
18138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18139 "%s: pHostapdState is Null", __func__);
18140 return -EINVAL;
18141 }
18142
18143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18144 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018145 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18146 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18147 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018148
18149 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18150 {
18151 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18152
18153 /* default value */
18154 pConfig->num_accept_mac = 0;
18155 pConfig->num_deny_mac = 0;
18156
18157 /**
18158 * access control policy
18159 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18160 * listed in hostapd.deny file.
18161 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18162 * listed in hostapd.accept file.
18163 */
18164 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18165 {
18166 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18167 }
18168 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18169 {
18170 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18171 }
18172 else
18173 {
18174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18175 "%s:Acl Policy : %d is not supported",
18176 __func__, params->acl_policy);
18177 return -ENOTSUPP;
18178 }
18179
18180 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18181 {
18182 pConfig->num_accept_mac = params->n_acl_entries;
18183 for (i = 0; i < params->n_acl_entries; i++)
18184 {
18185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18186 "** Add ACL MAC entry %i in WhiletList :"
18187 MAC_ADDRESS_STR, i,
18188 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18189
18190 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18191 sizeof(qcmacaddr));
18192 }
18193 }
18194 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18195 {
18196 pConfig->num_deny_mac = params->n_acl_entries;
18197 for (i = 0; i < params->n_acl_entries; i++)
18198 {
18199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18200 "** Add ACL MAC entry %i in BlackList :"
18201 MAC_ADDRESS_STR, i,
18202 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18203
18204 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18205 sizeof(qcmacaddr));
18206 }
18207 }
18208
18209 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18210 {
18211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18212 "%s: SAP Set Mac Acl fail", __func__);
18213 return -EINVAL;
18214 }
18215 }
18216 else
18217 {
18218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018219 "%s: Invalid device_mode = %s (%d)",
18220 __func__, hdd_device_modetoString(pAdapter->device_mode),
18221 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018222 return -EINVAL;
18223 }
18224
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018225 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018226 return 0;
18227}
18228
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018229static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18230 struct net_device *dev,
18231 const struct cfg80211_acl_data *params)
18232{
18233 int ret;
18234 vos_ssr_protect(__func__);
18235 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18236 vos_ssr_unprotect(__func__);
18237
18238 return ret;
18239}
18240
Leo Chang9056f462013-08-01 19:21:11 -070018241#ifdef WLAN_NL80211_TESTMODE
18242#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018243void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018244(
18245 void *pAdapter,
18246 void *indCont
18247)
18248{
Leo Changd9df8aa2013-09-26 13:32:26 -070018249 tSirLPHBInd *lphbInd;
18250 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018251 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018252
18253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018254 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018255
c_hpothu73f35e62014-04-18 13:40:08 +053018256 if (pAdapter == NULL)
18257 {
18258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18259 "%s: pAdapter is NULL\n",__func__);
18260 return;
18261 }
18262
Leo Chang9056f462013-08-01 19:21:11 -070018263 if (NULL == indCont)
18264 {
18265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018266 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070018267 return;
18268 }
18269
c_hpothu73f35e62014-04-18 13:40:08 +053018270 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070018271 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070018272 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053018273 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070018274 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070018275 GFP_ATOMIC);
18276 if (!skb)
18277 {
18278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18279 "LPHB timeout, NL buffer alloc fail");
18280 return;
18281 }
18282
Leo Changac3ba772013-10-07 09:47:04 -070018283 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070018284 {
18285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18286 "WLAN_HDD_TM_ATTR_CMD put fail");
18287 goto nla_put_failure;
18288 }
Leo Changac3ba772013-10-07 09:47:04 -070018289 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070018290 {
18291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18292 "WLAN_HDD_TM_ATTR_TYPE put fail");
18293 goto nla_put_failure;
18294 }
Leo Changac3ba772013-10-07 09:47:04 -070018295 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070018296 sizeof(tSirLPHBInd), lphbInd))
18297 {
18298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18299 "WLAN_HDD_TM_ATTR_DATA put fail");
18300 goto nla_put_failure;
18301 }
Leo Chang9056f462013-08-01 19:21:11 -070018302 cfg80211_testmode_event(skb, GFP_ATOMIC);
18303 return;
18304
18305nla_put_failure:
18306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18307 "NLA Put fail");
18308 kfree_skb(skb);
18309
18310 return;
18311}
18312#endif /* FEATURE_WLAN_LPHB */
18313
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018314static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070018315{
18316 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
18317 int err = 0;
18318#ifdef FEATURE_WLAN_LPHB
18319 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070018320 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018321
18322 ENTER();
18323
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018324 err = wlan_hdd_validate_context(pHddCtx);
18325 if (0 != err)
18326 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018327 return err;
18328 }
Leo Chang9056f462013-08-01 19:21:11 -070018329#endif /* FEATURE_WLAN_LPHB */
18330
18331 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
18332 if (err)
18333 {
18334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18335 "%s Testmode INV ATTR", __func__);
18336 return err;
18337 }
18338
18339 if (!tb[WLAN_HDD_TM_ATTR_CMD])
18340 {
18341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18342 "%s Testmode INV CMD", __func__);
18343 return -EINVAL;
18344 }
18345
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018346 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18347 TRACE_CODE_HDD_CFG80211_TESTMODE,
18348 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070018349 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
18350 {
18351#ifdef FEATURE_WLAN_LPHB
18352 /* Low Power Heartbeat configuration request */
18353 case WLAN_HDD_TM_CMD_WLAN_HB:
18354 {
18355 int buf_len;
18356 void *buf;
18357 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080018358 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070018359
18360 if (!tb[WLAN_HDD_TM_ATTR_DATA])
18361 {
18362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18363 "%s Testmode INV DATA", __func__);
18364 return -EINVAL;
18365 }
18366
18367 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
18368 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080018369
18370 hb_params_temp =(tSirLPHBReq *)buf;
18371 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
18372 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
18373 return -EINVAL;
18374
Leo Chang9056f462013-08-01 19:21:11 -070018375 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
18376 if (NULL == hb_params)
18377 {
18378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18379 "%s Request Buffer Alloc Fail", __func__);
18380 return -EINVAL;
18381 }
18382
18383 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070018384 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
18385 hb_params,
18386 wlan_hdd_cfg80211_lphb_ind_handler);
18387 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070018388 {
Leo Changd9df8aa2013-09-26 13:32:26 -070018389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18390 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070018391 vos_mem_free(hb_params);
18392 }
Leo Chang9056f462013-08-01 19:21:11 -070018393 return 0;
18394 }
18395#endif /* FEATURE_WLAN_LPHB */
18396 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18398 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070018399 return -EOPNOTSUPP;
18400 }
18401
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018402 EXIT();
18403 return err;
Leo Chang9056f462013-08-01 19:21:11 -070018404}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018405
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053018406static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
18407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
18408 struct wireless_dev *wdev,
18409#endif
18410 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018411{
18412 int ret;
18413
18414 vos_ssr_protect(__func__);
18415 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
18416 vos_ssr_unprotect(__func__);
18417
18418 return ret;
18419}
Leo Chang9056f462013-08-01 19:21:11 -070018420#endif /* CONFIG_NL80211_TESTMODE */
18421
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018422static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018423 struct net_device *dev,
18424 int idx, struct survey_info *survey)
18425{
18426 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18427 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053018428 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018429 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053018430 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018431 v_S7_t snr,rssi;
18432 int status, i, j, filled = 0;
18433
18434 ENTER();
18435
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018436 if (NULL == pAdapter)
18437 {
18438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18439 "%s: HDD adapter is Null", __func__);
18440 return -ENODEV;
18441 }
18442
18443 if (NULL == wiphy)
18444 {
18445 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18446 "%s: wiphy is Null", __func__);
18447 return -ENODEV;
18448 }
18449
18450 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18451 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018452 if (0 != status)
18453 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018454 return status;
18455 }
18456
Mihir Sheted9072e02013-08-21 17:02:29 +053018457 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18458
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018459 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053018460 0 != pAdapter->survey_idx ||
18461 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018462 {
18463 /* The survey dump ops when implemented completely is expected to
18464 * return a survey of all channels and the ops is called by the
18465 * kernel with incremental values of the argument 'idx' till it
18466 * returns -ENONET. But we can only support the survey for the
18467 * operating channel for now. survey_idx is used to track
18468 * that the ops is called only once and then return -ENONET for
18469 * the next iteration
18470 */
18471 pAdapter->survey_idx = 0;
18472 return -ENONET;
18473 }
18474
Mukul Sharma9d5233b2015-06-11 20:28:20 +053018475 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18476 {
18477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18478 "%s: Roaming in progress, hence return ", __func__);
18479 return -ENONET;
18480 }
18481
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018482 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18483
18484 wlan_hdd_get_snr(pAdapter, &snr);
18485 wlan_hdd_get_rssi(pAdapter, &rssi);
18486
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018487 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18488 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
18489 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018490 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
18491 hdd_wlan_get_freq(channel, &freq);
18492
18493
18494 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
18495 {
18496 if (NULL == wiphy->bands[i])
18497 {
18498 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
18499 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
18500 continue;
18501 }
18502
18503 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
18504 {
18505 struct ieee80211_supported_band *band = wiphy->bands[i];
18506
18507 if (band->channels[j].center_freq == (v_U16_t)freq)
18508 {
18509 survey->channel = &band->channels[j];
18510 /* The Rx BDs contain SNR values in dB for the received frames
18511 * while the supplicant expects noise. So we calculate and
18512 * return the value of noise (dBm)
18513 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
18514 */
18515 survey->noise = rssi - snr;
18516 survey->filled = SURVEY_INFO_NOISE_DBM;
18517 filled = 1;
18518 }
18519 }
18520 }
18521
18522 if (filled)
18523 pAdapter->survey_idx = 1;
18524 else
18525 {
18526 pAdapter->survey_idx = 0;
18527 return -ENONET;
18528 }
18529
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018530 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018531 return 0;
18532}
18533
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018534static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
18535 struct net_device *dev,
18536 int idx, struct survey_info *survey)
18537{
18538 int ret;
18539
18540 vos_ssr_protect(__func__);
18541 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
18542 vos_ssr_unprotect(__func__);
18543
18544 return ret;
18545}
18546
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018547/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018548 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018549 * this is called when cfg80211 driver resume
18550 * driver updates latest sched_scan scan result(if any) to cfg80211 database
18551 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018552int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018553{
18554 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18555 hdd_adapter_t *pAdapter;
18556 hdd_adapter_list_node_t *pAdapterNode, *pNext;
18557 VOS_STATUS status = VOS_STATUS_SUCCESS;
18558
18559 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018560
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018561 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018562 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018563 return 0;
18564 }
18565
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018566 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
18567 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018568 spin_lock(&pHddCtx->schedScan_lock);
18569 pHddCtx->isWiphySuspended = FALSE;
18570 if (TRUE != pHddCtx->isSchedScanUpdatePending)
18571 {
18572 spin_unlock(&pHddCtx->schedScan_lock);
18573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18574 "%s: Return resume is not due to PNO indication", __func__);
18575 return 0;
18576 }
18577 // Reset flag to avoid updatating cfg80211 data old results again
18578 pHddCtx->isSchedScanUpdatePending = FALSE;
18579 spin_unlock(&pHddCtx->schedScan_lock);
18580
18581 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
18582
18583 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
18584 {
18585 pAdapter = pAdapterNode->pAdapter;
18586 if ( (NULL != pAdapter) &&
18587 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
18588 {
18589 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018590 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18592 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018593 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018594 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018595 {
18596 /* Acquire wakelock to handle the case where APP's tries to
18597 * suspend immediately after updating the scan results. Whis
18598 * results in app's is in suspended state and not able to
18599 * process the connect request to AP
18600 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053018601 hdd_prevent_suspend_timeout(2000,
18602 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018603 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018604 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018605
18606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18607 "%s : cfg80211 scan result database updated", __func__);
18608
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018609 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018610 return 0;
18611
18612 }
18613 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18614 pAdapterNode = pNext;
18615 }
18616
18617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18618 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018619 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018620 return 0;
18621}
18622
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018623int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
18624{
18625 int ret;
18626
18627 vos_ssr_protect(__func__);
18628 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
18629 vos_ssr_unprotect(__func__);
18630
18631 return ret;
18632}
18633
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018634/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018635 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018636 * this is called when cfg80211 driver suspends
18637 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018638int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018639 struct cfg80211_wowlan *wow)
18640{
18641 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018642 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018643
18644 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018645
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018646 ret = wlan_hdd_validate_context(pHddCtx);
18647 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018648 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018649 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018650 }
18651
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018652
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018653 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18654 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
18655 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018656 pHddCtx->isWiphySuspended = TRUE;
18657
18658 EXIT();
18659
18660 return 0;
18661}
18662
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018663int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
18664 struct cfg80211_wowlan *wow)
18665{
18666 int ret;
18667
18668 vos_ssr_protect(__func__);
18669 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
18670 vos_ssr_unprotect(__func__);
18671
18672 return ret;
18673}
Jeff Johnson295189b2012-06-20 16:38:30 -070018674/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018675static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070018676{
18677 .add_virtual_intf = wlan_hdd_add_virtual_intf,
18678 .del_virtual_intf = wlan_hdd_del_virtual_intf,
18679 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
18680 .change_station = wlan_hdd_change_station,
18681#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
18682 .add_beacon = wlan_hdd_cfg80211_add_beacon,
18683 .del_beacon = wlan_hdd_cfg80211_del_beacon,
18684 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018685#else
18686 .start_ap = wlan_hdd_cfg80211_start_ap,
18687 .change_beacon = wlan_hdd_cfg80211_change_beacon,
18688 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070018689#endif
18690 .change_bss = wlan_hdd_cfg80211_change_bss,
18691 .add_key = wlan_hdd_cfg80211_add_key,
18692 .get_key = wlan_hdd_cfg80211_get_key,
18693 .del_key = wlan_hdd_cfg80211_del_key,
18694 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080018695#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070018696 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080018697#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018698 .scan = wlan_hdd_cfg80211_scan,
18699 .connect = wlan_hdd_cfg80211_connect,
18700 .disconnect = wlan_hdd_cfg80211_disconnect,
18701 .join_ibss = wlan_hdd_cfg80211_join_ibss,
18702 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
18703 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
18704 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
18705 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070018706 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
18707 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053018708 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070018709#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18710 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
18711 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
18712 .set_txq_params = wlan_hdd_set_txq_params,
18713#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018714 .get_station = wlan_hdd_cfg80211_get_station,
18715 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
18716 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018717 .add_station = wlan_hdd_cfg80211_add_station,
18718#ifdef FEATURE_WLAN_LFR
18719 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
18720 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
18721 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
18722#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018723#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
18724 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
18725#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018726#ifdef FEATURE_WLAN_TDLS
18727 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
18728 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
18729#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018730#ifdef WLAN_FEATURE_GTK_OFFLOAD
18731 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
18732#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018733#ifdef FEATURE_WLAN_SCAN_PNO
18734 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
18735 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
18736#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018737 .resume = wlan_hdd_cfg80211_resume_wlan,
18738 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018739 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070018740#ifdef WLAN_NL80211_TESTMODE
18741 .testmode_cmd = wlan_hdd_cfg80211_testmode,
18742#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018743 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070018744};
18745