blob: dd14f10b3febc857b9c6bf5520d20f632f0a4490 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05302 * Copyright (c) 2012-2018 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"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530100#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530101
Jeff Johnson295189b2012-06-20 16:38:30 -0700102
103#define g_mode_rates_size (12)
104#define a_mode_rates_size (8)
105#define FREQ_BASE_80211G (2407)
106#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700107#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530108#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700109#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800110 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700111
112#define HDD2GHZCHAN(freq, chan, flag) { \
113 .band = IEEE80211_BAND_2GHZ, \
114 .center_freq = (freq), \
115 .hw_value = (chan),\
116 .flags = (flag), \
117 .max_antenna_gain = 0 ,\
118 .max_power = 30, \
119}
120
121#define HDD5GHZCHAN(freq, chan, flag) { \
122 .band = IEEE80211_BAND_5GHZ, \
123 .center_freq = (freq), \
124 .hw_value = (chan),\
125 .flags = (flag), \
126 .max_antenna_gain = 0 ,\
127 .max_power = 30, \
128}
129
130#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
131{\
132 .bitrate = rate, \
133 .hw_value = rate_id, \
134 .flags = flag, \
135}
136
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530137#ifdef WLAN_FEATURE_VOWIFI_11R
138#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
139#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
140#endif
141
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530142#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530143#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530144
Sunil Duttc69bccb2014-05-26 21:30:20 +0530145#ifdef WLAN_FEATURE_LINK_LAYER_STATS
146/*
147 * Used to allocate the size of 4096 for the link layer stats.
148 * The size of 4096 is considered assuming that all data per
149 * respective event fit with in the limit.Please take a call
150 * on the limit based on the data requirements on link layer
151 * statistics.
152 */
153#define LL_STATS_EVENT_BUF_SIZE 4096
154#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530155#ifdef WLAN_FEATURE_EXTSCAN
156/*
157 * Used to allocate the size of 4096 for the EXTScan NL data.
158 * The size of 4096 is considered assuming that all data per
159 * respective event fit with in the limit.Please take a call
160 * on the limit based on the data requirements.
161 */
162
163#define EXTSCAN_EVENT_BUF_SIZE 4096
164#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
165#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530166
Atul Mittal115287b2014-07-08 13:26:33 +0530167/*EXT TDLS*/
168/*
169 * Used to allocate the size of 4096 for the TDLS.
170 * The size of 4096 is considered assuming that all data per
171 * respective event fit with in the limit.Please take a call
172 * on the limit based on the data requirements on link layer
173 * statistics.
174 */
175#define EXTTDLS_EVENT_BUF_SIZE 4096
176
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530177/*
178 * Values for Mac spoofing feature
179 *
180 */
181#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
182#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
183#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530184#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
185
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530186/*
187 * max_sched_scan_plans defined to 10
188 */
189#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530190
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530191static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700192{
193 WLAN_CIPHER_SUITE_WEP40,
194 WLAN_CIPHER_SUITE_WEP104,
195 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800196#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700197#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
198 WLAN_CIPHER_SUITE_KRK,
199 WLAN_CIPHER_SUITE_CCMP,
200#else
201 WLAN_CIPHER_SUITE_CCMP,
202#endif
203#ifdef FEATURE_WLAN_WAPI
204 WLAN_CIPHER_SUITE_SMS4,
205#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700206#ifdef WLAN_FEATURE_11W
207 WLAN_CIPHER_SUITE_AES_CMAC,
208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700209};
210
211static inline int is_broadcast_ether_addr(const u8 *addr)
212{
213 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
214 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
215}
216
Agrawal Ashish97dec502015-11-26 20:20:58 +0530217const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530218{
Jeff Johnson295189b2012-06-20 16:38:30 -0700219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2417, 2, 0) ,
221 HDD2GHZCHAN(2422, 3, 0) ,
222 HDD2GHZCHAN(2427, 4, 0) ,
223 HDD2GHZCHAN(2432, 5, 0) ,
224 HDD2GHZCHAN(2437, 6, 0) ,
225 HDD2GHZCHAN(2442, 7, 0) ,
226 HDD2GHZCHAN(2447, 8, 0) ,
227 HDD2GHZCHAN(2452, 9, 0) ,
228 HDD2GHZCHAN(2457, 10, 0) ,
229 HDD2GHZCHAN(2462, 11, 0) ,
230 HDD2GHZCHAN(2467, 12, 0) ,
231 HDD2GHZCHAN(2472, 13, 0) ,
232 HDD2GHZCHAN(2484, 14, 0) ,
233};
234
Agrawal Ashish97dec502015-11-26 20:20:58 +0530235const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700236{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700237 HDD5GHZCHAN(4920, 240, 0) ,
238 HDD5GHZCHAN(4940, 244, 0) ,
239 HDD5GHZCHAN(4960, 248, 0) ,
240 HDD5GHZCHAN(4980, 252, 0) ,
241 HDD5GHZCHAN(5040, 208, 0) ,
242 HDD5GHZCHAN(5060, 212, 0) ,
243 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700244 HDD5GHZCHAN(5180, 36, 0) ,
245 HDD5GHZCHAN(5200, 40, 0) ,
246 HDD5GHZCHAN(5220, 44, 0) ,
247 HDD5GHZCHAN(5240, 48, 0) ,
248 HDD5GHZCHAN(5260, 52, 0) ,
249 HDD5GHZCHAN(5280, 56, 0) ,
250 HDD5GHZCHAN(5300, 60, 0) ,
251 HDD5GHZCHAN(5320, 64, 0) ,
252 HDD5GHZCHAN(5500,100, 0) ,
253 HDD5GHZCHAN(5520,104, 0) ,
254 HDD5GHZCHAN(5540,108, 0) ,
255 HDD5GHZCHAN(5560,112, 0) ,
256 HDD5GHZCHAN(5580,116, 0) ,
257 HDD5GHZCHAN(5600,120, 0) ,
258 HDD5GHZCHAN(5620,124, 0) ,
259 HDD5GHZCHAN(5640,128, 0) ,
260 HDD5GHZCHAN(5660,132, 0) ,
261 HDD5GHZCHAN(5680,136, 0) ,
262 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800263#ifdef FEATURE_WLAN_CH144
264 HDD5GHZCHAN(5720,144, 0) ,
265#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700266 HDD5GHZCHAN(5745,149, 0) ,
267 HDD5GHZCHAN(5765,153, 0) ,
268 HDD5GHZCHAN(5785,157, 0) ,
269 HDD5GHZCHAN(5805,161, 0) ,
270 HDD5GHZCHAN(5825,165, 0) ,
271};
272
273static struct ieee80211_rate g_mode_rates[] =
274{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530275 HDD_G_MODE_RATETAB(10, 0x1, 0),
276 HDD_G_MODE_RATETAB(20, 0x2, 0),
277 HDD_G_MODE_RATETAB(55, 0x4, 0),
278 HDD_G_MODE_RATETAB(110, 0x8, 0),
279 HDD_G_MODE_RATETAB(60, 0x10, 0),
280 HDD_G_MODE_RATETAB(90, 0x20, 0),
281 HDD_G_MODE_RATETAB(120, 0x40, 0),
282 HDD_G_MODE_RATETAB(180, 0x80, 0),
283 HDD_G_MODE_RATETAB(240, 0x100, 0),
284 HDD_G_MODE_RATETAB(360, 0x200, 0),
285 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700286 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530287};
Jeff Johnson295189b2012-06-20 16:38:30 -0700288
289static struct ieee80211_rate a_mode_rates[] =
290{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530291 HDD_G_MODE_RATETAB(60, 0x10, 0),
292 HDD_G_MODE_RATETAB(90, 0x20, 0),
293 HDD_G_MODE_RATETAB(120, 0x40, 0),
294 HDD_G_MODE_RATETAB(180, 0x80, 0),
295 HDD_G_MODE_RATETAB(240, 0x100, 0),
296 HDD_G_MODE_RATETAB(360, 0x200, 0),
297 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 HDD_G_MODE_RATETAB(540, 0x800, 0),
299};
300
301static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
302{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530303 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700304 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
305 .band = IEEE80211_BAND_2GHZ,
306 .bitrates = g_mode_rates,
307 .n_bitrates = g_mode_rates_size,
308 .ht_cap.ht_supported = 1,
309 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
310 | IEEE80211_HT_CAP_GRN_FLD
311 | IEEE80211_HT_CAP_DSSSCCK40
312 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
313 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
314 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
315 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
316 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
317 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
318};
319
Jeff Johnson295189b2012-06-20 16:38:30 -0700320static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
321{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530322 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700323 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
324 .band = IEEE80211_BAND_5GHZ,
325 .bitrates = a_mode_rates,
326 .n_bitrates = a_mode_rates_size,
327 .ht_cap.ht_supported = 1,
328 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
329 | IEEE80211_HT_CAP_GRN_FLD
330 | IEEE80211_HT_CAP_DSSSCCK40
331 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
332 | IEEE80211_HT_CAP_SGI_40
333 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
334 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
335 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
336 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
337 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
338 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
339};
340
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530341/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700342 TX/RX direction for each kind of interface */
343static const struct ieee80211_txrx_stypes
344wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
345 [NL80211_IFTYPE_STATION] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ACTION) |
348 BIT(SIR_MAC_MGMT_PROBE_REQ),
349 },
350 [NL80211_IFTYPE_AP] = {
351 .tx = 0xffff,
352 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
353 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
354 BIT(SIR_MAC_MGMT_PROBE_REQ) |
355 BIT(SIR_MAC_MGMT_DISASSOC) |
356 BIT(SIR_MAC_MGMT_AUTH) |
357 BIT(SIR_MAC_MGMT_DEAUTH) |
358 BIT(SIR_MAC_MGMT_ACTION),
359 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700360 [NL80211_IFTYPE_ADHOC] = {
361 .tx = 0xffff,
362 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
363 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_PROBE_REQ) |
365 BIT(SIR_MAC_MGMT_DISASSOC) |
366 BIT(SIR_MAC_MGMT_AUTH) |
367 BIT(SIR_MAC_MGMT_DEAUTH) |
368 BIT(SIR_MAC_MGMT_ACTION),
369 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700370 [NL80211_IFTYPE_P2P_CLIENT] = {
371 .tx = 0xffff,
372 .rx = BIT(SIR_MAC_MGMT_ACTION) |
373 BIT(SIR_MAC_MGMT_PROBE_REQ),
374 },
375 [NL80211_IFTYPE_P2P_GO] = {
376 /* This is also same as for SoftAP */
377 .tx = 0xffff,
378 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
379 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
380 BIT(SIR_MAC_MGMT_PROBE_REQ) |
381 BIT(SIR_MAC_MGMT_DISASSOC) |
382 BIT(SIR_MAC_MGMT_AUTH) |
383 BIT(SIR_MAC_MGMT_DEAUTH) |
384 BIT(SIR_MAC_MGMT_ACTION),
385 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700386};
387
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800388#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800389static const struct ieee80211_iface_limit
390wlan_hdd_iface_limit[] = {
391 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800392 /* max = 3 ; Our driver create two interfaces during driver init
393 * wlan0 and p2p0 interfaces. p2p0 is considered as station
394 * interface until a group is formed. In JB architecture, once the
395 * group is formed, interface type of p2p0 is changed to P2P GO or
396 * Client.
397 * When supplicant remove the group, it first issue a set interface
398 * cmd to change the mode back to Station. In JB this works fine as
399 * we advertize two station type interface during driver init.
400 * Some vendors create separate interface for P2P GO/Client,
401 * after group formation(Third one). But while group remove
402 * supplicant first tries to change the mode(3rd interface) to STATION
403 * But as we advertized only two sta type interfaces nl80211 was
404 * returning error for the third one which was leading to failure in
405 * delete interface. Ideally while removing the group, supplicant
406 * should not try to change the 3rd interface mode to Station type.
407 * Till we get a fix in wpa_supplicant, we advertize max STA
408 * interface type to 3
409 */
410 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 .types = BIT(NL80211_IFTYPE_STATION),
412 },
413 {
414 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700415 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800416 },
417 {
418 .max = 1,
419 .types = BIT(NL80211_IFTYPE_P2P_GO) |
420 BIT(NL80211_IFTYPE_P2P_CLIENT),
421 },
422};
423
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530424/* interface limits for sta + monitor SCC */
425static const struct ieee80211_iface_limit
426wlan_hdd_iface_sta_mon_limit[] = {
427 {
428 .max = 1,
429 .types = BIT(NL80211_IFTYPE_STATION),
430 },
431 {
432 .max = 1, /* Monitor interface */
433 .types = BIT(NL80211_IFTYPE_MONITOR),
434 },
435};
436
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800437/* By default, only single channel concurrency is allowed */
438static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530439wlan_hdd_iface_combination[] = {
440 {
441 .limits = wlan_hdd_iface_limit,
442 .num_different_channels = 1,
443 /*
444 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
445 * and p2p0 interfaces during driver init
446 * Some vendors create separate interface for P2P operations.
447 * wlan0: STA interface
448 * p2p0: P2P Device interface, action frames goes
449 * through this interface.
450 * p2p-xx: P2P interface, After GO negotiation this interface is
451 * created for p2p operations(GO/CLIENT interface).
452 */
453 .max_interfaces = WLAN_MAX_INTERFACES,
454 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
455 .beacon_int_infra_match = false,
456 },
457 {
458 .limits = wlan_hdd_iface_sta_mon_limit,
459 .num_different_channels = 1,
460 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
461 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
462 .beacon_int_infra_match = false,
463 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800464};
465#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800466
Jeff Johnson295189b2012-06-20 16:38:30 -0700467static struct cfg80211_ops wlan_hdd_cfg80211_ops;
468
469/* Data rate 100KBPS based on IE Index */
470struct index_data_rate_type
471{
472 v_U8_t beacon_rate_index;
473 v_U16_t supported_rate[4];
474};
475
476/* 11B, 11G Rate table include Basic rate and Extended rate
477 The IDX field is the rate index
478 The HI field is the rate when RSSI is strong or being ignored
479 (in this case we report actual rate)
480 The MID field is the rate when RSSI is moderate
481 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
482 The LO field is the rate when RSSI is low
483 (in this case we don't report rates, actual current rate used)
484 */
485static const struct
486{
487 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700488 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700489} supported_data_rate[] =
490{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700491/* IDX HI HM LM LO (RSSI-based index */
492 {2, { 10, 10, 10, 0}},
493 {4, { 20, 20, 10, 0}},
494 {11, { 55, 20, 10, 0}},
495 {12, { 60, 55, 20, 0}},
496 {18, { 90, 55, 20, 0}},
497 {22, {110, 55, 20, 0}},
498 {24, {120, 90, 60, 0}},
499 {36, {180, 120, 60, 0}},
500 {44, {220, 180, 60, 0}},
501 {48, {240, 180, 90, 0}},
502 {66, {330, 180, 90, 0}},
503 {72, {360, 240, 90, 0}},
504 {96, {480, 240, 120, 0}},
505 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700506};
507
508/* MCS Based rate table */
509static struct index_data_rate_type supported_mcs_rate[] =
510{
511/* MCS L20 L40 S20 S40 */
512 {0, {65, 135, 72, 150}},
513 {1, {130, 270, 144, 300}},
514 {2, {195, 405, 217, 450}},
515 {3, {260, 540, 289, 600}},
516 {4, {390, 810, 433, 900}},
517 {5, {520, 1080, 578, 1200}},
518 {6, {585, 1215, 650, 1350}},
519 {7, {650, 1350, 722, 1500}}
520};
521
Leo Chang6f8870f2013-03-26 18:11:36 -0700522#ifdef WLAN_FEATURE_11AC
523
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530524#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700525
526struct index_vht_data_rate_type
527{
528 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530529 v_U16_t supported_VHT80_rate[2];
530 v_U16_t supported_VHT40_rate[2];
531 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700532};
533
534typedef enum
535{
536 DATA_RATE_11AC_MAX_MCS_7,
537 DATA_RATE_11AC_MAX_MCS_8,
538 DATA_RATE_11AC_MAX_MCS_9,
539 DATA_RATE_11AC_MAX_MCS_NA
540} eDataRate11ACMaxMcs;
541
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530542/* SSID broadcast type */
543typedef enum eSSIDBcastType
544{
545 eBCAST_UNKNOWN = 0,
546 eBCAST_NORMAL = 1,
547 eBCAST_HIDDEN = 2,
548} tSSIDBcastType;
549
Leo Chang6f8870f2013-03-26 18:11:36 -0700550/* MCS Based VHT rate table */
551static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
552{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530553/* MCS L80 S80 L40 S40 L20 S40*/
554 {0, {293, 325}, {135, 150}, {65, 72}},
555 {1, {585, 650}, {270, 300}, {130, 144}},
556 {2, {878, 975}, {405, 450}, {195, 217}},
557 {3, {1170, 1300}, {540, 600}, {260, 289}},
558 {4, {1755, 1950}, {810, 900}, {390, 433}},
559 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
560 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
561 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
562 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
563 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700564};
565#endif /* WLAN_FEATURE_11AC */
566
c_hpothu79aab322014-07-14 21:11:01 +0530567/*array index points to MCS and array value points respective rssi*/
568static int rssiMcsTbl[][10] =
569{
570/*MCS 0 1 2 3 4 5 6 7 8 9*/
571 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
572 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
573 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
574};
575
Jeff Johnson295189b2012-06-20 16:38:30 -0700576extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530577#ifdef FEATURE_WLAN_SCAN_PNO
578static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
579#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700580
Leo Chang9056f462013-08-01 19:21:11 -0700581#ifdef WLAN_NL80211_TESTMODE
582enum wlan_hdd_tm_attr
583{
584 WLAN_HDD_TM_ATTR_INVALID = 0,
585 WLAN_HDD_TM_ATTR_CMD = 1,
586 WLAN_HDD_TM_ATTR_DATA = 2,
587 WLAN_HDD_TM_ATTR_TYPE = 3,
588 /* keep last */
589 WLAN_HDD_TM_ATTR_AFTER_LAST,
590 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
591};
592
593enum wlan_hdd_tm_cmd
594{
595 WLAN_HDD_TM_CMD_WLAN_HB = 1,
596};
597
598#define WLAN_HDD_TM_DATA_MAX_LEN 5000
599
600static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
601{
602 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
603 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
604 .len = WLAN_HDD_TM_DATA_MAX_LEN },
605};
606#endif /* WLAN_NL80211_TESTMODE */
607
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800608#ifdef FEATURE_WLAN_CH_AVOID
609/*
610 * FUNCTION: wlan_hdd_send_avoid_freq_event
611 * This is called when wlan driver needs to send vendor specific
612 * avoid frequency range event to userspace
613 */
614int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
615 tHddAvoidFreqList *pAvoidFreqList)
616{
617 struct sk_buff *vendor_event;
618
619 ENTER();
620
621 if (!pHddCtx)
622 {
623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
624 "%s: HDD context is null", __func__);
625 return -1;
626 }
627
628 if (!pAvoidFreqList)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 "%s: pAvoidFreqList is null", __func__);
632 return -1;
633 }
634
635 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530636#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
637 NULL,
638#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800639 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530640 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800641 GFP_KERNEL);
642 if (!vendor_event)
643 {
644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
645 "%s: cfg80211_vendor_event_alloc failed", __func__);
646 return -1;
647 }
648
649 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
650 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
651
652 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
653
654 EXIT();
655 return 0;
656}
657#endif /* FEATURE_WLAN_CH_AVOID */
658
Srinivas Dasari030bad32015-02-18 23:23:54 +0530659/*
660 * FUNCTION: __wlan_hdd_cfg80211_nan_request
661 * This is called when wlan driver needs to send vendor specific
662 * nan request event.
663 */
664static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
665 struct wireless_dev *wdev,
666 const void *data, int data_len)
667{
668 tNanRequestReq nan_req;
669 VOS_STATUS status;
670 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530671 struct net_device *dev = wdev->netdev;
672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
673 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530674 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
675
676 if (0 == data_len)
677 {
678 hddLog(VOS_TRACE_LEVEL_ERROR,
679 FL("NAN - Invalid Request, length = 0"));
680 return ret_val;
681 }
682
683 if (NULL == data)
684 {
685 hddLog(VOS_TRACE_LEVEL_ERROR,
686 FL("NAN - Invalid Request, data is NULL"));
687 return ret_val;
688 }
689
690 status = wlan_hdd_validate_context(pHddCtx);
691 if (0 != status)
692 {
693 hddLog(VOS_TRACE_LEVEL_ERROR,
694 FL("HDD context is not valid"));
695 return -EINVAL;
696 }
697
698 hddLog(LOG1, FL("Received NAN command"));
699 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
700 (tANI_U8 *)data, data_len);
701
702 /* check the NAN Capability */
703 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
704 {
705 hddLog(VOS_TRACE_LEVEL_ERROR,
706 FL("NAN is not supported by Firmware"));
707 return -EINVAL;
708 }
709
710 nan_req.request_data_len = data_len;
711 nan_req.request_data = data;
712
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530713 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530714 if (VOS_STATUS_SUCCESS == status)
715 {
716 ret_val = 0;
717 }
718 return ret_val;
719}
720
721/*
722 * FUNCTION: wlan_hdd_cfg80211_nan_request
723 * Wrapper to protect the nan vendor command from ssr
724 */
725static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
726 struct wireless_dev *wdev,
727 const void *data, int data_len)
728{
729 int ret;
730
731 vos_ssr_protect(__func__);
732 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
733 vos_ssr_unprotect(__func__);
734
735 return ret;
736}
737
738/*
739 * FUNCTION: wlan_hdd_cfg80211_nan_callback
740 * This is a callback function and it gets called
741 * when we need to report nan response event to
742 * upper layers.
743 */
744static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
745{
746 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
747 struct sk_buff *vendor_event;
748 int status;
749 tSirNanEvent *data;
750
751 ENTER();
752 if (NULL == msg)
753 {
754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
755 FL(" msg received here is null"));
756 return;
757 }
758 data = msg;
759
760 status = wlan_hdd_validate_context(pHddCtx);
761
762 if (0 != status)
763 {
764 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
765 FL("HDD context is not valid"));
766 return;
767 }
768
769 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
771 NULL,
772#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530773 data->event_data_len +
774 NLMSG_HDRLEN,
775 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
776 GFP_KERNEL);
777
778 if (!vendor_event)
779 {
780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
781 FL("cfg80211_vendor_event_alloc failed"));
782 return;
783 }
784 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
785 data->event_data_len, data->event_data))
786 {
787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
788 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
789 kfree_skb(vendor_event);
790 return;
791 }
792 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
793 EXIT();
794}
795
796/*
797 * FUNCTION: wlan_hdd_cfg80211_nan_init
798 * This function is called to register the callback to sme layer
799 */
800inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
801{
802 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
803}
804
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530805/*
806 * define short names for the global vendor params
807 * used by __wlan_hdd_cfg80211_get_station_cmd()
808 */
809#define STATION_INVALID \
810 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
811#define STATION_INFO \
812 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
813#define STATION_ASSOC_FAIL_REASON \
814 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530815#define STATION_REMOTE \
816 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530817#define STATION_MAX \
818 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
819
820static const struct nla_policy
821hdd_get_station_policy[STATION_MAX + 1] = {
822 [STATION_INFO] = {.type = NLA_FLAG},
823 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
824};
825
826/**
827 * hdd_get_station_assoc_fail() - Handle get station assoc fail
828 * @hdd_ctx: HDD context within host driver
829 * @wdev: wireless device
830 *
831 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
832 * Validate cmd attributes and send the station info to upper layers.
833 *
834 * Return: Success(0) or reason code for failure
835 */
836static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
837 hdd_adapter_t *adapter)
838{
839 struct sk_buff *skb = NULL;
840 uint32_t nl_buf_len;
841 hdd_station_ctx_t *hdd_sta_ctx;
842
843 nl_buf_len = NLMSG_HDRLEN;
844 nl_buf_len += sizeof(uint32_t);
845 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
846
847 if (!skb) {
848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
849 return -ENOMEM;
850 }
851
852 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
853
854 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
855 hdd_sta_ctx->conn_info.assoc_status_code)) {
856 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
857 goto fail;
858 }
859 return cfg80211_vendor_cmd_reply(skb);
860fail:
861 if (skb)
862 kfree_skb(skb);
863 return -EINVAL;
864}
865
866/**
867 * hdd_map_auth_type() - transform auth type specific to
868 * vendor command
869 * @auth_type: csr auth type
870 *
871 * Return: Success(0) or reason code for failure
872 */
873static int hdd_convert_auth_type(uint32_t auth_type)
874{
875 uint32_t ret_val;
876
877 switch (auth_type) {
878 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
879 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
880 break;
881 case eCSR_AUTH_TYPE_SHARED_KEY:
882 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
883 break;
884 case eCSR_AUTH_TYPE_WPA:
885 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
886 break;
887 case eCSR_AUTH_TYPE_WPA_PSK:
888 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
889 break;
890 case eCSR_AUTH_TYPE_AUTOSWITCH:
891 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
892 break;
893 case eCSR_AUTH_TYPE_WPA_NONE:
894 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
895 break;
896 case eCSR_AUTH_TYPE_RSN:
897 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
898 break;
899 case eCSR_AUTH_TYPE_RSN_PSK:
900 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
901 break;
902 case eCSR_AUTH_TYPE_FT_RSN:
903 ret_val = QCA_WLAN_AUTH_TYPE_FT;
904 break;
905 case eCSR_AUTH_TYPE_FT_RSN_PSK:
906 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
907 break;
908 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
909 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
910 break;
911 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
912 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
913 break;
914#ifdef FEATURE_WLAN_ESE
915 case eCSR_AUTH_TYPE_CCKM_WPA:
916 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
917 break;
918 case eCSR_AUTH_TYPE_CCKM_RSN:
919 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
920 break;
921#endif
922 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
923 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
924 break;
925 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
926 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
927 break;
928 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
929 case eCSR_AUTH_TYPE_FAILED:
930 case eCSR_AUTH_TYPE_NONE:
931 default:
932 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
933 break;
934 }
935 return ret_val;
936}
937
938/**
939 * hdd_map_dot_11_mode() - transform dot11mode type specific to
940 * vendor command
941 * @dot11mode: dot11mode
942 *
943 * Return: Success(0) or reason code for failure
944 */
945static int hdd_convert_dot11mode(uint32_t dot11mode)
946{
947 uint32_t ret_val;
948
949 switch (dot11mode) {
950 case eCSR_CFG_DOT11_MODE_11A:
951 ret_val = QCA_WLAN_802_11_MODE_11A;
952 break;
953 case eCSR_CFG_DOT11_MODE_11B:
954 ret_val = QCA_WLAN_802_11_MODE_11B;
955 break;
956 case eCSR_CFG_DOT11_MODE_11G:
957 ret_val = QCA_WLAN_802_11_MODE_11G;
958 break;
959 case eCSR_CFG_DOT11_MODE_11N:
960 ret_val = QCA_WLAN_802_11_MODE_11N;
961 break;
962 case eCSR_CFG_DOT11_MODE_11AC:
963 ret_val = QCA_WLAN_802_11_MODE_11AC;
964 break;
965 case eCSR_CFG_DOT11_MODE_AUTO:
966 case eCSR_CFG_DOT11_MODE_ABG:
967 default:
968 ret_val = QCA_WLAN_802_11_MODE_INVALID;
969 }
970 return ret_val;
971}
972
973/**
974 * hdd_add_tx_bitrate() - add tx bitrate attribute
975 * @skb: pointer to sk buff
976 * @hdd_sta_ctx: pointer to hdd station context
977 * @idx: attribute index
978 *
979 * Return: Success(0) or reason code for failure
980 */
981static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
982 hdd_station_ctx_t *hdd_sta_ctx,
983 int idx)
984{
985 struct nlattr *nla_attr;
986 uint32_t bitrate, bitrate_compat;
987
988 nla_attr = nla_nest_start(skb, idx);
989 if (!nla_attr)
990 goto fail;
991 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
992 bitrate = cfg80211_calculate_bitrate(&hdd_sta_ctx->conn_info.txrate);
993
994 /* report 16-bit bitrate only if we can */
995 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
996 if (bitrate > 0 &&
997 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
999 goto fail;
1000 }
1001 if (bitrate_compat > 0 &&
1002 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1003 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1004 goto fail;
1005 }
1006 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1007 hdd_sta_ctx->conn_info.txrate.nss)) {
1008 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1009 goto fail;
1010 }
1011 nla_nest_end(skb, nla_attr);
1012 return 0;
1013fail:
1014 return -EINVAL;
1015}
1016
1017/**
1018 * hdd_add_sta_info() - add station info attribute
1019 * @skb: pointer to sk buff
1020 * @hdd_sta_ctx: pointer to hdd station context
1021 * @idx: attribute index
1022 *
1023 * Return: Success(0) or reason code for failure
1024 */
1025static int32_t hdd_add_sta_info(struct sk_buff *skb,
1026 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1027{
1028 struct nlattr *nla_attr;
1029
1030 nla_attr = nla_nest_start(skb, idx);
1031 if (!nla_attr)
1032 goto fail;
1033 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
1034 (hdd_sta_ctx->conn_info.signal + 100))) {
1035 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1036 goto fail;
1037 }
1038 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1039 goto fail;
1040 nla_nest_end(skb, nla_attr);
1041 return 0;
1042fail:
1043 return -EINVAL;
1044}
1045
1046/**
1047 * hdd_add_survey_info() - add survey info attribute
1048 * @skb: pointer to sk buff
1049 * @hdd_sta_ctx: pointer to hdd station context
1050 * @idx: attribute index
1051 *
1052 * Return: Success(0) or reason code for failure
1053 */
1054static int32_t hdd_add_survey_info(struct sk_buff *skb,
1055 hdd_station_ctx_t *hdd_sta_ctx,
1056 int idx)
1057{
1058 struct nlattr *nla_attr;
1059
1060 nla_attr = nla_nest_start(skb, idx);
1061 if (!nla_attr)
1062 goto fail;
1063 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1064 hdd_sta_ctx->conn_info.freq) ||
1065 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
1066 (hdd_sta_ctx->conn_info.noise + 100))) {
1067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1068 goto fail;
1069 }
1070 nla_nest_end(skb, nla_attr);
1071 return 0;
1072fail:
1073 return -EINVAL;
1074}
1075
1076/**
1077 * hdd_add_link_standard_info() - add link info attribute
1078 * @skb: pointer to sk buff
1079 * @hdd_sta_ctx: pointer to hdd station context
1080 * @idx: attribute index
1081 *
1082 * Return: Success(0) or reason code for failure
1083 */
1084static int32_t
1085hdd_add_link_standard_info(struct sk_buff *skb,
1086 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1087{
1088 struct nlattr *nla_attr;
1089
1090 nla_attr = nla_nest_start(skb, idx);
1091 if (!nla_attr)
1092 goto fail;
1093 if (nla_put(skb,
1094 NL80211_ATTR_SSID,
1095 hdd_sta_ctx->conn_info.SSID.SSID.length,
1096 hdd_sta_ctx->conn_info.SSID.SSID.ssId)) {
1097 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1098 goto fail;
1099 }
1100 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1101 goto fail;
1102 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1103 goto fail;
1104 nla_nest_end(skb, nla_attr);
1105 return 0;
1106fail:
1107 return -EINVAL;
1108}
1109
1110/**
1111 * hdd_add_ap_standard_info() - add ap info attribute
1112 * @skb: pointer to sk buff
1113 * @hdd_sta_ctx: pointer to hdd station context
1114 * @idx: attribute index
1115 *
1116 * Return: Success(0) or reason code for failure
1117 */
1118static int32_t
1119hdd_add_ap_standard_info(struct sk_buff *skb,
1120 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1121{
1122 struct nlattr *nla_attr;
1123
1124 nla_attr = nla_nest_start(skb, idx);
1125 if (!nla_attr)
1126 goto fail;
1127 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1128 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1129 sizeof(hdd_sta_ctx->conn_info.vht_caps),
1130 &hdd_sta_ctx->conn_info.vht_caps)) {
1131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1132 goto fail;
1133 }
1134 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1135 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1136 sizeof(hdd_sta_ctx->conn_info.ht_caps),
1137 &hdd_sta_ctx->conn_info.ht_caps)) {
1138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1139 goto fail;
1140 }
1141 nla_nest_end(skb, nla_attr);
1142 return 0;
1143fail:
1144 return -EINVAL;
1145}
1146
1147/**
1148 * hdd_get_station_info() - send BSS information to supplicant
1149 * @hdd_ctx: pointer to hdd context
1150 * @adapter: pointer to adapter
1151 *
1152 * Return: 0 if success else error status
1153 */
1154static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1155 hdd_adapter_t *adapter)
1156{
1157 struct sk_buff *skb = NULL;
1158 uint8_t *tmp_hs20 = NULL;
1159 uint32_t nl_buf_len;
1160 hdd_station_ctx_t *hdd_sta_ctx;
1161
1162 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1163
1164 nl_buf_len = NLMSG_HDRLEN;
1165 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.SSID.SSID.length) +
1166 sizeof(hdd_sta_ctx->conn_info.freq) +
1167 sizeof(hdd_sta_ctx->conn_info.noise) +
1168 sizeof(hdd_sta_ctx->conn_info.signal) +
1169 (sizeof(uint32_t) * 2) +
1170 sizeof(hdd_sta_ctx->conn_info.txrate.nss) +
1171 sizeof(hdd_sta_ctx->conn_info.roam_count) +
1172 sizeof(hdd_sta_ctx->conn_info.authType) +
1173 sizeof(hdd_sta_ctx->conn_info.dot11Mode);
1174 if (hdd_sta_ctx->conn_info.conn_flag.vht_present)
1175 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_caps);
1176 if (hdd_sta_ctx->conn_info.conn_flag.ht_present)
1177 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_caps);
1178 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present) {
1179 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->conn_info.hs20vendor_ie);
1180 nl_buf_len += (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) -
1181 1);
1182 }
1183 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1184 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.ht_operation);
1185 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1186 nl_buf_len += sizeof(hdd_sta_ctx->conn_info.vht_operation);
1187
1188
1189 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1190 if (!skb) {
1191 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1192 __func__, __LINE__);
1193 return -ENOMEM;
1194 }
1195
1196 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1197 LINK_INFO_STANDARD_NL80211_ATTR)) {
1198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1199 goto fail;
1200 }
1201 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1202 AP_INFO_STANDARD_NL80211_ATTR)) {
1203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1204 goto fail;
1205 }
1206 if (nla_put_u32(skb, INFO_ROAM_COUNT,
1207 hdd_sta_ctx->conn_info.roam_count) ||
1208 nla_put_u32(skb, INFO_AKM,
1209 hdd_convert_auth_type(
1210 hdd_sta_ctx->conn_info.authType)) ||
1211 nla_put_u32(skb, WLAN802_11_MODE,
1212 hdd_convert_dot11mode(
1213 hdd_sta_ctx->conn_info.dot11Mode))) {
1214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1215 goto fail;
1216 }
1217 if (hdd_sta_ctx->conn_info.conn_flag.ht_op_present)
1218 if (nla_put(skb, HT_OPERATION,
1219 (sizeof(hdd_sta_ctx->conn_info.ht_operation)),
1220 &hdd_sta_ctx->conn_info.ht_operation)) {
1221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1222 goto fail;
1223 }
1224 if (hdd_sta_ctx->conn_info.conn_flag.vht_op_present)
1225 if (nla_put(skb, VHT_OPERATION,
1226 (sizeof(hdd_sta_ctx->conn_info.vht_operation)),
1227 &hdd_sta_ctx->conn_info.vht_operation)) {
1228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1229 goto fail;
1230 }
1231 if (hdd_sta_ctx->conn_info.conn_flag.hs20_present)
1232 if (nla_put(skb, AP_INFO_HS20_INDICATION,
1233 (sizeof(hdd_sta_ctx->conn_info.hs20vendor_ie) - 1),
1234 tmp_hs20 + 1)) {
1235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1236 goto fail;
1237 }
1238
1239 return cfg80211_vendor_cmd_reply(skb);
1240fail:
1241 if (skb)
1242 kfree_skb(skb);
1243 return -EINVAL;
1244}
1245
1246/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301247 * hdd_add_survey_info_sap_get_len - get data length used in
1248 * hdd_add_survey_info_sap()
1249 *
1250 * This function calculates the data length used in hdd_add_survey_info_sap()
1251 *
1252 * Return: total data length used in hdd_add_survey_info_sap()
1253 */
1254static uint32_t hdd_add_survey_info_sap_get_len(void)
1255{
1256 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1257}
1258
1259/**
1260 * hdd_add_survey_info - add survey info attribute
1261 * @skb: pointer to response skb buffer
1262 * @stainfo: station information
1263 * @idx: attribute type index for nla_next_start()
1264 *
1265 * This function adds survey info attribute to response skb buffer
1266 *
1267 * Return : 0 on success and errno on failure
1268 */
1269static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1270 struct hdd_cache_sta_info *stainfo,
1271 int idx)
1272{
1273 struct nlattr *nla_attr;
1274
1275 nla_attr = nla_nest_start(skb, idx);
1276 if (!nla_attr)
1277 goto fail;
1278 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1279 stainfo->freq)) {
1280 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1281 FL("put fail"));
1282 goto fail;
1283 }
1284 nla_nest_end(skb, nla_attr);
1285 return 0;
1286fail:
1287 return -EINVAL;
1288}
1289
1290/**
1291 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1292 * hdd_add_tx_bitrate_sap()
1293 *
1294 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1295 *
1296 * Return: total data length used in hdd_add_tx_bitrate_sap()
1297 */
1298static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1299{
1300 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1301}
1302
1303/**
1304 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1305 * @skb: pointer to response skb buffer
1306 * @stainfo: station information
1307 * @idx: attribute type index for nla_next_start()
1308 *
1309 * This function adds vht nss attribute to response skb buffer
1310 *
1311 * Return : 0 on success and errno on failure
1312 */
1313static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1314 struct hdd_cache_sta_info *stainfo,
1315 int idx)
1316{
1317 struct nlattr *nla_attr;
1318
1319 nla_attr = nla_nest_start(skb, idx);
1320 if (!nla_attr)
1321 goto fail;
1322
1323 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1324 stainfo->nss)) {
1325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1326 FL("put fail"));
1327 goto fail;
1328 }
1329 nla_nest_end(skb, nla_attr);
1330 return 0;
1331fail:
1332 return -EINVAL;
1333}
1334
1335/**
1336 * hdd_add_sta_info_sap_get_len - get data length used in
1337 * hdd_add_sta_info_sap()
1338 *
1339 * This function calculates the data length used in hdd_add_sta_info_sap()
1340 *
1341 * Return: total data length used in hdd_add_sta_info_sap()
1342 */
1343static uint32_t hdd_add_sta_info_sap_get_len(void)
1344{
1345 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1346 hdd_add_tx_bitrate_sap_get_len());
1347}
1348
1349/**
1350 * hdd_add_sta_info_sap - add sta signal info attribute
1351 * @skb: pointer to response skb buffer
1352 * @rssi: peer rssi value
1353 * @stainfo: station information
1354 * @idx: attribute type index for nla_next_start()
1355 *
1356 * This function adds sta signal attribute to response skb buffer
1357 *
1358 * Return : 0 on success and errno on failure
1359 */
1360static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1361 struct hdd_cache_sta_info *stainfo, int idx)
1362{
1363 struct nlattr *nla_attr;
1364
1365 nla_attr = nla_nest_start(skb, idx);
1366 if (!nla_attr)
1367 goto fail;
1368
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301369 /* upperlayer expects positive rssi value */
1370 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1372 FL("put fail"));
1373 goto fail;
1374 }
1375 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1377 FL("put fail"));
1378 goto fail;
1379 }
1380
1381 nla_nest_end(skb, nla_attr);
1382 return 0;
1383fail:
1384 return -EINVAL;
1385}
1386
1387/**
1388 * hdd_add_link_standard_info_sap_get_len - get data length used in
1389 * hdd_add_link_standard_info_sap()
1390 *
1391 * This function calculates the data length used in
1392 * hdd_add_link_standard_info_sap()
1393 *
1394 * Return: total data length used in hdd_add_link_standard_info_sap()
1395 */
1396static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1397{
1398 return ((NLA_HDRLEN) +
1399 hdd_add_survey_info_sap_get_len() +
1400 hdd_add_sta_info_sap_get_len() +
1401 (sizeof(uint32_t) + NLA_HDRLEN));
1402}
1403
1404/**
1405 * hdd_add_link_standard_info_sap - add add link info attribut
1406 * @skb: pointer to response skb buffer
1407 * @stainfo: station information
1408 * @idx: attribute type index for nla_next_start()
1409 *
1410 * This function adds link info attribut to response skb buffer
1411 *
1412 * Return : 0 on success and errno on failure
1413 */
1414static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1415 struct hdd_cache_sta_info *stainfo,
1416 int idx)
1417{
1418 struct nlattr *nla_attr;
1419
1420 nla_attr = nla_nest_start(skb, idx);
1421 if (!nla_attr)
1422 goto fail;
1423 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1424 goto fail;
1425 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1426 goto fail;
1427
1428 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1430 FL("put fail"));
1431 goto fail;
1432 }
1433
1434 nla_nest_end(skb, nla_attr);
1435 return 0;
1436fail:
1437 return -EINVAL;
1438}
1439
1440/**
1441 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1442 * hdd_add_ap_standard_info_sap()
1443 * @stainfo: station information
1444 *
1445 * This function calculates the data length used in
1446 * hdd_add_ap_standard_info_sap()
1447 *
1448 * Return: total data length used in hdd_add_ap_standard_info_sap()
1449 */
1450static uint32_t hdd_add_ap_standard_info_sap_get_len(
1451 struct hdd_cache_sta_info *stainfo)
1452{
1453 uint32_t len;
1454
1455 len = NLA_HDRLEN;
1456 if (stainfo->vht_present)
1457 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1458 if (stainfo->ht_present)
1459 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1460
1461 return len;
1462}
1463
1464/**
1465 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1466 * @skb: pointer to response skb buffer
1467 * @stainfo: station information
1468 * @idx: attribute type index for nla_next_start()
1469 *
1470 * This function adds HT and VHT info attributes to response skb buffer
1471 *
1472 * Return : 0 on success and errno on failure
1473 */
1474static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1475 struct hdd_cache_sta_info *stainfo,
1476 int idx)
1477{
1478 struct nlattr *nla_attr;
1479
1480 nla_attr = nla_nest_start(skb, idx);
1481 if (!nla_attr)
1482 goto fail;
1483
1484 if (stainfo->vht_present) {
1485 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1486 sizeof(stainfo->vht_caps),
1487 &stainfo->vht_caps)) {
1488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1489 FL("put fail"));
1490 goto fail;
1491 }
1492 }
1493 if (stainfo->ht_present) {
1494 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1495 sizeof(stainfo->ht_caps),
1496 &stainfo->ht_caps)) {
1497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1498 FL("put fail"));
1499 goto fail;
1500 }
1501 }
1502 nla_nest_end(skb, nla_attr);
1503 return 0;
1504fail:
1505 return -EINVAL;
1506}
1507
1508/**
1509 * hdd_decode_ch_width - decode channel band width based
1510 * @ch_width: encoded enum value holding channel band width
1511 *
1512 * This function decodes channel band width from the given encoded enum value.
1513 *
1514 * Returns: decoded channel band width.
1515 */
1516static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1517{
1518 switch (ch_width) {
1519 case 0:
1520 return 20;
1521 case 1:
1522 return 40;
1523 case 2:
1524 return 80;
1525 default:
1526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1527 "invalid enum: %d", ch_width);
1528 return 20;
1529 }
1530}
1531
1532/**
1533 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1534 * @hdd_ctx: hdd context
1535 * @adapter: hostapd interface
1536 * @mac_addr: mac address of requested peer
1537 *
1538 * This function collect and indicate the cached(deleted) peer's info
1539 *
1540 * Return: 0 on success, otherwise error value
1541 */
1542static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1543 hdd_adapter_t *adapter,
1544 v_MACADDR_t mac_addr)
1545{
1546 struct hdd_cache_sta_info *stainfo;
1547 struct sk_buff *skb = NULL;
1548 uint32_t nl_buf_len;
1549 uint8_t cw;
1550 ptSapContext sap_ctx;
1551 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1552
1553 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1554 if(sap_ctx == NULL){
1555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1556 FL("psapCtx is NULL"));
1557 return -ENOENT;
1558 }
1559
1560 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1561 mac_addr.bytes);
1562 if (!stainfo) {
1563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1564 "peer " MAC_ADDRESS_STR " not found",
1565 MAC_ADDR_ARRAY(mac_addr.bytes));
1566 return -EINVAL;
1567 }
1568 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1570 "peer " MAC_ADDRESS_STR " is in connected state",
1571 MAC_ADDR_ARRAY(mac_addr.bytes));
1572 return -EINVAL;
1573 }
1574
1575
1576 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1577 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1578 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1579 (sizeof(cw) + NLA_HDRLEN) +
1580 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1581
1582 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1583 if (!skb) {
1584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1585 return -ENOMEM;
1586 }
1587
1588 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1589 LINK_INFO_STANDARD_NL80211_ATTR)) {
1590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1591 goto fail;
1592 }
1593
1594 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1595 AP_INFO_STANDARD_NL80211_ATTR)) {
1596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1597 goto fail;
1598 }
1599
1600 /* upper layer expects decoded channel BW */
1601 cw = hdd_decode_ch_width(stainfo->ch_width);
1602 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1603 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1604 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1605 goto fail;
1606 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301607 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1609 goto fail;
1610 }
1611
1612 vos_mem_zero(stainfo, sizeof(*stainfo));
1613
1614 return cfg80211_vendor_cmd_reply(skb);
1615fail:
1616 if (skb)
1617 kfree_skb(skb);
1618
1619 return -EINVAL;
1620}
1621
1622/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301623 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1624 * @wiphy: corestack handler
1625 * @wdev: wireless device
1626 * @data: data
1627 * @data_len: data length
1628 *
1629 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1630 * Validate cmd attributes and send the station info to upper layers.
1631 *
1632 * Return: Success(0) or reason code for failure
1633 */
1634static int32_t
1635__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1636 struct wireless_dev *wdev,
1637 const void *data,
1638 int data_len)
1639{
1640 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1641 struct net_device *dev = wdev->netdev;
1642 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1643 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1644 int32_t status;
1645
1646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1647 if (VOS_FTM_MODE == hdd_get_conparam()) {
1648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1649 status = -EPERM;
1650 goto out;
1651 }
1652
1653 status = wlan_hdd_validate_context(hdd_ctx);
1654 if (0 != status)
1655 goto out;
1656
1657
1658 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1659 data, data_len, NULL);
1660 if (status) {
1661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1662 goto out;
1663 }
1664
1665 /* Parse and fetch Command Type*/
1666 if (tb[STATION_INFO]) {
1667 status = hdd_get_station_info(hdd_ctx, adapter);
1668 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1669 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301670 } else if (tb[STATION_REMOTE]) {
1671 v_MACADDR_t mac_addr;
1672
1673 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1674 adapter->device_mode != WLAN_HDD_P2P_GO) {
1675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1676 adapter->device_mode);
1677 status = -EINVAL;
1678 goto out;
1679 }
1680
1681 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1682 VOS_MAC_ADDRESS_LEN);
1683
1684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1685 MAC_ADDR_ARRAY(mac_addr.bytes));
1686
1687 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1688 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301689 } else {
1690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1691 status = -EINVAL;
1692 goto out;
1693 }
1694 EXIT();
1695out:
1696 return status;
1697}
1698
1699/**
1700 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1701 * @wiphy: corestack handler
1702 * @wdev: wireless device
1703 * @data: data
1704 * @data_len: data length
1705 *
1706 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1707 * Validate cmd attributes and send the station info to upper layers.
1708 *
1709 * Return: Success(0) or reason code for failure
1710 */
1711static int32_t
1712hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1713 struct wireless_dev *wdev,
1714 const void *data,
1715 int data_len)
1716{
1717 int ret;
1718
1719 vos_ssr_protect(__func__);
1720 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1721 vos_ssr_unprotect(__func__);
1722
1723 return ret;
1724}
1725
1726/*
1727 * undef short names defined for get station command
1728 * used by __wlan_hdd_cfg80211_get_station_cmd()
1729 */
1730#undef STATION_INVALID
1731#undef STATION_INFO
1732#undef STATION_ASSOC_FAIL_REASON
1733#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301734
Sunil Duttc69bccb2014-05-26 21:30:20 +05301735#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1736
1737static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1738 struct sk_buff *vendor_event)
1739{
1740 if (nla_put_u8(vendor_event,
1741 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1742 stats->rate.preamble) ||
1743 nla_put_u8(vendor_event,
1744 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1745 stats->rate.nss) ||
1746 nla_put_u8(vendor_event,
1747 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1748 stats->rate.bw) ||
1749 nla_put_u8(vendor_event,
1750 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1751 stats->rate.rateMcsIdx) ||
1752 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1753 stats->rate.bitrate ) ||
1754 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1755 stats->txMpdu ) ||
1756 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1757 stats->rxMpdu ) ||
1758 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1759 stats->mpduLost ) ||
1760 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1761 stats->retries) ||
1762 nla_put_u32(vendor_event,
1763 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1764 stats->retriesShort ) ||
1765 nla_put_u32(vendor_event,
1766 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1767 stats->retriesLong))
1768 {
1769 hddLog(VOS_TRACE_LEVEL_ERROR,
1770 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1771 return FALSE;
1772 }
1773 return TRUE;
1774}
1775
1776static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1777 struct sk_buff *vendor_event)
1778{
1779 u32 i = 0;
1780 struct nlattr *rateInfo;
1781 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1782 stats->type) ||
1783 nla_put(vendor_event,
1784 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1785 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1786 nla_put_u32(vendor_event,
1787 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1788 stats->capabilities) ||
1789 nla_put_u32(vendor_event,
1790 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1791 stats->numRate))
1792 {
1793 hddLog(VOS_TRACE_LEVEL_ERROR,
1794 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1795 goto error;
1796 }
1797
1798 rateInfo = nla_nest_start(vendor_event,
1799 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301800 if(!rateInfo)
1801 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301802 for (i = 0; i < stats->numRate; i++)
1803 {
1804 struct nlattr *rates;
1805 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1806 stats->rateStats +
1807 (i * sizeof(tSirWifiRateStat)));
1808 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301809 if(!rates)
1810 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301811
1812 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1813 {
1814 hddLog(VOS_TRACE_LEVEL_ERROR,
1815 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1816 return FALSE;
1817 }
1818 nla_nest_end(vendor_event, rates);
1819 }
1820 nla_nest_end(vendor_event, rateInfo);
1821
1822 return TRUE;
1823error:
1824 return FALSE;
1825}
1826
1827static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1828 struct sk_buff *vendor_event)
1829{
1830 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1831 stats->ac ) ||
1832 nla_put_u32(vendor_event,
1833 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1834 stats->txMpdu ) ||
1835 nla_put_u32(vendor_event,
1836 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1837 stats->rxMpdu ) ||
1838 nla_put_u32(vendor_event,
1839 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1840 stats->txMcast ) ||
1841 nla_put_u32(vendor_event,
1842 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1843 stats->rxMcast ) ||
1844 nla_put_u32(vendor_event,
1845 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1846 stats->rxAmpdu ) ||
1847 nla_put_u32(vendor_event,
1848 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1849 stats->txAmpdu ) ||
1850 nla_put_u32(vendor_event,
1851 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1852 stats->mpduLost )||
1853 nla_put_u32(vendor_event,
1854 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1855 stats->retries ) ||
1856 nla_put_u32(vendor_event,
1857 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1858 stats->retriesShort ) ||
1859 nla_put_u32(vendor_event,
1860 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1861 stats->retriesLong ) ||
1862 nla_put_u32(vendor_event,
1863 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1864 stats->contentionTimeMin ) ||
1865 nla_put_u32(vendor_event,
1866 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1867 stats->contentionTimeMax ) ||
1868 nla_put_u32(vendor_event,
1869 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1870 stats->contentionTimeAvg ) ||
1871 nla_put_u32(vendor_event,
1872 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1873 stats->contentionNumSamples ))
1874 {
1875 hddLog(VOS_TRACE_LEVEL_ERROR,
1876 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1877 return FALSE;
1878 }
1879 return TRUE;
1880}
1881
1882static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1883 struct sk_buff *vendor_event)
1884{
Dino Myclec8f3f332014-07-21 16:48:27 +05301885 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301886 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1887 nla_put(vendor_event,
1888 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1889 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1890 nla_put_u32(vendor_event,
1891 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1892 stats->state ) ||
1893 nla_put_u32(vendor_event,
1894 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1895 stats->roaming ) ||
1896 nla_put_u32(vendor_event,
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1898 stats->capabilities ) ||
1899 nla_put(vendor_event,
1900 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
1901 strlen(stats->ssid), stats->ssid) ||
1902 nla_put(vendor_event,
1903 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
1904 WNI_CFG_BSSID_LEN, stats->bssid) ||
1905 nla_put(vendor_event,
1906 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
1907 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
1908 nla_put(vendor_event,
1909 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
1910 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
1911 )
1912 {
1913 hddLog(VOS_TRACE_LEVEL_ERROR,
1914 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1915 return FALSE;
1916 }
1917 return TRUE;
1918}
1919
Dino Mycle3b9536d2014-07-09 22:05:24 +05301920static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
1921 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922 struct sk_buff *vendor_event)
1923{
1924 int i = 0;
1925 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301926 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1927 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301928 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301929
Sunil Duttc69bccb2014-05-26 21:30:20 +05301930 if (FALSE == put_wifi_interface_info(
1931 &pWifiIfaceStat->info,
1932 vendor_event))
1933 {
1934 hddLog(VOS_TRACE_LEVEL_ERROR,
1935 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1936 return FALSE;
1937
1938 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05301939 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1940 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1941 if (NULL == pWifiIfaceStatTL)
1942 {
1943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1944 return FALSE;
1945 }
1946
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301947 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1948 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1949 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1950 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1951
1952 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1953 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1954 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1955 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301956
1957 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1958 {
1959 if (VOS_STATUS_SUCCESS ==
1960 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1961 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1962 {
1963 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1964 * obtained from TL structure
1965 */
1966
1967 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1968 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301969 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1970
Srinivas Dasari98947432014-11-07 19:41:24 +05301971 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1972 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1973 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1974 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1975 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1976 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1977 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1978 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301979
Srinivas Dasari98947432014-11-07 19:41:24 +05301980 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1981 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1982 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1983 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1984 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1985 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1986 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1987 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301988
Srinivas Dasari98947432014-11-07 19:41:24 +05301989 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1990 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1991 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1992 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1993 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1994 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1995 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1996 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301997 }
1998 else
1999 {
2000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2001 }
2002
Dino Mycle3b9536d2014-07-09 22:05:24 +05302003 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2004 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2005 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2006 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2007 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2008 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2009 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2010 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2011 }
2012 else
2013 {
2014 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2015 }
2016
2017
Sunil Duttc69bccb2014-05-26 21:30:20 +05302018
2019 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302020 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2021 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2022 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302023 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2024 pWifiIfaceStat->beaconRx) ||
2025 nla_put_u32(vendor_event,
2026 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2027 pWifiIfaceStat->mgmtRx) ||
2028 nla_put_u32(vendor_event,
2029 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2030 pWifiIfaceStat->mgmtActionRx) ||
2031 nla_put_u32(vendor_event,
2032 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2033 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302034 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302035 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2036 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302037 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302038 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2039 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302040 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302041 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2042 pWifiIfaceStat->rssiAck))
2043 {
2044 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302045 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2046 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047 return FALSE;
2048 }
2049
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302050#ifdef FEATURE_EXT_LL_STAT
2051 /*
2052 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2053 * then host should send Leaky AP stats to upper layer,
2054 * otherwise no need to send these stats.
2055 */
2056 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2057 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2058 )
2059 {
2060 hddLog(VOS_TRACE_LEVEL_INFO,
2061 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2062 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2063 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2064 pWifiIfaceStat->leakyApStat.rx_leak_window,
2065 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2066 if (nla_put_u32(vendor_event,
2067 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2068 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2069 nla_put_u32(vendor_event,
2070 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2071 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2072 nla_put_u32(vendor_event,
2073 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2074 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
2075 nla_put_u64(vendor_event,
2076 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2077 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2078 {
2079 hddLog(VOS_TRACE_LEVEL_ERROR,
2080 FL("EXT_LL_STAT put fail"));
2081 vos_mem_free(pWifiIfaceStatTL);
2082 return FALSE;
2083 }
2084 }
2085#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302086 wmmInfo = nla_nest_start(vendor_event,
2087 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302088 if(!wmmInfo)
2089 {
2090 vos_mem_free(pWifiIfaceStatTL);
2091 return FALSE;
2092 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302093 for (i = 0; i < WIFI_AC_MAX; i++)
2094 {
2095 struct nlattr *wmmStats;
2096 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302097 if(!wmmStats)
2098 {
2099 vos_mem_free(pWifiIfaceStatTL);
2100 return FALSE;
2101 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302102 if (FALSE == put_wifi_wmm_ac_stat(
2103 &pWifiIfaceStat->AccessclassStats[i],
2104 vendor_event))
2105 {
2106 hddLog(VOS_TRACE_LEVEL_ERROR,
2107 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302108 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302109 return FALSE;
2110 }
2111
2112 nla_nest_end(vendor_event, wmmStats);
2113 }
2114 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302115 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302116 return TRUE;
2117}
2118
2119static tSirWifiInterfaceMode
2120 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2121{
2122 switch (deviceMode)
2123 {
2124 case WLAN_HDD_INFRA_STATION:
2125 return WIFI_INTERFACE_STA;
2126 case WLAN_HDD_SOFTAP:
2127 return WIFI_INTERFACE_SOFTAP;
2128 case WLAN_HDD_P2P_CLIENT:
2129 return WIFI_INTERFACE_P2P_CLIENT;
2130 case WLAN_HDD_P2P_GO:
2131 return WIFI_INTERFACE_P2P_GO;
2132 case WLAN_HDD_IBSS:
2133 return WIFI_INTERFACE_IBSS;
2134 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302135 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302136 }
2137}
2138
2139static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2140 tpSirWifiInterfaceInfo pInfo)
2141{
2142 v_U8_t *staMac = NULL;
2143 hdd_station_ctx_t *pHddStaCtx;
2144 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2145 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2146
2147 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2148
2149 vos_mem_copy(pInfo->macAddr,
2150 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2151
2152 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2153 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2154 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2155 {
2156 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2157 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2158 {
2159 pInfo->state = WIFI_DISCONNECTED;
2160 }
2161 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2162 {
2163 hddLog(VOS_TRACE_LEVEL_ERROR,
2164 "%s: Session ID %d, Connection is in progress", __func__,
2165 pAdapter->sessionId);
2166 pInfo->state = WIFI_ASSOCIATING;
2167 }
2168 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2169 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2170 {
2171 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2172 hddLog(VOS_TRACE_LEVEL_ERROR,
2173 "%s: client " MAC_ADDRESS_STR
2174 " is in the middle of WPS/EAPOL exchange.", __func__,
2175 MAC_ADDR_ARRAY(staMac));
2176 pInfo->state = WIFI_AUTHENTICATING;
2177 }
2178 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2179 {
2180 pInfo->state = WIFI_ASSOCIATED;
2181 vos_mem_copy(pInfo->bssid,
2182 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2183 vos_mem_copy(pInfo->ssid,
2184 pHddStaCtx->conn_info.SSID.SSID.ssId,
2185 pHddStaCtx->conn_info.SSID.SSID.length);
2186 //NULL Terminate the string.
2187 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2188 }
2189 }
2190 vos_mem_copy(pInfo->countryStr,
2191 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2192
2193 vos_mem_copy(pInfo->apCountryStr,
2194 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2195
2196 return TRUE;
2197}
2198
2199/*
2200 * hdd_link_layer_process_peer_stats () - This function is called after
2201 * receiving Link Layer Peer statistics from FW.This function converts
2202 * the firmware data to the NL data and sends the same to the kernel/upper
2203 * layers.
2204 */
2205static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2206 v_VOID_t *pData)
2207{
2208 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302209 tpSirWifiPeerStat pWifiPeerStat;
2210 tpSirWifiPeerInfo pWifiPeerInfo;
2211 struct nlattr *peerInfo;
2212 struct sk_buff *vendor_event;
2213 int status, i;
2214
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302215 ENTER();
2216
Sunil Duttc69bccb2014-05-26 21:30:20 +05302217 status = wlan_hdd_validate_context(pHddCtx);
2218 if (0 != status)
2219 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302220 return;
2221 }
2222
2223 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2224
2225 hddLog(VOS_TRACE_LEVEL_INFO,
2226 "LL_STATS_PEER_ALL : numPeers %u",
2227 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302228 /*
2229 * Allocate a size of 4096 for the peer stats comprising
2230 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2231 * sizeof (tSirWifiRateStat).Each field is put with an
2232 * NL attribute.The size of 4096 is considered assuming
2233 * that number of rates shall not exceed beyond 50 with
2234 * the sizeof (tSirWifiRateStat) being 32.
2235 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302236 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2237 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302238 if (!vendor_event)
2239 {
2240 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302241 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302242 __func__);
2243 return;
2244 }
2245 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302246 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2247 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2248 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302249 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2250 pWifiPeerStat->numPeers))
2251 {
2252 hddLog(VOS_TRACE_LEVEL_ERROR,
2253 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2254 kfree_skb(vendor_event);
2255 return;
2256 }
2257
2258 peerInfo = nla_nest_start(vendor_event,
2259 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302260 if(!peerInfo)
2261 {
2262 hddLog(VOS_TRACE_LEVEL_ERROR,
2263 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2264 __func__);
2265 kfree_skb(vendor_event);
2266 return;
2267 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302268
2269 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2270 pWifiPeerStat->peerInfo);
2271
2272 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2273 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302274 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302275 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302276
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302277 if(!peers)
2278 {
2279 hddLog(VOS_TRACE_LEVEL_ERROR,
2280 "%s: peer stats put fail",
2281 __func__);
2282 kfree_skb(vendor_event);
2283 return;
2284 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302285 if (FALSE == put_wifi_peer_info(
2286 pWifiPeerInfo, vendor_event))
2287 {
2288 hddLog(VOS_TRACE_LEVEL_ERROR,
2289 "%s: put_wifi_peer_info put fail", __func__);
2290 kfree_skb(vendor_event);
2291 return;
2292 }
2293
2294 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2295 pWifiPeerStat->peerInfo +
2296 (i * sizeof(tSirWifiPeerInfo)) +
2297 (numRate * sizeof (tSirWifiRateStat)));
2298 nla_nest_end(vendor_event, peers);
2299 }
2300 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302301 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302302 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302303}
2304
2305/*
2306 * hdd_link_layer_process_iface_stats () - This function is called after
2307 * receiving Link Layer Interface statistics from FW.This function converts
2308 * the firmware data to the NL data and sends the same to the kernel/upper
2309 * layers.
2310 */
2311static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2312 v_VOID_t *pData)
2313{
2314 tpSirWifiIfaceStat pWifiIfaceStat;
2315 struct sk_buff *vendor_event;
2316 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2317 int status;
2318
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302319 ENTER();
2320
Sunil Duttc69bccb2014-05-26 21:30:20 +05302321 status = wlan_hdd_validate_context(pHddCtx);
2322 if (0 != status)
2323 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302324 return;
2325 }
2326 /*
2327 * Allocate a size of 4096 for the interface stats comprising
2328 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2329 * assuming that all these fit with in the limit.Please take
2330 * a call on the limit based on the data requirements on
2331 * interface statistics.
2332 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302333 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2334 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302335 if (!vendor_event)
2336 {
2337 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302338 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302339 return;
2340 }
2341
2342 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2343
Dino Mycle3b9536d2014-07-09 22:05:24 +05302344
2345 if (FALSE == hdd_get_interface_info( pAdapter,
2346 &pWifiIfaceStat->info))
2347 {
2348 hddLog(VOS_TRACE_LEVEL_ERROR,
2349 FL("hdd_get_interface_info get fail") );
2350 kfree_skb(vendor_event);
2351 return;
2352 }
2353
2354 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2355 vendor_event))
2356 {
2357 hddLog(VOS_TRACE_LEVEL_ERROR,
2358 FL("put_wifi_iface_stats fail") );
2359 kfree_skb(vendor_event);
2360 return;
2361 }
2362
Sunil Duttc69bccb2014-05-26 21:30:20 +05302363 hddLog(VOS_TRACE_LEVEL_INFO,
2364 "WMI_LINK_STATS_IFACE Data");
2365
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302366 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302367
2368 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302369}
2370
2371/*
2372 * hdd_link_layer_process_radio_stats () - This function is called after
2373 * receiving Link Layer Radio statistics from FW.This function converts
2374 * the firmware data to the NL data and sends the same to the kernel/upper
2375 * layers.
2376 */
2377static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2378 v_VOID_t *pData)
2379{
2380 int status, i;
2381 tpSirWifiRadioStat pWifiRadioStat;
2382 tpSirWifiChannelStats pWifiChannelStats;
2383 struct sk_buff *vendor_event;
2384 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2385 struct nlattr *chList;
2386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302387 ENTER();
2388
Sunil Duttc69bccb2014-05-26 21:30:20 +05302389 status = wlan_hdd_validate_context(pHddCtx);
2390 if (0 != status)
2391 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302392 return;
2393 }
2394 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2395
2396 hddLog(VOS_TRACE_LEVEL_INFO,
2397 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302398 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302399 " radio is %d onTime is %u "
2400 " txTime is %u rxTime is %u "
2401 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302402 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302403 " onTimePnoScan is %u onTimeHs20 is %u "
2404 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302405 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302406 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2407 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2408 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302409 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302410 pWifiRadioStat->onTimeRoamScan,
2411 pWifiRadioStat->onTimePnoScan,
2412 pWifiRadioStat->onTimeHs20,
2413 pWifiRadioStat->numChannels);
2414 /*
2415 * Allocate a size of 4096 for the Radio stats comprising
2416 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2417 * (tSirWifiChannelStats).Each channel data is put with an
2418 * NL attribute.The size of 4096 is considered assuming that
2419 * number of channels shall not exceed beyond 60 with the
2420 * sizeof (tSirWifiChannelStats) being 24 bytes.
2421 */
2422
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302423 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2424 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302425 if (!vendor_event)
2426 {
2427 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302428 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302429 return;
2430 }
2431
2432 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302433 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2434 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2435 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302436 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2437 pWifiRadioStat->radio) ||
2438 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302439 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2440 NUM_RADIOS) ||
2441 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302442 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2443 pWifiRadioStat->onTime) ||
2444 nla_put_u32(vendor_event,
2445 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2446 pWifiRadioStat->txTime) ||
2447 nla_put_u32(vendor_event,
2448 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2449 pWifiRadioStat->rxTime) ||
2450 nla_put_u32(vendor_event,
2451 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2452 pWifiRadioStat->onTimeScan) ||
2453 nla_put_u32(vendor_event,
2454 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2455 pWifiRadioStat->onTimeNbd) ||
2456 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302457 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2458 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302459 nla_put_u32(vendor_event,
2460 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2461 pWifiRadioStat->onTimeRoamScan) ||
2462 nla_put_u32(vendor_event,
2463 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2464 pWifiRadioStat->onTimePnoScan) ||
2465 nla_put_u32(vendor_event,
2466 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2467 pWifiRadioStat->onTimeHs20) ||
2468 nla_put_u32(vendor_event,
2469 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2470 pWifiRadioStat->numChannels))
2471 {
2472 hddLog(VOS_TRACE_LEVEL_ERROR,
2473 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2474 kfree_skb(vendor_event);
2475 return ;
2476 }
2477
2478 chList = nla_nest_start(vendor_event,
2479 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302480 if(!chList)
2481 {
2482 hddLog(VOS_TRACE_LEVEL_ERROR,
2483 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2484 __func__);
2485 kfree_skb(vendor_event);
2486 return;
2487 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302488 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2489 {
2490 struct nlattr *chInfo;
2491
2492 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2493 pWifiRadioStat->channels +
2494 (i * sizeof(tSirWifiChannelStats)));
2495
Sunil Duttc69bccb2014-05-26 21:30:20 +05302496 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302497 if(!chInfo)
2498 {
2499 hddLog(VOS_TRACE_LEVEL_ERROR,
2500 "%s: failed to put chInfo",
2501 __func__);
2502 kfree_skb(vendor_event);
2503 return;
2504 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302505
2506 if (nla_put_u32(vendor_event,
2507 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2508 pWifiChannelStats->channel.width) ||
2509 nla_put_u32(vendor_event,
2510 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2511 pWifiChannelStats->channel.centerFreq) ||
2512 nla_put_u32(vendor_event,
2513 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2514 pWifiChannelStats->channel.centerFreq0) ||
2515 nla_put_u32(vendor_event,
2516 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2517 pWifiChannelStats->channel.centerFreq1) ||
2518 nla_put_u32(vendor_event,
2519 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2520 pWifiChannelStats->onTime) ||
2521 nla_put_u32(vendor_event,
2522 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2523 pWifiChannelStats->ccaBusyTime))
2524 {
2525 hddLog(VOS_TRACE_LEVEL_ERROR,
2526 FL("cfg80211_vendor_event_alloc failed") );
2527 kfree_skb(vendor_event);
2528 return ;
2529 }
2530 nla_nest_end(vendor_event, chInfo);
2531 }
2532 nla_nest_end(vendor_event, chList);
2533
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302534 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302535
2536 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302537 return;
2538}
2539
2540/*
2541 * hdd_link_layer_stats_ind_callback () - This function is called after
2542 * receiving Link Layer indications from FW.This callback converts the firmware
2543 * data to the NL data and send the same to the kernel/upper layers.
2544 */
2545static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2546 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302547 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302548{
Dino Mycled3d50022014-07-07 12:58:25 +05302549 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2550 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302551 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302552 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302553 int status;
2554
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302555 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302556
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302557 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302558 if (0 != status)
2559 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302560 return;
2561 }
2562
Dino Mycled3d50022014-07-07 12:58:25 +05302563 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2564 if (NULL == pAdapter)
2565 {
2566 hddLog(VOS_TRACE_LEVEL_ERROR,
2567 FL(" MAC address %pM does not exist with host"),
2568 macAddr);
2569 return;
2570 }
2571
Sunil Duttc69bccb2014-05-26 21:30:20 +05302572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302573 "%s: Interface: %s LLStats indType: %d", __func__,
2574 pAdapter->dev->name, indType);
2575
Sunil Duttc69bccb2014-05-26 21:30:20 +05302576 switch (indType)
2577 {
2578 case SIR_HAL_LL_STATS_RESULTS_RSP:
2579 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302580 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302581 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2582 "respId = %u, moreResultToFollow = %u",
2583 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2584 macAddr, linkLayerStatsResults->respId,
2585 linkLayerStatsResults->moreResultToFollow);
2586
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302587 spin_lock(&hdd_context_lock);
2588 context = &pHddCtx->ll_stats_context;
2589 /* validate response received from target */
2590 if ((context->request_id != linkLayerStatsResults->respId) ||
2591 !(context->request_bitmap & linkLayerStatsResults->paramId))
2592 {
2593 spin_unlock(&hdd_context_lock);
2594 hddLog(LOGE,
2595 FL("Error : Request id %d response id %d request bitmap 0x%x"
2596 "response bitmap 0x%x"),
2597 context->request_id, linkLayerStatsResults->respId,
2598 context->request_bitmap, linkLayerStatsResults->paramId);
2599 return;
2600 }
2601 spin_unlock(&hdd_context_lock);
2602
Sunil Duttc69bccb2014-05-26 21:30:20 +05302603 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2604 {
2605 hdd_link_layer_process_radio_stats(pAdapter,
2606 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302607 spin_lock(&hdd_context_lock);
2608 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2609 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302610 }
2611 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2612 {
2613 hdd_link_layer_process_iface_stats(pAdapter,
2614 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302615 spin_lock(&hdd_context_lock);
2616 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2617 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302618 }
2619 else if ( linkLayerStatsResults->paramId &
2620 WMI_LINK_STATS_ALL_PEER )
2621 {
2622 hdd_link_layer_process_peer_stats(pAdapter,
2623 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302624 spin_lock(&hdd_context_lock);
2625 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2626 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302627 } /* WMI_LINK_STATS_ALL_PEER */
2628 else
2629 {
2630 hddLog(VOS_TRACE_LEVEL_ERROR,
2631 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2632 }
2633
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302634 spin_lock(&hdd_context_lock);
2635 /* complete response event if all requests are completed */
2636 if (0 == context->request_bitmap)
2637 complete(&context->response_event);
2638 spin_unlock(&hdd_context_lock);
2639
Sunil Duttc69bccb2014-05-26 21:30:20 +05302640 break;
2641 }
2642 default:
2643 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2644 break;
2645 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302646
2647 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302648 return;
2649}
2650
2651const struct
2652nla_policy
2653qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2654{
2655 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2656 { .type = NLA_U32 },
2657 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2658 { .type = NLA_U32 },
2659};
2660
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302661static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2662 struct wireless_dev *wdev,
2663 const void *data,
2664 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302665{
2666 int status;
2667 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302668 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302669 struct net_device *dev = wdev->netdev;
2670 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2671 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2672
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302673 ENTER();
2674
Sunil Duttc69bccb2014-05-26 21:30:20 +05302675 status = wlan_hdd_validate_context(pHddCtx);
2676 if (0 != status)
2677 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302678 return -EINVAL;
2679 }
2680
2681 if (NULL == pAdapter)
2682 {
2683 hddLog(VOS_TRACE_LEVEL_ERROR,
2684 FL("HDD adapter is Null"));
2685 return -ENODEV;
2686 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302687 /* check the LLStats Capability */
2688 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2689 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2690 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302691 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302692 FL("Link Layer Statistics not supported by Firmware"));
2693 return -EINVAL;
2694 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302695
2696 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2697 (struct nlattr *)data,
2698 data_len, qca_wlan_vendor_ll_set_policy))
2699 {
2700 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2701 return -EINVAL;
2702 }
2703 if (!tb_vendor
2704 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2705 {
2706 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2707 return -EINVAL;
2708 }
2709 if (!tb_vendor[
2710 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2711 {
2712 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2713 return -EINVAL;
2714 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302715 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302716 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302717
Dino Mycledf0a5d92014-07-04 09:41:55 +05302718 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302719 nla_get_u32(
2720 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2721
Dino Mycledf0a5d92014-07-04 09:41:55 +05302722 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302723 nla_get_u32(
2724 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2725
Dino Mycled3d50022014-07-07 12:58:25 +05302726 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2727 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302728
2729
2730 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302731 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2732 "Statistics Gathering = %d ",
2733 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2734 linkLayerStatsSetReq.mpduSizeThreshold,
2735 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302736
2737 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2738 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302739 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302740 {
2741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2742 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302743 return -EINVAL;
2744
2745 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302746
Sunil Duttc69bccb2014-05-26 21:30:20 +05302747 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302748 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302749 {
2750 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2751 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302752 return -EINVAL;
2753 }
2754
2755 pAdapter->isLinkLayerStatsSet = 1;
2756
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302757 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302758 return 0;
2759}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302760static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2761 struct wireless_dev *wdev,
2762 const void *data,
2763 int data_len)
2764{
2765 int ret = 0;
2766
2767 vos_ssr_protect(__func__);
2768 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2769 vos_ssr_unprotect(__func__);
2770
2771 return ret;
2772}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302773
2774const struct
2775nla_policy
2776qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2777{
2778 /* Unsigned 32bit value provided by the caller issuing the GET stats
2779 * command. When reporting
2780 * the stats results, the driver uses the same value to indicate
2781 * which GET request the results
2782 * correspond to.
2783 */
2784 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2785
2786 /* Unsigned 32bit value . bit mask to identify what statistics are
2787 requested for retrieval */
2788 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2789};
2790
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302791static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2792 struct wireless_dev *wdev,
2793 const void *data,
2794 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302795{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302796 unsigned long rc;
2797 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302798 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2799 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302800 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302801 struct net_device *dev = wdev->netdev;
2802 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302803 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302804 int status;
2805
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302806 ENTER();
2807
Sunil Duttc69bccb2014-05-26 21:30:20 +05302808 status = wlan_hdd_validate_context(pHddCtx);
2809 if (0 != status)
2810 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302811 return -EINVAL ;
2812 }
2813
2814 if (NULL == pAdapter)
2815 {
2816 hddLog(VOS_TRACE_LEVEL_FATAL,
2817 "%s: HDD adapter is Null", __func__);
2818 return -ENODEV;
2819 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302820
2821 if (pHddStaCtx == NULL)
2822 {
2823 hddLog(VOS_TRACE_LEVEL_FATAL,
2824 "%s: HddStaCtx is Null", __func__);
2825 return -ENODEV;
2826 }
2827
Dino Mycledf0a5d92014-07-04 09:41:55 +05302828 /* check the LLStats Capability */
2829 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2830 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2831 {
2832 hddLog(VOS_TRACE_LEVEL_ERROR,
2833 FL("Link Layer Statistics not supported by Firmware"));
2834 return -EINVAL;
2835 }
2836
Sunil Duttc69bccb2014-05-26 21:30:20 +05302837
2838 if (!pAdapter->isLinkLayerStatsSet)
2839 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302840 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302841 "%s: isLinkLayerStatsSet : %d",
2842 __func__, pAdapter->isLinkLayerStatsSet);
2843 return -EINVAL;
2844 }
2845
Mukul Sharma10313ba2015-07-29 19:14:39 +05302846 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2847 {
2848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2849 "%s: Roaming in progress, so unable to proceed this request", __func__);
2850 return -EBUSY;
2851 }
2852
Sunil Duttc69bccb2014-05-26 21:30:20 +05302853 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2854 (struct nlattr *)data,
2855 data_len, qca_wlan_vendor_ll_get_policy))
2856 {
2857 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2858 return -EINVAL;
2859 }
2860
2861 if (!tb_vendor
2862 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2863 {
2864 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2865 return -EINVAL;
2866 }
2867
2868 if (!tb_vendor
2869 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2870 {
2871 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2872 return -EINVAL;
2873 }
2874
Sunil Duttc69bccb2014-05-26 21:30:20 +05302875
Dino Mycledf0a5d92014-07-04 09:41:55 +05302876 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302877 nla_get_u32( tb_vendor[
2878 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302879 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302880 nla_get_u32( tb_vendor[
2881 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2882
Dino Mycled3d50022014-07-07 12:58:25 +05302883 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2884 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302885
2886 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302887 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2888 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302889 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302890
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302891 spin_lock(&hdd_context_lock);
2892 context = &pHddCtx->ll_stats_context;
2893 context->request_id = linkLayerStatsGetReq.reqId;
2894 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2895 INIT_COMPLETION(context->response_event);
2896 spin_unlock(&hdd_context_lock);
2897
Sunil Duttc69bccb2014-05-26 21:30:20 +05302898 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302899 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302900 {
2901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2902 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302903 return -EINVAL;
2904 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302905
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302906 rc = wait_for_completion_timeout(&context->response_event,
2907 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2908 if (!rc)
2909 {
2910 hddLog(LOGE,
2911 FL("Target response timed out request id %d request bitmap 0x%x"),
2912 context->request_id, context->request_bitmap);
2913 return -ETIMEDOUT;
2914 }
2915
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302916 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302917 return 0;
2918}
2919
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302920static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2921 struct wireless_dev *wdev,
2922 const void *data,
2923 int data_len)
2924{
2925 int ret = 0;
2926
2927 vos_ssr_protect(__func__);
2928 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2929 vos_ssr_unprotect(__func__);
2930
2931 return ret;
2932}
2933
Sunil Duttc69bccb2014-05-26 21:30:20 +05302934const struct
2935nla_policy
2936qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2937{
2938 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2939 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2940 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2941 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2942};
2943
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302944static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2945 struct wireless_dev *wdev,
2946 const void *data,
2947 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302948{
2949 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2950 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302951 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302952 struct net_device *dev = wdev->netdev;
2953 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2954 u32 statsClearReqMask;
2955 u8 stopReq;
2956 int status;
2957
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302958 ENTER();
2959
Sunil Duttc69bccb2014-05-26 21:30:20 +05302960 status = wlan_hdd_validate_context(pHddCtx);
2961 if (0 != status)
2962 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302963 return -EINVAL;
2964 }
2965
2966 if (NULL == pAdapter)
2967 {
2968 hddLog(VOS_TRACE_LEVEL_FATAL,
2969 "%s: HDD adapter is Null", __func__);
2970 return -ENODEV;
2971 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302972 /* check the LLStats Capability */
2973 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2974 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2975 {
2976 hddLog(VOS_TRACE_LEVEL_ERROR,
2977 FL("Enable LLStats Capability"));
2978 return -EINVAL;
2979 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302980
2981 if (!pAdapter->isLinkLayerStatsSet)
2982 {
2983 hddLog(VOS_TRACE_LEVEL_FATAL,
2984 "%s: isLinkLayerStatsSet : %d",
2985 __func__, pAdapter->isLinkLayerStatsSet);
2986 return -EINVAL;
2987 }
2988
2989 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2990 (struct nlattr *)data,
2991 data_len, qca_wlan_vendor_ll_clr_policy))
2992 {
2993 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2994 return -EINVAL;
2995 }
2996
2997 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2998
2999 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3000 {
3001 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3002 return -EINVAL;
3003
3004 }
3005
Sunil Duttc69bccb2014-05-26 21:30:20 +05303006
Dino Mycledf0a5d92014-07-04 09:41:55 +05303007 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303008 nla_get_u32(
3009 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3010
Dino Mycledf0a5d92014-07-04 09:41:55 +05303011 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303012 nla_get_u8(
3013 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3014
3015 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303016 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303017
Dino Mycled3d50022014-07-07 12:58:25 +05303018 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3019 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303020
3021 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303022 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3023 "statsClearReqMask = 0x%X, stopReq = %d",
3024 linkLayerStatsClearReq.reqId,
3025 linkLayerStatsClearReq.macAddr,
3026 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303027 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303028
3029 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303030 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303031 {
3032 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303033 hdd_station_ctx_t *pHddStaCtx;
3034
3035 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3036 if (VOS_STATUS_SUCCESS !=
3037 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3038 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3039 {
3040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3041 "WLANTL_ClearInterfaceStats Failed", __func__);
3042 return -EINVAL;
3043 }
3044 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3045 (statsClearReqMask & WIFI_STATS_IFACE)) {
3046 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3047 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3048 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3049 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3050 }
3051
Sunil Duttc69bccb2014-05-26 21:30:20 +05303052 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3053 2 * sizeof(u32) +
3054 NLMSG_HDRLEN);
3055
3056 if (temp_skbuff != NULL)
3057 {
3058
3059 if (nla_put_u32(temp_skbuff,
3060 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3061 statsClearReqMask) ||
3062 nla_put_u32(temp_skbuff,
3063 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3064 stopReq))
3065 {
3066 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3067 kfree_skb(temp_skbuff);
3068 return -EINVAL;
3069 }
3070 /* If the ask is to stop the stats collection as part of clear
3071 * (stopReq = 1) , ensure that no further requests of get
3072 * go to the firmware by having isLinkLayerStatsSet set to 0.
3073 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303074 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303075 * case the firmware is just asked to clear the statistics.
3076 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303077 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303078 pAdapter->isLinkLayerStatsSet = 0;
3079 return cfg80211_vendor_cmd_reply(temp_skbuff);
3080 }
3081 return -ENOMEM;
3082 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303083
3084 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303085 return -EINVAL;
3086}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303087static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3088 struct wireless_dev *wdev,
3089 const void *data,
3090 int data_len)
3091{
3092 int ret = 0;
3093
3094 vos_ssr_protect(__func__);
3095 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3096 vos_ssr_unprotect(__func__);
3097
3098 return ret;
3099
3100
3101}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303102#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3103
Dino Mycle6fb96c12014-06-10 11:52:40 +05303104#ifdef WLAN_FEATURE_EXTSCAN
3105static const struct nla_policy
3106wlan_hdd_extscan_config_policy
3107 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3108{
3109 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3110 { .type = NLA_U32 },
3111 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3112 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303113 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3114 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303115 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3116 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3117 { .type = NLA_U32 },
3118 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3119 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3120
3121 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3122 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3123 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3124 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3125 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303126 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3127 { .type = NLA_U32 },
3128 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3129 { .type = NLA_U32 },
3130 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3131 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303132 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3133 { .type = NLA_U32 },
3134 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3135 { .type = NLA_U32 },
3136 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3137 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303138 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3139 { .type = NLA_U8 },
3140 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303141 { .type = NLA_U8 },
3142 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3143 { .type = NLA_U8 },
3144 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3145 { .type = NLA_U8 },
3146
3147 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3148 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303149 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3150 .type = NLA_UNSPEC,
3151 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3153 { .type = NLA_S32 },
3154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3155 { .type = NLA_S32 },
3156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3157 { .type = NLA_U32 },
3158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3159 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303160 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3161 { .type = NLA_U32 },
3162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3163 { .type = NLA_BINARY,
3164 .len = IEEE80211_MAX_SSID_LEN + 1 },
3165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303166 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3168 { .type = NLA_U32 },
3169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3170 { .type = NLA_U8 },
3171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3172 { .type = NLA_S32 },
3173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3174 { .type = NLA_S32 },
3175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3176 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303177};
3178
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303179/**
3180 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3181 * @ctx: hdd global context
3182 * @data: capabilities data
3183 *
3184 * Return: none
3185 */
3186static void
3187wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303188{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303189 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303190 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303191 tSirEXTScanCapabilitiesEvent *data =
3192 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303193
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303194 ENTER();
3195
3196 if (wlan_hdd_validate_context(pHddCtx))
3197 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303198 return;
3199 }
3200
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303201 if (!pMsg)
3202 {
3203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3204 return;
3205 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303206
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303207 vos_spin_lock_acquire(&hdd_context_lock);
3208
3209 context = &pHddCtx->ext_scan_context;
3210 /* validate response received from target*/
3211 if (context->request_id != data->requestId)
3212 {
3213 vos_spin_lock_release(&hdd_context_lock);
3214 hddLog(LOGE,
3215 FL("Target response id did not match: request_id %d resposne_id %d"),
3216 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303217 return;
3218 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303219 else
3220 {
3221 context->capability_response = *data;
3222 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303223 }
3224
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303225 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303226
Dino Mycle6fb96c12014-06-10 11:52:40 +05303227 return;
3228}
3229
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303230/*
3231 * define short names for the global vendor params
3232 * used by wlan_hdd_send_ext_scan_capability()
3233 */
3234#define PARAM_REQUEST_ID \
3235 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3236#define PARAM_STATUS \
3237 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3238#define MAX_SCAN_CACHE_SIZE \
3239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3240#define MAX_SCAN_BUCKETS \
3241 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3242#define MAX_AP_CACHE_PER_SCAN \
3243 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3244#define MAX_RSSI_SAMPLE_SIZE \
3245 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3246#define MAX_SCAN_RPT_THRHOLD \
3247 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3248#define MAX_HOTLIST_BSSIDS \
3249 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3250#define MAX_BSSID_HISTORY_ENTRIES \
3251 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3252#define MAX_HOTLIST_SSIDS \
3253 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303254#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3255 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303256
3257static int wlan_hdd_send_ext_scan_capability(void *ctx)
3258{
3259 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3260 struct sk_buff *skb = NULL;
3261 int ret;
3262 tSirEXTScanCapabilitiesEvent *data;
3263 tANI_U32 nl_buf_len;
3264
3265 ret = wlan_hdd_validate_context(pHddCtx);
3266 if (0 != ret)
3267 {
3268 return ret;
3269 }
3270
3271 data = &(pHddCtx->ext_scan_context.capability_response);
3272
3273 nl_buf_len = NLMSG_HDRLEN;
3274 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3275 (sizeof(data->status) + NLA_HDRLEN) +
3276 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3277 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3278 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3279 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3280 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3281 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3282 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3283 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3284
3285 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3286
3287 if (!skb)
3288 {
3289 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3290 return -ENOMEM;
3291 }
3292
3293 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3294 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3295 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3296 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3297 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3298 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3299 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3300 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3301
3302 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3303 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3304 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3305 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3306 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3307 data->maxApPerScan) ||
3308 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3309 data->maxRssiSampleSize) ||
3310 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3311 data->maxScanReportingThreshold) ||
3312 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3313 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3314 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303315 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3316 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303317 {
3318 hddLog(LOGE, FL("nla put fail"));
3319 goto nla_put_failure;
3320 }
3321
3322 cfg80211_vendor_cmd_reply(skb);
3323 return 0;
3324
3325nla_put_failure:
3326 kfree_skb(skb);
3327 return -EINVAL;;
3328}
3329
3330/*
3331 * done with short names for the global vendor params
3332 * used by wlan_hdd_send_ext_scan_capability()
3333 */
3334#undef PARAM_REQUEST_ID
3335#undef PARAM_STATUS
3336#undef MAX_SCAN_CACHE_SIZE
3337#undef MAX_SCAN_BUCKETS
3338#undef MAX_AP_CACHE_PER_SCAN
3339#undef MAX_RSSI_SAMPLE_SIZE
3340#undef MAX_SCAN_RPT_THRHOLD
3341#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303342#undef MAX_BSSID_HISTORY_ENTRIES
3343#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303344
3345static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3346{
3347 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3348 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303349 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303350 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303351
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303352 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303353
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303354 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303355 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303356
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303357 if (!pMsg)
3358 {
3359 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303360 return;
3361 }
3362
Dino Mycle6fb96c12014-06-10 11:52:40 +05303363 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3364 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3365
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303366 context = &pHddCtx->ext_scan_context;
3367 spin_lock(&hdd_context_lock);
3368 if (context->request_id == pData->requestId) {
3369 context->response_status = pData->status ? -EINVAL : 0;
3370 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303371 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303372 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303373
3374 /*
3375 * Store the Request ID for comparing with the requestID obtained
3376 * in other requests.HDD shall return a failure is the extscan_stop
3377 * request is issued with a different requestId as that of the
3378 * extscan_start request. Also, This requestId shall be used while
3379 * indicating the full scan results to the upper layers.
3380 * The requestId is stored with the assumption that the firmware
3381 * shall return the ext scan start request's requestId in ext scan
3382 * start response.
3383 */
3384 if (pData->status == 0)
3385 pMac->sme.extScanStartReqId = pData->requestId;
3386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303387 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303388 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303389}
3390
3391
3392static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3393{
3394 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3395 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303396 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303398 ENTER();
3399
3400 if (wlan_hdd_validate_context(pHddCtx)){
3401 return;
3402 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303403
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303404 if (!pMsg)
3405 {
3406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303407 return;
3408 }
3409
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303410 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3411 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303413 context = &pHddCtx->ext_scan_context;
3414 spin_lock(&hdd_context_lock);
3415 if (context->request_id == pData->requestId) {
3416 context->response_status = pData->status ? -EINVAL : 0;
3417 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303418 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303419 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303420
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303421 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303422 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303423}
3424
Dino Mycle6fb96c12014-06-10 11:52:40 +05303425static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3426 void *pMsg)
3427{
3428 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303429 tpSirEXTScanSetBssidHotListRspParams pData =
3430 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303431 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303432
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303433 ENTER();
3434
3435 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303436 return;
3437 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303438
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303439 if (!pMsg)
3440 {
3441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3442 return;
3443 }
3444
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303445 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3446 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303447
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303448 context = &pHddCtx->ext_scan_context;
3449 spin_lock(&hdd_context_lock);
3450 if (context->request_id == pData->requestId) {
3451 context->response_status = pData->status ? -EINVAL : 0;
3452 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303454 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303455
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303456 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458}
3459
3460static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3461 void *pMsg)
3462{
3463 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303464 tpSirEXTScanResetBssidHotlistRspParams pData =
3465 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303466 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303467
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303468 ENTER();
3469
3470 if (wlan_hdd_validate_context(pHddCtx)) {
3471 return;
3472 }
3473 if (!pMsg)
3474 {
3475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303476 return;
3477 }
3478
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303479 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3480 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303481
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303482 context = &pHddCtx->ext_scan_context;
3483 spin_lock(&hdd_context_lock);
3484 if (context->request_id == pData->requestId) {
3485 context->response_status = pData->status ? -EINVAL : 0;
3486 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303487 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303488 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303490 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303491 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303492}
3493
Dino Mycle6fb96c12014-06-10 11:52:40 +05303494static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3495 void *pMsg)
3496{
3497 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3498 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303499 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303500 tANI_S32 totalResults;
3501 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303502 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3503 struct hdd_ext_scan_context *context;
3504 bool ignore_cached_results = false;
3505 tExtscanCachedScanResult *result;
3506 struct nlattr *nla_results;
3507 tANI_U16 ieLength= 0;
3508 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303509
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303510 ENTER();
3511
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303512 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303514
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303515 if (!pMsg)
3516 {
3517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3518 return;
3519 }
3520
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303521 spin_lock(&hdd_context_lock);
3522 context = &pHddCtx->ext_scan_context;
3523 ignore_cached_results = context->ignore_cached_results;
3524 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303525
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303526 if (ignore_cached_results) {
3527 hddLog(LOGE,
3528 FL("Ignore the cached results received after timeout"));
3529 return;
3530 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303531
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303532 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3533 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303534
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303535 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303537 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3538 scan_id_index++) {
3539 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303541 totalResults = result->num_results;
3542 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3543 result->scan_id, result->flags, totalResults);
3544 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303545
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303546 do{
3547 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3548 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3549 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303550
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303551 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3552 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3553
3554 if (!skb) {
3555 hddLog(VOS_TRACE_LEVEL_ERROR,
3556 FL("cfg80211_vendor_event_alloc failed"));
3557 return;
3558 }
3559
3560 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3561
3562 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3563 pData->requestId) ||
3564 nla_put_u32(skb,
3565 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3566 resultsPerEvent)) {
3567 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3568 goto fail;
3569 }
3570 if (nla_put_u8(skb,
3571 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3572 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573 {
3574 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3575 goto fail;
3576 }
3577
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303578 if (nla_put_u32(skb,
3579 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3580 result->scan_id)) {
3581 hddLog(LOGE, FL("put fail"));
3582 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303584
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303585 nla_results = nla_nest_start(skb,
3586 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3587 if (!nla_results)
3588 goto fail;
3589
3590 if (resultsPerEvent) {
3591 struct nlattr *aps;
3592 struct nlattr *nla_result;
3593
3594 nla_result = nla_nest_start(skb, scan_id_index);
3595 if(!nla_result)
3596 goto fail;
3597
3598 if (nla_put_u32(skb,
3599 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3600 result->scan_id) ||
3601 nla_put_u32(skb,
3602 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3603 result->flags) ||
3604 nla_put_u32(skb,
3605 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3606 totalResults)) {
3607 hddLog(LOGE, FL("put fail"));
3608 goto fail;
3609 }
3610
3611 aps = nla_nest_start(skb,
3612 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3613 if (!aps)
3614 {
3615 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3616 goto fail;
3617 }
3618
3619 head_ptr = (tpSirWifiScanResult) &(result->ap);
3620
3621 for (j = 0; j < resultsPerEvent; j++, i++) {
3622 struct nlattr *ap;
3623 pSirWifiScanResult = head_ptr + i;
3624
3625 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303626 * Firmware returns timestamp from extscan_start till
3627 * BSSID was cached (in micro seconds). Add this with
3628 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303629 * to derive the time since boot when the
3630 * BSSID was cached.
3631 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303632 pSirWifiScanResult->ts +=
3633 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303634 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3635 "Ssid (%s)"
3636 "Bssid: %pM "
3637 "Channel (%u)"
3638 "Rssi (%d)"
3639 "RTT (%u)"
3640 "RTT_SD (%u)"
3641 "Beacon Period %u"
3642 "Capability 0x%x "
3643 "Ie length %d",
3644 i,
3645 pSirWifiScanResult->ts,
3646 pSirWifiScanResult->ssid,
3647 pSirWifiScanResult->bssid,
3648 pSirWifiScanResult->channel,
3649 pSirWifiScanResult->rssi,
3650 pSirWifiScanResult->rtt,
3651 pSirWifiScanResult->rtt_sd,
3652 pSirWifiScanResult->beaconPeriod,
3653 pSirWifiScanResult->capability,
3654 ieLength);
3655
3656 ap = nla_nest_start(skb, j + 1);
3657 if (!ap)
3658 {
3659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3660 goto fail;
3661 }
3662
3663 if (nla_put_u64(skb,
3664 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3665 pSirWifiScanResult->ts) )
3666 {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3668 goto fail;
3669 }
3670 if (nla_put(skb,
3671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3672 sizeof(pSirWifiScanResult->ssid),
3673 pSirWifiScanResult->ssid) )
3674 {
3675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3676 goto fail;
3677 }
3678 if (nla_put(skb,
3679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3680 sizeof(pSirWifiScanResult->bssid),
3681 pSirWifiScanResult->bssid) )
3682 {
3683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3684 goto fail;
3685 }
3686 if (nla_put_u32(skb,
3687 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3688 pSirWifiScanResult->channel) )
3689 {
3690 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3691 goto fail;
3692 }
3693 if (nla_put_s32(skb,
3694 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3695 pSirWifiScanResult->rssi) )
3696 {
3697 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3698 goto fail;
3699 }
3700 if (nla_put_u32(skb,
3701 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3702 pSirWifiScanResult->rtt) )
3703 {
3704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3705 goto fail;
3706 }
3707 if (nla_put_u32(skb,
3708 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3709 pSirWifiScanResult->rtt_sd))
3710 {
3711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3712 goto fail;
3713 }
3714 if (nla_put_u32(skb,
3715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3716 pSirWifiScanResult->beaconPeriod))
3717 {
3718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3719 goto fail;
3720 }
3721 if (nla_put_u32(skb,
3722 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3723 pSirWifiScanResult->capability))
3724 {
3725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3726 goto fail;
3727 }
3728 if (nla_put_u32(skb,
3729 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3730 ieLength))
3731 {
3732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3733 goto fail;
3734 }
3735
3736 if (ieLength)
3737 if (nla_put(skb,
3738 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3739 ieLength, ie)) {
3740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3741 goto fail;
3742 }
3743
3744 nla_nest_end(skb, ap);
3745 }
3746 nla_nest_end(skb, aps);
3747 nla_nest_end(skb, nla_result);
3748 }
3749
3750 nla_nest_end(skb, nla_results);
3751
3752 cfg80211_vendor_cmd_reply(skb);
3753
3754 } while (totalResults > 0);
3755 }
3756
3757 if (!pData->moreData) {
3758 spin_lock(&hdd_context_lock);
3759 context->response_status = 0;
3760 complete(&context->response_event);
3761 spin_unlock(&hdd_context_lock);
3762 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303763
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303764 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303765 return;
3766fail:
3767 kfree_skb(skb);
3768 return;
3769}
3770
3771static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3772 void *pMsg)
3773{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303774 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303775 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3776 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303777 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303778
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303779 ENTER();
3780
3781 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303782 hddLog(LOGE,
3783 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303784 return;
3785 }
3786 if (!pMsg)
3787 {
3788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303789 return;
3790 }
3791
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303792 if (pData->bss_found)
3793 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3794 else
3795 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3796
Dino Mycle6fb96c12014-06-10 11:52:40 +05303797 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303798#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3799 NULL,
3800#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303801 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303802 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303803
3804 if (!skb) {
3805 hddLog(VOS_TRACE_LEVEL_ERROR,
3806 FL("cfg80211_vendor_event_alloc failed"));
3807 return;
3808 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303809
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303810 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3811 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3812 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3813 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3814
3815 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303816 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3817 "Ssid (%s) "
3818 "Bssid (" MAC_ADDRESS_STR ") "
3819 "Channel (%u) "
3820 "Rssi (%d) "
3821 "RTT (%u) "
3822 "RTT_SD (%u) ",
3823 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303824 pData->bssHotlist[i].ts,
3825 pData->bssHotlist[i].ssid,
3826 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3827 pData->bssHotlist[i].channel,
3828 pData->bssHotlist[i].rssi,
3829 pData->bssHotlist[i].rtt,
3830 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303831 }
3832
3833 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3834 pData->requestId) ||
3835 nla_put_u32(skb,
3836 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303837 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303838 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3839 goto fail;
3840 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303841 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303842 struct nlattr *aps;
3843
3844 aps = nla_nest_start(skb,
3845 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3846 if (!aps)
3847 goto fail;
3848
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303849 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303850 struct nlattr *ap;
3851
3852 ap = nla_nest_start(skb, i + 1);
3853 if (!ap)
3854 goto fail;
3855
3856 if (nla_put_u64(skb,
3857 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303858 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303859 nla_put(skb,
3860 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303861 sizeof(pData->bssHotlist[i].ssid),
3862 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303863 nla_put(skb,
3864 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303865 sizeof(pData->bssHotlist[i].bssid),
3866 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303867 nla_put_u32(skb,
3868 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303869 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303870 nla_put_s32(skb,
3871 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303872 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303873 nla_put_u32(skb,
3874 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303875 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303876 nla_put_u32(skb,
3877 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303878 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303879 goto fail;
3880
3881 nla_nest_end(skb, ap);
3882 }
3883 nla_nest_end(skb, aps);
3884
3885 if (nla_put_u8(skb,
3886 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3887 pData->moreData))
3888 goto fail;
3889 }
3890
3891 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303892 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303893 return;
3894
3895fail:
3896 kfree_skb(skb);
3897 return;
3898
3899}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303900
3901static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3902 void *pMsg)
3903{
3904 struct sk_buff *skb;
3905 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3906 tpSirWifiFullScanResultEvent pData =
3907 (tpSirWifiFullScanResultEvent) (pMsg);
3908
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303909 ENTER();
3910
3911 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303912 hddLog(LOGE,
3913 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303914 return;
3915 }
3916 if (!pMsg)
3917 {
3918 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303919 return;
3920 }
3921
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303922 /*
3923 * If the full scan result including IE data exceeds NL 4K size
3924 * limitation, drop that beacon/probe rsp frame.
3925 */
3926 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3927 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3928 return;
3929 }
3930
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303932#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3933 NULL,
3934#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303935 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3936 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3937 GFP_KERNEL);
3938
3939 if (!skb) {
3940 hddLog(VOS_TRACE_LEVEL_ERROR,
3941 FL("cfg80211_vendor_event_alloc failed"));
3942 return;
3943 }
3944
Dino Mycle6fb96c12014-06-10 11:52:40 +05303945 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3946 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3947 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3948 "Ssid (%s)"
3949 "Bssid (" MAC_ADDRESS_STR ")"
3950 "Channel (%u)"
3951 "Rssi (%d)"
3952 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303953 "RTT_SD (%u)"
3954 "Bcn Period %d"
3955 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303956 pData->ap.ts,
3957 pData->ap.ssid,
3958 MAC_ADDR_ARRAY(pData->ap.bssid),
3959 pData->ap.channel,
3960 pData->ap.rssi,
3961 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303962 pData->ap.rtt_sd,
3963 pData->ap.beaconPeriod,
3964 pData->ap.capability);
3965
Dino Mycle6fb96c12014-06-10 11:52:40 +05303966 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3967 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3968 pData->requestId) ||
3969 nla_put_u64(skb,
3970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3971 pData->ap.ts) ||
3972 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3973 sizeof(pData->ap.ssid),
3974 pData->ap.ssid) ||
3975 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3976 WNI_CFG_BSSID_LEN,
3977 pData->ap.bssid) ||
3978 nla_put_u32(skb,
3979 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3980 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303981 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303982 pData->ap.rssi) ||
3983 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3984 pData->ap.rtt) ||
3985 nla_put_u32(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3987 pData->ap.rtt_sd) ||
3988 nla_put_u16(skb,
3989 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3990 pData->ap.beaconPeriod) ||
3991 nla_put_u16(skb,
3992 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3993 pData->ap.capability) ||
3994 nla_put_u32(skb,
3995 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303996 pData->ieLength) ||
3997 nla_put_u8(skb,
3998 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3999 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304000 {
4001 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4002 goto nla_put_failure;
4003 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304004
4005 if (pData->ieLength) {
4006 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4007 pData->ieLength,
4008 pData->ie))
4009 {
4010 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4011 goto nla_put_failure;
4012 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304013 }
4014
4015 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304016 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304017 return;
4018
4019nla_put_failure:
4020 kfree_skb(skb);
4021 return;
4022}
4023
4024static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4025 void *pMsg)
4026{
4027 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4028 struct sk_buff *skb = NULL;
4029 tpSirEXTScanResultsAvailableIndParams pData =
4030 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4031
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304032 ENTER();
4033
4034 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304035 hddLog(LOGE,
4036 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304037 return;
4038 }
4039 if (!pMsg)
4040 {
4041 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304042 return;
4043 }
4044
4045 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304046#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4047 NULL,
4048#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304049 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4050 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4051 GFP_KERNEL);
4052
4053 if (!skb) {
4054 hddLog(VOS_TRACE_LEVEL_ERROR,
4055 FL("cfg80211_vendor_event_alloc failed"));
4056 return;
4057 }
4058
Dino Mycle6fb96c12014-06-10 11:52:40 +05304059 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4060 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4061 pData->numResultsAvailable);
4062 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4063 pData->requestId) ||
4064 nla_put_u32(skb,
4065 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4066 pData->numResultsAvailable)) {
4067 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4068 goto nla_put_failure;
4069 }
4070
4071 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304072 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304073 return;
4074
4075nla_put_failure:
4076 kfree_skb(skb);
4077 return;
4078}
4079
4080static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4081{
4082 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4083 struct sk_buff *skb = NULL;
4084 tpSirEXTScanProgressIndParams pData =
4085 (tpSirEXTScanProgressIndParams) pMsg;
4086
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304087 ENTER();
4088
4089 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304090 hddLog(LOGE,
4091 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304092 return;
4093 }
4094 if (!pMsg)
4095 {
4096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304097 return;
4098 }
4099
4100 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304101#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4102 NULL,
4103#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304104 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4105 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4106 GFP_KERNEL);
4107
4108 if (!skb) {
4109 hddLog(VOS_TRACE_LEVEL_ERROR,
4110 FL("cfg80211_vendor_event_alloc failed"));
4111 return;
4112 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304113 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304114 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4115 pData->extScanEventType);
4116 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4117 pData->status);
4118
4119 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4120 pData->extScanEventType) ||
4121 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304122 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4123 pData->requestId) ||
4124 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304125 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4126 pData->status)) {
4127 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4128 goto nla_put_failure;
4129 }
4130
4131 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304132 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304133 return;
4134
4135nla_put_failure:
4136 kfree_skb(skb);
4137 return;
4138}
4139
4140void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4141 void *pMsg)
4142{
4143 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4144
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304145 ENTER();
4146
Dino Mycle6fb96c12014-06-10 11:52:40 +05304147 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304148 return;
4149 }
4150
4151 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4152
4153
4154 switch(evType) {
4155 case SIR_HAL_EXTSCAN_START_RSP:
4156 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4157 break;
4158
4159 case SIR_HAL_EXTSCAN_STOP_RSP:
4160 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4161 break;
4162 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4163 /* There is no need to send this response to upper layer
4164 Just log the message */
4165 hddLog(VOS_TRACE_LEVEL_INFO,
4166 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4167 break;
4168 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4169 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4170 break;
4171
4172 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4173 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4174 break;
4175
Dino Mycle6fb96c12014-06-10 11:52:40 +05304176 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304177 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304178 break;
4179 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4180 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4181 break;
4182 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4183 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4184 break;
4185 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4186 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4187 break;
4188 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4189 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4190 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304191 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4192 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4193 break;
4194 default:
4195 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4196 break;
4197 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304198 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304199}
4200
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304201static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4202 struct wireless_dev *wdev,
4203 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304204{
Dino Myclee8843b32014-07-04 14:21:45 +05304205 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304206 struct net_device *dev = wdev->netdev;
4207 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4208 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4209 struct nlattr
4210 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4211 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304212 struct hdd_ext_scan_context *context;
4213 unsigned long rc;
4214 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304215
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304216 ENTER();
4217
Dino Mycle6fb96c12014-06-10 11:52:40 +05304218 status = wlan_hdd_validate_context(pHddCtx);
4219 if (0 != status)
4220 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304221 return -EINVAL;
4222 }
Dino Myclee8843b32014-07-04 14:21:45 +05304223 /* check the EXTScan Capability */
4224 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304225 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4226 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304227 {
4228 hddLog(VOS_TRACE_LEVEL_ERROR,
4229 FL("EXTScan not enabled/supported by Firmware"));
4230 return -EINVAL;
4231 }
4232
Dino Mycle6fb96c12014-06-10 11:52:40 +05304233 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4234 data, dataLen,
4235 wlan_hdd_extscan_config_policy)) {
4236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4237 return -EINVAL;
4238 }
4239
4240 /* Parse and fetch request Id */
4241 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4243 return -EINVAL;
4244 }
4245
Dino Myclee8843b32014-07-04 14:21:45 +05304246 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304247 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304248 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304249
Dino Myclee8843b32014-07-04 14:21:45 +05304250 reqMsg.sessionId = pAdapter->sessionId;
4251 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304252
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304253 vos_spin_lock_acquire(&hdd_context_lock);
4254 context = &pHddCtx->ext_scan_context;
4255 context->request_id = reqMsg.requestId;
4256 INIT_COMPLETION(context->response_event);
4257 vos_spin_lock_release(&hdd_context_lock);
4258
Dino Myclee8843b32014-07-04 14:21:45 +05304259 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304260 if (!HAL_STATUS_SUCCESS(status)) {
4261 hddLog(VOS_TRACE_LEVEL_ERROR,
4262 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304263 return -EINVAL;
4264 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304265
4266 rc = wait_for_completion_timeout(&context->response_event,
4267 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4268 if (!rc) {
4269 hddLog(LOGE, FL("Target response timed out"));
4270 return -ETIMEDOUT;
4271 }
4272
4273 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4274 if (ret)
4275 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4276
4277 return ret;
4278
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304279 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304280 return 0;
4281}
4282
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304283static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4284 struct wireless_dev *wdev,
4285 const void *data, int dataLen)
4286{
4287 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304288
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304289 vos_ssr_protect(__func__);
4290 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4291 vos_ssr_unprotect(__func__);
4292
4293 return ret;
4294}
4295
4296static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4297 struct wireless_dev *wdev,
4298 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304299{
Dino Myclee8843b32014-07-04 14:21:45 +05304300 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304301 struct net_device *dev = wdev->netdev;
4302 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4303 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4304 struct nlattr
4305 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4306 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304307 struct hdd_ext_scan_context *context;
4308 unsigned long rc;
4309 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304310
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304311 ENTER();
4312
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304313 if (VOS_FTM_MODE == hdd_get_conparam()) {
4314 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4315 return -EINVAL;
4316 }
4317
Dino Mycle6fb96c12014-06-10 11:52:40 +05304318 status = wlan_hdd_validate_context(pHddCtx);
4319 if (0 != status)
4320 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304321 return -EINVAL;
4322 }
Dino Myclee8843b32014-07-04 14:21:45 +05304323 /* check the EXTScan Capability */
4324 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304325 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4326 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304327 {
4328 hddLog(VOS_TRACE_LEVEL_ERROR,
4329 FL("EXTScan not enabled/supported by Firmware"));
4330 return -EINVAL;
4331 }
4332
Dino Mycle6fb96c12014-06-10 11:52:40 +05304333 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4334 data, dataLen,
4335 wlan_hdd_extscan_config_policy)) {
4336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4337 return -EINVAL;
4338 }
4339 /* Parse and fetch request Id */
4340 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4341 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4342 return -EINVAL;
4343 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304344
Dino Myclee8843b32014-07-04 14:21:45 +05304345 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304346 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4347
Dino Myclee8843b32014-07-04 14:21:45 +05304348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304349
Dino Myclee8843b32014-07-04 14:21:45 +05304350 reqMsg.sessionId = pAdapter->sessionId;
4351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352
4353 /* Parse and fetch flush parameter */
4354 if (!tb
4355 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4356 {
4357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4358 goto failed;
4359 }
Dino Myclee8843b32014-07-04 14:21:45 +05304360 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304361 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4362
Dino Myclee8843b32014-07-04 14:21:45 +05304363 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304364
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304365 spin_lock(&hdd_context_lock);
4366 context = &pHddCtx->ext_scan_context;
4367 context->request_id = reqMsg.requestId;
4368 context->ignore_cached_results = false;
4369 INIT_COMPLETION(context->response_event);
4370 spin_unlock(&hdd_context_lock);
4371
Dino Myclee8843b32014-07-04 14:21:45 +05304372 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304373 if (!HAL_STATUS_SUCCESS(status)) {
4374 hddLog(VOS_TRACE_LEVEL_ERROR,
4375 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304376 return -EINVAL;
4377 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304378
4379 rc = wait_for_completion_timeout(&context->response_event,
4380 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4381 if (!rc) {
4382 hddLog(LOGE, FL("Target response timed out"));
4383 retval = -ETIMEDOUT;
4384 spin_lock(&hdd_context_lock);
4385 context->ignore_cached_results = true;
4386 spin_unlock(&hdd_context_lock);
4387 } else {
4388 spin_lock(&hdd_context_lock);
4389 retval = context->response_status;
4390 spin_unlock(&hdd_context_lock);
4391 }
4392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304393 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304394 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304395
4396failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304397 return -EINVAL;
4398}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304399static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4400 struct wireless_dev *wdev,
4401 const void *data, int dataLen)
4402{
4403 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304404
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304405 vos_ssr_protect(__func__);
4406 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4407 vos_ssr_unprotect(__func__);
4408
4409 return ret;
4410}
4411
4412static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304413 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304414 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304415{
4416 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4417 struct net_device *dev = wdev->netdev;
4418 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4419 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4420 struct nlattr
4421 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4422 struct nlattr
4423 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4424 struct nlattr *apTh;
4425 eHalStatus status;
4426 tANI_U8 i = 0;
4427 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304428 struct hdd_ext_scan_context *context;
4429 tANI_U32 request_id;
4430 unsigned long rc;
4431 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304432
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304433 ENTER();
4434
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304435 if (VOS_FTM_MODE == hdd_get_conparam()) {
4436 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4437 return -EINVAL;
4438 }
4439
Dino Mycle6fb96c12014-06-10 11:52:40 +05304440 status = wlan_hdd_validate_context(pHddCtx);
4441 if (0 != status)
4442 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304443 return -EINVAL;
4444 }
Dino Myclee8843b32014-07-04 14:21:45 +05304445 /* check the EXTScan Capability */
4446 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304447 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4448 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304449 {
4450 hddLog(VOS_TRACE_LEVEL_ERROR,
4451 FL("EXTScan not enabled/supported by Firmware"));
4452 return -EINVAL;
4453 }
4454
Dino Mycle6fb96c12014-06-10 11:52:40 +05304455 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4456 data, dataLen,
4457 wlan_hdd_extscan_config_policy)) {
4458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4459 return -EINVAL;
4460 }
4461
4462 /* Parse and fetch request Id */
4463 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4464 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4465 return -EINVAL;
4466 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304467 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4468 vos_mem_malloc(sizeof(*pReqMsg));
4469 if (!pReqMsg) {
4470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4471 return -ENOMEM;
4472 }
4473
Dino Myclee8843b32014-07-04 14:21:45 +05304474
Dino Mycle6fb96c12014-06-10 11:52:40 +05304475 pReqMsg->requestId = nla_get_u32(
4476 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4477 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4478
4479 /* Parse and fetch number of APs */
4480 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4482 goto fail;
4483 }
4484
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304485 /* Parse and fetch lost ap sample size */
4486 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4487 hddLog(LOGE, FL("attr lost ap sample size failed"));
4488 goto fail;
4489 }
4490
4491 pReqMsg->lostBssidSampleSize = nla_get_u32(
4492 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4493 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4494
Dino Mycle6fb96c12014-06-10 11:52:40 +05304495 pReqMsg->sessionId = pAdapter->sessionId;
4496 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4497
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304498 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304499 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304500 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4501 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4502 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4503 goto fail;
4504 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304505 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304506
4507 nla_for_each_nested(apTh,
4508 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304509 if (i == pReqMsg->numBssid) {
4510 hddLog(LOGW, FL("Ignoring excess AP"));
4511 break;
4512 }
4513
Dino Mycle6fb96c12014-06-10 11:52:40 +05304514 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4515 nla_data(apTh), nla_len(apTh),
4516 NULL)) {
4517 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4518 goto fail;
4519 }
4520
4521 /* Parse and fetch MAC address */
4522 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4523 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4524 goto fail;
4525 }
4526 memcpy(pReqMsg->ap[i].bssid, nla_data(
4527 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4528 sizeof(tSirMacAddr));
4529 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4530
4531 /* Parse and fetch low RSSI */
4532 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4534 goto fail;
4535 }
4536 pReqMsg->ap[i].low = nla_get_s32(
4537 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4538 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4539
4540 /* Parse and fetch high RSSI */
4541 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4543 goto fail;
4544 }
4545 pReqMsg->ap[i].high = nla_get_s32(
4546 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4547 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4548 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304549 i++;
4550 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304551
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304552 if (i < pReqMsg->numBssid) {
4553 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4554 i, pReqMsg->numBssid);
4555 pReqMsg->numBssid = i;
4556 }
4557
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304558 context = &pHddCtx->ext_scan_context;
4559 spin_lock(&hdd_context_lock);
4560 INIT_COMPLETION(context->response_event);
4561 context->request_id = request_id = pReqMsg->requestId;
4562 spin_unlock(&hdd_context_lock);
4563
Dino Mycle6fb96c12014-06-10 11:52:40 +05304564 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4565 if (!HAL_STATUS_SUCCESS(status)) {
4566 hddLog(VOS_TRACE_LEVEL_ERROR,
4567 FL("sme_SetBssHotlist failed(err=%d)"), status);
4568 vos_mem_free(pReqMsg);
4569 return -EINVAL;
4570 }
4571
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304572 /* request was sent -- wait for the response */
4573 rc = wait_for_completion_timeout(&context->response_event,
4574 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4575
4576 if (!rc) {
4577 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4578 retval = -ETIMEDOUT;
4579 } else {
4580 spin_lock(&hdd_context_lock);
4581 if (context->request_id == request_id)
4582 retval = context->response_status;
4583 else
4584 retval = -EINVAL;
4585 spin_unlock(&hdd_context_lock);
4586 }
4587
Dino Myclee8843b32014-07-04 14:21:45 +05304588 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304589 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304590 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304591
4592fail:
4593 vos_mem_free(pReqMsg);
4594 return -EINVAL;
4595}
4596
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304597static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4598 struct wireless_dev *wdev,
4599 const void *data, int dataLen)
4600{
4601 int ret = 0;
4602
4603 vos_ssr_protect(__func__);
4604 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4605 dataLen);
4606 vos_ssr_unprotect(__func__);
4607
4608 return ret;
4609}
4610
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304611static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304612 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304613 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304615 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4616 struct net_device *dev = wdev->netdev;
4617 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4618 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4619 uint8_t num_channels = 0;
4620 uint8_t num_chan_new = 0;
4621 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304622 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304623 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304624 tWifiBand wifiBand;
4625 eHalStatus status;
4626 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304627 tANI_U8 i,j,k;
4628 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304629
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304630 ENTER();
4631
Dino Mycle6fb96c12014-06-10 11:52:40 +05304632 status = wlan_hdd_validate_context(pHddCtx);
4633 if (0 != status)
4634 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304635 return -EINVAL;
4636 }
Dino Myclee8843b32014-07-04 14:21:45 +05304637
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4639 data, dataLen,
4640 wlan_hdd_extscan_config_policy)) {
4641 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4642 return -EINVAL;
4643 }
4644
4645 /* Parse and fetch request Id */
4646 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4648 return -EINVAL;
4649 }
4650 requestId = nla_get_u32(
4651 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4652 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4653
4654 /* Parse and fetch wifi band */
4655 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4656 {
4657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4658 return -EINVAL;
4659 }
4660 wifiBand = nla_get_u32(
4661 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4662 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4663
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304664 /* Parse and fetch max channels */
4665 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4666 {
4667 hddLog(LOGE, FL("attr max channels failed"));
4668 return -EINVAL;
4669 }
4670 maxChannels = nla_get_u32(
4671 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4672 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4673
Dino Mycle6fb96c12014-06-10 11:52:40 +05304674 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304675 wifiBand, chan_list,
4676 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304677 if (eHAL_STATUS_SUCCESS != status) {
4678 hddLog(VOS_TRACE_LEVEL_ERROR,
4679 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4680 return -EINVAL;
4681 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304682
Agrawal Ashish16abf782016-08-18 22:42:59 +05304683 num_channels = VOS_MIN(num_channels, maxChannels);
4684 num_chan_new = num_channels;
4685 /* remove the indoor only channels if iface is SAP */
4686 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4687 {
4688 num_chan_new = 0;
4689 for (i = 0; i < num_channels; i++)
4690 for (j = 0; j < IEEE80211_NUM_BANDS; j++) {
4691 if (wiphy->bands[j] == NULL)
4692 continue;
4693 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4694 if ((chan_list[i] ==
4695 wiphy->bands[j]->channels[k].center_freq) &&
4696 (!(wiphy->bands[j]->channels[k].flags &
4697 IEEE80211_CHAN_INDOOR_ONLY))) {
4698 chan_list[num_chan_new] = chan_list[i];
4699 num_chan_new++;
4700 }
4701 }
4702 }
4703 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304704
Agrawal Ashish16abf782016-08-18 22:42:59 +05304705 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4706 for (i = 0; i < num_chan_new; i++)
4707 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4708 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304709
4710 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304711 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304712 NLMSG_HDRLEN);
4713
4714 if (!replySkb) {
4715 hddLog(VOS_TRACE_LEVEL_ERROR,
4716 FL("valid channels: buffer alloc fail"));
4717 return -EINVAL;
4718 }
4719 if (nla_put_u32(replySkb,
4720 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304721 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304723 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724
4725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4726 kfree_skb(replySkb);
4727 return -EINVAL;
4728 }
4729
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304730 ret = cfg80211_vendor_cmd_reply(replySkb);
4731
4732 EXIT();
4733 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304734}
4735
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304736static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4737 struct wireless_dev *wdev,
4738 const void *data, int dataLen)
4739{
4740 int ret = 0;
4741
4742 vos_ssr_protect(__func__);
4743 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4744 dataLen);
4745 vos_ssr_unprotect(__func__);
4746
4747 return ret;
4748}
4749
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304750static int hdd_extscan_start_fill_bucket_channel_spec(
4751 hdd_context_t *pHddCtx,
4752 tpSirEXTScanStartReqParams pReqMsg,
4753 struct nlattr **tb)
4754{
4755 struct nlattr *bucket[
4756 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4757 struct nlattr *channel[
4758 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4759 struct nlattr *buckets;
4760 struct nlattr *channels;
4761 int rem1, rem2;
4762 eHalStatus status;
4763 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304764 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304765 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4766 tANI_U32 passive_max_chn_time, active_max_chn_time;
4767
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304768 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304769 bktIndex = 0;
4770
4771 nla_for_each_nested(buckets,
4772 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304773 if (bktIndex >= expected_buckets) {
4774 hddLog(LOGW, FL("ignoring excess buckets"));
4775 break;
4776 }
4777
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304778 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4780 nla_data(buckets), nla_len(buckets),
4781 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304782 hddLog(LOGE, FL("nla_parse failed"));
4783 return -EINVAL;
4784 }
4785
4786 /* Parse and fetch bucket spec */
4787 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4788 hddLog(LOGE, FL("attr bucket index failed"));
4789 return -EINVAL;
4790 }
4791 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4792 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4793 hddLog(LOG1, FL("Bucket spec Index %d"),
4794 pReqMsg->buckets[bktIndex].bucket);
4795
4796 /* Parse and fetch wifi band */
4797 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4798 hddLog(LOGE, FL("attr wifi band failed"));
4799 return -EINVAL;
4800 }
4801 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4802 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4803 hddLog(LOG1, FL("Wifi band %d"),
4804 pReqMsg->buckets[bktIndex].band);
4805
4806 /* Parse and fetch period */
4807 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4808 hddLog(LOGE, FL("attr period failed"));
4809 return -EINVAL;
4810 }
4811 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4812 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4813 hddLog(LOG1, FL("period %d"),
4814 pReqMsg->buckets[bktIndex].period);
4815
4816 /* Parse and fetch report events */
4817 if (!bucket[
4818 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4819 hddLog(LOGE, FL("attr report events failed"));
4820 return -EINVAL;
4821 }
4822 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4823 bucket[
4824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4825 hddLog(LOG1, FL("report events %d"),
4826 pReqMsg->buckets[bktIndex].reportEvents);
4827
4828 /* Parse and fetch max period */
4829 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4830 hddLog(LOGE, FL("attr max period failed"));
4831 return -EINVAL;
4832 }
4833 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4834 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4835 hddLog(LOG1, FL("max period %u"),
4836 pReqMsg->buckets[bktIndex].max_period);
4837
4838 /* Parse and fetch exponent */
4839 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4840 hddLog(LOGE, FL("attr exponent failed"));
4841 return -EINVAL;
4842 }
4843 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4844 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4845 hddLog(LOG1, FL("exponent %u"),
4846 pReqMsg->buckets[bktIndex].exponent);
4847
4848 /* Parse and fetch step count */
4849 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4850 hddLog(LOGE, FL("attr step count failed"));
4851 return -EINVAL;
4852 }
4853 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4854 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4855 hddLog(LOG1, FL("Step count %u"),
4856 pReqMsg->buckets[bktIndex].step_count);
4857
4858 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4859 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4860
4861 /* Framework shall pass the channel list if the input WiFi band is
4862 * WIFI_BAND_UNSPECIFIED.
4863 * If the input WiFi band is specified (any value other than
4864 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4865 */
4866 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4867 numChannels = 0;
4868 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4869 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4870 pReqMsg->buckets[bktIndex].band,
4871 chanList, &numChannels);
4872 if (!HAL_STATUS_SUCCESS(status)) {
4873 hddLog(LOGE,
4874 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4875 status);
4876 return -EINVAL;
4877 }
4878
4879 pReqMsg->buckets[bktIndex].numChannels =
4880 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4881 hddLog(LOG1, FL("Num channels %d"),
4882 pReqMsg->buckets[bktIndex].numChannels);
4883
4884 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4885 j++) {
4886 pReqMsg->buckets[bktIndex].channels[j].channel =
4887 chanList[j];
4888 pReqMsg->buckets[bktIndex].channels[j].
4889 chnlClass = 0;
4890 if (CSR_IS_CHANNEL_DFS(
4891 vos_freq_to_chan(chanList[j]))) {
4892 pReqMsg->buckets[bktIndex].channels[j].
4893 passive = 1;
4894 pReqMsg->buckets[bktIndex].channels[j].
4895 dwellTimeMs = passive_max_chn_time;
4896 } else {
4897 pReqMsg->buckets[bktIndex].channels[j].
4898 passive = 0;
4899 pReqMsg->buckets[bktIndex].channels[j].
4900 dwellTimeMs = active_max_chn_time;
4901 }
4902
4903 hddLog(LOG1,
4904 "Channel %u Passive %u Dwell time %u ms",
4905 pReqMsg->buckets[bktIndex].channels[j].channel,
4906 pReqMsg->buckets[bktIndex].channels[j].passive,
4907 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4908 }
4909
4910 bktIndex++;
4911 continue;
4912 }
4913
4914 /* Parse and fetch number of channels */
4915 if (!bucket[
4916 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4917 hddLog(LOGE, FL("attr num channels failed"));
4918 return -EINVAL;
4919 }
4920
4921 pReqMsg->buckets[bktIndex].numChannels =
4922 nla_get_u32(bucket[
4923 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4924 hddLog(LOG1, FL("num channels %d"),
4925 pReqMsg->buckets[bktIndex].numChannels);
4926
4927 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4928 hddLog(LOGE, FL("attr channel spec failed"));
4929 return -EINVAL;
4930 }
4931
4932 j = 0;
4933 nla_for_each_nested(channels,
4934 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4935 if (nla_parse(channel,
4936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4937 nla_data(channels), nla_len(channels),
4938 wlan_hdd_extscan_config_policy)) {
4939 hddLog(LOGE, FL("nla_parse failed"));
4940 return -EINVAL;
4941 }
4942
4943 /* Parse and fetch channel */
4944 if (!channel[
4945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4946 hddLog(LOGE, FL("attr channel failed"));
4947 return -EINVAL;
4948 }
4949 pReqMsg->buckets[bktIndex].channels[j].channel =
4950 nla_get_u32(channel[
4951 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4952 hddLog(LOG1, FL("channel %u"),
4953 pReqMsg->buckets[bktIndex].channels[j].channel);
4954
4955 /* Parse and fetch dwell time */
4956 if (!channel[
4957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4958 hddLog(LOGE, FL("attr dwelltime failed"));
4959 return -EINVAL;
4960 }
4961 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4962 nla_get_u32(channel[
4963 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4964
4965 hddLog(LOG1, FL("Dwell time (%u ms)"),
4966 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4967
4968
4969 /* Parse and fetch channel spec passive */
4970 if (!channel[
4971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4972 hddLog(LOGE,
4973 FL("attr channel spec passive failed"));
4974 return -EINVAL;
4975 }
4976 pReqMsg->buckets[bktIndex].channels[j].passive =
4977 nla_get_u8(channel[
4978 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4979 hddLog(LOG1, FL("Chnl spec passive %u"),
4980 pReqMsg->buckets[bktIndex].channels[j].passive);
4981
4982 j++;
4983 }
4984
4985 bktIndex++;
4986 }
4987
4988 return 0;
4989}
4990
4991
4992/*
4993 * define short names for the global vendor params
4994 * used by wlan_hdd_cfg80211_extscan_start()
4995 */
4996#define PARAM_MAX \
4997QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4998#define PARAM_REQUEST_ID \
4999QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5000#define PARAM_BASE_PERIOD \
5001QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5002#define PARAM_MAX_AP_PER_SCAN \
5003QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5004#define PARAM_RPT_THRHLD_PERCENT \
5005QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5006#define PARAM_RPT_THRHLD_NUM_SCANS \
5007QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5008#define PARAM_NUM_BUCKETS \
5009QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5010
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305011static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305012 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305013 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305014{
Dino Myclee8843b32014-07-04 14:21:45 +05305015 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305016 struct net_device *dev = wdev->netdev;
5017 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5018 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5019 struct nlattr *tb[PARAM_MAX + 1];
5020 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305021 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305022 tANI_U32 request_id;
5023 struct hdd_ext_scan_context *context;
5024 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305025
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305026 ENTER();
5027
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305028 if (VOS_FTM_MODE == hdd_get_conparam()) {
5029 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5030 return -EINVAL;
5031 }
5032
Dino Mycle6fb96c12014-06-10 11:52:40 +05305033 status = wlan_hdd_validate_context(pHddCtx);
5034 if (0 != status)
5035 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305036 return -EINVAL;
5037 }
Dino Myclee8843b32014-07-04 14:21:45 +05305038 /* check the EXTScan Capability */
5039 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305040 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5041 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305042 {
5043 hddLog(VOS_TRACE_LEVEL_ERROR,
5044 FL("EXTScan not enabled/supported by Firmware"));
5045 return -EINVAL;
5046 }
5047
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305048 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305049 data, dataLen,
5050 wlan_hdd_extscan_config_policy)) {
5051 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5052 return -EINVAL;
5053 }
5054
5055 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305056 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5058 return -EINVAL;
5059 }
5060
Dino Myclee8843b32014-07-04 14:21:45 +05305061 pReqMsg = (tpSirEXTScanStartReqParams)
5062 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305063 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305064 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5065 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305066 }
5067
5068 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305069 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305070 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5071
5072 pReqMsg->sessionId = pAdapter->sessionId;
5073 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5074
5075 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305076 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305077 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5078 goto fail;
5079 }
5080 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305081 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305082 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5083 pReqMsg->basePeriod);
5084
5085 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305086 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305087 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5088 goto fail;
5089 }
5090 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305091 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305092 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5093 pReqMsg->maxAPperScan);
5094
5095 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305096 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5098 goto fail;
5099 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305100 pReqMsg->reportThresholdPercent = nla_get_u8(
5101 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305102 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305103 pReqMsg->reportThresholdPercent);
5104
5105 /* Parse and fetch report threshold num scans */
5106 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5107 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5108 goto fail;
5109 }
5110 pReqMsg->reportThresholdNumScans = nla_get_u8(
5111 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5112 hddLog(LOG1, FL("Report Threshold num scans %d"),
5113 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305114
5115 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305116 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5118 goto fail;
5119 }
5120 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305121 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305122 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5123 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5124 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5125 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5126 }
5127 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5128 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305129
Dino Mycle6fb96c12014-06-10 11:52:40 +05305130 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5131 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5132 goto fail;
5133 }
5134
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305135 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305136
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305137 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5138 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305139
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305140 context = &pHddCtx->ext_scan_context;
5141 spin_lock(&hdd_context_lock);
5142 INIT_COMPLETION(context->response_event);
5143 context->request_id = request_id = pReqMsg->requestId;
5144 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305145
Dino Mycle6fb96c12014-06-10 11:52:40 +05305146 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5147 if (!HAL_STATUS_SUCCESS(status)) {
5148 hddLog(VOS_TRACE_LEVEL_ERROR,
5149 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305150 goto fail;
5151 }
5152
Srinivas Dasari91727c12016-03-23 17:59:06 +05305153 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5154
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305155 /* request was sent -- wait for the response */
5156 rc = wait_for_completion_timeout(&context->response_event,
5157 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5158
5159 if (!rc) {
5160 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5161 retval = -ETIMEDOUT;
5162 } else {
5163 spin_lock(&hdd_context_lock);
5164 if (context->request_id == request_id)
5165 retval = context->response_status;
5166 else
5167 retval = -EINVAL;
5168 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305169 }
5170
Dino Myclee8843b32014-07-04 14:21:45 +05305171 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305172 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305173 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305174
5175fail:
5176 vos_mem_free(pReqMsg);
5177 return -EINVAL;
5178}
5179
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305180/*
5181 * done with short names for the global vendor params
5182 * used by wlan_hdd_cfg80211_extscan_start()
5183 */
5184#undef PARAM_MAX
5185#undef PARAM_REQUEST_ID
5186#undef PARAM_BASE_PERIOD
5187#undef PARAMS_MAX_AP_PER_SCAN
5188#undef PARAMS_RPT_THRHLD_PERCENT
5189#undef PARAMS_RPT_THRHLD_NUM_SCANS
5190#undef PARAMS_NUM_BUCKETS
5191
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305192static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5193 struct wireless_dev *wdev,
5194 const void *data, int dataLen)
5195{
5196 int ret = 0;
5197
5198 vos_ssr_protect(__func__);
5199 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5200 vos_ssr_unprotect(__func__);
5201
5202 return ret;
5203}
5204
5205static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305206 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305207 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305208{
Dino Myclee8843b32014-07-04 14:21:45 +05305209 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305210 struct net_device *dev = wdev->netdev;
5211 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5212 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5213 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5214 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305215 int retval;
5216 unsigned long rc;
5217 struct hdd_ext_scan_context *context;
5218 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305219
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305220 ENTER();
5221
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305222 if (VOS_FTM_MODE == hdd_get_conparam()) {
5223 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5224 return -EINVAL;
5225 }
5226
Dino Mycle6fb96c12014-06-10 11:52:40 +05305227 status = wlan_hdd_validate_context(pHddCtx);
5228 if (0 != status)
5229 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305230 return -EINVAL;
5231 }
Dino Myclee8843b32014-07-04 14:21:45 +05305232 /* check the EXTScan Capability */
5233 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305234 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5235 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305236 {
5237 hddLog(VOS_TRACE_LEVEL_ERROR,
5238 FL("EXTScan not enabled/supported by Firmware"));
5239 return -EINVAL;
5240 }
5241
Dino Mycle6fb96c12014-06-10 11:52:40 +05305242 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5243 data, dataLen,
5244 wlan_hdd_extscan_config_policy)) {
5245 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5246 return -EINVAL;
5247 }
5248
5249 /* Parse and fetch request Id */
5250 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5252 return -EINVAL;
5253 }
5254
Dino Myclee8843b32014-07-04 14:21:45 +05305255 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305256 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305257 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305258
Dino Myclee8843b32014-07-04 14:21:45 +05305259 reqMsg.sessionId = pAdapter->sessionId;
5260 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305261
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305262 context = &pHddCtx->ext_scan_context;
5263 spin_lock(&hdd_context_lock);
5264 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305265 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305266 spin_unlock(&hdd_context_lock);
5267
Dino Myclee8843b32014-07-04 14:21:45 +05305268 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305269 if (!HAL_STATUS_SUCCESS(status)) {
5270 hddLog(VOS_TRACE_LEVEL_ERROR,
5271 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305272 return -EINVAL;
5273 }
5274
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305275 /* request was sent -- wait for the response */
5276 rc = wait_for_completion_timeout(&context->response_event,
5277 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5278
5279 if (!rc) {
5280 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5281 retval = -ETIMEDOUT;
5282 } else {
5283 spin_lock(&hdd_context_lock);
5284 if (context->request_id == request_id)
5285 retval = context->response_status;
5286 else
5287 retval = -EINVAL;
5288 spin_unlock(&hdd_context_lock);
5289 }
5290
5291 return retval;
5292
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305293 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305294 return 0;
5295}
5296
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305297static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5298 struct wireless_dev *wdev,
5299 const void *data, int dataLen)
5300{
5301 int ret = 0;
5302
5303 vos_ssr_protect(__func__);
5304 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5305 vos_ssr_unprotect(__func__);
5306
5307 return ret;
5308}
5309
5310static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305311 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305312 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305313{
Dino Myclee8843b32014-07-04 14:21:45 +05305314 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305315 struct net_device *dev = wdev->netdev;
5316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5317 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5318 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5319 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305320 struct hdd_ext_scan_context *context;
5321 tANI_U32 request_id;
5322 unsigned long rc;
5323 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305324
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305325 ENTER();
5326
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305327 if (VOS_FTM_MODE == hdd_get_conparam()) {
5328 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5329 return -EINVAL;
5330 }
5331
Dino Mycle6fb96c12014-06-10 11:52:40 +05305332 status = wlan_hdd_validate_context(pHddCtx);
5333 if (0 != status)
5334 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305335 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305336 return -EINVAL;
5337 }
Dino Myclee8843b32014-07-04 14:21:45 +05305338 /* check the EXTScan Capability */
5339 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305340 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5341 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305342 {
5343 hddLog(VOS_TRACE_LEVEL_ERROR,
5344 FL("EXTScan not enabled/supported by Firmware"));
5345 return -EINVAL;
5346 }
5347
Dino Mycle6fb96c12014-06-10 11:52:40 +05305348 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5349 data, dataLen,
5350 wlan_hdd_extscan_config_policy)) {
5351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5352 return -EINVAL;
5353 }
5354
5355 /* Parse and fetch request Id */
5356 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5358 return -EINVAL;
5359 }
5360
Dino Myclee8843b32014-07-04 14:21:45 +05305361 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305362 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305363 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305364
Dino Myclee8843b32014-07-04 14:21:45 +05305365 reqMsg.sessionId = pAdapter->sessionId;
5366 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305367
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305368 context = &pHddCtx->ext_scan_context;
5369 spin_lock(&hdd_context_lock);
5370 INIT_COMPLETION(context->response_event);
5371 context->request_id = request_id = reqMsg.requestId;
5372 spin_unlock(&hdd_context_lock);
5373
Dino Myclee8843b32014-07-04 14:21:45 +05305374 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305375 if (!HAL_STATUS_SUCCESS(status)) {
5376 hddLog(VOS_TRACE_LEVEL_ERROR,
5377 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305378 return -EINVAL;
5379 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305380
5381 /* request was sent -- wait for the response */
5382 rc = wait_for_completion_timeout(&context->response_event,
5383 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5384 if (!rc) {
5385 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5386 retval = -ETIMEDOUT;
5387 } else {
5388 spin_lock(&hdd_context_lock);
5389 if (context->request_id == request_id)
5390 retval = context->response_status;
5391 else
5392 retval = -EINVAL;
5393 spin_unlock(&hdd_context_lock);
5394 }
5395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305396 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305397 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305398}
5399
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305400static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5401 struct wireless_dev *wdev,
5402 const void *data, int dataLen)
5403{
5404 int ret = 0;
5405
5406 vos_ssr_protect(__func__);
5407 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5408 vos_ssr_unprotect(__func__);
5409
5410 return ret;
5411}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305412#endif /* WLAN_FEATURE_EXTSCAN */
5413
Atul Mittal115287b2014-07-08 13:26:33 +05305414/*EXT TDLS*/
5415static const struct nla_policy
5416wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5417{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305418 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5419 .type = NLA_UNSPEC,
5420 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305421 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5422 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5423 {.type = NLA_S32 },
5424 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5425 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5426
5427};
5428
5429static const struct nla_policy
5430wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5431{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305432 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5433 .type = NLA_UNSPEC,
5434 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305435
5436};
5437
5438static const struct nla_policy
5439wlan_hdd_tdls_config_state_change_policy[
5440 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5441{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305442 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5443 .type = NLA_UNSPEC,
5444 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305445 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5446 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305447 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5448 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5449 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305450
5451};
5452
5453static const struct nla_policy
5454wlan_hdd_tdls_config_get_status_policy[
5455 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5456{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305457 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5458 .type = NLA_UNSPEC,
5459 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305460 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5461 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305462 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5463 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5464 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305465
5466};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305467
5468static const struct nla_policy
5469wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5470{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305471 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5472 .type = NLA_UNSPEC,
5473 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305474};
5475
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305476static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305477 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305478 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305479 int data_len)
5480{
5481
5482 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5483 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305485 ENTER();
5486
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305487 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305488 return -EINVAL;
5489 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305490 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305491 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305492 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305493 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305494 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305495 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305496 return -ENOTSUPP;
5497 }
5498
5499 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5500 data, data_len, wlan_hdd_mac_config)) {
5501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5502 return -EINVAL;
5503 }
5504
5505 /* Parse and fetch mac address */
5506 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5507 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5508 return -EINVAL;
5509 }
5510
5511 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5512 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5513 VOS_MAC_ADDR_LAST_3_BYTES);
5514
Siddharth Bhal76972212014-10-15 16:22:51 +05305515 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5516
5517 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305518 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5519 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305520 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5521 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5522 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5523 {
5524 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5525 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5526 VOS_MAC_ADDRESS_LEN);
5527 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305528 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305529
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305530 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5531 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305533 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305534 return 0;
5535}
5536
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305537static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5538 struct wireless_dev *wdev,
5539 const void *data,
5540 int data_len)
5541{
5542 int ret = 0;
5543
5544 vos_ssr_protect(__func__);
5545 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5546 vos_ssr_unprotect(__func__);
5547
5548 return ret;
5549}
5550
5551static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305552 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305553 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305554 int data_len)
5555{
5556 u8 peer[6] = {0};
5557 struct net_device *dev = wdev->netdev;
5558 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5559 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5560 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5561 eHalStatus ret;
5562 tANI_S32 state;
5563 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305564 tANI_S32 global_operating_class = 0;
5565 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305566 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305567 int retVal;
5568
5569 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305570
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305571 if (!pAdapter) {
5572 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5573 return -EINVAL;
5574 }
5575
Atul Mittal115287b2014-07-08 13:26:33 +05305576 ret = wlan_hdd_validate_context(pHddCtx);
5577 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305578 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305579 return -EINVAL;
5580 }
5581 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305583 return -ENOTSUPP;
5584 }
5585 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5586 data, data_len,
5587 wlan_hdd_tdls_config_get_status_policy)) {
5588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5589 return -EINVAL;
5590 }
5591
5592 /* Parse and fetch mac address */
5593 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5595 return -EINVAL;
5596 }
5597
5598 memcpy(peer, nla_data(
5599 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5600 sizeof(peer));
5601 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5602
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305603 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305604
Atul Mittal115287b2014-07-08 13:26:33 +05305605 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305606 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305607 NLMSG_HDRLEN);
5608
5609 if (!skb) {
5610 hddLog(VOS_TRACE_LEVEL_ERROR,
5611 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5612 return -EINVAL;
5613 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305614 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 +05305615 reason,
5616 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305617 global_operating_class,
5618 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305619 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305620 if (nla_put_s32(skb,
5621 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5622 state) ||
5623 nla_put_s32(skb,
5624 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5625 reason) ||
5626 nla_put_s32(skb,
5627 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5628 global_operating_class) ||
5629 nla_put_s32(skb,
5630 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5631 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305632
5633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5634 goto nla_put_failure;
5635 }
5636
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305637 retVal = cfg80211_vendor_cmd_reply(skb);
5638 EXIT();
5639 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305640
5641nla_put_failure:
5642 kfree_skb(skb);
5643 return -EINVAL;
5644}
5645
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305646static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5647 struct wireless_dev *wdev,
5648 const void *data,
5649 int data_len)
5650{
5651 int ret = 0;
5652
5653 vos_ssr_protect(__func__);
5654 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5655 vos_ssr_unprotect(__func__);
5656
5657 return ret;
5658}
5659
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305660static int wlan_hdd_cfg80211_exttdls_callback(
5661#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5662 const tANI_U8* mac,
5663#else
5664 tANI_U8* mac,
5665#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305666 tANI_S32 state,
5667 tANI_S32 reason,
5668 void *ctx)
5669{
5670 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305671 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305672 tANI_S32 global_operating_class = 0;
5673 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305674 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305675
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305676 ENTER();
5677
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305678 if (!pAdapter) {
5679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5680 return -EINVAL;
5681 }
5682
5683 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305684 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305686 return -EINVAL;
5687 }
5688
5689 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305690 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305691 return -ENOTSUPP;
5692 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305693 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5694#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5695 NULL,
5696#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305697 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5698 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5699 GFP_KERNEL);
5700
5701 if (!skb) {
5702 hddLog(VOS_TRACE_LEVEL_ERROR,
5703 FL("cfg80211_vendor_event_alloc failed"));
5704 return -EINVAL;
5705 }
5706 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305707 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5708 reason,
5709 state,
5710 global_operating_class,
5711 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305712 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5713 MAC_ADDR_ARRAY(mac));
5714
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305715 if (nla_put(skb,
5716 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5717 VOS_MAC_ADDR_SIZE, mac) ||
5718 nla_put_s32(skb,
5719 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5720 state) ||
5721 nla_put_s32(skb,
5722 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5723 reason) ||
5724 nla_put_s32(skb,
5725 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5726 channel) ||
5727 nla_put_s32(skb,
5728 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5729 global_operating_class)
5730 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5732 goto nla_put_failure;
5733 }
5734
5735 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305736 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305737 return (0);
5738
5739nla_put_failure:
5740 kfree_skb(skb);
5741 return -EINVAL;
5742}
5743
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305744static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305745 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305746 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305747 int data_len)
5748{
5749 u8 peer[6] = {0};
5750 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305751 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5752 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5753 eHalStatus status;
5754 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305755 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305756 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305757
5758 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305759
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305760 if (!dev) {
5761 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5762 return -EINVAL;
5763 }
5764
5765 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5766 if (!pAdapter) {
5767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5768 return -EINVAL;
5769 }
5770
Atul Mittal115287b2014-07-08 13:26:33 +05305771 status = wlan_hdd_validate_context(pHddCtx);
5772 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305774 return -EINVAL;
5775 }
5776 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305777 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305778 return -ENOTSUPP;
5779 }
5780 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5781 data, data_len,
5782 wlan_hdd_tdls_config_enable_policy)) {
5783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5784 return -EINVAL;
5785 }
5786
5787 /* Parse and fetch mac address */
5788 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5790 return -EINVAL;
5791 }
5792
5793 memcpy(peer, nla_data(
5794 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5795 sizeof(peer));
5796 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5797
5798 /* Parse and fetch channel */
5799 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5801 return -EINVAL;
5802 }
5803 pReqMsg.channel = nla_get_s32(
5804 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5805 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5806
5807 /* Parse and fetch global operating class */
5808 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5810 return -EINVAL;
5811 }
5812 pReqMsg.global_operating_class = nla_get_s32(
5813 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5814 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5815 pReqMsg.global_operating_class);
5816
5817 /* Parse and fetch latency ms */
5818 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5820 return -EINVAL;
5821 }
5822 pReqMsg.max_latency_ms = nla_get_s32(
5823 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5825 pReqMsg.max_latency_ms);
5826
5827 /* Parse and fetch required bandwidth kbps */
5828 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5829 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5830 return -EINVAL;
5831 }
5832
5833 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5834 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5835 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5836 pReqMsg.min_bandwidth_kbps);
5837
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305838 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305839 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305840 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305841 wlan_hdd_cfg80211_exttdls_callback);
5842
5843 EXIT();
5844 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305845}
5846
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305847static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5848 struct wireless_dev *wdev,
5849 const void *data,
5850 int data_len)
5851{
5852 int ret = 0;
5853
5854 vos_ssr_protect(__func__);
5855 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5856 vos_ssr_unprotect(__func__);
5857
5858 return ret;
5859}
5860
5861static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305862 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305863 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305864 int data_len)
5865{
5866 u8 peer[6] = {0};
5867 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305868 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5869 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5870 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305871 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305872 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305873
5874 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305875
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305876 if (!dev) {
5877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5878 return -EINVAL;
5879 }
5880
5881 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5882 if (!pAdapter) {
5883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5884 return -EINVAL;
5885 }
5886
Atul Mittal115287b2014-07-08 13:26:33 +05305887 status = wlan_hdd_validate_context(pHddCtx);
5888 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305890 return -EINVAL;
5891 }
5892 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305894 return -ENOTSUPP;
5895 }
5896 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5897 data, data_len,
5898 wlan_hdd_tdls_config_disable_policy)) {
5899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5900 return -EINVAL;
5901 }
5902 /* Parse and fetch mac address */
5903 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5904 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5905 return -EINVAL;
5906 }
5907
5908 memcpy(peer, nla_data(
5909 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5910 sizeof(peer));
5911 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5912
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305913 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5914
5915 EXIT();
5916 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305917}
5918
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305919static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5920 struct wireless_dev *wdev,
5921 const void *data,
5922 int data_len)
5923{
5924 int ret = 0;
5925
5926 vos_ssr_protect(__func__);
5927 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5928 vos_ssr_unprotect(__func__);
5929
5930 return ret;
5931}
5932
Dasari Srinivas7875a302014-09-26 17:50:57 +05305933static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305934__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305935 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305936 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305937{
5938 struct net_device *dev = wdev->netdev;
5939 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5940 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5941 struct sk_buff *skb = NULL;
5942 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305943 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305944
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305945 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305946
5947 ret = wlan_hdd_validate_context(pHddCtx);
5948 if (0 != ret)
5949 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305950 return ret;
5951 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305952 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5953 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5954 fset |= WIFI_FEATURE_INFRA;
5955 }
5956
5957 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5958 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5959 fset |= WIFI_FEATURE_INFRA_5G;
5960 }
5961
5962#ifdef WLAN_FEATURE_P2P
5963 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5964 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5965 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5966 fset |= WIFI_FEATURE_P2P;
5967 }
5968#endif
5969
5970 /* Soft-AP is supported currently by default */
5971 fset |= WIFI_FEATURE_SOFT_AP;
5972
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305973 /* HOTSPOT is a supplicant feature, enable it by default */
5974 fset |= WIFI_FEATURE_HOTSPOT;
5975
Dasari Srinivas7875a302014-09-26 17:50:57 +05305976#ifdef WLAN_FEATURE_EXTSCAN
5977 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305978 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5979 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5980 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305981 fset |= WIFI_FEATURE_EXTSCAN;
5982 }
5983#endif
5984
Dasari Srinivas7875a302014-09-26 17:50:57 +05305985 if (sme_IsFeatureSupportedByFW(NAN)) {
5986 hddLog(LOG1, FL("NAN is supported by firmware"));
5987 fset |= WIFI_FEATURE_NAN;
5988 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305989
5990 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05305991 if (sme_IsFeatureSupportedByFW(RTT) &&
5992 pHddCtx->cfg_ini->enable_rtt_support) {
5993 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305994 fset |= WIFI_FEATURE_D2AP_RTT;
5995 }
5996
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05305997 if (sme_IsFeatureSupportedByFW(RTT3)) {
5998 hddLog(LOG1, FL("RTT3 is supported by firmware"));
5999 fset |= WIFI_FEATURE_RTT3;
6000 }
6001
Dasari Srinivas7875a302014-09-26 17:50:57 +05306002#ifdef FEATURE_WLAN_BATCH_SCAN
6003 if (fset & WIFI_FEATURE_EXTSCAN) {
6004 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6005 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6006 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6007 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6008 fset |= WIFI_FEATURE_BATCH_SCAN;
6009 }
6010#endif
6011
6012#ifdef FEATURE_WLAN_SCAN_PNO
6013 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6014 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6015 hddLog(LOG1, FL("PNO is supported by firmware"));
6016 fset |= WIFI_FEATURE_PNO;
6017 }
6018#endif
6019
6020 /* STA+STA is supported currently by default */
6021 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6022
6023#ifdef FEATURE_WLAN_TDLS
6024 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6025 sme_IsFeatureSupportedByFW(TDLS)) {
6026 hddLog(LOG1, FL("TDLS is supported by firmware"));
6027 fset |= WIFI_FEATURE_TDLS;
6028 }
6029
6030 /* TDLS_OFFCHANNEL is not supported currently by default */
6031#endif
6032
6033#ifdef WLAN_AP_STA_CONCURRENCY
6034 /* AP+STA concurrency is supported currently by default */
6035 fset |= WIFI_FEATURE_AP_STA;
6036#endif
6037
Mukul Sharma5add0532015-08-17 15:57:47 +05306038#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306039 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6040 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306041 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6042 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306043 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306044#endif
6045
Dasari Srinivas7875a302014-09-26 17:50:57 +05306046 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6047 NLMSG_HDRLEN);
6048
6049 if (!skb) {
6050 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6051 return -EINVAL;
6052 }
6053 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6054
6055 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6056 hddLog(LOGE, FL("nla put fail"));
6057 goto nla_put_failure;
6058 }
6059
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306060 ret = cfg80211_vendor_cmd_reply(skb);
6061 EXIT();
6062 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306063
6064nla_put_failure:
6065 kfree_skb(skb);
6066 return -EINVAL;
6067}
6068
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306069static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306070wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6071 struct wireless_dev *wdev,
6072 const void *data, int data_len)
6073{
6074 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306075 vos_ssr_protect(__func__);
6076 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6077 vos_ssr_unprotect(__func__);
6078
6079 return ret;
6080}
6081
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306082
6083static const struct
6084nla_policy
6085qca_wlan_vendor_wifi_logger_get_ring_data_policy
6086[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6087 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6088 = {.type = NLA_U32 },
6089};
6090
6091static int
6092 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6093 struct wireless_dev *wdev,
6094 const void *data,
6095 int data_len)
6096{
6097 int ret;
6098 VOS_STATUS status;
6099 uint32_t ring_id;
6100 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6101 struct nlattr *tb
6102 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6103
6104 ENTER();
6105
6106 ret = wlan_hdd_validate_context(hdd_ctx);
6107 if (0 != ret) {
6108 return ret;
6109 }
6110
6111 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6112 data, data_len,
6113 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6114 hddLog(LOGE, FL("Invalid attribute"));
6115 return -EINVAL;
6116 }
6117
6118 /* Parse and fetch ring id */
6119 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6120 hddLog(LOGE, FL("attr ATTR failed"));
6121 return -EINVAL;
6122 }
6123
6124 ring_id = nla_get_u32(
6125 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6126
6127 hddLog(LOG1, FL("Bug report triggered by framework"));
6128
6129 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6130 WLAN_LOG_INDICATOR_FRAMEWORK,
6131 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306132 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306133 );
6134 if (VOS_STATUS_SUCCESS != status) {
6135 hddLog(LOGE, FL("Failed to trigger bug report"));
6136
6137 return -EINVAL;
6138 }
6139
6140 return 0;
6141
6142
6143}
6144
6145
6146static int
6147 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6148 struct wireless_dev *wdev,
6149 const void *data,
6150 int data_len)
6151{
6152 int ret = 0;
6153
6154 vos_ssr_protect(__func__);
6155 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6156 wdev, data, data_len);
6157 vos_ssr_unprotect(__func__);
6158
6159 return ret;
6160
6161}
6162
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306163#define MAX_CONCURRENT_MATRIX \
6164 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6165#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6166 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6167static const struct nla_policy
6168wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6169 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6170};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306171
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306172static int
6173__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306174 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306175 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306176{
6177 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6178 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306179 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306180 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306181 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6182 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306183
6184 ENTER();
6185
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306186 ret = wlan_hdd_validate_context(pHddCtx);
6187 if (0 != ret)
6188 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306189 return ret;
6190 }
6191
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306192 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6193 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306194 hddLog(LOGE, FL("Invalid ATTR"));
6195 return -EINVAL;
6196 }
6197
6198 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306199 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306200 hddLog(LOGE, FL("Attr max feature set size failed"));
6201 return -EINVAL;
6202 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306203 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306204 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6205
6206 /* Fill feature combination matrix */
6207 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306208 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6209 WIFI_FEATURE_P2P;
6210
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306211 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6212 WIFI_FEATURE_SOFT_AP;
6213
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306214 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6215 WIFI_FEATURE_SOFT_AP;
6216
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306217 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6218 WIFI_FEATURE_SOFT_AP |
6219 WIFI_FEATURE_P2P;
6220
6221 /* Add more feature combinations here */
6222
6223 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6224 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6225 hddLog(LOG1, "Feature set matrix");
6226 for (i = 0; i < feature_sets; i++)
6227 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6228
6229 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6230 sizeof(u32) * feature_sets +
6231 NLMSG_HDRLEN);
6232
6233 if (reply_skb) {
6234 if (nla_put_u32(reply_skb,
6235 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6236 feature_sets) ||
6237 nla_put(reply_skb,
6238 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6239 sizeof(u32) * feature_sets, feature_set_matrix)) {
6240 hddLog(LOGE, FL("nla put fail"));
6241 kfree_skb(reply_skb);
6242 return -EINVAL;
6243 }
6244
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306245 ret = cfg80211_vendor_cmd_reply(reply_skb);
6246 EXIT();
6247 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306248 }
6249 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6250 return -ENOMEM;
6251
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306252}
6253
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306254#undef MAX_CONCURRENT_MATRIX
6255#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6256
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306257static int
6258wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6259 struct wireless_dev *wdev,
6260 const void *data, int data_len)
6261{
6262 int ret = 0;
6263
6264 vos_ssr_protect(__func__);
6265 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6266 data_len);
6267 vos_ssr_unprotect(__func__);
6268
6269 return ret;
6270}
6271
c_manjeecfd1efb2015-09-25 19:32:34 +05306272
6273static int
6274__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6275 struct wireless_dev *wdev,
6276 const void *data, int data_len)
6277{
6278 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6279 int ret;
6280 ENTER();
6281
6282 ret = wlan_hdd_validate_context(pHddCtx);
6283 if (0 != ret)
6284 {
6285 return ret;
6286 }
6287
6288 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6289 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6290 {
6291 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306292 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306293 }
6294 /*call common API for FW mem dump req*/
6295 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6296
Abhishek Singhc783fa72015-12-09 18:07:34 +05306297 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306298 {
6299 /*indicate to userspace the status of fw mem dump */
6300 wlan_indicate_mem_dump_complete(true);
6301 }
6302 else
6303 {
6304 /*else send failure to userspace */
6305 wlan_indicate_mem_dump_complete(false);
6306 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306307 EXIT();
6308 return ret;
6309}
6310
6311/**
6312 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6313 * @wiphy: pointer to wireless wiphy structure.
6314 * @wdev: pointer to wireless_dev structure.
6315 * @data: Pointer to the NL data.
6316 * @data_len:Length of @data
6317 *
6318 * This is called when wlan driver needs to get the firmware memory dump
6319 * via vendor specific command.
6320 *
6321 * Return: 0 on success, error number otherwise.
6322 */
6323
6324static int
6325wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6326 struct wireless_dev *wdev,
6327 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306328{
6329 int ret = 0;
6330 vos_ssr_protect(__func__);
6331 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6332 data_len);
6333 vos_ssr_unprotect(__func__);
6334 return ret;
6335}
c_manjeecfd1efb2015-09-25 19:32:34 +05306336
Sushant Kaushik8e644982015-09-23 12:18:54 +05306337static const struct
6338nla_policy
6339qca_wlan_vendor_wifi_logger_start_policy
6340[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6341 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6342 = {.type = NLA_U32 },
6343 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6344 = {.type = NLA_U32 },
6345 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6346 = {.type = NLA_U32 },
6347};
6348
6349/**
6350 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6351 * or disable the collection of packet statistics from the firmware
6352 * @wiphy: WIPHY structure pointer
6353 * @wdev: Wireless device structure pointer
6354 * @data: Pointer to the data received
6355 * @data_len: Length of the data received
6356 *
6357 * This function is used to enable or disable the collection of packet
6358 * statistics from the firmware
6359 *
6360 * Return: 0 on success and errno on failure
6361 */
6362static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6363 struct wireless_dev *wdev,
6364 const void *data,
6365 int data_len)
6366{
6367 eHalStatus status;
6368 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6369 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6370 tAniWifiStartLog start_log;
6371
6372 status = wlan_hdd_validate_context(hdd_ctx);
6373 if (0 != status) {
6374 return -EINVAL;
6375 }
6376
6377 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6378 data, data_len,
6379 qca_wlan_vendor_wifi_logger_start_policy)) {
6380 hddLog(LOGE, FL("Invalid attribute"));
6381 return -EINVAL;
6382 }
6383
6384 /* Parse and fetch ring id */
6385 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6386 hddLog(LOGE, FL("attr ATTR failed"));
6387 return -EINVAL;
6388 }
6389 start_log.ringId = nla_get_u32(
6390 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6391 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6392
6393 /* Parse and fetch verbose level */
6394 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6395 hddLog(LOGE, FL("attr verbose_level failed"));
6396 return -EINVAL;
6397 }
6398 start_log.verboseLevel = nla_get_u32(
6399 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6400 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6401
6402 /* Parse and fetch flag */
6403 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6404 hddLog(LOGE, FL("attr flag failed"));
6405 return -EINVAL;
6406 }
6407 start_log.flag = nla_get_u32(
6408 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6409 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6410
6411 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306412 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6413 !vos_isPktStatsEnabled()))
6414
Sushant Kaushik8e644982015-09-23 12:18:54 +05306415 {
6416 hddLog(LOGE, FL("per pkt stats not enabled"));
6417 return -EINVAL;
6418 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306419
Sushant Kaushik33200572015-08-05 16:46:20 +05306420 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306421 return 0;
6422}
6423
6424/**
6425 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6426 * or disable the collection of packet statistics from the firmware
6427 * @wiphy: WIPHY structure pointer
6428 * @wdev: Wireless device structure pointer
6429 * @data: Pointer to the data received
6430 * @data_len: Length of the data received
6431 *
6432 * This function is used to enable or disable the collection of packet
6433 * statistics from the firmware
6434 *
6435 * Return: 0 on success and errno on failure
6436 */
6437static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6438 struct wireless_dev *wdev,
6439 const void *data,
6440 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306441{
6442 int ret = 0;
6443
6444 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306445
6446 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6447 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306448 vos_ssr_unprotect(__func__);
6449
6450 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306451}
6452
6453
Agarwal Ashish738843c2014-09-25 12:27:56 +05306454static const struct nla_policy
6455wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6456 +1] =
6457{
6458 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6459};
6460
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306461static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306462 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306463 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306464 int data_len)
6465{
6466 struct net_device *dev = wdev->netdev;
6467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6468 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6469 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6470 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6471 eHalStatus status;
6472 u32 dfsFlag = 0;
6473
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306474 ENTER();
6475
Agarwal Ashish738843c2014-09-25 12:27:56 +05306476 status = wlan_hdd_validate_context(pHddCtx);
6477 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306478 return -EINVAL;
6479 }
6480 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6481 data, data_len,
6482 wlan_hdd_set_no_dfs_flag_config_policy)) {
6483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6484 return -EINVAL;
6485 }
6486
6487 /* Parse and fetch required bandwidth kbps */
6488 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6489 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6490 return -EINVAL;
6491 }
6492
6493 dfsFlag = nla_get_u32(
6494 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6495 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6496 dfsFlag);
6497
6498 pHddCtx->disable_dfs_flag = dfsFlag;
6499
6500 sme_disable_dfs_channel(hHal, dfsFlag);
6501 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306502
6503 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306504 return 0;
6505}
Atul Mittal115287b2014-07-08 13:26:33 +05306506
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306507static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6508 struct wireless_dev *wdev,
6509 const void *data,
6510 int data_len)
6511{
6512 int ret = 0;
6513
6514 vos_ssr_protect(__func__);
6515 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6516 vos_ssr_unprotect(__func__);
6517
6518 return ret;
6519
6520}
6521
Mukul Sharma2a271632014-10-13 14:59:01 +05306522const struct
6523nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6524{
6525 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306526 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6527 .type = NLA_UNSPEC,
6528 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306529};
6530
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306531static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306532 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306533{
6534
6535 u8 bssid[6] = {0};
6536 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6537 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6538 eHalStatus status = eHAL_STATUS_SUCCESS;
6539 v_U32_t isFwrRoamEnabled = FALSE;
6540 int ret;
6541
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306542 ENTER();
6543
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306544 ret = wlan_hdd_validate_context(pHddCtx);
6545 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306546 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306547 }
6548
6549 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6550 data, data_len,
6551 qca_wlan_vendor_attr);
6552 if (ret){
6553 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6554 return -EINVAL;
6555 }
6556
6557 /* Parse and fetch Enable flag */
6558 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6560 return -EINVAL;
6561 }
6562
6563 isFwrRoamEnabled = nla_get_u32(
6564 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6565
6566 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6567
6568 /* Parse and fetch bssid */
6569 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6571 return -EINVAL;
6572 }
6573
6574 memcpy(bssid, nla_data(
6575 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6576 sizeof(bssid));
6577 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6578
6579 //Update roaming
6580 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306581 if (!HAL_STATUS_SUCCESS(status)) {
6582 hddLog(LOGE,
6583 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6584 return -EINVAL;
6585 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306586 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306587 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306588}
6589
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306590static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6591 struct wireless_dev *wdev, const void *data, int data_len)
6592{
6593 int ret = 0;
6594
6595 vos_ssr_protect(__func__);
6596 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6597 vos_ssr_unprotect(__func__);
6598
6599 return ret;
6600}
6601
Sushant Kaushik847890c2015-09-28 16:05:17 +05306602static const struct
6603nla_policy
6604qca_wlan_vendor_get_wifi_info_policy[
6605 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6606 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6607 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6608};
6609
6610
6611/**
6612 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6613 * @wiphy: pointer to wireless wiphy structure.
6614 * @wdev: pointer to wireless_dev structure.
6615 * @data: Pointer to the data to be passed via vendor interface
6616 * @data_len:Length of the data to be passed
6617 *
6618 * This is called when wlan driver needs to send wifi driver related info
6619 * (driver/fw version) to the user space application upon request.
6620 *
6621 * Return: Return the Success or Failure code.
6622 */
6623static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6624 struct wireless_dev *wdev,
6625 const void *data, int data_len)
6626{
6627 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6628 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6629 tSirVersionString version;
6630 uint32 version_len;
6631 uint8 attr;
6632 int status;
6633 struct sk_buff *reply_skb = NULL;
6634
6635 if (VOS_FTM_MODE == hdd_get_conparam()) {
6636 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6637 return -EINVAL;
6638 }
6639
6640 status = wlan_hdd_validate_context(hdd_ctx);
6641 if (0 != status) {
6642 hddLog(LOGE, FL("HDD context is not valid"));
6643 return -EINVAL;
6644 }
6645
6646 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6647 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6648 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6649 return -EINVAL;
6650 }
6651
6652 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6653 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6654 QWLAN_VERSIONSTR);
6655 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6656 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6657 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6658 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6659 hdd_ctx->fw_Version);
6660 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6661 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6662 } else {
6663 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6664 return -EINVAL;
6665 }
6666
6667 version_len = strlen(version);
6668 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6669 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6670 if (!reply_skb) {
6671 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6672 return -ENOMEM;
6673 }
6674
6675 if (nla_put(reply_skb, attr, version_len, version)) {
6676 hddLog(LOGE, FL("nla put fail"));
6677 kfree_skb(reply_skb);
6678 return -EINVAL;
6679 }
6680
6681 return cfg80211_vendor_cmd_reply(reply_skb);
6682}
6683
6684/**
6685 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6686 * @wiphy: pointer to wireless wiphy structure.
6687 * @wdev: pointer to wireless_dev structure.
6688 * @data: Pointer to the data to be passed via vendor interface
6689 * @data_len:Length of the data to be passed
6690 * @data_len: Length of the data received
6691 *
6692 * This function is used to enable or disable the collection of packet
6693 * statistics from the firmware
6694 *
6695 * Return: 0 on success and errno on failure
6696 */
6697
6698static int
6699wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6700 struct wireless_dev *wdev,
6701 const void *data, int data_len)
6702
6703
6704{
6705 int ret = 0;
6706
6707 vos_ssr_protect(__func__);
6708 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6709 wdev, data, data_len);
6710 vos_ssr_unprotect(__func__);
6711
6712 return ret;
6713}
6714
6715
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306716/*
6717 * define short names for the global vendor params
6718 * used by __wlan_hdd_cfg80211_monitor_rssi()
6719 */
6720#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6721#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6722#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6723#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6724#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6725
6726/**---------------------------------------------------------------------------
6727
6728 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6729 monitor start is completed successfully.
6730
6731 \return - None
6732
6733 --------------------------------------------------------------------------*/
6734void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6735{
6736 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6737
6738 if (NULL == pHddCtx)
6739 {
6740 hddLog(VOS_TRACE_LEVEL_ERROR,
6741 "%s: HDD context is NULL",__func__);
6742 return;
6743 }
6744
6745 if (VOS_STATUS_SUCCESS == status)
6746 {
6747 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6748 }
6749 else
6750 {
6751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6752 }
6753
6754 return;
6755}
6756
6757/**---------------------------------------------------------------------------
6758
6759 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6760 stop is completed successfully.
6761
6762 \return - None
6763
6764 --------------------------------------------------------------------------*/
6765void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6766{
6767 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6768
6769 if (NULL == pHddCtx)
6770 {
6771 hddLog(VOS_TRACE_LEVEL_ERROR,
6772 "%s: HDD context is NULL",__func__);
6773 return;
6774 }
6775
6776 if (VOS_STATUS_SUCCESS == status)
6777 {
6778 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6779 }
6780 else
6781 {
6782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6783 }
6784
6785 return;
6786}
6787
6788/**
6789 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6790 * @wiphy: Pointer to wireless phy
6791 * @wdev: Pointer to wireless device
6792 * @data: Pointer to data
6793 * @data_len: Data length
6794 *
6795 * Return: 0 on success, negative errno on failure
6796 */
6797
6798static int
6799__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6800 struct wireless_dev *wdev,
6801 const void *data,
6802 int data_len)
6803{
6804 struct net_device *dev = wdev->netdev;
6805 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6806 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6807 hdd_station_ctx_t *pHddStaCtx;
6808 struct nlattr *tb[PARAM_MAX + 1];
6809 tpSirRssiMonitorReq pReq;
6810 eHalStatus status;
6811 int ret;
6812 uint32_t control;
6813 static const struct nla_policy policy[PARAM_MAX + 1] = {
6814 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6815 [PARAM_CONTROL] = { .type = NLA_U32 },
6816 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6817 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6818 };
6819
6820 ENTER();
6821
6822 ret = wlan_hdd_validate_context(hdd_ctx);
6823 if (0 != ret) {
6824 return -EINVAL;
6825 }
6826
6827 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6828 hddLog(LOGE, FL("Not in Connected state!"));
6829 return -ENOTSUPP;
6830 }
6831
6832 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6833 hddLog(LOGE, FL("Invalid ATTR"));
6834 return -EINVAL;
6835 }
6836
6837 if (!tb[PARAM_REQUEST_ID]) {
6838 hddLog(LOGE, FL("attr request id failed"));
6839 return -EINVAL;
6840 }
6841
6842 if (!tb[PARAM_CONTROL]) {
6843 hddLog(LOGE, FL("attr control failed"));
6844 return -EINVAL;
6845 }
6846
6847 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6848
6849 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6850 if(NULL == pReq)
6851 {
6852 hddLog(LOGE,
6853 FL("vos_mem_alloc failed "));
6854 return eHAL_STATUS_FAILED_ALLOC;
6855 }
6856 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6857
6858 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6859 pReq->sessionId = pAdapter->sessionId;
6860 pReq->rssiMonitorCbContext = hdd_ctx;
6861 control = nla_get_u32(tb[PARAM_CONTROL]);
6862 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6863
6864 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6865 pReq->requestId, pReq->sessionId, control);
6866
6867 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6868 if (!tb[PARAM_MIN_RSSI]) {
6869 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306870 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306871 }
6872
6873 if (!tb[PARAM_MAX_RSSI]) {
6874 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306875 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306876 }
6877
6878 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6879 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6880 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6881
6882 if (!(pReq->minRssi < pReq->maxRssi)) {
6883 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6884 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306885 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306886 }
6887 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6888 pReq->minRssi, pReq->maxRssi);
6889 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6890
6891 }
6892 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6893 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6894 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6895 }
6896 else {
6897 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306898 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306899 }
6900
6901 if (!HAL_STATUS_SUCCESS(status)) {
6902 hddLog(LOGE,
6903 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306904 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306905 }
6906
6907 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306908fail:
6909 vos_mem_free(pReq);
6910 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306911}
6912
6913/*
6914 * done with short names for the global vendor params
6915 * used by __wlan_hdd_cfg80211_monitor_rssi()
6916 */
6917#undef PARAM_MAX
6918#undef PARAM_CONTROL
6919#undef PARAM_REQUEST_ID
6920#undef PARAM_MAX_RSSI
6921#undef PARAM_MIN_RSSI
6922
6923/**
6924 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6925 * @wiphy: wiphy structure pointer
6926 * @wdev: Wireless device structure pointer
6927 * @data: Pointer to the data received
6928 * @data_len: Length of @data
6929 *
6930 * Return: 0 on success; errno on failure
6931 */
6932static int
6933wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6934 const void *data, int data_len)
6935{
6936 int ret;
6937
6938 vos_ssr_protect(__func__);
6939 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6940 vos_ssr_unprotect(__func__);
6941
6942 return ret;
6943}
6944
6945/**
6946 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6947 * @hddctx: HDD context
6948 * @data: rssi breached event data
6949 *
6950 * This function reads the rssi breached event %data and fill in the skb with
6951 * NL attributes and send up the NL event.
6952 * This callback execute in atomic context and must not invoke any
6953 * blocking calls.
6954 *
6955 * Return: none
6956 */
6957void hdd_rssi_threshold_breached_cb(void *hddctx,
6958 struct rssi_breach_event *data)
6959{
6960 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6961 int status;
6962 struct sk_buff *skb;
6963
6964 ENTER();
6965 status = wlan_hdd_validate_context(pHddCtx);
6966
6967 if (0 != status) {
6968 return;
6969 }
6970
6971 if (!data) {
6972 hddLog(LOGE, FL("data is null"));
6973 return;
6974 }
6975
6976 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6977#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6978 NULL,
6979#endif
6980 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6981 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6982 GFP_KERNEL);
6983
6984 if (!skb) {
6985 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6986 return;
6987 }
6988
6989 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6990 data->request_id, data->curr_rssi);
6991 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6992 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6993
6994 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6995 data->request_id) ||
6996 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6997 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6998 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6999 data->curr_rssi)) {
7000 hddLog(LOGE, FL("nla put fail"));
7001 goto fail;
7002 }
7003
7004 cfg80211_vendor_event(skb, GFP_KERNEL);
7005 return;
7006
7007fail:
7008 kfree_skb(skb);
7009 return;
7010}
7011
7012
7013
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307014/**
7015 * __wlan_hdd_cfg80211_setband() - set band
7016 * @wiphy: Pointer to wireless phy
7017 * @wdev: Pointer to wireless device
7018 * @data: Pointer to data
7019 * @data_len: Data length
7020 *
7021 * Return: 0 on success, negative errno on failure
7022 */
7023static int
7024__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7025 struct wireless_dev *wdev,
7026 const void *data,
7027 int data_len)
7028{
7029 struct net_device *dev = wdev->netdev;
7030 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7031 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7032 int ret;
7033 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7034 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7035
7036 ENTER();
7037
7038 ret = wlan_hdd_validate_context(hdd_ctx);
7039 if (0 != ret) {
7040 hddLog(LOGE, FL("HDD context is not valid"));
7041 return ret;
7042 }
7043
7044 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7045 policy)) {
7046 hddLog(LOGE, FL("Invalid ATTR"));
7047 return -EINVAL;
7048 }
7049
7050 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7051 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7052 return -EINVAL;
7053 }
7054
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307055 hdd_ctx->isSetBandByNL = TRUE;
7056 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307057 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307058 hdd_ctx->isSetBandByNL = FALSE;
7059
7060 EXIT();
7061 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307062}
7063
7064/**
7065 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7066 * @wiphy: wiphy structure pointer
7067 * @wdev: Wireless device structure pointer
7068 * @data: Pointer to the data received
7069 * @data_len: Length of @data
7070 *
7071 * Return: 0 on success; errno on failure
7072 */
7073static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7074 struct wireless_dev *wdev,
7075 const void *data,
7076 int data_len)
7077{
7078 int ret = 0;
7079
7080 vos_ssr_protect(__func__);
7081 ret = __wlan_hdd_cfg80211_setband(wiphy,
7082 wdev, data, data_len);
7083 vos_ssr_unprotect(__func__);
7084
7085 return ret;
7086}
7087
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307088#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7089/**
7090 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7091 * @hdd_ctx: HDD context
7092 * @request_id: [input] request id
7093 * @pattern_id: [output] pattern id
7094 *
7095 * This function loops through request id to pattern id array
7096 * if the slot is available, store the request id and return pattern id
7097 * if entry exists, return the pattern id
7098 *
7099 * Return: 0 on success and errno on failure
7100 */
7101static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7102 uint32_t request_id,
7103 uint8_t *pattern_id)
7104{
7105 uint32_t i;
7106
7107 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7108 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7109 {
7110 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7111 {
7112 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7113 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7114 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7115 return 0;
7116 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7117 request_id) {
7118 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7119 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7120 return 0;
7121 }
7122 }
7123 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7124 return -EINVAL;
7125}
7126
7127/**
7128 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7129 * @hdd_ctx: HDD context
7130 * @request_id: [input] request id
7131 * @pattern_id: [output] pattern id
7132 *
7133 * This function loops through request id to pattern id array
7134 * reset request id to 0 (slot available again) and
7135 * return pattern id
7136 *
7137 * Return: 0 on success and errno on failure
7138 */
7139static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7140 uint32_t request_id,
7141 uint8_t *pattern_id)
7142{
7143 uint32_t i;
7144
7145 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7146 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7147 {
7148 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7149 {
7150 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7151 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7152 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7153 return 0;
7154 }
7155 }
7156 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7157 return -EINVAL;
7158}
7159
7160
7161/*
7162 * define short names for the global vendor params
7163 * used by __wlan_hdd_cfg80211_offloaded_packets()
7164 */
7165#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7166#define PARAM_REQUEST_ID \
7167 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7168#define PARAM_CONTROL \
7169 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7170#define PARAM_IP_PACKET \
7171 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7172#define PARAM_SRC_MAC_ADDR \
7173 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7174#define PARAM_DST_MAC_ADDR \
7175 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7176#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7177
7178/**
7179 * wlan_hdd_add_tx_ptrn() - add tx pattern
7180 * @adapter: adapter pointer
7181 * @hdd_ctx: hdd context
7182 * @tb: nl attributes
7183 *
7184 * This function reads the NL attributes and forms a AddTxPtrn message
7185 * posts it to SME.
7186 *
7187 */
7188static int
7189wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7190 struct nlattr **tb)
7191{
7192 struct sSirAddPeriodicTxPtrn *add_req;
7193 eHalStatus status;
7194 uint32_t request_id, ret, len;
7195 uint8_t pattern_id = 0;
7196 v_MACADDR_t dst_addr;
7197 uint16_t eth_type = htons(ETH_P_IP);
7198
7199 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7200 {
7201 hddLog(LOGE, FL("Not in Connected state!"));
7202 return -ENOTSUPP;
7203 }
7204
7205 add_req = vos_mem_malloc(sizeof(*add_req));
7206 if (!add_req)
7207 {
7208 hddLog(LOGE, FL("memory allocation failed"));
7209 return -ENOMEM;
7210 }
7211
7212 /* Parse and fetch request Id */
7213 if (!tb[PARAM_REQUEST_ID])
7214 {
7215 hddLog(LOGE, FL("attr request id failed"));
7216 goto fail;
7217 }
7218
7219 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7220 hddLog(LOG1, FL("Request Id: %u"), request_id);
7221 if (request_id == 0)
7222 {
7223 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307224 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307225 }
7226
7227 if (!tb[PARAM_PERIOD])
7228 {
7229 hddLog(LOGE, FL("attr period failed"));
7230 goto fail;
7231 }
7232 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7233 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7234 if (add_req->usPtrnIntervalMs == 0)
7235 {
7236 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7237 goto fail;
7238 }
7239
7240 if (!tb[PARAM_SRC_MAC_ADDR])
7241 {
7242 hddLog(LOGE, FL("attr source mac address failed"));
7243 goto fail;
7244 }
7245 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7246 VOS_MAC_ADDR_SIZE);
7247 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7248 MAC_ADDR_ARRAY(add_req->macAddress));
7249
7250 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7251 VOS_MAC_ADDR_SIZE))
7252 {
7253 hddLog(LOGE,
7254 FL("input src mac address and connected ap bssid are different"));
7255 goto fail;
7256 }
7257
7258 if (!tb[PARAM_DST_MAC_ADDR])
7259 {
7260 hddLog(LOGE, FL("attr dst mac address failed"));
7261 goto fail;
7262 }
7263 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7264 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7265 MAC_ADDR_ARRAY(dst_addr.bytes));
7266
7267 if (!tb[PARAM_IP_PACKET])
7268 {
7269 hddLog(LOGE, FL("attr ip packet failed"));
7270 goto fail;
7271 }
7272 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7273 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7274
7275 if (add_req->ucPtrnSize < 0 ||
7276 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7277 HDD_ETH_HEADER_LEN))
7278 {
7279 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7280 add_req->ucPtrnSize);
7281 goto fail;
7282 }
7283
7284 len = 0;
7285 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7286 len += VOS_MAC_ADDR_SIZE;
7287 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7288 VOS_MAC_ADDR_SIZE);
7289 len += VOS_MAC_ADDR_SIZE;
7290 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7291 len += 2;
7292
7293 /*
7294 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7295 * ------------------------------------------------------------
7296 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7297 * ------------------------------------------------------------
7298 */
7299 vos_mem_copy(&add_req->ucPattern[len],
7300 nla_data(tb[PARAM_IP_PACKET]),
7301 add_req->ucPtrnSize);
7302 add_req->ucPtrnSize += len;
7303
7304 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7305 add_req->ucPattern, add_req->ucPtrnSize);
7306
7307 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7308 if (ret)
7309 {
7310 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7311 goto fail;
7312 }
7313 add_req->ucPtrnId = pattern_id;
7314 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7315
7316 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7317 if (!HAL_STATUS_SUCCESS(status))
7318 {
7319 hddLog(LOGE,
7320 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7321 goto fail;
7322 }
7323
7324 EXIT();
7325 vos_mem_free(add_req);
7326 return 0;
7327
7328fail:
7329 vos_mem_free(add_req);
7330 return -EINVAL;
7331}
7332
7333/**
7334 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7335 * @adapter: adapter pointer
7336 * @hdd_ctx: hdd context
7337 * @tb: nl attributes
7338 *
7339 * This function reads the NL attributes and forms a DelTxPtrn message
7340 * posts it to SME.
7341 *
7342 */
7343static int
7344wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7345 struct nlattr **tb)
7346{
7347 struct sSirDelPeriodicTxPtrn *del_req;
7348 eHalStatus status;
7349 uint32_t request_id, ret;
7350 uint8_t pattern_id = 0;
7351
7352 /* Parse and fetch request Id */
7353 if (!tb[PARAM_REQUEST_ID])
7354 {
7355 hddLog(LOGE, FL("attr request id failed"));
7356 return -EINVAL;
7357 }
7358 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7359 if (request_id == 0)
7360 {
7361 hddLog(LOGE, FL("request_id cannot be zero"));
7362 return -EINVAL;
7363 }
7364
7365 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7366 if (ret)
7367 {
7368 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7369 return -EINVAL;
7370 }
7371
7372 del_req = vos_mem_malloc(sizeof(*del_req));
7373 if (!del_req)
7374 {
7375 hddLog(LOGE, FL("memory allocation failed"));
7376 return -ENOMEM;
7377 }
7378
7379 vos_mem_set(del_req, sizeof(*del_req), 0);
7380 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7381 VOS_MAC_ADDR_SIZE);
7382 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7383 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7384 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7385 request_id, pattern_id, del_req->ucPatternIdBitmap);
7386
7387 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7388 if (!HAL_STATUS_SUCCESS(status))
7389 {
7390 hddLog(LOGE,
7391 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7392 goto fail;
7393 }
7394
7395 EXIT();
7396 vos_mem_free(del_req);
7397 return 0;
7398
7399fail:
7400 vos_mem_free(del_req);
7401 return -EINVAL;
7402}
7403
7404
7405/**
7406 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7407 * @wiphy: Pointer to wireless phy
7408 * @wdev: Pointer to wireless device
7409 * @data: Pointer to data
7410 * @data_len: Data length
7411 *
7412 * Return: 0 on success, negative errno on failure
7413 */
7414static int
7415__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7416 struct wireless_dev *wdev,
7417 const void *data,
7418 int data_len)
7419{
7420 struct net_device *dev = wdev->netdev;
7421 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7422 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7423 struct nlattr *tb[PARAM_MAX + 1];
7424 uint8_t control;
7425 int ret;
7426 static const struct nla_policy policy[PARAM_MAX + 1] =
7427 {
7428 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7429 [PARAM_CONTROL] = { .type = NLA_U32 },
7430 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7431 .len = VOS_MAC_ADDR_SIZE },
7432 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7433 .len = VOS_MAC_ADDR_SIZE },
7434 [PARAM_PERIOD] = { .type = NLA_U32 },
7435 };
7436
7437 ENTER();
7438
7439 ret = wlan_hdd_validate_context(hdd_ctx);
7440 if (0 != ret)
7441 {
7442 hddLog(LOGE, FL("HDD context is not valid"));
7443 return ret;
7444 }
7445
7446 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7447 {
7448 hddLog(LOGE,
7449 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7450 return -ENOTSUPP;
7451 }
7452
7453 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7454 {
7455 hddLog(LOGE, FL("Invalid ATTR"));
7456 return -EINVAL;
7457 }
7458
7459 if (!tb[PARAM_CONTROL])
7460 {
7461 hddLog(LOGE, FL("attr control failed"));
7462 return -EINVAL;
7463 }
7464 control = nla_get_u32(tb[PARAM_CONTROL]);
7465 hddLog(LOG1, FL("Control: %d"), control);
7466
7467 if (control == WLAN_START_OFFLOADED_PACKETS)
7468 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7469 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7470 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7471 else
7472 {
7473 hddLog(LOGE, FL("Invalid control: %d"), control);
7474 return -EINVAL;
7475 }
7476}
7477
7478/*
7479 * done with short names for the global vendor params
7480 * used by __wlan_hdd_cfg80211_offloaded_packets()
7481 */
7482#undef PARAM_MAX
7483#undef PARAM_REQUEST_ID
7484#undef PARAM_CONTROL
7485#undef PARAM_IP_PACKET
7486#undef PARAM_SRC_MAC_ADDR
7487#undef PARAM_DST_MAC_ADDR
7488#undef PARAM_PERIOD
7489
7490/**
7491 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7492 * @wiphy: wiphy structure pointer
7493 * @wdev: Wireless device structure pointer
7494 * @data: Pointer to the data received
7495 * @data_len: Length of @data
7496 *
7497 * Return: 0 on success; errno on failure
7498 */
7499static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7500 struct wireless_dev *wdev,
7501 const void *data,
7502 int data_len)
7503{
7504 int ret = 0;
7505
7506 vos_ssr_protect(__func__);
7507 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7508 wdev, data, data_len);
7509 vos_ssr_unprotect(__func__);
7510
7511 return ret;
7512}
7513#endif
7514
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307515static const struct
7516nla_policy
7517qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307518 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7519 .type = NLA_BINARY,
7520 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307521};
7522
7523/**
7524 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7525 * get link properties like nss, rate flags and operating frequency for
7526 * the connection with the given peer.
7527 * @wiphy: WIPHY structure pointer
7528 * @wdev: Wireless device structure pointer
7529 * @data: Pointer to the data received
7530 * @data_len: Length of the data received
7531 *
7532 * This function return the above link properties on success.
7533 *
7534 * Return: 0 on success and errno on failure
7535 */
7536static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7537 struct wireless_dev *wdev,
7538 const void *data,
7539 int data_len)
7540{
7541 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7542 struct net_device *dev = wdev->netdev;
7543 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7544 hdd_station_ctx_t *hdd_sta_ctx;
7545 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7546 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7547 uint32_t sta_id;
7548 struct sk_buff *reply_skb;
7549 uint32_t rate_flags = 0;
7550 uint8_t nss;
7551 uint8_t final_rate_flags = 0;
7552 uint32_t freq;
7553 v_CONTEXT_t pVosContext = NULL;
7554 ptSapContext pSapCtx = NULL;
7555
7556 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7557 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7558 return -EINVAL;
7559 }
7560
7561 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7562 qca_wlan_vendor_attr_policy)) {
7563 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7564 return -EINVAL;
7565 }
7566
7567 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7568 hddLog(VOS_TRACE_LEVEL_ERROR,
7569 FL("Attribute peerMac not provided for mode=%d"),
7570 adapter->device_mode);
7571 return -EINVAL;
7572 }
7573
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307574 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7575 hddLog(VOS_TRACE_LEVEL_ERROR,
7576 FL("Attribute peerMac is invalid=%d"),
7577 adapter->device_mode);
7578 return -EINVAL;
7579 }
7580
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307581 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7582 sizeof(peer_mac));
7583 hddLog(VOS_TRACE_LEVEL_INFO,
7584 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7585 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7586
7587 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7588 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7589 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7590 if ((hdd_sta_ctx->conn_info.connState !=
7591 eConnectionState_Associated) ||
7592 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7593 VOS_MAC_ADDRESS_LEN)) {
7594 hddLog(VOS_TRACE_LEVEL_ERROR,
7595 FL("Not Associated to mac "MAC_ADDRESS_STR),
7596 MAC_ADDR_ARRAY(peer_mac));
7597 return -EINVAL;
7598 }
7599
7600 nss = 1; //pronto supports only one spatial stream
7601 freq = vos_chan_to_freq(
7602 hdd_sta_ctx->conn_info.operationChannel);
7603 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7604
7605 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7606 adapter->device_mode == WLAN_HDD_SOFTAP) {
7607
7608 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7609 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7610 if(pSapCtx == NULL){
7611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7612 FL("psapCtx is NULL"));
7613 return -ENOENT;
7614 }
7615
7616
7617 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7618 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7619 !vos_is_macaddr_broadcast(
7620 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7621 vos_mem_compare(
7622 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7623 peer_mac, VOS_MAC_ADDRESS_LEN))
7624 break;
7625 }
7626
7627 if (WLAN_MAX_STA_COUNT == sta_id) {
7628 hddLog(VOS_TRACE_LEVEL_ERROR,
7629 FL("No active peer with mac="MAC_ADDRESS_STR),
7630 MAC_ADDR_ARRAY(peer_mac));
7631 return -EINVAL;
7632 }
7633
7634 nss = 1; //pronto supports only one spatial stream
7635 freq = vos_chan_to_freq(
7636 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7637 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7638 } else {
7639 hddLog(VOS_TRACE_LEVEL_ERROR,
7640 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7641 MAC_ADDR_ARRAY(peer_mac));
7642 return -EINVAL;
7643 }
7644
7645 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7646 if (rate_flags & eHAL_TX_RATE_VHT80) {
7647 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7648 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7649 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7650 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7651 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7652 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7653 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7654 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7655 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7656 if (rate_flags & eHAL_TX_RATE_HT40)
7657 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7658 }
7659
7660 if (rate_flags & eHAL_TX_RATE_SGI) {
7661 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7662 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7663 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7664 }
7665 }
7666
7667 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7668 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7669
7670 if (NULL == reply_skb) {
7671 hddLog(VOS_TRACE_LEVEL_ERROR,
7672 FL("getLinkProperties: skb alloc failed"));
7673 return -EINVAL;
7674 }
7675
7676 if (nla_put_u8(reply_skb,
7677 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7678 nss) ||
7679 nla_put_u8(reply_skb,
7680 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7681 final_rate_flags) ||
7682 nla_put_u32(reply_skb,
7683 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7684 freq)) {
7685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7686 kfree_skb(reply_skb);
7687 return -EINVAL;
7688 }
7689
7690 return cfg80211_vendor_cmd_reply(reply_skb);
7691}
7692
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307693#define BEACON_MISS_THRESH_2_4 \
7694 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7695#define BEACON_MISS_THRESH_5_0 \
7696 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307697#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7698#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7699#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7700#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307701#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7702 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307703
7704/**
7705 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7706 * vendor command
7707 *
7708 * @wiphy: wiphy device pointer
7709 * @wdev: wireless device pointer
7710 * @data: Vendor command data buffer
7711 * @data_len: Buffer length
7712 *
7713 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7714 *
7715 * Return: EOK or other error codes.
7716 */
7717
7718static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7719 struct wireless_dev *wdev,
7720 const void *data,
7721 int data_len)
7722{
7723 struct net_device *dev = wdev->netdev;
7724 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7725 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7726 hdd_station_ctx_t *pHddStaCtx;
7727 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7728 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307729 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307730 eHalStatus status;
7731 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307732 uint8_t hb_thresh_val;
7733
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307734 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7735 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7736 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307737 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7738 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7739 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307740 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7741 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307742 };
7743
7744 ENTER();
7745
7746 if (VOS_FTM_MODE == hdd_get_conparam()) {
7747 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7748 return -EINVAL;
7749 }
7750
7751 ret_val = wlan_hdd_validate_context(pHddCtx);
7752 if (ret_val) {
7753 return ret_val;
7754 }
7755
7756 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7757
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307758 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7759 hddLog(LOGE, FL("Invalid ATTR"));
7760 return -EINVAL;
7761 }
7762
7763 /* check the Wifi Capability */
7764 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7765 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7766 {
7767 hddLog(VOS_TRACE_LEVEL_ERROR,
7768 FL("WIFICONFIG not supported by Firmware"));
7769 return -EINVAL;
7770 }
7771
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307772 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7773 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7774 modifyRoamParamsReq.value =
7775 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7776
7777 if (eHAL_STATUS_SUCCESS !=
7778 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7779 {
7780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7781 ret_val = -EINVAL;
7782 }
7783 return ret_val;
7784 }
7785
7786 /* Moved this down in order to provide provision to set beacon
7787 * miss penalty count irrespective of connection state.
7788 */
7789 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7790 hddLog(LOGE, FL("Not in Connected state!"));
7791 return -ENOTSUPP;
7792 }
7793
7794 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307795
7796 if (!pReq) {
7797 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7798 "%s: Not able to allocate memory for tSetWifiConfigParams",
7799 __func__);
7800 return eHAL_STATUS_E_MALLOC_FAILED;
7801 }
7802
7803 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7804
7805 pReq->sessionId = pAdapter->sessionId;
7806 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7807
7808 if (tb[PARAM_MODULATED_DTIM]) {
7809 pReq->paramValue = nla_get_u32(
7810 tb[PARAM_MODULATED_DTIM]);
7811 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7812 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307813 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307814 hdd_set_pwrparams(pHddCtx);
7815 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7816 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7817
7818 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7819 iw_full_power_cbfn, pAdapter,
7820 eSME_FULL_PWR_NEEDED_BY_HDD);
7821 }
7822 else
7823 {
7824 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7825 }
7826 }
7827
7828 if (tb[PARAM_STATS_AVG_FACTOR]) {
7829 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7830 pReq->paramValue = nla_get_u16(
7831 tb[PARAM_STATS_AVG_FACTOR]);
7832 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7833 pReq->paramType, pReq->paramValue);
7834 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7835
7836 if (eHAL_STATUS_SUCCESS != status)
7837 {
7838 vos_mem_free(pReq);
7839 pReq = NULL;
7840 ret_val = -EPERM;
7841 return ret_val;
7842 }
7843 }
7844
7845
7846 if (tb[PARAM_GUARD_TIME]) {
7847 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7848 pReq->paramValue = nla_get_u32(
7849 tb[PARAM_GUARD_TIME]);
7850 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7851 pReq->paramType, pReq->paramValue);
7852 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7853
7854 if (eHAL_STATUS_SUCCESS != status)
7855 {
7856 vos_mem_free(pReq);
7857 pReq = NULL;
7858 ret_val = -EPERM;
7859 return ret_val;
7860 }
7861
7862 }
7863
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307864 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7865 hb_thresh_val = nla_get_u8(
7866 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7867
7868 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7869 hb_thresh_val);
7870 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7871 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7872 NULL, eANI_BOOLEAN_FALSE);
7873
7874 status = sme_update_hb_threshold(
7875 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7876 WNI_CFG_HEART_BEAT_THRESHOLD,
7877 hb_thresh_val, eCSR_BAND_24);
7878 if (eHAL_STATUS_SUCCESS != status) {
7879 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7880 vos_mem_free(pReq);
7881 pReq = NULL;
7882 return -EPERM;
7883 }
7884 }
7885
7886 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7887 hb_thresh_val = nla_get_u8(
7888 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7889
7890 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7891 hb_thresh_val);
7892 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7893 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7894 NULL, eANI_BOOLEAN_FALSE);
7895
7896 status = sme_update_hb_threshold(
7897 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7898 WNI_CFG_HEART_BEAT_THRESHOLD,
7899 hb_thresh_val, eCSR_BAND_5G);
7900 if (eHAL_STATUS_SUCCESS != status) {
7901 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7902 vos_mem_free(pReq);
7903 pReq = NULL;
7904 return -EPERM;
7905 }
7906 }
7907
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307908 EXIT();
7909 return ret_val;
7910}
7911
7912/**
7913 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7914 * vendor command
7915 *
7916 * @wiphy: wiphy device pointer
7917 * @wdev: wireless device pointer
7918 * @data: Vendor command data buffer
7919 * @data_len: Buffer length
7920 *
7921 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7922 *
7923 * Return: EOK or other error codes.
7924 */
7925static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7926 struct wireless_dev *wdev,
7927 const void *data,
7928 int data_len)
7929{
7930 int ret;
7931
7932 vos_ssr_protect(__func__);
7933 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7934 data, data_len);
7935 vos_ssr_unprotect(__func__);
7936
7937 return ret;
7938}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05307939
7940/*
7941 * define short names for the global vendor params
7942 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
7943 */
7944#define STATS_SET_INVALID \
7945 QCA_ATTR_NUD_STATS_SET_INVALID
7946#define STATS_SET_START \
7947 QCA_ATTR_NUD_STATS_SET_START
7948#define STATS_GW_IPV4 \
7949 QCA_ATTR_NUD_STATS_GW_IPV4
7950#define STATS_SET_MAX \
7951 QCA_ATTR_NUD_STATS_SET_MAX
7952
7953const struct nla_policy
7954qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
7955{
7956 [STATS_SET_START] = {.type = NLA_FLAG },
7957 [STATS_GW_IPV4] = {.type = NLA_U32 },
7958};
7959
7960/**
7961 * hdd_set_nud_stats_cb() - hdd callback api to get status
7962 * @data: pointer to adapter
7963 * @rsp: status
7964 *
7965 * Return: None
7966 */
7967static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
7968{
7969
7970 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
7971
7972 if (NULL == adapter)
7973 return;
7974
7975 if (VOS_STATUS_SUCCESS == rsp) {
7976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7977 "%s success received STATS_SET_START", __func__);
7978 } else {
7979 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7980 "%s STATS_SET_START Failed!!", __func__);
7981 }
7982 return;
7983}
7984
7985/**
7986 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
7987 * @wiphy: pointer to wireless wiphy structure.
7988 * @wdev: pointer to wireless_dev structure.
7989 * @data: pointer to apfind configuration data.
7990 * @data_len: the length in byte of apfind data.
7991 *
7992 * This is called when wlan driver needs to send arp stats to
7993 * firmware.
7994 *
7995 * Return: An error code or 0 on success.
7996 */
7997static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
7998 struct wireless_dev *wdev,
7999 const void *data, int data_len)
8000{
8001 struct nlattr *tb[STATS_SET_MAX + 1];
8002 struct net_device *dev = wdev->netdev;
8003 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8004 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308005 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308006 setArpStatsParams arp_stats_params;
8007 int err = 0;
8008
8009 ENTER();
8010
8011 err = wlan_hdd_validate_context(hdd_ctx);
8012 if (0 != err)
8013 return err;
8014
8015 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8017 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8018 return -EINVAL;
8019 }
8020
8021 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8022 qca_wlan_vendor_set_nud_stats);
8023 if (err)
8024 {
8025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8026 "%s STATS_SET_START ATTR", __func__);
8027 return err;
8028 }
8029
8030 if (tb[STATS_SET_START])
8031 {
8032 if (!tb[STATS_GW_IPV4]) {
8033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8034 "%s STATS_SET_START CMD", __func__);
8035 return -EINVAL;
8036 }
8037 arp_stats_params.flag = true;
8038 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8039 } else {
8040 arp_stats_params.flag = false;
8041 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308042 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8044 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308045 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8046 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308047
8048 arp_stats_params.pkt_type = 1; // ARP packet type
8049
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308050 if (arp_stats_params.flag) {
8051 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8052 WLANTL_SetARPFWDatapath(pVosContext, true);
8053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8054 "%s Set FW in data path for ARP with tgt IP :%d",
8055 __func__, hdd_ctx->track_arp_ip);
8056 }
8057 else {
8058 WLANTL_SetARPFWDatapath(pVosContext, false);
8059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8060 "%s Remove FW from data path", __func__);
8061 }
8062
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308063 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8064 arp_stats_params.data_ctx = adapter;
8065
8066 if (eHAL_STATUS_SUCCESS !=
8067 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8069 "%s STATS_SET_START CMD Failed!!", __func__);
8070 return -EINVAL;
8071 }
8072
8073 EXIT();
8074
8075 return err;
8076}
8077
8078/**
8079 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8080 * @wiphy: pointer to wireless wiphy structure.
8081 * @wdev: pointer to wireless_dev structure.
8082 * @data: pointer to apfind configuration data.
8083 * @data_len: the length in byte of apfind data.
8084 *
8085 * This is called when wlan driver needs to send arp stats to
8086 * firmware.
8087 *
8088 * Return: An error code or 0 on success.
8089 */
8090static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8091 struct wireless_dev *wdev,
8092 const void *data, int data_len)
8093{
8094 int ret;
8095
8096 vos_ssr_protect(__func__);
8097 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8098 vos_ssr_unprotect(__func__);
8099
8100 return ret;
8101}
8102#undef STATS_SET_INVALID
8103#undef STATS_SET_START
8104#undef STATS_GW_IPV4
8105#undef STATS_SET_MAX
8106
8107/*
8108 * define short names for the global vendor params
8109 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8110 */
8111#define STATS_GET_INVALID \
8112 QCA_ATTR_NUD_STATS_SET_INVALID
8113#define COUNT_FROM_NETDEV \
8114 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8115#define COUNT_TO_LOWER_MAC \
8116 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8117#define RX_COUNT_BY_LOWER_MAC \
8118 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8119#define COUNT_TX_SUCCESS \
8120 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8121#define RSP_RX_COUNT_BY_LOWER_MAC \
8122 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8123#define RSP_RX_COUNT_BY_UPPER_MAC \
8124 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8125#define RSP_COUNT_TO_NETDEV \
8126 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8127#define RSP_COUNT_OUT_OF_ORDER_DROP \
8128 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8129#define AP_LINK_ACTIVE \
8130 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8131#define AP_LINK_DAD \
8132 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8133#define STATS_GET_MAX \
8134 QCA_ATTR_NUD_STATS_GET_MAX
8135
8136const struct nla_policy
8137qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8138{
8139 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8140 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8141 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8142 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8143 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8144 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8145 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8146 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8147 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8148 [AP_LINK_DAD] = {.type = NLA_FLAG },
8149};
8150
8151static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8152{
8153
8154 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8155 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8156 struct hdd_nud_stats_context *context;
8157 int status;
8158
8159 ENTER();
8160
8161 if (NULL == adapter)
8162 return;
8163
8164 status = wlan_hdd_validate_context(hdd_ctx);
8165 if (0 != status) {
8166 return;
8167 }
8168
8169 if (!rsp) {
8170 hddLog(LOGE, FL("data is null"));
8171 return;
8172 }
8173
8174 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8175 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8176 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8177 adapter->dad |= rsp->dad;
8178
8179 spin_lock(&hdd_context_lock);
8180 context = &hdd_ctx->nud_stats_context;
8181 complete(&context->response_event);
8182 spin_unlock(&hdd_context_lock);
8183
8184 return;
8185}
8186static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8187 struct wireless_dev *wdev,
8188 const void *data, int data_len)
8189{
8190 int err = 0;
8191 unsigned long rc;
8192 struct hdd_nud_stats_context *context;
8193 struct net_device *dev = wdev->netdev;
8194 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8195 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8196 getArpStatsParams arp_stats_params;
8197 struct sk_buff *skb;
8198
8199 ENTER();
8200
8201 err = wlan_hdd_validate_context(hdd_ctx);
8202 if (0 != err)
8203 return err;
8204
8205 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8206 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8207 arp_stats_params.data_ctx = adapter;
8208
8209 spin_lock(&hdd_context_lock);
8210 context = &hdd_ctx->nud_stats_context;
8211 INIT_COMPLETION(context->response_event);
8212 spin_unlock(&hdd_context_lock);
8213
8214 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8216 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8217 return -EINVAL;
8218 }
8219
8220 if (eHAL_STATUS_SUCCESS !=
8221 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8223 "%s STATS_SET_START CMD Failed!!", __func__);
8224 return -EINVAL;
8225 }
8226
8227 rc = wait_for_completion_timeout(&context->response_event,
8228 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8229 if (!rc)
8230 {
8231 hddLog(LOGE,
8232 FL("Target response timed out request "));
8233 return -ETIMEDOUT;
8234 }
8235
8236 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8237 WLAN_NUD_STATS_LEN);
8238 if (!skb)
8239 {
8240 hddLog(VOS_TRACE_LEVEL_ERROR,
8241 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8242 __func__);
8243 return -ENOMEM;
8244 }
8245
8246 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8247 adapter->hdd_stats.hddArpStats.txCount) ||
8248 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8249 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8250 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8251 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8252 nla_put_u16(skb, COUNT_TX_SUCCESS,
8253 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8254 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8255 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8256 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8257 adapter->hdd_stats.hddArpStats.rxCount) ||
8258 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8259 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8260 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8261 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8262 hddLog(LOGE, FL("nla put fail"));
8263 kfree_skb(skb);
8264 return -EINVAL;
8265 }
8266 if (adapter->con_status)
8267 nla_put_flag(skb, AP_LINK_ACTIVE);
8268 if (adapter->dad)
8269 nla_put_flag(skb, AP_LINK_DAD);
8270
8271 cfg80211_vendor_cmd_reply(skb);
8272 return err;
8273}
8274
8275static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8276 struct wireless_dev *wdev,
8277 const void *data, int data_len)
8278{
8279 int ret;
8280
8281 vos_ssr_protect(__func__);
8282 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8283 vos_ssr_unprotect(__func__);
8284
8285 return ret;
8286}
8287
8288#undef QCA_ATTR_NUD_STATS_SET_INVALID
8289#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8290#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8291#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8292#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8293#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8294#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8295#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8296#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8297#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8298#undef QCA_ATTR_NUD_STATS_GET_MAX
8299
8300
8301
Kapil Guptaee33bf12016-12-20 18:27:37 +05308302#ifdef WLAN_FEATURE_APFIND
8303/**
8304 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8305 * @wiphy: pointer to wireless wiphy structure.
8306 * @wdev: pointer to wireless_dev structure.
8307 * @data: pointer to apfind configuration data.
8308 * @data_len: the length in byte of apfind data.
8309 *
8310 * This is called when wlan driver needs to send APFIND configurations to
8311 * firmware.
8312 *
8313 * Return: An error code or 0 on success.
8314 */
8315static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8316 struct wireless_dev *wdev,
8317 const void *data, int data_len)
8318{
8319 struct sme_ap_find_request_req apfind_req;
8320 VOS_STATUS status;
8321 int ret_val;
8322 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8323
8324 ENTER();
8325
8326 ret_val = wlan_hdd_validate_context(hdd_ctx);
8327 if (ret_val)
8328 return ret_val;
8329
8330 if (VOS_FTM_MODE == hdd_get_conparam()) {
8331 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8332 return -EPERM;
8333 }
8334
8335 apfind_req.request_data_len = data_len;
8336 apfind_req.request_data = data;
8337
8338 status = sme_apfind_set_cmd(&apfind_req);
8339 if (VOS_STATUS_SUCCESS != status) {
8340 ret_val = -EIO;
8341 }
8342 return ret_val;
8343}
8344
8345/**
8346 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8347 * @wiphy: pointer to wireless wiphy structure.
8348 * @wdev: pointer to wireless_dev structure.
8349 * @data: pointer to apfind configuration data.
8350 * @data_len: the length in byte of apfind data.
8351 *
8352 * This is called when wlan driver needs to send APFIND configurations to
8353 * firmware.
8354 *
8355 * Return: An error code or 0 on success.
8356 */
8357static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8358 struct wireless_dev *wdev,
8359 const void *data, int data_len)
8360{
8361 int ret;
8362
8363 vos_ssr_protect(__func__);
8364 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8365 vos_ssr_unprotect(__func__);
8366
8367 return ret;
8368}
8369#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308370const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8371{
Mukul Sharma2a271632014-10-13 14:59:01 +05308372 {
8373 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8374 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8375 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8376 WIPHY_VENDOR_CMD_NEED_NETDEV |
8377 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308378 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308379 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308380
8381 {
8382 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8383 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8384 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8385 WIPHY_VENDOR_CMD_NEED_NETDEV |
8386 WIPHY_VENDOR_CMD_NEED_RUNNING,
8387 .doit = wlan_hdd_cfg80211_nan_request
8388 },
8389
Sunil Duttc69bccb2014-05-26 21:30:20 +05308390#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8391 {
8392 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8393 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8394 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8395 WIPHY_VENDOR_CMD_NEED_NETDEV |
8396 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308397 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308398 },
8399
8400 {
8401 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8402 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8403 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8404 WIPHY_VENDOR_CMD_NEED_NETDEV |
8405 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308406 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308407 },
8408
8409 {
8410 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8411 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8412 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8413 WIPHY_VENDOR_CMD_NEED_NETDEV |
8414 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308415 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308416 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308417#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308418#ifdef WLAN_FEATURE_EXTSCAN
8419 {
8420 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8421 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8422 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8423 WIPHY_VENDOR_CMD_NEED_NETDEV |
8424 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308425 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308426 },
8427 {
8428 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8429 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8430 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8431 WIPHY_VENDOR_CMD_NEED_NETDEV |
8432 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308433 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308434 },
8435 {
8436 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8437 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8438 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8439 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308440 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308441 },
8442 {
8443 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8444 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8445 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8446 WIPHY_VENDOR_CMD_NEED_NETDEV |
8447 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308448 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308449 },
8450 {
8451 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8452 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8453 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8454 WIPHY_VENDOR_CMD_NEED_NETDEV |
8455 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308456 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308457 },
8458 {
8459 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8460 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8461 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8462 WIPHY_VENDOR_CMD_NEED_NETDEV |
8463 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308464 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308465 },
8466 {
8467 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8468 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8469 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8470 WIPHY_VENDOR_CMD_NEED_NETDEV |
8471 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308472 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308473 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308474#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308475/*EXT TDLS*/
8476 {
8477 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8478 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8479 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8480 WIPHY_VENDOR_CMD_NEED_NETDEV |
8481 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308482 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308483 },
8484 {
8485 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8486 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8487 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8488 WIPHY_VENDOR_CMD_NEED_NETDEV |
8489 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308490 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308491 },
8492 {
8493 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8494 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8495 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8496 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308497 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308498 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308499 {
8500 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8501 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8502 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8503 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308504 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308505 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308506 {
8507 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8508 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8509 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8510 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308511 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308512 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308513 {
8514 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8515 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8516 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8517 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308518 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308519 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308520 {
8521 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8522 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8523 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8524 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308525 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308526 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308527 {
8528 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308529 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8530 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8531 WIPHY_VENDOR_CMD_NEED_NETDEV |
8532 WIPHY_VENDOR_CMD_NEED_RUNNING,
8533 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8534 },
8535 {
8536 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308537 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8538 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8539 WIPHY_VENDOR_CMD_NEED_NETDEV |
8540 WIPHY_VENDOR_CMD_NEED_RUNNING,
8541 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308542 },
8543 {
8544 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8545 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8546 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8547 WIPHY_VENDOR_CMD_NEED_NETDEV,
8548 .doit = wlan_hdd_cfg80211_wifi_logger_start
8549 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308550 {
8551 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8552 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8553 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8554 WIPHY_VENDOR_CMD_NEED_NETDEV|
8555 WIPHY_VENDOR_CMD_NEED_RUNNING,
8556 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308557 },
8558 {
8559 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8560 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8561 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8562 WIPHY_VENDOR_CMD_NEED_NETDEV |
8563 WIPHY_VENDOR_CMD_NEED_RUNNING,
8564 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308565 },
8566 {
8567 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8568 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8569 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8570 WIPHY_VENDOR_CMD_NEED_NETDEV |
8571 WIPHY_VENDOR_CMD_NEED_RUNNING,
8572 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308573 },
8574#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8575 {
8576 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8577 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8578 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8579 WIPHY_VENDOR_CMD_NEED_NETDEV |
8580 WIPHY_VENDOR_CMD_NEED_RUNNING,
8581 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308582 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308583#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308584 {
8585 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8586 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8587 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8588 WIPHY_VENDOR_CMD_NEED_NETDEV |
8589 WIPHY_VENDOR_CMD_NEED_RUNNING,
8590 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308591 },
8592 {
8593 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8594 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8595 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8596 WIPHY_VENDOR_CMD_NEED_NETDEV |
8597 WIPHY_VENDOR_CMD_NEED_RUNNING,
8598 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308599 },
8600#ifdef WLAN_FEATURE_APFIND
8601 {
8602 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8603 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8604 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8605 WIPHY_VENDOR_CMD_NEED_NETDEV,
8606 .doit = wlan_hdd_cfg80211_apfind_cmd
8607 },
8608#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308609 {
8610 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8611 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8612 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8613 WIPHY_VENDOR_CMD_NEED_NETDEV |
8614 WIPHY_VENDOR_CMD_NEED_RUNNING,
8615 .doit = wlan_hdd_cfg80211_set_nud_stats
8616 },
8617 {
8618 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8619 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8620 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8621 WIPHY_VENDOR_CMD_NEED_NETDEV |
8622 WIPHY_VENDOR_CMD_NEED_RUNNING,
8623 .doit = wlan_hdd_cfg80211_get_nud_stats
8624 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308625 {
8626 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8627 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8628 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8629 WIPHY_VENDOR_CMD_NEED_NETDEV |
8630 WIPHY_VENDOR_CMD_NEED_RUNNING,
8631 .doit = hdd_cfg80211_get_station_cmd
8632 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308633};
8634
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008635/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308636static const
8637struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008638{
8639#ifdef FEATURE_WLAN_CH_AVOID
8640 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308641 .vendor_id = QCA_NL80211_VENDOR_ID,
8642 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008643 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308644#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8645#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8646 {
8647 /* Index = 1*/
8648 .vendor_id = QCA_NL80211_VENDOR_ID,
8649 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8650 },
8651 {
8652 /* Index = 2*/
8653 .vendor_id = QCA_NL80211_VENDOR_ID,
8654 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8655 },
8656 {
8657 /* Index = 3*/
8658 .vendor_id = QCA_NL80211_VENDOR_ID,
8659 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8660 },
8661 {
8662 /* Index = 4*/
8663 .vendor_id = QCA_NL80211_VENDOR_ID,
8664 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8665 },
8666 {
8667 /* Index = 5*/
8668 .vendor_id = QCA_NL80211_VENDOR_ID,
8669 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8670 },
8671 {
8672 /* Index = 6*/
8673 .vendor_id = QCA_NL80211_VENDOR_ID,
8674 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8675 },
8676#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308677#ifdef WLAN_FEATURE_EXTSCAN
8678 {
8679 .vendor_id = QCA_NL80211_VENDOR_ID,
8680 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8681 },
8682 {
8683 .vendor_id = QCA_NL80211_VENDOR_ID,
8684 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8685 },
8686 {
8687 .vendor_id = QCA_NL80211_VENDOR_ID,
8688 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8689 },
8690 {
8691 .vendor_id = QCA_NL80211_VENDOR_ID,
8692 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8693 },
8694 {
8695 .vendor_id = QCA_NL80211_VENDOR_ID,
8696 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8697 },
8698 {
8699 .vendor_id = QCA_NL80211_VENDOR_ID,
8700 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8701 },
8702 {
8703 .vendor_id = QCA_NL80211_VENDOR_ID,
8704 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8705 },
8706 {
8707 .vendor_id = QCA_NL80211_VENDOR_ID,
8708 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8709 },
8710 {
8711 .vendor_id = QCA_NL80211_VENDOR_ID,
8712 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8713 },
8714 {
8715 .vendor_id = QCA_NL80211_VENDOR_ID,
8716 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8717 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308718#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308719/*EXT TDLS*/
8720 {
8721 .vendor_id = QCA_NL80211_VENDOR_ID,
8722 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8723 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308724 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8725 .vendor_id = QCA_NL80211_VENDOR_ID,
8726 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8727 },
8728
Srinivas Dasari030bad32015-02-18 23:23:54 +05308729
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308730 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308731 .vendor_id = QCA_NL80211_VENDOR_ID,
8732 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8733 },
8734
Sushant Kaushik084f6592015-09-10 13:11:56 +05308735 {
8736 .vendor_id = QCA_NL80211_VENDOR_ID,
8737 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308738 },
8739 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8740 .vendor_id = QCA_NL80211_VENDOR_ID,
8741 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8742 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308743 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8744 .vendor_id = QCA_NL80211_VENDOR_ID,
8745 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8746 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308747 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8748 .vendor_id = QCA_NL80211_VENDOR_ID,
8749 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8750 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008751};
8752
Jeff Johnson295189b2012-06-20 16:38:30 -07008753/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308754 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308755 * This function is called by hdd_wlan_startup()
8756 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308757 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008758 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308759struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008760{
8761 struct wiphy *wiphy;
8762 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308763 /*
8764 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008765 */
8766 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8767
8768 if (!wiphy)
8769 {
8770 /* Print error and jump into err label and free the memory */
8771 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8772 return NULL;
8773 }
8774
Sunil Duttc69bccb2014-05-26 21:30:20 +05308775
Jeff Johnson295189b2012-06-20 16:38:30 -07008776 return wiphy;
8777}
8778
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308779#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8780 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8781/**
8782 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8783 * @wiphy: pointer to wiphy
8784 * @config: pointer to config
8785 *
8786 * Return: None
8787 */
8788static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8789 hdd_config_t *config)
8790{
8791 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8792 if (config->max_sched_scan_plan_interval)
8793 wiphy->max_sched_scan_plan_interval =
8794 config->max_sched_scan_plan_interval;
8795 if (config->max_sched_scan_plan_iterations)
8796 wiphy->max_sched_scan_plan_iterations =
8797 config->max_sched_scan_plan_iterations;
8798}
8799#else
8800static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8801 hdd_config_t *config)
8802{
8803}
8804#endif
8805
Jeff Johnson295189b2012-06-20 16:38:30 -07008806/*
8807 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308808 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008809 * private ioctl to change the band value
8810 */
8811int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8812{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308813 int i, j;
8814 eNVChannelEnabledType channelEnabledState;
8815
Jeff Johnsone7245742012-09-05 17:12:55 -07008816 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308817
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308818 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008819 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308820
8821 if (NULL == wiphy->bands[i])
8822 {
8823 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8824 __func__, i);
8825 continue;
8826 }
8827
8828 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8829 {
8830 struct ieee80211_supported_band *band = wiphy->bands[i];
8831
8832 channelEnabledState = vos_nv_getChannelEnabledState(
8833 band->channels[j].hw_value);
8834
8835 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
8836 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308837 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308838 continue;
8839 }
8840 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
8841 {
8842 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8843 continue;
8844 }
8845
8846 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8847 NV_CHANNEL_INVALID == channelEnabledState)
8848 {
8849 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8850 }
8851 else if (NV_CHANNEL_DFS == channelEnabledState)
8852 {
8853 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8854 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8855 }
8856 else
8857 {
8858 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8859 |IEEE80211_CHAN_RADAR);
8860 }
8861 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008862 }
8863 return 0;
8864}
8865/*
8866 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308867 * This function is called by hdd_wlan_startup()
8868 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 * This function is used to initialize and register wiphy structure.
8870 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308871int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008872 struct wiphy *wiphy,
8873 hdd_config_t *pCfg
8874 )
8875{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308876 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308877 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8878
Jeff Johnsone7245742012-09-05 17:12:55 -07008879 ENTER();
8880
Jeff Johnson295189b2012-06-20 16:38:30 -07008881 /* Now bind the underlying wlan device with wiphy */
8882 set_wiphy_dev(wiphy, dev);
8883
8884 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008885
Kiet Lam6c583332013-10-14 05:37:09 +05308886#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07008887 /* the flag for the other case would be initialzed in
8888 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05308889#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8890 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
8891#else
Amar Singhal0a402232013-10-11 20:57:16 -07008892 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05308893#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05308894#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008895
Amar Singhalfddc28c2013-09-05 13:03:40 -07008896 /* This will disable updating of NL channels from passive to
8897 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
8899 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
8900#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07008901 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308902#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07008903
Amar Singhala49cbc52013-10-08 18:37:44 -07008904
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008905#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07008906 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
8907 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
8908 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07008909 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308910#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05308911 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05308912#else
8913 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
8914#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008915#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07008916
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008917#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008918 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08008919#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008920 || pCfg->isFastRoamIniFeatureEnabled
8921#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08008922#ifdef FEATURE_WLAN_ESE
8923 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07008924#endif
8925 )
8926 {
8927 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
8928 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08008929#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008930#ifdef FEATURE_WLAN_TDLS
8931 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
8932 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
8933#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308934#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05308935 if (pCfg->configPNOScanSupport)
8936 {
8937 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
8938 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
8939 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
8940 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
8941 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308942#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008943
Abhishek Singh10d85972015-04-17 10:27:23 +05308944#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8945 wiphy->features |= NL80211_FEATURE_HT_IBSS;
8946#endif
8947
Amar Singhalfddc28c2013-09-05 13:03:40 -07008948#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008949 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
8950 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07008951 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07008952 driver need to determine what to do with both
8953 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07008954
8955 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07008956#else
8957 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07008958#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008959
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308960 wiphy->max_scan_ssids = MAX_SCAN_SSID;
8961
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05308962 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07008963
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308964 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
8965
Jeff Johnson295189b2012-06-20 16:38:30 -07008966 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05308967 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
8968 | BIT(NL80211_IFTYPE_ADHOC)
8969 | BIT(NL80211_IFTYPE_P2P_CLIENT)
8970 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308971 | BIT(NL80211_IFTYPE_AP)
8972 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07008973
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308974 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008975 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308976#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
8977 if( pCfg->enableMCC )
8978 {
8979 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308980 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008981
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308982 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308983 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008984
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308985 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05308986 wiphy->iface_combinations = wlan_hdd_iface_combination;
8987 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008988#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05308989 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08008990
Jeff Johnson295189b2012-06-20 16:38:30 -07008991 /* Before registering we need to update the ht capabilitied based
8992 * on ini values*/
8993 if( !pCfg->ShortGI20MhzEnable )
8994 {
8995 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
8996 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 }
8998
8999 if( !pCfg->ShortGI40MhzEnable )
9000 {
9001 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9002 }
9003
9004 if( !pCfg->nChannelBondingMode5GHz )
9005 {
9006 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9007 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309008 /*
9009 * In case of static linked driver at the time of driver unload,
9010 * module exit doesn't happens. Module cleanup helps in cleaning
9011 * of static memory.
9012 * If driver load happens statically, at the time of driver unload,
9013 * wiphy flags don't get reset because of static memory.
9014 * It's better not to store channel in static memory.
9015 */
9016 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9017 wiphy->bands[IEEE80211_BAND_2GHZ]->channels =
9018 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
9019 if (wiphy->bands[IEEE80211_BAND_2GHZ]->channels == NULL)
9020 {
9021 hddLog(VOS_TRACE_LEVEL_ERROR,
9022 FL("Not enough memory to allocate channels"));
9023 return -ENOMEM;
9024 }
9025 vos_mem_copy(wiphy->bands[IEEE80211_BAND_2GHZ]->channels,
9026 &hdd_channels_2_4_GHZ[0],
9027 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009028
Agrawal Ashish97dec502015-11-26 20:20:58 +05309029 if (true == hdd_is_5g_supported(pHddCtx))
9030 {
9031 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9032 wiphy->bands[IEEE80211_BAND_5GHZ]->channels =
9033 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
9034 if (wiphy->bands[IEEE80211_BAND_5GHZ]->channels == NULL)
9035 {
9036 hddLog(VOS_TRACE_LEVEL_ERROR,
9037 FL("Not enough memory to allocate channels"));
9038 vos_mem_free(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
9039 wiphy->bands[IEEE80211_BAND_2GHZ]->channels = NULL;
9040 return -ENOMEM;
9041 }
9042 vos_mem_copy(wiphy->bands[IEEE80211_BAND_5GHZ]->channels,
9043 &hdd_channels_5_GHZ[0],
9044 sizeof(hdd_channels_5_GHZ));
9045 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309046
9047 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9048 {
9049
9050 if (NULL == wiphy->bands[i])
9051 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309052 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309053 __func__, i);
9054 continue;
9055 }
9056
9057 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9058 {
9059 struct ieee80211_supported_band *band = wiphy->bands[i];
9060
9061 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
9062 {
9063 // Enable social channels for P2P
9064 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9065 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9066 else
9067 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9068 continue;
9069 }
9070 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
9071 {
9072 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9073 continue;
9074 }
9075 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009076 }
9077 /*Initialise the supported cipher suite details*/
9078 wiphy->cipher_suites = hdd_cipher_suites;
9079 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9080
9081 /*signal strength in mBm (100*dBm) */
9082 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9083
9084#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309085 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009086#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009087
Sunil Duttc69bccb2014-05-26 21:30:20 +05309088 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9089 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009090 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9091 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9092
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309093 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9094
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309095 EXIT();
9096 return 0;
9097}
9098
9099/* In this function we are registering wiphy. */
9100int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9101{
9102 ENTER();
9103 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 if (0 > wiphy_register(wiphy))
9105 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309106 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009107 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9108 return -EIO;
9109 }
9110
9111 EXIT();
9112 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309113}
Jeff Johnson295189b2012-06-20 16:38:30 -07009114
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309115/* In this function we are updating channel list when,
9116 regulatory domain is FCC and country code is US.
9117 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9118 As per FCC smart phone is not a indoor device.
9119 GO should not opeate on indoor channels */
9120void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9121{
9122 int j;
9123 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9124 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9125 //Default counrtycode from NV at the time of wiphy initialization.
9126 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9127 &defaultCountryCode[0]))
9128 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009129 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309130 }
9131 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9132 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309133 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
9134 {
9135 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
9136 return;
9137 }
9138 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
9139 {
9140 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
9141 // Mark UNII -1 band channel as passive
9142 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9143 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9144 }
9145 }
9146}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309147/* This function registers for all frame which supplicant is interested in */
9148void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009149{
Jeff Johnson295189b2012-06-20 16:38:30 -07009150 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9151 /* Register for all P2P action, public action etc frames */
9152 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009153 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309154 /* Register frame indication call back */
9155 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009156 /* Right now we are registering these frame when driver is getting
9157 initialized. Once we will move to 2.6.37 kernel, in which we have
9158 frame register ops, we will move this code as a part of that */
9159 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309160 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009161 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9162
9163 /* GAS Initial Response */
9164 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9165 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309166
Jeff Johnson295189b2012-06-20 16:38:30 -07009167 /* GAS Comeback Request */
9168 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9169 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9170
9171 /* GAS Comeback Response */
9172 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9173 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9174
9175 /* P2P Public Action */
9176 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309177 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009178 P2P_PUBLIC_ACTION_FRAME_SIZE );
9179
9180 /* P2P Action */
9181 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9182 (v_U8_t*)P2P_ACTION_FRAME,
9183 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009184
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309185 /* WNM BSS Transition Request frame */
9186 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9187 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9188 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009189
9190 /* WNM-Notification */
9191 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9192 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9193 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009194}
9195
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309196void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009197{
Jeff Johnson295189b2012-06-20 16:38:30 -07009198 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9199 /* Register for all P2P action, public action etc frames */
9200 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9201
Jeff Johnsone7245742012-09-05 17:12:55 -07009202 ENTER();
9203
Jeff Johnson295189b2012-06-20 16:38:30 -07009204 /* Right now we are registering these frame when driver is getting
9205 initialized. Once we will move to 2.6.37 kernel, in which we have
9206 frame register ops, we will move this code as a part of that */
9207 /* GAS Initial Request */
9208
9209 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9210 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9211
9212 /* GAS Initial Response */
9213 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9214 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309215
Jeff Johnson295189b2012-06-20 16:38:30 -07009216 /* GAS Comeback Request */
9217 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9218 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9219
9220 /* GAS Comeback Response */
9221 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9222 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9223
9224 /* P2P Public Action */
9225 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309226 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009227 P2P_PUBLIC_ACTION_FRAME_SIZE );
9228
9229 /* P2P Action */
9230 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9231 (v_U8_t*)P2P_ACTION_FRAME,
9232 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009233 /* WNM-Notification */
9234 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9235 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9236 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009237}
9238
9239#ifdef FEATURE_WLAN_WAPI
9240void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309241 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009242{
9243 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9244 tCsrRoamSetKey setKey;
9245 v_BOOL_t isConnected = TRUE;
9246 int status = 0;
9247 v_U32_t roamId= 0xFF;
9248 tANI_U8 *pKeyPtr = NULL;
9249 int n = 0;
9250
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309251 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9252 __func__, hdd_device_modetoString(pAdapter->device_mode),
9253 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009254
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309255 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 setKey.keyId = key_index; // Store Key ID
9257 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9258 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9259 setKey.paeRole = 0 ; // the PAE role
9260 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9261 {
9262 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9263 }
9264 else
9265 {
9266 isConnected = hdd_connIsConnected(pHddStaCtx);
9267 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9268 }
9269 setKey.keyLength = key_Len;
9270 pKeyPtr = setKey.Key;
9271 memcpy( pKeyPtr, key, key_Len);
9272
Arif Hussain6d2a3322013-11-17 19:50:10 -08009273 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 __func__, key_Len);
9275 for (n = 0 ; n < key_Len; n++)
9276 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9277 __func__,n,setKey.Key[n]);
9278
9279 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9280 if ( isConnected )
9281 {
9282 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9283 pAdapter->sessionId, &setKey, &roamId );
9284 }
9285 if ( status != 0 )
9286 {
9287 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9288 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9289 __LINE__, status );
9290 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9291 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309292 /* Need to clear any trace of key value in the memory.
9293 * Thus zero out the memory even though it is local
9294 * variable.
9295 */
9296 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009297}
9298#endif /* FEATURE_WLAN_WAPI*/
9299
9300#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309301int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009302 beacon_data_t **ppBeacon,
9303 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009304#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309305int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009306 beacon_data_t **ppBeacon,
9307 struct cfg80211_beacon_data *params,
9308 int dtim_period)
9309#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309310{
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 int size;
9312 beacon_data_t *beacon = NULL;
9313 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309314 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9315 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009316
Jeff Johnsone7245742012-09-05 17:12:55 -07009317 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009318 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309319 {
9320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9321 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309323 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009324
9325 old = pAdapter->sessionCtx.ap.beacon;
9326
9327 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309328 {
9329 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9330 FL("session(%d) old and new heads points to NULL"),
9331 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009332 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309333 }
9334
9335 if (params->tail && !params->tail_len)
9336 {
9337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9338 FL("tail_len is zero but tail is not NULL"));
9339 return -EINVAL;
9340 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009341
Jeff Johnson295189b2012-06-20 16:38:30 -07009342#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9343 /* Kernel 3.0 is not updating dtim_period for set beacon */
9344 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309345 {
9346 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9347 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309349 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009350#endif
9351
Kapil Gupta137ef892016-12-13 19:38:00 +05309352 if (params->head)
9353 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009354 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309355 head = params->head;
9356 } else
9357 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309359 head = old->head;
9360 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009361
Kapil Gupta137ef892016-12-13 19:38:00 +05309362 if (params->tail || !old)
9363 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309365 tail = params->tail;
9366 } else
9367 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309369 tail = old->tail;
9370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009371
Kapil Gupta137ef892016-12-13 19:38:00 +05309372 if (params->proberesp_ies || !old)
9373 {
9374 proberesp_ies_len = params->proberesp_ies_len;
9375 proberesp_ies = params->proberesp_ies;
9376 } else
9377 {
9378 proberesp_ies_len = old->proberesp_ies_len;
9379 proberesp_ies = old->proberesp_ies;
9380 }
9381
9382 if (params->assocresp_ies || !old)
9383 {
9384 assocresp_ies_len = params->assocresp_ies_len;
9385 assocresp_ies = params->assocresp_ies;
9386 } else
9387 {
9388 assocresp_ies_len = old->assocresp_ies_len;
9389 assocresp_ies = old->assocresp_ies;
9390 }
9391
9392 size = sizeof(beacon_data_t) + head_len + tail_len +
9393 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009394
9395 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309397 {
9398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9399 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309401 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009402
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009403#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309404 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009405 beacon->dtim_period = params->dtim_period;
9406 else
9407 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009408#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309409 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009410 beacon->dtim_period = dtim_period;
9411 else
9412 beacon->dtim_period = old->dtim_period;
9413#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309414
Jeff Johnson295189b2012-06-20 16:38:30 -07009415 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9416 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309417 beacon->proberesp_ies = beacon->tail + tail_len;
9418 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9419
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 beacon->head_len = head_len;
9421 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309422 beacon->proberesp_ies_len = proberesp_ies_len;
9423 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009424
c_manjee527ecac2017-01-25 12:25:27 +05309425 if (head && head_len)
9426 memcpy(beacon->head, head, head_len);
9427 if (tail && tail_len)
9428 memcpy(beacon->tail, tail, tail_len);
9429 if (proberesp_ies && proberesp_ies_len)
9430 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9431 if (assocresp_ies && assocresp_ies_len)
9432 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009433
9434 *ppBeacon = beacon;
9435
9436 kfree(old);
9437
9438 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009439}
Jeff Johnson295189b2012-06-20 16:38:30 -07009440
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309441v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9442#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9443 const v_U8_t *pIes,
9444#else
9445 v_U8_t *pIes,
9446#endif
9447 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009448{
9449 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309450 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009451 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309452
Jeff Johnson295189b2012-06-20 16:38:30 -07009453 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309454 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 elem_id = ptr[0];
9456 elem_len = ptr[1];
9457 left -= 2;
9458 if(elem_len > left)
9459 {
9460 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009461 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009462 eid,elem_len,left);
9463 return NULL;
9464 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309465 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 {
9467 return ptr;
9468 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309469
Jeff Johnson295189b2012-06-20 16:38:30 -07009470 left -= elem_len;
9471 ptr += (elem_len + 2);
9472 }
9473 return NULL;
9474}
9475
Jeff Johnson295189b2012-06-20 16:38:30 -07009476/* Check if rate is 11g rate or not */
9477static int wlan_hdd_rate_is_11g(u8 rate)
9478{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009479 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009480 u8 i;
9481 for (i = 0; i < 8; i++)
9482 {
9483 if(rate == gRateArray[i])
9484 return TRUE;
9485 }
9486 return FALSE;
9487}
9488
9489/* Check for 11g rate and set proper 11g only mode */
9490static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9491 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9492{
9493 u8 i, num_rates = pIe[0];
9494
9495 pIe += 1;
9496 for ( i = 0; i < num_rates; i++)
9497 {
9498 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9499 {
9500 /* If rate set have 11g rate than change the mode to 11G */
9501 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9502 if (pIe[i] & BASIC_RATE_MASK)
9503 {
9504 /* If we have 11g rate as basic rate, it means mode
9505 is 11g only mode.
9506 */
9507 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9508 *pCheckRatesfor11g = FALSE;
9509 }
9510 }
9511 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9512 {
9513 *require_ht = TRUE;
9514 }
9515 }
9516 return;
9517}
9518
9519static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9520{
9521 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9522 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9523 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9524 u8 checkRatesfor11g = TRUE;
9525 u8 require_ht = FALSE;
9526 u8 *pIe=NULL;
9527
9528 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9529
9530 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9531 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9532 if (pIe != NULL)
9533 {
9534 pIe += 1;
9535 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9536 &pConfig->SapHw_mode);
9537 }
9538
9539 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9540 WLAN_EID_EXT_SUPP_RATES);
9541 if (pIe != NULL)
9542 {
9543
9544 pIe += 1;
9545 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9546 &pConfig->SapHw_mode);
9547 }
9548
9549 if( pConfig->channel > 14 )
9550 {
9551 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9552 }
9553
9554 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9555 WLAN_EID_HT_CAPABILITY);
9556
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309557 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009558 {
9559 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9560 if(require_ht)
9561 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9562 }
9563}
9564
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309565static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9566 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9567{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009568 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309569 v_U8_t *pIe = NULL;
9570 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9571
9572 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9573 pBeacon->tail, pBeacon->tail_len);
9574
9575 if (pIe)
9576 {
9577 ielen = pIe[1] + 2;
9578 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9579 {
9580 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9581 }
9582 else
9583 {
9584 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9585 return -EINVAL;
9586 }
9587 *total_ielen += ielen;
9588 }
9589 return 0;
9590}
9591
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009592static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9593 v_U8_t *genie, v_U8_t *total_ielen)
9594{
9595 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9596 int left = pBeacon->tail_len;
9597 v_U8_t *ptr = pBeacon->tail;
9598 v_U8_t elem_id, elem_len;
9599 v_U16_t ielen = 0;
9600
9601 if ( NULL == ptr || 0 == left )
9602 return;
9603
9604 while (left >= 2)
9605 {
9606 elem_id = ptr[0];
9607 elem_len = ptr[1];
9608 left -= 2;
9609 if (elem_len > left)
9610 {
9611 hddLog( VOS_TRACE_LEVEL_ERROR,
9612 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9613 elem_id, elem_len, left);
9614 return;
9615 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309616 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009617 {
9618 /* skipping the VSIE's which we don't want to include or
9619 * it will be included by existing code
9620 */
9621 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9622#ifdef WLAN_FEATURE_WFD
9623 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9624#endif
9625 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9626 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9627 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9628 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9629 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9630 {
9631 ielen = ptr[1] + 2;
9632 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9633 {
9634 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9635 *total_ielen += ielen;
9636 }
9637 else
9638 {
9639 hddLog( VOS_TRACE_LEVEL_ERROR,
9640 "IE Length is too big "
9641 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9642 elem_id, elem_len, *total_ielen);
9643 }
9644 }
9645 }
9646
9647 left -= elem_len;
9648 ptr += (elem_len + 2);
9649 }
9650 return;
9651}
9652
Kapil Gupta137ef892016-12-13 19:38:00 +05309653int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009654{
9655 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309656 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009658 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309659 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009660
9661 genie = vos_mem_malloc(MAX_GENIE_LEN);
9662
9663 if(genie == NULL) {
9664
9665 return -ENOMEM;
9666 }
9667
Kapil Gupta137ef892016-12-13 19:38:00 +05309668 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309669 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9670 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009671 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309672 hddLog(LOGE,
9673 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309674 ret = -EINVAL;
9675 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009676 }
9677
9678#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309679 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9680 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9681 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309682 hddLog(LOGE,
9683 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309684 ret = -EINVAL;
9685 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 }
9687#endif
9688
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309689 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9690 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009691 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309692 hddLog(LOGE,
9693 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309694 ret = -EINVAL;
9695 goto done;
9696 }
9697
9698 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9699 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009700 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009702
9703 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9704 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9705 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9706 {
9707 hddLog(LOGE,
9708 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009709 ret = -EINVAL;
9710 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009711 }
9712
9713 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9714 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9715 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9716 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9717 ==eHAL_STATUS_FAILURE)
9718 {
9719 hddLog(LOGE,
9720 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009721 ret = -EINVAL;
9722 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009723 }
9724
9725 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309726 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009727 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309728 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009729 u8 probe_rsp_ie_len[3] = {0};
9730 u8 counter = 0;
9731 /* Check Probe Resp Length if it is greater then 255 then Store
9732 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9733 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9734 Store More then 255 bytes into One Variable.
9735 */
9736 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9737 {
9738 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9739 {
9740 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9741 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9742 }
9743 else
9744 {
9745 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9746 rem_probe_resp_ie_len = 0;
9747 }
9748 }
9749
9750 rem_probe_resp_ie_len = 0;
9751
9752 if (probe_rsp_ie_len[0] > 0)
9753 {
9754 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9755 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309756 (tANI_U8*)&pBeacon->
9757 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 probe_rsp_ie_len[0], NULL,
9759 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9760 {
9761 hddLog(LOGE,
9762 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009763 ret = -EINVAL;
9764 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009765 }
9766 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9767 }
9768
9769 if (probe_rsp_ie_len[1] > 0)
9770 {
9771 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9772 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309773 (tANI_U8*)&pBeacon->
9774 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 probe_rsp_ie_len[1], NULL,
9776 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9777 {
9778 hddLog(LOGE,
9779 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009780 ret = -EINVAL;
9781 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 }
9783 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9784 }
9785
9786 if (probe_rsp_ie_len[2] > 0)
9787 {
9788 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9789 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309790 (tANI_U8*)&pBeacon->
9791 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009792 probe_rsp_ie_len[2], NULL,
9793 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9794 {
9795 hddLog(LOGE,
9796 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009797 ret = -EINVAL;
9798 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 }
9800 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9801 }
9802
9803 if (probe_rsp_ie_len[1] == 0 )
9804 {
9805 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9806 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9807 eANI_BOOLEAN_FALSE) )
9808 {
9809 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009810 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009811 }
9812 }
9813
9814 if (probe_rsp_ie_len[2] == 0 )
9815 {
9816 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9817 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9818 eANI_BOOLEAN_FALSE) )
9819 {
9820 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009821 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009822 }
9823 }
9824
9825 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9826 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9827 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9828 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9829 == eHAL_STATUS_FAILURE)
9830 {
9831 hddLog(LOGE,
9832 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009833 ret = -EINVAL;
9834 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009835 }
9836 }
9837 else
9838 {
9839 // Reset WNI_CFG_PROBE_RSP Flags
9840 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9841
9842 hddLog(VOS_TRACE_LEVEL_INFO,
9843 "%s: No Probe Response IE received in set beacon",
9844 __func__);
9845 }
9846
9847 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309848 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 {
9850 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309851 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9852 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009853 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9854 {
9855 hddLog(LOGE,
9856 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009857 ret = -EINVAL;
9858 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009859 }
9860
9861 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9862 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9863 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9864 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9865 == eHAL_STATUS_FAILURE)
9866 {
9867 hddLog(LOGE,
9868 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009869 ret = -EINVAL;
9870 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 }
9872 }
9873 else
9874 {
9875 hddLog(VOS_TRACE_LEVEL_INFO,
9876 "%s: No Assoc Response IE received in set beacon",
9877 __func__);
9878
9879 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9880 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9881 eANI_BOOLEAN_FALSE) )
9882 {
9883 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009884 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 }
9886 }
9887
Jeff Johnsone7245742012-09-05 17:12:55 -07009888done:
Jeff Johnson295189b2012-06-20 16:38:30 -07009889 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309890 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009891}
Jeff Johnson295189b2012-06-20 16:38:30 -07009892
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309893/*
Jeff Johnson295189b2012-06-20 16:38:30 -07009894 * FUNCTION: wlan_hdd_validate_operation_channel
9895 * called by wlan_hdd_cfg80211_start_bss() and
9896 * wlan_hdd_cfg80211_set_channel()
9897 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309898 * channel list.
9899 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07009900VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009901{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309902
Jeff Johnson295189b2012-06-20 16:38:30 -07009903 v_U32_t num_ch = 0;
9904 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
9905 u32 indx = 0;
9906 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309907 v_U8_t fValidChannel = FALSE, count = 0;
9908 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309909
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
9911
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309912 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07009913 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309914 /* Validate the channel */
9915 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309917 if ( channel == rfChannels[count].channelNum )
9918 {
9919 fValidChannel = TRUE;
9920 break;
9921 }
9922 }
9923 if (fValidChannel != TRUE)
9924 {
9925 hddLog(VOS_TRACE_LEVEL_ERROR,
9926 "%s: Invalid Channel [%d]", __func__, channel);
9927 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 }
9929 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309930 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05309932 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
9933 valid_ch, &num_ch))
9934 {
9935 hddLog(VOS_TRACE_LEVEL_ERROR,
9936 "%s: failed to get valid channel list", __func__);
9937 return VOS_STATUS_E_FAILURE;
9938 }
9939 for (indx = 0; indx < num_ch; indx++)
9940 {
9941 if (channel == valid_ch[indx])
9942 {
9943 break;
9944 }
9945 }
9946
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309947 if (indx >= num_ch)
9948 {
9949 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9950 {
9951 eCsrBand band;
9952 unsigned int freq;
9953
9954 sme_GetFreqBand(hHal, &band);
9955
9956 if (eCSR_BAND_5G == band)
9957 {
9958#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9959 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9960 {
9961 freq = ieee80211_channel_to_frequency(channel,
9962 IEEE80211_BAND_2GHZ);
9963 }
9964 else
9965 {
9966 freq = ieee80211_channel_to_frequency(channel,
9967 IEEE80211_BAND_5GHZ);
9968 }
9969#else
9970 freq = ieee80211_channel_to_frequency(channel);
9971#endif
9972 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
9973 return VOS_STATUS_SUCCESS;
9974 }
9975 }
9976
9977 hddLog(VOS_TRACE_LEVEL_ERROR,
9978 "%s: Invalid Channel [%d]", __func__, channel);
9979 return VOS_STATUS_E_FAILURE;
9980 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05309982
Jeff Johnson295189b2012-06-20 16:38:30 -07009983 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309984
Jeff Johnson295189b2012-06-20 16:38:30 -07009985}
9986
Viral Modi3a32cc52013-02-08 11:14:52 -08009987/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309988 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08009989 * This function is used to set the channel number
9990 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309991static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08009992 struct ieee80211_channel *chan,
9993 enum nl80211_channel_type channel_type
9994 )
9995{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309996 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08009997 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07009998 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08009999 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010000 hdd_context_t *pHddCtx;
10001 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010002
10003 ENTER();
10004
10005 if( NULL == dev )
10006 {
10007 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010008 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010009 return -ENODEV;
10010 }
10011 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010012
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010013 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10014 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10015 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010016 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010017 "%s: device_mode = %s (%d) freq = %d", __func__,
10018 hdd_device_modetoString(pAdapter->device_mode),
10019 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010020
10021 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10022 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010023 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010024 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010025 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010026 }
10027
10028 /*
10029 * Do freq to chan conversion
10030 * TODO: for 11a
10031 */
10032
10033 channel = ieee80211_frequency_to_channel(freq);
10034
10035 /* Check freq range */
10036 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10037 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10038 {
10039 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010040 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010041 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10042 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10043 return -EINVAL;
10044 }
10045
10046 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10047
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010048 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10049 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010050 {
10051 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10052 {
10053 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010054 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010055 return -EINVAL;
10056 }
10057 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10058 "%s: set channel to [%d] for device mode =%d",
10059 __func__, channel,pAdapter->device_mode);
10060 }
10061 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010062 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010063 )
10064 {
10065 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10066 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10067 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10068
10069 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10070 {
10071 /* Link is up then return cant set channel*/
10072 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010073 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010074 return -EINVAL;
10075 }
10076
10077 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10078 pHddStaCtx->conn_info.operationChannel = channel;
10079 pRoamProfile->ChannelInfo.ChannelList =
10080 &pHddStaCtx->conn_info.operationChannel;
10081 }
10082 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010083 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010084 )
10085 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010086 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10087 {
10088 if(VOS_STATUS_SUCCESS !=
10089 wlan_hdd_validate_operation_channel(pAdapter,channel))
10090 {
10091 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010092 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010093 return -EINVAL;
10094 }
10095 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10096 }
10097 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010098 {
10099 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10100
10101 /* If auto channel selection is configured as enable/ 1 then ignore
10102 channel set by supplicant
10103 */
10104 if ( cfg_param->apAutoChannelSelection )
10105 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010106 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10107 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010108 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010109 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10110 __func__, hdd_device_modetoString(pAdapter->device_mode),
10111 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010112 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010113 else
10114 {
10115 if(VOS_STATUS_SUCCESS !=
10116 wlan_hdd_validate_operation_channel(pAdapter,channel))
10117 {
10118 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010119 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010120 return -EINVAL;
10121 }
10122 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10123 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010124 }
10125 }
10126 else
10127 {
10128 hddLog(VOS_TRACE_LEVEL_FATAL,
10129 "%s: Invalid device mode failed to set valid channel", __func__);
10130 return -EINVAL;
10131 }
10132 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010133 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010134}
10135
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010136static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10137 struct net_device *dev,
10138 struct ieee80211_channel *chan,
10139 enum nl80211_channel_type channel_type
10140 )
10141{
10142 int ret;
10143
10144 vos_ssr_protect(__func__);
10145 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10146 vos_ssr_unprotect(__func__);
10147
10148 return ret;
10149}
10150
Anurag Chouhan83026002016-12-13 22:46:21 +053010151#ifdef DHCP_SERVER_OFFLOAD
10152void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10153 VOS_STATUS status)
10154{
10155 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10156
10157 ENTER();
10158
10159 if (NULL == adapter)
10160 {
10161 hddLog(VOS_TRACE_LEVEL_ERROR,
10162 "%s: adapter is NULL",__func__);
10163 return;
10164 }
10165
10166 adapter->dhcp_status.dhcp_offload_status = status;
10167 vos_event_set(&adapter->dhcp_status.vos_event);
10168 return;
10169}
10170
10171/**
10172 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10173 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010174 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010175 *
10176 * Return: None
10177 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010178VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10179 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010180{
10181 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10182 sir_dhcp_srv_offload_info dhcp_srv_info;
10183 tANI_U8 num_entries = 0;
10184 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10185 tANI_U8 num;
10186 tANI_U32 temp;
10187 VOS_STATUS ret;
10188
10189 ENTER();
10190
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010191 if (!re_init) {
10192 ret = wlan_hdd_validate_context(hdd_ctx);
10193 if (0 != ret)
10194 return VOS_STATUS_E_INVAL;
10195 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010196
10197 /* Prepare the request to send to SME */
10198 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10199 if (NULL == dhcp_srv_info) {
10200 hddLog(VOS_TRACE_LEVEL_ERROR,
10201 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10202 return VOS_STATUS_E_NOMEM;
10203 }
10204
10205 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10206
10207 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10208 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10209 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10210 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10211 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10212 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10213
10214 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10215 srv_ip,
10216 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010217 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010218 if (num_entries != IPADDR_NUM_ENTRIES) {
10219 hddLog(VOS_TRACE_LEVEL_ERROR,
10220 "%s: incorrect IP address (%s) assigned for DHCP server!",
10221 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10222 vos_mem_free(dhcp_srv_info);
10223 return VOS_STATUS_E_FAILURE;
10224 }
10225
10226 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10227 hddLog(VOS_TRACE_LEVEL_ERROR,
10228 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10229 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10230 vos_mem_free(dhcp_srv_info);
10231 return VOS_STATUS_E_FAILURE;
10232 }
10233
10234 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10235 hddLog(VOS_TRACE_LEVEL_ERROR,
10236 "%s: invalid IP address (%s)! The last field must be less than 100!",
10237 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10238 vos_mem_free(dhcp_srv_info);
10239 return VOS_STATUS_E_FAILURE;
10240 }
10241
10242 for (num = 0; num < num_entries; num++) {
10243 temp = srv_ip[num];
10244 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10245 }
10246
10247 if (eHAL_STATUS_SUCCESS !=
10248 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10249 hddLog(VOS_TRACE_LEVEL_ERROR,
10250 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10251 vos_mem_free(dhcp_srv_info);
10252 return VOS_STATUS_E_FAILURE;
10253 }
10254
10255 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10256 "%s: enable DHCP Server offload successfully!", __func__);
10257
10258 vos_mem_free(dhcp_srv_info);
10259 return 0;
10260}
10261#endif /* DHCP_SERVER_OFFLOAD */
10262
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010263/*
10264 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10265 * @wiphy_chan: wiphy channel number
10266 * @rfChannel: channel hw value
10267 * @disable: Disable/enable the flags
10268 *
10269 * Modify wiphy flags and cds state if channel is indoor.
10270 *
10271 * Return: void
10272 */
10273void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
10274 v_U32_t rfChannel, bool disable)
10275{
10276 v_U32_t channelLoop;
10277 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10278
10279 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10280
10281 if (rfChannels[channelLoop].channelNum == rfChannel) {
10282 channelEnum = (eRfChannels)channelLoop;
10283 break;
10284 }
10285 }
10286
10287 if (INVALID_RF_CHANNEL == channelEnum)
10288 return;
10289
10290 if (disable) {
10291 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10292 wiphy_chan->flags |=
10293 IEEE80211_CHAN_DISABLED;
10294 regChannels[channelEnum].enabled =
10295 NV_CHANNEL_DISABLE;
10296 }
10297 } else {
10298 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10299 wiphy_chan->flags &=
10300 ~IEEE80211_CHAN_DISABLED;
10301 /*
10302 * Indoor channels are marked as DFS
10303 * during regulatory processing
10304 */
10305
10306 regChannels[channelEnum].enabled =
10307 NV_CHANNEL_DFS;
10308 }
10309 }
10310
10311}
10312
10313void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
10314 bool disable)
10315{
10316 int band_num;
10317 int chan_num;
10318 v_U32_t rfChannel;
10319 struct ieee80211_channel *wiphy_chan;
10320 struct wiphy *wiphy;
10321
10322 ENTER();
10323 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10324
10325 wiphy = hdd_ctx->wiphy;
10326 for (band_num = 0; band_num < IEEE80211_NUM_BANDS; band_num++) {
10327
10328 if (wiphy->bands[band_num] == NULL)
10329 continue;
10330
10331 for (chan_num = 0;
10332 chan_num < wiphy->bands[band_num]->n_channels;
10333 chan_num++) {
10334
10335 wiphy_chan =
10336 &(wiphy->bands[band_num]->channels[chan_num]);
10337 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10338
10339 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
10340 disable);
10341 }
10342 }
10343 EXIT();
10344}
10345
10346
Jeff Johnson295189b2012-06-20 16:38:30 -070010347#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10348static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10349 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010350#else
10351static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10352 struct cfg80211_beacon_data *params,
10353 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010354 enum nl80211_hidden_ssid hidden_ssid,
10355 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010356#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010357{
10358 tsap_Config_t *pConfig;
10359 beacon_data_t *pBeacon = NULL;
10360 struct ieee80211_mgmt *pMgmt_frame;
10361 v_U8_t *pIe=NULL;
10362 v_U16_t capab_info;
10363 eCsrAuthType RSNAuthType;
10364 eCsrEncryptionType RSNEncryptType;
10365 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010366 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 tpWLAN_SAPEventCB pSapEventCallback;
10368 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010369 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010370 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010372 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010373 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010374 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010375 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010376 v_BOOL_t MFPCapable = VOS_FALSE;
10377 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010378 v_BOOL_t sapEnable11AC =
10379 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010380 u_int16_t prev_rsn_length = 0;
10381
Jeff Johnson295189b2012-06-20 16:38:30 -070010382 ENTER();
10383
Nitesh Shah9b066282017-06-06 18:05:52 +053010384 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010385 iniConfig = pHddCtx->cfg_ini;
10386
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010387 /* Mark the indoor channel (passive) to disable */
10388 if (iniConfig->disable_indoor_channel) {
10389 hdd_update_indoor_channel(pHddCtx, true);
10390
10391 if (!VOS_IS_STATUS_SUCCESS(
10392 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10393 hdd_update_indoor_channel(pHddCtx, false);
10394 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
10395 FL("Can't start BSS: update channel list failed"));
10396 return eHAL_STATUS_FAILURE;
10397 }
10398 }
10399
Jeff Johnson295189b2012-06-20 16:38:30 -070010400 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10401
10402 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10403
10404 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10405
10406 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10407
10408 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10409
10410 //channel is already set in the set_channel Call back
10411 //pConfig->channel = pCommitConfig->channel;
10412
10413 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010414 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010415 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10416
10417 pConfig->dtim_period = pBeacon->dtim_period;
10418
Arif Hussain6d2a3322013-11-17 19:50:10 -080010419 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010420 pConfig->dtim_period);
10421
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010422 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010423 {
10424 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010426 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10427 {
10428 tANI_BOOLEAN restartNeeded;
10429 pConfig->ieee80211d = 1;
10430 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10431 sme_setRegInfo(hHal, pConfig->countryCode);
10432 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10433 }
10434 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010436 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010437 pConfig->ieee80211d = 1;
10438 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10439 sme_setRegInfo(hHal, pConfig->countryCode);
10440 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010441 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010442 else
10443 {
10444 pConfig->ieee80211d = 0;
10445 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010446 /*
10447 * If auto channel is configured i.e. channel is 0,
10448 * so skip channel validation.
10449 */
10450 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10451 {
10452 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10453 {
10454 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010455 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010456 return -EINVAL;
10457 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010458 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010459 }
10460 else
10461 {
10462 if(1 != pHddCtx->is_dynamic_channel_range_set)
10463 {
10464 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10465 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10466 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10467 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010468 pHddCtx->is_dynamic_channel_range_set = 0;
10469 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010470 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010471 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010472 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 {
10474 pConfig->ieee80211d = 0;
10475 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010476
10477#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10478 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10479 pConfig->authType = eSAP_OPEN_SYSTEM;
10480 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10481 pConfig->authType = eSAP_SHARED_KEY;
10482 else
10483 pConfig->authType = eSAP_AUTO_SWITCH;
10484#else
10485 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10486 pConfig->authType = eSAP_OPEN_SYSTEM;
10487 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10488 pConfig->authType = eSAP_SHARED_KEY;
10489 else
10490 pConfig->authType = eSAP_AUTO_SWITCH;
10491#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010492
10493 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010494
10495 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010496 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010497#ifdef SAP_AUTH_OFFLOAD
10498 /* In case of sap offload, hostapd.conf is configuted with open mode and
10499 * security is configured from ini file. Due to open mode in hostapd.conf
10500 * privacy bit is set to false which will result in not sending,
10501 * data packets as encrypted.
10502 * If enable_sap_auth_offload is enabled in ini and
10503 * sap_auth_offload_sec_type is type of WPA2-PSK,
10504 * driver will set privacy bit to 1.
10505 */
10506 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10507 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10508 pConfig->privacy = VOS_TRUE;
10509#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010510
10511 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10512
10513 /*Set wps station to configured*/
10514 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10515
10516 if(pIe)
10517 {
10518 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10519 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010520 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -070010521 return -EINVAL;
10522 }
10523 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10524 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010525 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010526 /* Check 15 bit of WPS IE as it contain information for wps state
10527 * WPS state
10528 */
10529 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10530 {
10531 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10532 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10533 {
10534 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10535 }
10536 }
10537 }
10538 else
10539 {
10540 pConfig->wps_state = SAP_WPS_DISABLED;
10541 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010542 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010543
c_hpothufe599e92014-06-16 11:38:55 +053010544 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10545 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
10546 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
10547 eCSR_ENCRYPT_TYPE_NONE;
10548
Jeff Johnson295189b2012-06-20 16:38:30 -070010549 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053010550 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010551 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010552 WLAN_EID_RSN);
10553 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010554 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010555 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010556 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10557 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10558 pConfig->RSNWPAReqIELength);
10559 else
10560 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10561 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010562 /* The actual processing may eventually be more extensive than
10563 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070010564 * by the app.
10565 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010566 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010567 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10568 &RSNEncryptType,
10569 &mcRSNEncryptType,
10570 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010571 &MFPCapable,
10572 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010573 pConfig->RSNWPAReqIE[1]+2,
10574 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010575
10576 if( VOS_STATUS_SUCCESS == status )
10577 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010578 /* Now copy over all the security attributes you have
10579 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010580 * */
10581 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10582 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10583 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10584 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010585 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010586 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010587 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10588 }
10589 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010590
Jeff Johnson295189b2012-06-20 16:38:30 -070010591 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10592 pBeacon->tail, pBeacon->tail_len);
10593
10594 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
10595 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010596 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010597 {
10598 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053010599 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010601 if (pConfig->RSNWPAReqIELength <=
10602 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
10603 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
10604 pIe[1] + 2);
10605 else
10606 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10607 pConfig->RSNWPAReqIELength);
10608
Jeff Johnson295189b2012-06-20 16:38:30 -070010609 }
10610 else
10611 {
10612 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053010613 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
10614 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
10615 pConfig->RSNWPAReqIELength);
10616 else
10617 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
10618 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010619 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070010620 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
10621 &RSNEncryptType,
10622 &mcRSNEncryptType,
10623 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080010624 &MFPCapable,
10625 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053010626 pConfig->RSNWPAReqIE[1]+2,
10627 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010628
10629 if( VOS_STATUS_SUCCESS == status )
10630 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010631 /* Now copy over all the security attributes you have
10632 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070010633 * */
10634 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
10635 pConfig->mcRSNEncryptType = mcRSNEncryptType;
10636 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
10637 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053010638 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010639 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070010640 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
10641 }
10642 }
10643 }
10644
Kapil Gupta137ef892016-12-13 19:38:00 +053010645 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070010646 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
10647 return -EINVAL;
10648 }
10649
Jeff Johnson295189b2012-06-20 16:38:30 -070010650 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
10651
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010652#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010653 if (params->ssid != NULL)
10654 {
10655 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
10656 pConfig->SSIDinfo.ssid.length = params->ssid_len;
10657 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10658 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10659 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010660#else
10661 if (ssid != NULL)
10662 {
10663 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
10664 pConfig->SSIDinfo.ssid.length = ssid_len;
10665 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
10666 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
10667 }
10668#endif
10669
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010670 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070010671 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010672
Jeff Johnson295189b2012-06-20 16:38:30 -070010673 /* default value */
10674 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
10675 pConfig->num_accept_mac = 0;
10676 pConfig->num_deny_mac = 0;
10677
10678 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10679 pBeacon->tail, pBeacon->tail_len);
10680
10681 /* pIe for black list is following form:
10682 type : 1 byte
10683 length : 1 byte
10684 OUI : 4 bytes
10685 acl type : 1 byte
10686 no of mac addr in black list: 1 byte
10687 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010688 */
10689 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010690 {
10691 pConfig->SapMacaddr_acl = pIe[6];
10692 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010693 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010694 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010695 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
10696 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010697 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10698 for (i = 0; i < pConfig->num_deny_mac; i++)
10699 {
10700 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10701 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010702 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 }
10704 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
10705 pBeacon->tail, pBeacon->tail_len);
10706
10707 /* pIe for white list is following form:
10708 type : 1 byte
10709 length : 1 byte
10710 OUI : 4 bytes
10711 acl type : 1 byte
10712 no of mac addr in white list: 1 byte
10713 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010714 */
10715 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010716 {
10717 pConfig->SapMacaddr_acl = pIe[6];
10718 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080010719 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010720 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010721 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
10722 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010723 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
10724 for (i = 0; i < pConfig->num_accept_mac; i++)
10725 {
10726 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
10727 acl_entry++;
10728 }
10729 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053010730
Jeff Johnson295189b2012-06-20 16:38:30 -070010731 wlan_hdd_set_sapHwmode(pHostapdAdapter);
10732
Jeff Johnsone7245742012-09-05 17:12:55 -070010733#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010734 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010735 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
10736 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053010737 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
10738 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080010739 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
10740 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010741 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
10742 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070010743 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010744 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070010745 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010746 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010747
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010748 /* If ACS disable and selected channel <= 14
10749 * OR
10750 * ACS enabled and ACS operating band is choosen as 2.4
10751 * AND
10752 * VHT in 2.4G Disabled
10753 * THEN
10754 * Fallback to 11N mode
10755 */
10756 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
10757 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053010758 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010759 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010760 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053010761 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
10762 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070010763 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
10764 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010765 }
10766#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010767
Jeff Johnson295189b2012-06-20 16:38:30 -070010768 // ht_capab is not what the name conveys,this is used for protection bitmap
10769 pConfig->ht_capab =
10770 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
10771
Kapil Gupta137ef892016-12-13 19:38:00 +053010772 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070010773 {
10774 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
10775 return -EINVAL;
10776 }
10777
10778 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010779 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070010780 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
10781 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010782 pConfig->obssProtEnabled =
10783 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070010784
Chet Lanctot8cecea22014-02-11 19:09:36 -080010785#ifdef WLAN_FEATURE_11W
10786 pConfig->mfpCapable = MFPCapable;
10787 pConfig->mfpRequired = MFPRequired;
10788 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
10789 pConfig->mfpCapable, pConfig->mfpRequired);
10790#endif
10791
Arif Hussain6d2a3322013-11-17 19:50:10 -080010792 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070010793 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010794 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
10795 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
10796 (int)pConfig->channel);
10797 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
10798 pConfig->SapHw_mode, pConfig->privacy,
10799 pConfig->authType);
10800 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
10801 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
10802 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
10803 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070010804
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010805 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070010806 {
10807 //Bss already started. just return.
10808 //TODO Probably it should update some beacon params.
10809 hddLog( LOGE, "Bss Already started...Ignore the request");
10810 EXIT();
10811 return 0;
10812 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010813
Agarwal Ashish51325b52014-06-16 16:50:49 +053010814 if (vos_max_concurrent_connections_reached()) {
10815 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10816 return -EINVAL;
10817 }
10818
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 pConfig->persona = pHostapdAdapter->device_mode;
10820
Peng Xu2446a892014-09-05 17:21:18 +053010821 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
10822 if ( NULL != psmeConfig)
10823 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010824 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053010825 sme_GetConfigParam(hHal, psmeConfig);
10826 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053010827#ifdef WLAN_FEATURE_AP_HT40_24G
10828 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
10829 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
10830 && pHddCtx->cfg_ini->apHT40_24GEnabled)
10831 {
10832 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
10833 sme_UpdateConfig (hHal, psmeConfig);
10834 }
10835#endif
Peng Xu2446a892014-09-05 17:21:18 +053010836 vos_mem_free(psmeConfig);
10837 }
Peng Xuafc34e32014-09-25 13:23:55 +053010838 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053010839
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010840 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10841
Jeff Johnson295189b2012-06-20 16:38:30 -070010842 pSapEventCallback = hdd_hostapd_SAPEventCB;
10843 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
10844 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
10845 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010846 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010847 ret = -EINVAL;
10848 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010849 }
10850
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010851 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070010852 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
10853
10854 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010855
Jeff Johnson295189b2012-06-20 16:38:30 -070010856 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010857 {
10858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010859 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070010860 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070010861 VOS_ASSERT(0);
10862 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010863
Jeff Johnson295189b2012-06-20 16:38:30 -070010864 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053010865 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
10866 VOS_STATUS_SUCCESS)
10867 {
10868 hddLog(LOGE,FL("Fail to get Softap sessionID"));
10869 VOS_ASSERT(0);
10870 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053010871 /* Initialize WMM configuation */
10872 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053010873 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010874
Anurag Chouhan83026002016-12-13 22:46:21 +053010875#ifdef DHCP_SERVER_OFFLOAD
10876 /* set dhcp server offload */
10877 if (iniConfig->enable_dhcp_srv_offload &&
10878 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010879 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010880 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010881 if (!VOS_IS_STATUS_SUCCESS(status))
10882 {
10883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10884 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010885 vos_event_reset(&pHostapdState->vosEvent);
10886 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10887 status = vos_wait_single_event(&pHostapdState->vosEvent,
10888 10000);
10889 if (!VOS_IS_STATUS_SUCCESS(status)) {
10890 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010891 ret = -EINVAL;
10892 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010893 }
10894 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010895 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010896 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
10897 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
10898 {
10899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10900 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
10901 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010902 vos_event_reset(&pHostapdState->vosEvent);
10903 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
10904 status = vos_wait_single_event(&pHostapdState->vosEvent,
10905 10000);
10906 if (!VOS_IS_STATUS_SUCCESS(status)) {
10907 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010908 ret = -EINVAL;
10909 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010910 }
10911 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010912 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010913#ifdef MDNS_OFFLOAD
10914 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010915 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010916 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
10917 if (VOS_IS_STATUS_SUCCESS(status))
10918 {
10919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10920 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010921 vos_event_reset(&pHostapdState->vosEvent);
10922 if (VOS_STATUS_SUCCESS ==
10923 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10924 status = vos_wait_single_event(&pHostapdState->vosEvent,
10925 10000);
10926 if (!VOS_IS_STATUS_SUCCESS(status)) {
10927 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010928 ret = -EINVAL;
10929 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010930 }
10931 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010932 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010933 status = vos_wait_single_event(&pHostapdAdapter->
10934 mdns_status.vos_event, 2000);
10935 if (!VOS_IS_STATUS_SUCCESS(status) ||
10936 pHostapdAdapter->mdns_status.mdns_enable_status ||
10937 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
10938 pHostapdAdapter->mdns_status.mdns_resp_status)
10939 {
10940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10941 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
10942 pHostapdAdapter->mdns_status.mdns_enable_status,
10943 pHostapdAdapter->mdns_status.mdns_fqdn_status,
10944 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010945 vos_event_reset(&pHostapdState->vosEvent);
10946 if (VOS_STATUS_SUCCESS ==
10947 WLANSAP_StopBss(pHddCtx->pvosContext)) {
10948 status = vos_wait_single_event(&pHostapdState->vosEvent,
10949 10000);
10950 if (!VOS_IS_STATUS_SUCCESS(status)) {
10951 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010952 ret = -EINVAL;
10953 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053010954 }
10955 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053010956 }
10957 }
10958#endif /* MDNS_OFFLOAD */
10959 } else {
10960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10961 ("DHCP Disabled ini %d, FW %d"),
10962 iniConfig->enable_dhcp_srv_offload,
10963 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053010964 }
10965#endif /* DHCP_SERVER_OFFLOAD */
10966
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010967#ifdef WLAN_FEATURE_P2P_DEBUG
10968 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
10969 {
10970 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
10971 {
10972 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10973 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010974 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010975 }
10976 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
10977 {
10978 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
10979 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080010980 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010981 }
10982 }
10983#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053010984 /* Check and restart SAP if it is on Unsafe channel */
10985 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070010986
Jeff Johnson295189b2012-06-20 16:38:30 -070010987 pHostapdState->bCommit = TRUE;
10988 EXIT();
10989
10990 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010991error:
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010992 /* Revert the indoor to passive marking if START BSS fails */
10993 if (iniConfig->disable_indoor_channel) {
10994 hdd_update_indoor_channel(pHddCtx, false);
10995 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
10996 }
10997
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010998 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
10999 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011000}
11001
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011002#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011003static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011004 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011005 struct beacon_parameters *params)
11006{
11007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011008 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011009 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011010
11011 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011012
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011013 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11014 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11015 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011016 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11017 hdd_device_modetoString(pAdapter->device_mode),
11018 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011019
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011020 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11021 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011022 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011023 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011024 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011025 }
11026
Agarwal Ashish51325b52014-06-16 16:50:49 +053011027 if (vos_max_concurrent_connections_reached()) {
11028 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11029 return -EINVAL;
11030 }
11031
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011032 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011033 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011034 )
11035 {
11036 beacon_data_t *old,*new;
11037
11038 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011039
Jeff Johnson295189b2012-06-20 16:38:30 -070011040 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011041 {
11042 hddLog(VOS_TRACE_LEVEL_WARN,
11043 FL("already beacon info added to session(%d)"),
11044 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011045 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011046 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011047
11048 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11049
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011050 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011051 {
11052 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011053 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011054 return -EINVAL;
11055 }
11056
11057 pAdapter->sessionCtx.ap.beacon = new;
11058
11059 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11060 }
11061
11062 EXIT();
11063 return status;
11064}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011065
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011066static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11067 struct net_device *dev,
11068 struct beacon_parameters *params)
11069{
11070 int ret;
11071
11072 vos_ssr_protect(__func__);
11073 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11074 vos_ssr_unprotect(__func__);
11075
11076 return ret;
11077}
11078
11079static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011080 struct net_device *dev,
11081 struct beacon_parameters *params)
11082{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011083 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011084 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11085 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011086 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011087
11088 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011089
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011090 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11091 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11092 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11093 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11094 __func__, hdd_device_modetoString(pAdapter->device_mode),
11095 pAdapter->device_mode);
11096
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011097 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11098 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011099 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011100 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011101 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011102 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011103
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011104 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011105 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011106 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011107 {
11108 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011109
Jeff Johnson295189b2012-06-20 16:38:30 -070011110 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011111
Jeff Johnson295189b2012-06-20 16:38:30 -070011112 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011113 {
11114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11115 FL("session(%d) old and new heads points to NULL"),
11116 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011117 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011118 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011119
11120 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11121
11122 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011123 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011124 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011125 return -EINVAL;
11126 }
11127
11128 pAdapter->sessionCtx.ap.beacon = new;
11129
11130 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11131 }
11132
11133 EXIT();
11134 return status;
11135}
11136
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011137static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11138 struct net_device *dev,
11139 struct beacon_parameters *params)
11140{
11141 int ret;
11142
11143 vos_ssr_protect(__func__);
11144 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11145 vos_ssr_unprotect(__func__);
11146
11147 return ret;
11148}
11149
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011150#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11151
11152#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011153static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011155#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011156static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011157 struct net_device *dev)
11158#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011159{
11160 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011161 hdd_context_t *pHddCtx = NULL;
11162 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011163 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011164 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011165
11166 ENTER();
11167
11168 if (NULL == pAdapter)
11169 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011171 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011172 return -ENODEV;
11173 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011174
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011175 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11176 TRACE_CODE_HDD_CFG80211_STOP_AP,
11177 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011178 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11179 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011180 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011181 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011182 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011183 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011184
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011185 pScanInfo = &pHddCtx->scan_info;
11186
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011187 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11188 __func__, hdd_device_modetoString(pAdapter->device_mode),
11189 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011190
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011191 ret = wlan_hdd_scan_abort(pAdapter);
11192
Girish Gowli4bf7a632014-06-12 13:42:11 +053011193 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011194 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11196 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011197
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011198 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011199 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11201 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011202
Jeff Johnsone7245742012-09-05 17:12:55 -070011203 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011204 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011205 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011206 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011207 }
11208
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011209 /* Delete all associated STAs before stopping AP/P2P GO */
11210 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011211 hdd_hostapd_stop(dev);
11212
Jeff Johnson295189b2012-06-20 16:38:30 -070011213 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011214 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011215 )
11216 {
11217 beacon_data_t *old;
11218
11219 old = pAdapter->sessionCtx.ap.beacon;
11220
11221 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011222 {
11223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11224 FL("session(%d) beacon data points to NULL"),
11225 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011226 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011227 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011228
Jeff Johnson295189b2012-06-20 16:38:30 -070011229 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011230
11231 mutex_lock(&pHddCtx->sap_lock);
11232 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11233 {
Jeff Johnson4416a782013-03-25 14:17:50 -070011234 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 {
11236 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11237
11238 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11239
11240 if (!VOS_IS_STATUS_SUCCESS(status))
11241 {
11242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011243 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011245 }
11246 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011247 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011248 /* BSS stopped, clear the active sessions for this device mode */
11249 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011250 }
11251 mutex_unlock(&pHddCtx->sap_lock);
11252
11253 if(status != VOS_STATUS_SUCCESS)
11254 {
11255 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011256 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011257 return -EINVAL;
11258 }
11259
Jeff Johnson4416a782013-03-25 14:17:50 -070011260 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011261 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11262 ==eHAL_STATUS_FAILURE)
11263 {
11264 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011265 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011266 }
11267
Jeff Johnson4416a782013-03-25 14:17:50 -070011268 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11270 eANI_BOOLEAN_FALSE) )
11271 {
11272 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011273 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011274 }
11275
11276 // Reset WNI_CFG_PROBE_RSP Flags
11277 wlan_hdd_reset_prob_rspies(pAdapter);
11278
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011279 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11280
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 pAdapter->sessionCtx.ap.beacon = NULL;
11282 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011283#ifdef WLAN_FEATURE_P2P_DEBUG
11284 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11285 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11286 {
11287 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11288 "GO got removed");
11289 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11290 }
11291#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011292 }
11293 EXIT();
11294 return status;
11295}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011296
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011297#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11298static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11299 struct net_device *dev)
11300{
11301 int ret;
11302
11303 vos_ssr_protect(__func__);
11304 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11305 vos_ssr_unprotect(__func__);
11306
11307 return ret;
11308}
11309#else
11310static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11311 struct net_device *dev)
11312{
11313 int ret;
11314
11315 vos_ssr_protect(__func__);
11316 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11317 vos_ssr_unprotect(__func__);
11318
11319 return ret;
11320}
11321#endif
11322
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011323#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11324
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011325static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011326 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011327 struct cfg80211_ap_settings *params)
11328{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011329 hdd_adapter_t *pAdapter;
11330 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011331 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011332
11333 ENTER();
11334
Girish Gowlib143d7a2015-02-18 19:39:55 +053011335 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011336 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011338 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011339 return -ENODEV;
11340 }
11341
11342 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11343 if (NULL == pAdapter)
11344 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011346 "%s: HDD adapter is Null", __func__);
11347 return -ENODEV;
11348 }
11349
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011350 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11351 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11352 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011353 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11354 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011356 "%s: HDD adapter magic is invalid", __func__);
11357 return -ENODEV;
11358 }
11359
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011360 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11361
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011362 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011363 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011364 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011365 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011366 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011367 }
11368
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011369 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11370 __func__, hdd_device_modetoString(pAdapter->device_mode),
11371 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011372
11373 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011374 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011375 )
11376 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011377 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011378
11379 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011380
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011381 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011382 {
11383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11384 FL("already beacon info added to session(%d)"),
11385 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011386 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011387 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011388
Girish Gowlib143d7a2015-02-18 19:39:55 +053011389#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11390 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11391 &new,
11392 &params->beacon);
11393#else
11394 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11395 &new,
11396 &params->beacon,
11397 params->dtim_period);
11398#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011399
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011400 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011401 {
11402 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011403 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011404 return -EINVAL;
11405 }
11406 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011407#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011408 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11409#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11410 params->channel, params->channel_type);
11411#else
11412 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11413#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011414#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011415 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011416 params->ssid_len, params->hidden_ssid,
11417 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011418 }
11419
11420 EXIT();
11421 return status;
11422}
11423
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011424static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11425 struct net_device *dev,
11426 struct cfg80211_ap_settings *params)
11427{
11428 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011429
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011430 vos_ssr_protect(__func__);
11431 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11432 vos_ssr_unprotect(__func__);
11433
11434 return ret;
11435}
11436
11437static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011438 struct net_device *dev,
11439 struct cfg80211_beacon_data *params)
11440{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011441 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011442 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011443 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011444
11445 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011446
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011447 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11448 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11449 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011450 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011451 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011452
11453 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11454 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011455 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011456 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011457 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011458 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011459
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011460 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011461 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011462 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011463 {
11464 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011465
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011466 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011467
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011468 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011469 {
11470 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11471 FL("session(%d) beacon data points to NULL"),
11472 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011473 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011474 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011475
11476 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11477
11478 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011479 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011480 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011481 return -EINVAL;
11482 }
11483
11484 pAdapter->sessionCtx.ap.beacon = new;
11485
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011486 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11487 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011488 }
11489
11490 EXIT();
11491 return status;
11492}
11493
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011494static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11495 struct net_device *dev,
11496 struct cfg80211_beacon_data *params)
11497{
11498 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011499
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011500 vos_ssr_protect(__func__);
11501 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11502 vos_ssr_unprotect(__func__);
11503
11504 return ret;
11505}
11506
11507#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011508
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011509static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 struct net_device *dev,
11511 struct bss_parameters *params)
11512{
11513 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011514 hdd_context_t *pHddCtx;
11515 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011516
11517 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011518
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011519 if (NULL == pAdapter)
11520 {
11521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11522 "%s: HDD adapter is Null", __func__);
11523 return -ENODEV;
11524 }
11525 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011526 ret = wlan_hdd_validate_context(pHddCtx);
11527 if (0 != ret)
11528 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011529 return ret;
11530 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011531 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11532 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11533 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011534 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11535 __func__, hdd_device_modetoString(pAdapter->device_mode),
11536 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011537
11538 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011539 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011540 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011541 {
11542 /* ap_isolate == -1 means that in change bss, upper layer doesn't
11543 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011544 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070011545 {
11546 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011547 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011548 }
11549
11550 EXIT();
11551 return 0;
11552}
11553
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011554static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
11555 struct net_device *dev,
11556 struct bss_parameters *params)
11557{
11558 int ret;
11559
11560 vos_ssr_protect(__func__);
11561 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
11562 vos_ssr_unprotect(__func__);
11563
11564 return ret;
11565}
Kiet Lam10841362013-11-01 11:36:50 +053011566/* FUNCTION: wlan_hdd_change_country_code_cd
11567* to wait for contry code completion
11568*/
11569void* wlan_hdd_change_country_code_cb(void *pAdapter)
11570{
11571 hdd_adapter_t *call_back_pAdapter = pAdapter;
11572 complete(&call_back_pAdapter->change_country_code);
11573 return NULL;
11574}
11575
Jeff Johnson295189b2012-06-20 16:38:30 -070011576/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011577 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
11579 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053011580int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011581 struct net_device *ndev,
11582 enum nl80211_iftype type,
11583 u32 *flags,
11584 struct vif_params *params
11585 )
11586{
11587 struct wireless_dev *wdev;
11588 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011589 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070011590 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011591 tCsrRoamProfile *pRoamProfile = NULL;
11592 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011593 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011594 eMib_dot11DesiredBssType connectedBssType;
11595 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011596 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011597
11598 ENTER();
11599
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011600 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011601 {
11602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11603 "%s: Adapter context is null", __func__);
11604 return VOS_STATUS_E_FAILURE;
11605 }
11606
11607 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11608 if (!pHddCtx)
11609 {
11610 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11611 "%s: HDD context is null", __func__);
11612 return VOS_STATUS_E_FAILURE;
11613 }
11614
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011615 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11616 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
11617 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011618 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011619 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070011620 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011621 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011622 }
11623
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011624 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11625 __func__, hdd_device_modetoString(pAdapter->device_mode),
11626 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011627
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053011628 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
11629 hddLog(VOS_TRACE_LEVEL_FATAL,
11630 "%s: STA + MON is in progress, cannot change interface",
11631 __func__);
11632 }
11633
Agarwal Ashish51325b52014-06-16 16:50:49 +053011634 if (vos_max_concurrent_connections_reached()) {
11635 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11636 return -EINVAL;
11637 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011638 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070011639 wdev = ndev->ieee80211_ptr;
11640
11641#ifdef WLAN_BTAMP_FEATURE
11642 if((NL80211_IFTYPE_P2P_CLIENT == type)||
11643 (NL80211_IFTYPE_ADHOC == type)||
11644 (NL80211_IFTYPE_AP == type)||
11645 (NL80211_IFTYPE_P2P_GO == type))
11646 {
11647 pHddCtx->isAmpAllowed = VOS_FALSE;
11648 // stop AMP traffic
11649 status = WLANBAP_StopAmp();
11650 if(VOS_STATUS_SUCCESS != status )
11651 {
11652 pHddCtx->isAmpAllowed = VOS_TRUE;
11653 hddLog(VOS_TRACE_LEVEL_FATAL,
11654 "%s: Failed to stop AMP", __func__);
11655 return -EINVAL;
11656 }
11657 }
11658#endif //WLAN_BTAMP_FEATURE
11659 /* Reset the current device mode bit mask*/
11660 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
11661
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053011662 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
11663 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
11664 (type == NL80211_IFTYPE_P2P_GO)))
11665 {
11666 /* Notify Mode change in case of concurrency.
11667 * Below function invokes TDLS teardown Functionality Since TDLS is
11668 * not Supported in case of concurrency i.e Once P2P session
11669 * is detected disable offchannel and teardown TDLS links
11670 */
11671 hddLog(LOG1,
11672 FL("Device mode = %d Interface type = %d"),
11673 pAdapter->device_mode, type);
11674 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
11675 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053011676
Jeff Johnson295189b2012-06-20 16:38:30 -070011677 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011678 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070011679 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011680 )
11681 {
11682 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080011683 if (!pWextState)
11684 {
11685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11686 "%s: pWextState is null", __func__);
11687 return VOS_STATUS_E_FAILURE;
11688 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011689 pRoamProfile = &pWextState->roamProfile;
11690 LastBSSType = pRoamProfile->BSSType;
11691
11692 switch (type)
11693 {
11694 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011695 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011696 hddLog(VOS_TRACE_LEVEL_INFO,
11697 "%s: setting interface Type to INFRASTRUCTURE", __func__);
11698 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011699#ifdef WLAN_FEATURE_11AC
11700 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
11701 {
11702 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
11703 }
11704#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011705 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070011706 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011708 //Check for sub-string p2p to confirm its a p2p interface
11709 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011710 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053011711#ifdef FEATURE_WLAN_TDLS
11712 mutex_lock(&pHddCtx->tdls_lock);
11713 wlan_hdd_tdls_exit(pAdapter, TRUE);
11714 mutex_unlock(&pHddCtx->tdls_lock);
11715#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011716 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11717 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11718 }
11719 else
11720 {
11721 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011723 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053011725
Jeff Johnson295189b2012-06-20 16:38:30 -070011726 case NL80211_IFTYPE_ADHOC:
11727 hddLog(VOS_TRACE_LEVEL_INFO,
11728 "%s: setting interface Type to ADHOC", __func__);
11729 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
11730 pRoamProfile->phyMode =
11731 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070011732 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053011734 hdd_set_ibss_ops( pAdapter );
11735 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053011736
11737 status = hdd_sta_id_hash_attach(pAdapter);
11738 if (VOS_STATUS_SUCCESS != status) {
11739 hddLog(VOS_TRACE_LEVEL_ERROR,
11740 FL("Failed to initialize hash for IBSS"));
11741 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 break;
11743
11744 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011746 {
11747 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11748 "%s: setting interface Type to %s", __func__,
11749 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
11750
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011751 //Cancel any remain on channel for GO mode
11752 if (NL80211_IFTYPE_P2P_GO == type)
11753 {
11754 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
11755 }
Mohit Khanna0f232092012-09-11 14:46:08 -070011756 if (NL80211_IFTYPE_AP == type)
11757 {
11758 /* As Loading WLAN Driver one interface being created for p2p device
11759 * address. This will take one HW STA and the max number of clients
11760 * that can connect to softAP will be reduced by one. so while changing
11761 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
11762 * interface as it is not required in SoftAP mode.
11763 */
11764
11765 // Get P2P Adapter
11766 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
11767
11768 if (pP2pAdapter)
11769 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053011770 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053011771 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070011772 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
11773 }
11774 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053011775 //Disable IMPS & BMPS for SAP/GO
11776 if(VOS_STATUS_E_FAILURE ==
11777 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
11778 {
11779 //Fail to Exit BMPS
11780 VOS_ASSERT(0);
11781 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053011782
11783 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
11784
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011785#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070011786
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011787 /* A Mutex Lock is introduced while changing the mode to
11788 * protect the concurrent access for the Adapters by TDLS
11789 * module.
11790 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011791 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011792#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053011794 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070011796 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11797 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011798#ifdef FEATURE_WLAN_TDLS
11799 mutex_unlock(&pHddCtx->tdls_lock);
11800#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011801 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
11802 (pConfig->apRandomBssidEnabled))
11803 {
11804 /* To meet Android requirements create a randomized
11805 MAC address of the form 02:1A:11:Fx:xx:xx */
11806 get_random_bytes(&ndev->dev_addr[3], 3);
11807 ndev->dev_addr[0] = 0x02;
11808 ndev->dev_addr[1] = 0x1A;
11809 ndev->dev_addr[2] = 0x11;
11810 ndev->dev_addr[3] |= 0xF0;
11811 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
11812 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080011813 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
11814 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070011815 }
11816
Jeff Johnson295189b2012-06-20 16:38:30 -070011817 hdd_set_ap_ops( pAdapter->dev );
11818
Kiet Lam10841362013-11-01 11:36:50 +053011819 /* This is for only SAP mode where users can
11820 * control country through ini.
11821 * P2P GO follows station country code
11822 * acquired during the STA scanning. */
11823 if((NL80211_IFTYPE_AP == type) &&
11824 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
11825 {
11826 int status = 0;
11827 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
11828 "%s: setting country code from INI ", __func__);
11829 init_completion(&pAdapter->change_country_code);
11830 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
11831 (void *)(tSmeChangeCountryCallback)
11832 wlan_hdd_change_country_code_cb,
11833 pConfig->apCntryCode, pAdapter,
11834 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053011835 eSIR_FALSE,
11836 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053011837 if (eHAL_STATUS_SUCCESS == status)
11838 {
11839 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011840 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053011841 &pAdapter->change_country_code,
11842 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011843 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053011844 {
11845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011846 FL("SME Timed out while setting country code %ld"),
11847 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080011848
11849 if (pHddCtx->isLogpInProgress)
11850 {
11851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11852 "%s: LOGP in Progress. Ignore!!!", __func__);
11853 return -EAGAIN;
11854 }
Kiet Lam10841362013-11-01 11:36:50 +053011855 }
11856 }
11857 else
11858 {
11859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011860 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053011861 return -EINVAL;
11862 }
11863 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053011864 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070011865 if(status != VOS_STATUS_SUCCESS)
11866 {
11867 hddLog(VOS_TRACE_LEVEL_FATAL,
11868 "%s: Error initializing the ap mode", __func__);
11869 return -EINVAL;
11870 }
11871 hdd_set_conparam(1);
11872
Nirav Shah7e3c8132015-06-22 23:51:42 +053011873 status = hdd_sta_id_hash_attach(pAdapter);
11874 if (VOS_STATUS_SUCCESS != status)
11875 {
11876 hddLog(VOS_TRACE_LEVEL_ERROR,
11877 FL("Failed to initialize hash for AP"));
11878 return -EINVAL;
11879 }
11880
Jeff Johnson295189b2012-06-20 16:38:30 -070011881 /*interface type changed update in wiphy structure*/
11882 if(wdev)
11883 {
11884 wdev->iftype = type;
11885 pHddCtx->change_iface = type;
11886 }
11887 else
11888 {
11889 hddLog(VOS_TRACE_LEVEL_ERROR,
11890 "%s: ERROR !!!! Wireless dev is NULL", __func__);
11891 return -EINVAL;
11892 }
11893 goto done;
11894 }
11895
11896 default:
11897 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11898 __func__);
11899 return -EOPNOTSUPP;
11900 }
11901 }
11902 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011903 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011904 )
11905 {
11906 switch(type)
11907 {
11908 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070011910 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053011911
11912 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011913#ifdef FEATURE_WLAN_TDLS
11914
11915 /* A Mutex Lock is introduced while changing the mode to
11916 * protect the concurrent access for the Adapters by TDLS
11917 * module.
11918 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053011919 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011920#endif
c_hpothu002231a2015-02-05 14:58:51 +053011921 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011922 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080011923 //Check for sub-string p2p to confirm its a p2p interface
11924 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011925 {
11926 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
11927 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
11928 }
11929 else
11930 {
11931 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070011932 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080011933 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053011934
11935 /* set con_mode to STA only when no SAP concurrency mode */
11936 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
11937 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070011938 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011939 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
11940 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053011941#ifdef FEATURE_WLAN_TDLS
11942 mutex_unlock(&pHddCtx->tdls_lock);
11943#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053011944 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070011945 if( VOS_STATUS_SUCCESS != status )
11946 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070011947 /* In case of JB, for P2P-GO, only change interface will be called,
11948 * This is the right place to enable back bmps_imps()
11949 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053011950 if (pHddCtx->hdd_wlan_suspended)
11951 {
11952 hdd_set_pwrparams(pHddCtx);
11953 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011954 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070011955 goto done;
11956 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070011957 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070011958 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070011959 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
11960 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070011961 goto done;
11962 default:
11963 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
11964 __func__);
11965 return -EOPNOTSUPP;
11966
11967 }
11968
11969 }
11970 else
11971 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011972 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
11973 __func__, hdd_device_modetoString(pAdapter->device_mode),
11974 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011975 return -EOPNOTSUPP;
11976 }
11977
11978
11979 if(pRoamProfile)
11980 {
11981 if ( LastBSSType != pRoamProfile->BSSType )
11982 {
11983 /*interface type changed update in wiphy structure*/
11984 wdev->iftype = type;
11985
11986 /*the BSS mode changed, We need to issue disconnect
11987 if connected or in IBSS disconnect state*/
11988 if ( hdd_connGetConnectedBssType(
11989 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
11990 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
11991 {
11992 /*need to issue a disconnect to CSR.*/
11993 INIT_COMPLETION(pAdapter->disconnect_comp_var);
11994 if( eHAL_STATUS_SUCCESS ==
11995 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
11996 pAdapter->sessionId,
11997 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
11998 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011999 ret = wait_for_completion_interruptible_timeout(
12000 &pAdapter->disconnect_comp_var,
12001 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12002 if (ret <= 0)
12003 {
12004 hddLog(VOS_TRACE_LEVEL_ERROR,
12005 FL("wait on disconnect_comp_var failed %ld"), ret);
12006 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012007 }
12008 }
12009 }
12010 }
12011
12012done:
12013 /*set bitmask based on updated value*/
12014 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012015
12016 /* Only STA mode support TM now
12017 * all other mode, TM feature should be disabled */
12018 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12019 (~VOS_STA & pHddCtx->concurrency_mode) )
12020 {
12021 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12022 }
12023
Jeff Johnson295189b2012-06-20 16:38:30 -070012024#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012025 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012026 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012027 {
12028 //we are ok to do AMP
12029 pHddCtx->isAmpAllowed = VOS_TRUE;
12030 }
12031#endif //WLAN_BTAMP_FEATURE
12032 EXIT();
12033 return 0;
12034}
12035
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012036/*
12037 * FUNCTION: wlan_hdd_cfg80211_change_iface
12038 * wrapper function to protect the actual implementation from SSR.
12039 */
12040int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12041 struct net_device *ndev,
12042 enum nl80211_iftype type,
12043 u32 *flags,
12044 struct vif_params *params
12045 )
12046{
12047 int ret;
12048
12049 vos_ssr_protect(__func__);
12050 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12051 vos_ssr_unprotect(__func__);
12052
12053 return ret;
12054}
12055
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012056#ifdef FEATURE_WLAN_TDLS
12057static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012058 struct net_device *dev,
12059#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12060 const u8 *mac,
12061#else
12062 u8 *mac,
12063#endif
12064 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012065{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012066 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012067 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012068 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012069 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012070 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012071 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012072
12073 ENTER();
12074
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012075 if (!dev) {
12076 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12077 return -EINVAL;
12078 }
12079
12080 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12081 if (!pAdapter) {
12082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12083 return -EINVAL;
12084 }
12085
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012086 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012087 {
12088 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12089 "Invalid arguments");
12090 return -EINVAL;
12091 }
Hoonki Lee27511902013-03-14 18:19:06 -070012092
12093 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12094 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12095 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012097 "%s: TDLS mode is disabled OR not enabled in FW."
12098 MAC_ADDRESS_STR " Request declined.",
12099 __func__, MAC_ADDR_ARRAY(mac));
12100 return -ENOTSUPP;
12101 }
12102
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012103 if (pHddCtx->isLogpInProgress)
12104 {
12105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12106 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012107 wlan_hdd_tdls_set_link_status(pAdapter,
12108 mac,
12109 eTDLS_LINK_IDLE,
12110 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012111 return -EBUSY;
12112 }
12113
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012114 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012115 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012116
12117 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012119 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12120 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012121 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012122 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012123 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012124
12125 /* in add station, we accept existing valid staId if there is */
12126 if ((0 == update) &&
12127 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12128 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012129 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012131 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012132 " link_status %d. staId %d. add station ignored.",
12133 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012134 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012135 return 0;
12136 }
12137 /* in change station, we accept only when staId is valid */
12138 if ((1 == update) &&
12139 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12140 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12141 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012142 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012144 "%s: " MAC_ADDRESS_STR
12145 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012146 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12147 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12148 mutex_unlock(&pHddCtx->tdls_lock);
12149 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012150 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012151 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012152
12153 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012154 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012155 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12157 "%s: " MAC_ADDRESS_STR
12158 " TDLS setup is ongoing. Request declined.",
12159 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012160 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012161 }
12162
12163 /* first to check if we reached to maximum supported TDLS peer.
12164 TODO: for now, return -EPERM looks working fine,
12165 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012166 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12167 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012168 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012169 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12170 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012171 " TDLS Max peer already connected. Request declined."
12172 " Num of peers (%d), Max allowed (%d).",
12173 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12174 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012175 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012176 }
12177 else
12178 {
12179 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012180 mutex_lock(&pHddCtx->tdls_lock);
12181 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012182 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012183 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012184 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012185 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12186 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12187 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012188 return -EPERM;
12189 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012190 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012191 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012192 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012193 wlan_hdd_tdls_set_link_status(pAdapter,
12194 mac,
12195 eTDLS_LINK_CONNECTING,
12196 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012197
Jeff Johnsond75fe012013-04-06 10:53:06 -070012198 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012199 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012200 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012202 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012203 if(StaParams->htcap_present)
12204 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012205 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012206 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012208 "ht_capa->extended_capabilities: %0x",
12209 StaParams->HTCap.extendedHtCapInfo);
12210 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012212 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012214 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012215 if(StaParams->vhtcap_present)
12216 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012218 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12219 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12220 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12221 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012222 {
12223 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012224 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012225 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012227 "[%d]: %x ", i, StaParams->supported_rates[i]);
12228 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012229 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012230 else if ((1 == update) && (NULL == StaParams))
12231 {
12232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12233 "%s : update is true, but staParams is NULL. Error!", __func__);
12234 return -EPERM;
12235 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012236
12237 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12238
12239 if (!update)
12240 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012241 /*Before adding sta make sure that device exited from BMPS*/
12242 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12243 {
12244 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12245 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12246 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12247 if (status != VOS_STATUS_SUCCESS) {
12248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12249 }
12250 }
12251
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012252 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012253 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012254 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012255 hddLog(VOS_TRACE_LEVEL_ERROR,
12256 FL("Failed to add TDLS peer STA. Enable Bmps"));
12257 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012258 return -EPERM;
12259 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012260 }
12261 else
12262 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012263 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012264 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012265 if (ret != eHAL_STATUS_SUCCESS) {
12266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12267 return -EPERM;
12268 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012269 }
12270
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012271 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012272 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12273
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012274 mutex_lock(&pHddCtx->tdls_lock);
12275 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12276
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012277 if ((pTdlsPeer != NULL) &&
12278 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012279 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012280 hddLog(VOS_TRACE_LEVEL_ERROR,
12281 FL("peer link status %u"), pTdlsPeer->link_status);
12282 mutex_unlock(&pHddCtx->tdls_lock);
12283 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012284 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012285 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012286
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012287 if (ret <= 0)
12288 {
12289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12290 "%s: timeout waiting for tdls add station indication %ld",
12291 __func__, ret);
12292 goto error;
12293 }
12294
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012295 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12296 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012298 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012299 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012300 }
12301
12302 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012303
12304error:
Atul Mittal115287b2014-07-08 13:26:33 +053012305 wlan_hdd_tdls_set_link_status(pAdapter,
12306 mac,
12307 eTDLS_LINK_IDLE,
12308 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012309 return -EPERM;
12310
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012311}
12312#endif
12313
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012314static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012316#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12317 const u8 *mac,
12318#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012319 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012320#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012321 struct station_parameters *params)
12322{
12323 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012324 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012325 hdd_context_t *pHddCtx;
12326 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012327 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012328 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012329#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012330 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012331 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012332 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012333 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012334#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012335
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012336 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012337
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012338 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012339 if ((NULL == pAdapter))
12340 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012342 "invalid adapter ");
12343 return -EINVAL;
12344 }
12345
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012346 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12347 TRACE_CODE_HDD_CHANGE_STATION,
12348 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012349 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012350
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012351 ret = wlan_hdd_validate_context(pHddCtx);
12352 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012353 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012354 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012355 }
12356
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012357 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12358
12359 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012360 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12362 "invalid HDD station context");
12363 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012364 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12366
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012367 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12368 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012369 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012370 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012371 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012372 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012373 WLANTL_STA_AUTHENTICATED);
12374
Gopichand Nakkala29149562013-05-10 21:43:41 +053012375 if (status != VOS_STATUS_SUCCESS)
12376 {
12377 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12378 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12379 return -EINVAL;
12380 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 }
12382 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012383 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12384 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012385#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012386 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12387 StaParams.capability = params->capability;
12388 StaParams.uapsd_queues = params->uapsd_queues;
12389 StaParams.max_sp = params->max_sp;
12390
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012391 /* Convert (first channel , number of channels) tuple to
12392 * the total list of channels. This goes with the assumption
12393 * that if the first channel is < 14, then the next channels
12394 * are an incremental of 1 else an incremental of 4 till the number
12395 * of channels.
12396 */
12397 if (0 != params->supported_channels_len) {
12398 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12399 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12400 {
12401 int wifi_chan_index;
12402 StaParams.supported_channels[j] = params->supported_channels[i];
12403 wifi_chan_index =
12404 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12405 no_of_channels = params->supported_channels[i+1];
12406 for(k=1; k <= no_of_channels; k++)
12407 {
12408 StaParams.supported_channels[j+1] =
12409 StaParams.supported_channels[j] + wifi_chan_index;
12410 j+=1;
12411 }
12412 }
12413 StaParams.supported_channels_len = j;
12414 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012415 if (params->supported_oper_classes_len >
12416 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12418 "received oper classes:%d, resetting it to max supported %d",
12419 params->supported_oper_classes_len,
12420 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12421 params->supported_oper_classes_len =
12422 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12423 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012424 vos_mem_copy(StaParams.supported_oper_classes,
12425 params->supported_oper_classes,
12426 params->supported_oper_classes_len);
12427 StaParams.supported_oper_classes_len =
12428 params->supported_oper_classes_len;
12429
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012430 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12432 "received extn capabilities:%d, resetting it to max supported",
12433 params->ext_capab_len);
12434 params->ext_capab_len = sizeof(StaParams.extn_capability);
12435 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012436 if (0 != params->ext_capab_len)
12437 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012438 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012439
12440 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012441 {
12442 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012443 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012444 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012445
12446 StaParams.supported_rates_len = params->supported_rates_len;
12447
12448 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12449 * The supported_rates array , for all the structures propogating till Add Sta
12450 * to the firmware has to be modified , if the supplicant (ieee80211) is
12451 * modified to send more rates.
12452 */
12453
12454 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12455 */
12456 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12457 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12458
12459 if (0 != StaParams.supported_rates_len) {
12460 int i = 0;
12461 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
12462 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012463 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012464 "Supported Rates with Length %d", StaParams.supported_rates_len);
12465 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012466 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012467 "[%d]: %0x", i, StaParams.supported_rates[i]);
12468 }
12469
12470 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012471 {
12472 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012473 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012474 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012475
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012476 if (0 != params->ext_capab_len ) {
12477 /*Define A Macro : TODO Sunil*/
12478 if ((1<<4) & StaParams.extn_capability[3]) {
12479 isBufSta = 1;
12480 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012481 /* TDLS Channel Switching Support */
12482 if ((1<<6) & StaParams.extn_capability[3]) {
12483 isOffChannelSupported = 1;
12484 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012485 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012486
12487 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053012488 (params->ht_capa || params->vht_capa ||
12489 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012490 /* TDLS Peer is WME/QoS capable */
12491 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012492
12493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12494 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
12495 __func__, isQosWmmSta, StaParams.htcap_present);
12496
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012497 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
12498 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012499 isOffChannelSupported,
12500 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012501
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053012502 if (VOS_STATUS_SUCCESS != status) {
12503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12504 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
12505 return -EINVAL;
12506 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012507 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
12508
12509 if (VOS_STATUS_SUCCESS != status) {
12510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12511 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
12512 return -EINVAL;
12513 }
12514 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012515#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053012516 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012517 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012518 return status;
12519}
12520
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012521#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
12522static int wlan_hdd_change_station(struct wiphy *wiphy,
12523 struct net_device *dev,
12524 const u8 *mac,
12525 struct station_parameters *params)
12526#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012527static int wlan_hdd_change_station(struct wiphy *wiphy,
12528 struct net_device *dev,
12529 u8 *mac,
12530 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012531#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012532{
12533 int ret;
12534
12535 vos_ssr_protect(__func__);
12536 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
12537 vos_ssr_unprotect(__func__);
12538
12539 return ret;
12540}
12541
Jeff Johnson295189b2012-06-20 16:38:30 -070012542/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012543 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 * This function is used to initialize the key information
12545 */
12546#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012547static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012548 struct net_device *ndev,
12549 u8 key_index, bool pairwise,
12550 const u8 *mac_addr,
12551 struct key_params *params
12552 )
12553#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012554static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012555 struct net_device *ndev,
12556 u8 key_index, const u8 *mac_addr,
12557 struct key_params *params
12558 )
12559#endif
12560{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012561 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012562 tCsrRoamSetKey setKey;
12563 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012564 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012565 v_U32_t roamId= 0xFF;
12566 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070012567 hdd_hostapd_state_t *pHostapdState;
12568 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012569 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012570 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012571 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012572 v_MACADDR_t *peerMacAddr;
12573 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012574 uint8_t staid = HDD_MAX_STA_COUNT;
12575 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012576
12577 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012578
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012579 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12580 TRACE_CODE_HDD_CFG80211_ADD_KEY,
12581 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012582 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12583 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012584 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012585 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012586 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012587 }
12588
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012589 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12590 __func__, hdd_device_modetoString(pAdapter->device_mode),
12591 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012592
12593 if (CSR_MAX_NUM_KEY <= key_index)
12594 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012595 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012596 key_index);
12597
12598 return -EINVAL;
12599 }
12600
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012601 if (CSR_MAX_KEY_LEN < params->key_len)
12602 {
12603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
12604 params->key_len);
12605
12606 return -EINVAL;
12607 }
12608
Jingxiang Gec438aea2017-10-26 16:44:00 +080012609 if (CSR_MAX_RSC_LEN < params->seq_len)
12610 {
12611 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
12612 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053012613
12614 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080012615 }
12616
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012617 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080012618 "%s: called with key index = %d & key length %d & seq length %d",
12619 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012620
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012621 peerMacAddr = (v_MACADDR_t *)mac_addr;
12622
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 /*extract key idx, key len and key*/
12624 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12625 setKey.keyId = key_index;
12626 setKey.keyLength = params->key_len;
12627 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080012628 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070012629
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012630 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 {
12632 case WLAN_CIPHER_SUITE_WEP40:
12633 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12634 break;
12635
12636 case WLAN_CIPHER_SUITE_WEP104:
12637 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
12638 break;
12639
12640 case WLAN_CIPHER_SUITE_TKIP:
12641 {
12642 u8 *pKey = &setKey.Key[0];
12643 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
12644
12645 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
12646
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012647 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070012648
12649 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012650 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012651 |--------------|----------|----------|
12652 <---16bytes---><--8bytes--><--8bytes-->
12653
12654 */
12655 /*Sme expects the 32 bytes key to be in the below order
12656
12657 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012658 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070012659 |--------------|----------|----------|
12660 <---16bytes---><--8bytes--><--8bytes-->
12661 */
12662 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012663 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070012664
12665 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012666 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012667
12668 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012669 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070012670
12671
12672 break;
12673 }
12674
12675 case WLAN_CIPHER_SUITE_CCMP:
12676 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
12677 break;
12678
12679#ifdef FEATURE_WLAN_WAPI
12680 case WLAN_CIPHER_SUITE_SMS4:
12681 {
12682 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
12683 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
12684 params->key, params->key_len);
12685 return 0;
12686 }
12687#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012688
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012689#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012690 case WLAN_CIPHER_SUITE_KRK:
12691 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
12692 break;
12693#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070012694
12695#ifdef WLAN_FEATURE_11W
12696 case WLAN_CIPHER_SUITE_AES_CMAC:
12697 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070012698 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070012699#endif
12700
Jeff Johnson295189b2012-06-20 16:38:30 -070012701 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012702 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012703 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012704 status = -EOPNOTSUPP;
12705 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012706 }
12707
12708 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
12709 __func__, setKey.encType);
12710
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012711 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070012712#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12713 (!pairwise)
12714#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012715 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070012716#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012717 )
12718 {
12719 /* set group key*/
12720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12721 "%s- %d: setting Broadcast key",
12722 __func__, __LINE__);
12723 setKey.keyDirection = eSIR_RX_ONLY;
12724 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12725 }
12726 else
12727 {
12728 /* set pairwise key*/
12729 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12730 "%s- %d: setting pairwise key",
12731 __func__, __LINE__);
12732 setKey.keyDirection = eSIR_TX_RX;
12733 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012734 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012735 }
12736 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
12737 {
12738 setKey.keyDirection = eSIR_TX_RX;
12739 /*Set the group key*/
12740 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12741 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070012742
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012743 if ( 0 != status )
12744 {
12745 hddLog(VOS_TRACE_LEVEL_ERROR,
12746 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012747 status = -EINVAL;
12748 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012749 }
12750 /*Save the keys here and call sme_RoamSetKey for setting
12751 the PTK after peer joins the IBSS network*/
12752 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
12753 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012754 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012755 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053012756 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
12757 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
12758 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012759 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012760 if( pHostapdState->bssState == BSS_START )
12761 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012762 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12763 vos_status = wlan_hdd_check_ula_done(pAdapter);
12764
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012765 if (peerMacAddr && (pairwise_set_key == true))
12766 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012767
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012768 if ( vos_status != VOS_STATUS_SUCCESS )
12769 {
12770 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12771 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12772 __LINE__, vos_status );
12773
12774 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
12775
12776 status = -EINVAL;
12777 goto end;
12778 }
12779
Jeff Johnson295189b2012-06-20 16:38:30 -070012780 status = WLANSAP_SetKeySta( pVosContext, &setKey);
12781
12782 if ( status != eHAL_STATUS_SUCCESS )
12783 {
12784 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12785 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
12786 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012787 status = -EINVAL;
12788 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012789 }
12790 }
12791
12792 /* Saving WEP keys */
12793 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
12794 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
12795 {
12796 //Save the wep key in ap context. Issue setkey after the BSS is started.
12797 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
12798 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
12799 }
12800 else
12801 {
12802 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012803 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012804 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
12805 }
12806 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012807 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
12808 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012809 {
12810 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12811 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12812
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012813#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12814 if (!pairwise)
12815#else
12816 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
12817#endif
12818 {
12819 /* set group key*/
12820 if (pHddStaCtx->roam_info.deferKeyComplete)
12821 {
12822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12823 "%s- %d: Perform Set key Complete",
12824 __func__, __LINE__);
12825 hdd_PerformRoamSetKeyComplete(pAdapter);
12826 }
12827 }
12828
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012829 if (pairwise_set_key == true)
12830 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012831
Jeff Johnson295189b2012-06-20 16:38:30 -070012832 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
12833
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080012834 pWextState->roamProfile.Keys.defaultIndex = key_index;
12835
12836
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070012837 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012838 params->key, params->key_len);
12839
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012840
Jeff Johnson295189b2012-06-20 16:38:30 -070012841 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
12842
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012843 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012844 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012845 __func__, setKey.peerMac[0], setKey.peerMac[1],
12846 setKey.peerMac[2], setKey.peerMac[3],
12847 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012848 setKey.keyDirection);
12849
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012850 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053012851
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012852 if ( vos_status != VOS_STATUS_SUCCESS )
12853 {
12854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012855 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
12856 __LINE__, vos_status );
12857
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012858 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012859
Nirav Shah4b53d4b2015-05-08 05:35:00 -070012860 status = -EINVAL;
12861 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012862
12863 }
12864
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012865#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012866 /* The supplicant may attempt to set the PTK once pre-authentication
12867 is done. Save the key in the UMAC and include it in the ADD BSS
12868 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012869 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012870 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012871 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012872 hddLog(VOS_TRACE_LEVEL_INFO_MED,
12873 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012874 status = 0;
12875 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053012876 }
12877 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
12878 {
12879 hddLog(VOS_TRACE_LEVEL_ERROR,
12880 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012881 status = -EINVAL;
12882 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012883 }
12884#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070012885
12886 /* issue set key request to SME*/
12887 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
12888 pAdapter->sessionId, &setKey, &roamId );
12889
12890 if ( 0 != status )
12891 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012892 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012893 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
12894 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012895 status = -EINVAL;
12896 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012897 }
12898
12899
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012900 /* in case of IBSS as there was no information available about WEP keys during
12901 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070012902 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012903 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
12904 !( ( IW_AUTH_KEY_MGMT_802_1X
12905 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070012906 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
12907 )
12908 &&
12909 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
12910 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
12911 )
12912 )
12913 {
12914 setKey.keyDirection = eSIR_RX_ONLY;
12915 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
12916
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012917 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070012918 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012919 __func__, setKey.peerMac[0], setKey.peerMac[1],
12920 setKey.peerMac[2], setKey.peerMac[3],
12921 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070012922 setKey.keyDirection);
12923
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012924 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012925 pAdapter->sessionId, &setKey, &roamId );
12926
12927 if ( 0 != status )
12928 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012929 hddLog(VOS_TRACE_LEVEL_ERROR,
12930 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012931 __func__, status);
12932 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012933 status = -EINVAL;
12934 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070012935 }
12936 }
12937 }
12938
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053012939 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012940 for (i = 0; i < params->seq_len; i++) {
12941 rsc_counter |= (params->seq[i] << i*8);
12942 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053012943 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
12944 }
12945
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012946end:
12947 /* Need to clear any trace of key value in the memory.
12948 * Thus zero out the memory even though it is local
12949 * variable.
12950 */
12951 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012952 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053012953 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012954}
12955
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012956#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12957static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12958 struct net_device *ndev,
12959 u8 key_index, bool pairwise,
12960 const u8 *mac_addr,
12961 struct key_params *params
12962 )
12963#else
12964static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
12965 struct net_device *ndev,
12966 u8 key_index, const u8 *mac_addr,
12967 struct key_params *params
12968 )
12969#endif
12970{
12971 int ret;
12972 vos_ssr_protect(__func__);
12973#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
12974 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
12975 mac_addr, params);
12976#else
12977 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
12978 params);
12979#endif
12980 vos_ssr_unprotect(__func__);
12981
12982 return ret;
12983}
12984
Jeff Johnson295189b2012-06-20 16:38:30 -070012985/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012986 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070012987 * This function is used to get the key information
12988 */
12989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012990static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012991 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012992 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012993 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070012994 const u8 *mac_addr, void *cookie,
12995 void (*callback)(void *cookie, struct key_params*)
12996 )
12997#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053012998static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012999 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013000 struct net_device *ndev,
13001 u8 key_index, const u8 *mac_addr, void *cookie,
13002 void (*callback)(void *cookie, struct key_params*)
13003 )
13004#endif
13005{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013006 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013007 hdd_wext_state_t *pWextState = NULL;
13008 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013009 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013010 hdd_context_t *pHddCtx;
13011 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013012
13013 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013014
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013015 if (NULL == pAdapter)
13016 {
13017 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13018 "%s: HDD adapter is Null", __func__);
13019 return -ENODEV;
13020 }
13021
13022 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13023 ret = wlan_hdd_validate_context(pHddCtx);
13024 if (0 != ret)
13025 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013026 return ret;
13027 }
13028
13029 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13030 pRoamProfile = &(pWextState->roamProfile);
13031
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013032 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13033 __func__, hdd_device_modetoString(pAdapter->device_mode),
13034 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013035
Jeff Johnson295189b2012-06-20 16:38:30 -070013036 memset(&params, 0, sizeof(params));
13037
13038 if (CSR_MAX_NUM_KEY <= key_index)
13039 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013040 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013041 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013042 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013043
13044 switch(pRoamProfile->EncryptionType.encryptionType[0])
13045 {
13046 case eCSR_ENCRYPT_TYPE_NONE:
13047 params.cipher = IW_AUTH_CIPHER_NONE;
13048 break;
13049
13050 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13051 case eCSR_ENCRYPT_TYPE_WEP40:
13052 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13053 break;
13054
13055 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13056 case eCSR_ENCRYPT_TYPE_WEP104:
13057 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13058 break;
13059
13060 case eCSR_ENCRYPT_TYPE_TKIP:
13061 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13062 break;
13063
13064 case eCSR_ENCRYPT_TYPE_AES:
13065 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13066 break;
13067
13068 default:
13069 params.cipher = IW_AUTH_CIPHER_NONE;
13070 break;
13071 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013072
c_hpothuaaf19692014-05-17 17:01:48 +053013073 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13074 TRACE_CODE_HDD_CFG80211_GET_KEY,
13075 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013076
Jeff Johnson295189b2012-06-20 16:38:30 -070013077 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13078 params.seq_len = 0;
13079 params.seq = NULL;
13080 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13081 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013082 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013083 return 0;
13084}
13085
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013086#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13087static int wlan_hdd_cfg80211_get_key(
13088 struct wiphy *wiphy,
13089 struct net_device *ndev,
13090 u8 key_index, bool pairwise,
13091 const u8 *mac_addr, void *cookie,
13092 void (*callback)(void *cookie, struct key_params*)
13093 )
13094#else
13095static int wlan_hdd_cfg80211_get_key(
13096 struct wiphy *wiphy,
13097 struct net_device *ndev,
13098 u8 key_index, const u8 *mac_addr, void *cookie,
13099 void (*callback)(void *cookie, struct key_params*)
13100 )
13101#endif
13102{
13103 int ret;
13104
13105 vos_ssr_protect(__func__);
13106#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13107 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13108 mac_addr, cookie, callback);
13109#else
13110 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13111 callback);
13112#endif
13113 vos_ssr_unprotect(__func__);
13114
13115 return ret;
13116}
13117
Jeff Johnson295189b2012-06-20 16:38:30 -070013118/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013119 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013120 * This function is used to delete the key information
13121 */
13122#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013123static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013124 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013125 u8 key_index,
13126 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013127 const u8 *mac_addr
13128 )
13129#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013130static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013131 struct net_device *ndev,
13132 u8 key_index,
13133 const u8 *mac_addr
13134 )
13135#endif
13136{
13137 int status = 0;
13138
13139 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013140 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013141 //it is observed that this is invalidating peer
13142 //key index whenever re-key is done. This is affecting data link.
13143 //It should be ok to ignore del_key.
13144#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013145 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13146 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013147 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13148 tCsrRoamSetKey setKey;
13149 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013150
Jeff Johnson295189b2012-06-20 16:38:30 -070013151 ENTER();
13152
13153 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13154 __func__,pAdapter->device_mode);
13155
13156 if (CSR_MAX_NUM_KEY <= key_index)
13157 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013158 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013159 key_index);
13160
13161 return -EINVAL;
13162 }
13163
13164 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13165 setKey.keyId = key_index;
13166
13167 if (mac_addr)
13168 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13169 else
13170 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13171
13172 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13173
13174 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013175 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013176 )
13177 {
13178
13179 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013180 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13181 if( pHostapdState->bssState == BSS_START)
13182 {
13183 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013184
Jeff Johnson295189b2012-06-20 16:38:30 -070013185 if ( status != eHAL_STATUS_SUCCESS )
13186 {
13187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13188 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13189 __LINE__, status );
13190 }
13191 }
13192 }
13193 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013194 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013195 )
13196 {
13197 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13198
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013199 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13200
13201 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013202 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013203 __func__, setKey.peerMac[0], setKey.peerMac[1],
13204 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013205 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013206 if(pAdapter->sessionCtx.station.conn_info.connState ==
13207 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013208 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013209 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013210 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013211
Jeff Johnson295189b2012-06-20 16:38:30 -070013212 if ( 0 != status )
13213 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013214 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013215 "%s: sme_RoamSetKey failure, returned %d",
13216 __func__, status);
13217 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13218 return -EINVAL;
13219 }
13220 }
13221 }
13222#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013223 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013224 return status;
13225}
13226
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013227#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13228static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13229 struct net_device *ndev,
13230 u8 key_index,
13231 bool pairwise,
13232 const u8 *mac_addr
13233 )
13234#else
13235static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13236 struct net_device *ndev,
13237 u8 key_index,
13238 const u8 *mac_addr
13239 )
13240#endif
13241{
13242 int ret;
13243
13244 vos_ssr_protect(__func__);
13245#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13246 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13247 mac_addr);
13248#else
13249 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13250#endif
13251 vos_ssr_unprotect(__func__);
13252
13253 return ret;
13254}
13255
Jeff Johnson295189b2012-06-20 16:38:30 -070013256/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013257 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013258 * This function is used to set the default tx key index
13259 */
13260#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013261static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013262 struct net_device *ndev,
13263 u8 key_index,
13264 bool unicast, bool multicast)
13265#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013266static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013267 struct net_device *ndev,
13268 u8 key_index)
13269#endif
13270{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013271 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013272 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013273 hdd_wext_state_t *pWextState;
13274 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013275 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013276
13277 ENTER();
13278
Gopichand Nakkala29149562013-05-10 21:43:41 +053013279 if ((NULL == pAdapter))
13280 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013282 "invalid adapter");
13283 return -EINVAL;
13284 }
13285
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013286 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13287 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13288 pAdapter->sessionId, key_index));
13289
Gopichand Nakkala29149562013-05-10 21:43:41 +053013290 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13291 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13292
13293 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13294 {
13295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13296 "invalid Wext state or HDD context");
13297 return -EINVAL;
13298 }
13299
Arif Hussain6d2a3322013-11-17 19:50:10 -080013300 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013301 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013302
Jeff Johnson295189b2012-06-20 16:38:30 -070013303 if (CSR_MAX_NUM_KEY <= key_index)
13304 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013305 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013306 key_index);
13307
13308 return -EINVAL;
13309 }
13310
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013311 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13312 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013313 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013314 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013315 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013316 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013317
Jeff Johnson295189b2012-06-20 16:38:30 -070013318 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013319 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013320 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013321 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013322 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013323 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013324#ifdef FEATURE_WLAN_WAPI
13325 (eCSR_ENCRYPT_TYPE_WPI !=
13326 pHddStaCtx->conn_info.ucEncryptionType) &&
13327#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013328 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013329 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013330 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013331 {
13332 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013333 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013334
Jeff Johnson295189b2012-06-20 16:38:30 -070013335 tCsrRoamSetKey setKey;
13336 v_U32_t roamId= 0xFF;
13337 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013338
13339 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013340 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013341
Jeff Johnson295189b2012-06-20 16:38:30 -070013342 Keys->defaultIndex = (u8)key_index;
13343 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13344 setKey.keyId = key_index;
13345 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013346
13347 vos_mem_copy(&setKey.Key[0],
13348 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013349 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013350
Gopichand Nakkala29149562013-05-10 21:43:41 +053013351 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013352
13353 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013354 &pHddStaCtx->conn_info.bssId[0],
13355 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013356
Gopichand Nakkala29149562013-05-10 21:43:41 +053013357 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13358 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13359 eCSR_ENCRYPT_TYPE_WEP104)
13360 {
13361 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13362 even though ap is configured for WEP-40 encryption. In this canse the key length
13363 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13364 type(104) and switching encryption type to 40*/
13365 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13366 eCSR_ENCRYPT_TYPE_WEP40;
13367 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13368 eCSR_ENCRYPT_TYPE_WEP40;
13369 }
13370
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013371 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013372 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013373
Jeff Johnson295189b2012-06-20 16:38:30 -070013374 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013375 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013376 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013377
Jeff Johnson295189b2012-06-20 16:38:30 -070013378 if ( 0 != status )
13379 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013380 hddLog(VOS_TRACE_LEVEL_ERROR,
13381 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013382 status);
13383 return -EINVAL;
13384 }
13385 }
13386 }
13387
13388 /* In SoftAp mode setting key direction for default mode */
13389 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13390 {
13391 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13392 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13393 (eCSR_ENCRYPT_TYPE_AES !=
13394 pWextState->roamProfile.EncryptionType.encryptionType[0])
13395 )
13396 {
13397 /* Saving key direction for default key index to TX default */
13398 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13399 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13400 }
13401 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013402 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013403 return status;
13404}
13405
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013406#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13407static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13408 struct net_device *ndev,
13409 u8 key_index,
13410 bool unicast, bool multicast)
13411#else
13412static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13413 struct net_device *ndev,
13414 u8 key_index)
13415#endif
13416{
13417 int ret;
13418 vos_ssr_protect(__func__);
13419#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13420 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13421 multicast);
13422#else
13423 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13424#endif
13425 vos_ssr_unprotect(__func__);
13426
13427 return ret;
13428}
13429
Jeff Johnson295189b2012-06-20 16:38:30 -070013430/*
13431 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13432 * This function is used to inform the BSS details to nl80211 interface.
13433 */
13434static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13435 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13436{
13437 struct net_device *dev = pAdapter->dev;
13438 struct wireless_dev *wdev = dev->ieee80211_ptr;
13439 struct wiphy *wiphy = wdev->wiphy;
13440 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13441 int chan_no;
13442 int ie_length;
13443 const char *ie;
13444 unsigned int freq;
13445 struct ieee80211_channel *chan;
13446 int rssi = 0;
13447 struct cfg80211_bss *bss = NULL;
13448
Jeff Johnson295189b2012-06-20 16:38:30 -070013449 if( NULL == pBssDesc )
13450 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013451 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013452 return bss;
13453 }
13454
13455 chan_no = pBssDesc->channelId;
13456 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13457 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13458
13459 if( NULL == ie )
13460 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013461 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013462 return bss;
13463 }
13464
13465#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
13466 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
13467 {
13468 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13469 }
13470 else
13471 {
13472 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13473 }
13474#else
13475 freq = ieee80211_channel_to_frequency(chan_no);
13476#endif
13477
13478 chan = __ieee80211_get_channel(wiphy, freq);
13479
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053013480 if (!chan) {
13481 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
13482 return NULL;
13483 }
13484
Abhishek Singhaee43942014-06-16 18:55:47 +053013485 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070013486
Anand N Sunkad9f80b742015-07-30 20:05:51 +053013487 return cfg80211_inform_bss(wiphy, chan,
13488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13489 CFG80211_BSS_FTYPE_UNKNOWN,
13490#endif
13491 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013492 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 pBssDesc->capabilityInfo,
13494 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053013495 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070013496}
13497
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013498/*
13499 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
13500 * interface that BSS might have been lost.
13501 * @pAdapter: adaptor
13502 * @bssid: bssid which might have been lost
13503 *
13504 * Return: bss which is unlinked from kernel cache
13505 */
13506struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
13507 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
13508{
13509 struct net_device *dev = pAdapter->dev;
13510 struct wireless_dev *wdev = dev->ieee80211_ptr;
13511 struct wiphy *wiphy = wdev->wiphy;
13512 struct cfg80211_bss *bss = NULL;
13513
Abhishek Singh5a597e62016-12-05 15:16:30 +053013514 bss = hdd_get_bss_entry(wiphy,
13515 NULL, bssid,
13516 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053013517 if (bss == NULL) {
13518 hddLog(LOGE, FL("BSS not present"));
13519 } else {
13520 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
13521 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
13522 cfg80211_unlink_bss(wiphy, bss);
13523 }
13524 return bss;
13525}
Jeff Johnson295189b2012-06-20 16:38:30 -070013526
13527
13528/*
13529 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
13530 * This function is used to inform the BSS details to nl80211 interface.
13531 */
13532struct cfg80211_bss*
13533wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
13534 tSirBssDescription *bss_desc
13535 )
13536{
13537 /*
13538 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
13539 already exists in bss data base of cfg80211 for that particular BSS ID.
13540 Using cfg80211_inform_bss_frame to update the bss entry instead of
13541 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
13542 now there is no possibility to get the mgmt(probe response) frame from PE,
13543 converting bss_desc to ieee80211_mgmt(probe response) and passing to
13544 cfg80211_inform_bss_frame.
13545 */
13546 struct net_device *dev = pAdapter->dev;
13547 struct wireless_dev *wdev = dev->ieee80211_ptr;
13548 struct wiphy *wiphy = wdev->wiphy;
13549 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013550#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13551 qcom_ie_age *qie_age = NULL;
13552 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
13553#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013554 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013555#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013556 const char *ie =
13557 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
13558 unsigned int freq;
13559 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013560 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013561 struct cfg80211_bss *bss_status = NULL;
13562 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
13563 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070013564 hdd_context_t *pHddCtx;
13565 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070013566#ifdef WLAN_OPEN_SOURCE
13567 struct timespec ts;
13568#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013569
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013570
Wilson Yangf80a0542013-10-07 13:02:37 -070013571 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13572 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070013573 if (0 != status)
13574 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013575 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013576 }
13577
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053013578 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070013579 if (!mgmt)
13580 {
13581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13582 "%s: memory allocation failed ", __func__);
13583 return NULL;
13584 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070013585
Jeff Johnson295189b2012-06-20 16:38:30 -070013586 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013587
13588#ifdef WLAN_OPEN_SOURCE
13589 /* Android does not want the timestamp from the frame.
13590 Instead it wants a monotonic increasing value */
13591 get_monotonic_boottime(&ts);
13592 mgmt->u.probe_resp.timestamp =
13593 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
13594#else
13595 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013596 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
13597 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070013598
13599#endif
13600
Jeff Johnson295189b2012-06-20 16:38:30 -070013601 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
13602 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013603
13604#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
13605 /* GPS Requirement: need age ie per entry. Using vendor specific. */
13606 /* Assuming this is the last IE, copy at the end */
13607 ie_length -=sizeof(qcom_ie_age);
13608 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
13609 qie_age->element_id = QCOM_VENDOR_IE_ID;
13610 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
13611 qie_age->oui_1 = QCOM_OUI1;
13612 qie_age->oui_2 = QCOM_OUI2;
13613 qie_age->oui_3 = QCOM_OUI3;
13614 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053013615 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
13616 * bss related timestamp is in units of ms. Due to this when scan results
13617 * are sent to lowi the scan age is high.To address this, send age in units
13618 * of 1/10 ms.
13619 */
13620 qie_age->age = (vos_timer_get_system_time() -
13621 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080013622#endif
13623
Jeff Johnson295189b2012-06-20 16:38:30 -070013624 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053013625 if (bss_desc->fProbeRsp)
13626 {
13627 mgmt->frame_control |=
13628 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
13629 }
13630 else
13631 {
13632 mgmt->frame_control |=
13633 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
13634 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013635
13636#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013637 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013638 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
13639 {
13640 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
13641 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013642 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070013643 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
13644
13645 {
13646 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
13647 }
13648 else
13649 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013650 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
13651 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070013652 kfree(mgmt);
13653 return NULL;
13654 }
13655#else
13656 freq = ieee80211_channel_to_frequency(chan_no);
13657#endif
13658 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013659 /*when the band is changed on the fly using the GUI, three things are done
13660 * 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)
13661 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
13662 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
13663 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
13664 * and discards the channels correponding to previous band and calls back with zero bss results.
13665 * 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
13666 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
13667 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
13668 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
13669 * So drop the bss and continue to next bss.
13670 */
13671 if(chan == NULL)
13672 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053013673 hddLog(VOS_TRACE_LEVEL_ERROR,
13674 FL("chan pointer is NULL, chan_no: %d freq: %d"),
13675 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070013676 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080013677 return NULL;
13678 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053013679 /*To keep the rssi icon of the connected AP in the scan window
13680 *and the rssi icon of the wireless networks in sync
13681 * */
13682 if (( eConnectionState_Associated ==
13683 pAdapter->sessionCtx.station.conn_info.connState ) &&
13684 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
13685 pAdapter->sessionCtx.station.conn_info.bssId,
13686 WNI_CFG_BSSID_LEN)) &&
13687 (pHddCtx->hdd_wlan_suspended == FALSE))
13688 {
13689 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
13690 rssi = (pAdapter->rssi * 100);
13691 }
13692 else
13693 {
13694 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
13695 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013696
Nirav Shah20ac06f2013-12-12 18:14:06 +053013697 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053013698 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
13699 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053013700
Jeff Johnson295189b2012-06-20 16:38:30 -070013701 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
13702 frame_len, rssi, GFP_KERNEL);
13703 kfree(mgmt);
13704 return bss_status;
13705}
13706
13707/*
13708 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
13709 * This function is used to update the BSS data base of CFG8011
13710 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013711struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013712 tCsrRoamInfo *pRoamInfo
13713 )
13714{
13715 tCsrRoamConnectedProfile roamProfile;
13716 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13717 struct cfg80211_bss *bss = NULL;
13718
13719 ENTER();
13720
13721 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
13722 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
13723
13724 if (NULL != roamProfile.pBssDesc)
13725 {
Girish Gowlif4b68022014-08-28 23:18:57 +053013726 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13727 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070013728
13729 if (NULL == bss)
13730 {
13731 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
13732 __func__);
13733 }
13734
13735 sme_RoamFreeConnectProfile(hHal, &roamProfile);
13736 }
13737 else
13738 {
13739 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
13740 __func__);
13741 }
13742 return bss;
13743}
13744
13745/*
13746 * FUNCTION: wlan_hdd_cfg80211_update_bss
13747 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013748static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
13749 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070013750 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013751{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013752 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013753 tCsrScanResultInfo *pScanResult;
13754 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013755 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013756 tScanResultHandle pResult;
13757 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070013758 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013759 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013760 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013761
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013762 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13763 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
13764 NO_SESSION, pAdapter->sessionId));
13765
Wilson Yangf80a0542013-10-07 13:02:37 -070013766 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013767 ret = wlan_hdd_validate_context(pHddCtx);
13768 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070013769 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053013770 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070013771 }
13772
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013773 if (pAdapter->request != NULL)
13774 {
13775 if ((pAdapter->request->n_ssids == 1)
13776 && (pAdapter->request->ssids != NULL)
13777 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
13778 is_p2p_scan = true;
13779 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013780 /*
13781 * start getting scan results and populate cgf80211 BSS database
13782 */
13783 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
13784
13785 /* no scan results */
13786 if (NULL == pResult)
13787 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013788 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
13789 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013790 wlan_hdd_get_frame_logs(pAdapter,
13791 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070013792 return status;
13793 }
13794
13795 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
13796
13797 while (pScanResult)
13798 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013799 /*
13800 * cfg80211_inform_bss() is not updating ie field of bss entry, if
13801 * entry already exists in bss data base of cfg80211 for that
13802 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
13803 * bss entry instead of cfg80211_inform_bss, But this call expects
13804 * mgmt packet as input. As of now there is no possibility to get
13805 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070013806 * ieee80211_mgmt(probe response) and passing to c
13807 * fg80211_inform_bss_frame.
13808 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013809 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
13810 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
13811 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013812 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13813 continue; //Skip the non p2p bss entries
13814 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
13816 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013817
Jeff Johnson295189b2012-06-20 16:38:30 -070013818
13819 if (NULL == bss_status)
13820 {
13821 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013822 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013823 }
13824 else
13825 {
Yue Maf49ba872013-08-19 12:04:25 -070013826 cfg80211_put_bss(
13827#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
13828 wiphy,
13829#endif
13830 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070013831 }
13832
13833 pScanResult = sme_ScanResultGetNext(hHal, pResult);
13834 }
13835
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013836 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053013837 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013838 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013839}
13840
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013841void
13842hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
13843{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013844 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080013845 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013846} /****** end hddPrintMacAddr() ******/
13847
13848void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013849hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013850{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013851 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013852 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013853 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
13854 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
13855 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013856} /****** end hddPrintPmkId() ******/
13857
13858//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
13859//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
13860
13861//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
13862//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
13863
13864#define dump_bssid(bssid) \
13865 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013866 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
13867 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013868 }
13869
13870#define dump_pmkid(pMac, pmkid) \
13871 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070013872 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
13873 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013874 }
13875
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070013876#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013877/*
13878 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
13879 * This function is used to notify the supplicant of a new PMKSA candidate.
13880 */
13881int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013882 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013883 int index, bool preauth )
13884{
Jeff Johnsone7245742012-09-05 17:12:55 -070013885#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013886 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013887 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013888
13889 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070013890 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013891
13892 if( NULL == pRoamInfo )
13893 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013894 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013895 return -EINVAL;
13896 }
13897
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013898 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
13899 {
13900 dump_bssid(pRoamInfo->bssid);
13901 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013902 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070013903 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013904#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013905 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013906}
13907#endif //FEATURE_WLAN_LFR
13908
Yue Maef608272013-04-08 23:09:17 -070013909#ifdef FEATURE_WLAN_LFR_METRICS
13910/*
13911 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
13912 * 802.11r/LFR metrics reporting function to report preauth initiation
13913 *
13914 */
13915#define MAX_LFR_METRICS_EVENT_LENGTH 100
13916VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
13917 tCsrRoamInfo *pRoamInfo)
13918{
13919 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13920 union iwreq_data wrqu;
13921
13922 ENTER();
13923
13924 if (NULL == pAdapter)
13925 {
13926 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13927 return VOS_STATUS_E_FAILURE;
13928 }
13929
13930 /* create the event */
13931 memset(&wrqu, 0, sizeof(wrqu));
13932 memset(metrics_notification, 0, sizeof(metrics_notification));
13933
13934 wrqu.data.pointer = metrics_notification;
13935 wrqu.data.length = scnprintf(metrics_notification,
13936 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
13937 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
13938
13939 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13940
13941 EXIT();
13942
13943 return VOS_STATUS_SUCCESS;
13944}
13945
13946/*
13947 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
13948 * 802.11r/LFR metrics reporting function to report preauth completion
13949 * or failure
13950 */
13951VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
13952 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
13953{
13954 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13955 union iwreq_data wrqu;
13956
13957 ENTER();
13958
13959 if (NULL == pAdapter)
13960 {
13961 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
13962 return VOS_STATUS_E_FAILURE;
13963 }
13964
13965 /* create the event */
13966 memset(&wrqu, 0, sizeof(wrqu));
13967 memset(metrics_notification, 0, sizeof(metrics_notification));
13968
13969 scnprintf(metrics_notification, sizeof(metrics_notification),
13970 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
13971 MAC_ADDR_ARRAY(pRoamInfo->bssid));
13972
13973 if (1 == preauth_status)
13974 strncat(metrics_notification, " TRUE", 5);
13975 else
13976 strncat(metrics_notification, " FALSE", 6);
13977
13978 wrqu.data.pointer = metrics_notification;
13979 wrqu.data.length = strlen(metrics_notification);
13980
13981 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
13982
13983 EXIT();
13984
13985 return VOS_STATUS_SUCCESS;
13986}
13987
13988/*
13989 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
13990 * 802.11r/LFR metrics reporting function to report handover initiation
13991 *
13992 */
13993VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
13994 tCsrRoamInfo *pRoamInfo)
13995{
13996 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
13997 union iwreq_data wrqu;
13998
13999 ENTER();
14000
14001 if (NULL == pAdapter)
14002 {
14003 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14004 return VOS_STATUS_E_FAILURE;
14005 }
14006
14007 /* create the event */
14008 memset(&wrqu, 0, sizeof(wrqu));
14009 memset(metrics_notification, 0, sizeof(metrics_notification));
14010
14011 wrqu.data.pointer = metrics_notification;
14012 wrqu.data.length = scnprintf(metrics_notification,
14013 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14014 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14015
14016 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14017
14018 EXIT();
14019
14020 return VOS_STATUS_SUCCESS;
14021}
14022#endif
14023
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014024
14025/**
14026 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14027 * @scan_req: scan request to be checked
14028 *
14029 * Return: true or false
14030 */
14031#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14032static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14033 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014034 *scan_req, hdd_context_t
14035 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014036{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014037 if (!scan_req || !scan_req->wiphy ||
14038 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014039 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14040 return false;
14041 }
14042 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14043 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14044 return false;
14045 }
14046 return true;
14047}
14048#else
14049static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14050 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014051 *scan_req, hdd_context_t
14052 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014053{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014054 if (!scan_req || !scan_req->wiphy ||
14055 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014056 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14057 return false;
14058 }
14059 return true;
14060}
14061#endif
14062
Mukul Sharmab392b642017-08-17 17:45:29 +053014063#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014064/*
14065 * FUNCTION: hdd_cfg80211_scan_done_callback
14066 * scanning callback function, called after finishing scan
14067 *
14068 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014069static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014070 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14071{
14072 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014073 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014074 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014075 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014076 struct cfg80211_scan_request *req = NULL;
14077 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014078 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014079 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014080 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014081 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014082
14083 ENTER();
14084
c_manjee1b4ab9a2016-10-26 11:36:55 +053014085 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14086 !pAdapter->dev) {
14087 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14088 return 0;
14089 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014090 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014091 if (NULL == pHddCtx) {
14092 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014093 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014094 }
14095
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014096#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014097 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014098 {
14099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014100 }
14101#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014102 pScanInfo = &pHddCtx->scan_info;
14103
Jeff Johnson295189b2012-06-20 16:38:30 -070014104 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014105 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014106 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014107 __func__, halHandle, pContext, (int) scanId, (int) status);
14108
Kiet Lamac06e2c2013-10-23 16:25:07 +053014109 pScanInfo->mScanPendingCounter = 0;
14110
Jeff Johnson295189b2012-06-20 16:38:30 -070014111 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014112 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014113 &pScanInfo->scan_req_completion_event,
14114 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014115 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014117 hddLog(VOS_TRACE_LEVEL_ERROR,
14118 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014119 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014120 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014121 }
14122
Yue Maef608272013-04-08 23:09:17 -070014123 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014124 {
14125 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014126 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014127 }
14128
14129 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014130 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014131 {
14132 hddLog(VOS_TRACE_LEVEL_INFO,
14133 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014134 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014135 (int) scanId);
14136 }
14137
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014139 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014140#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014141 {
14142 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14143 pAdapter);
14144 if (0 > ret)
14145 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014146 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014147
Jeff Johnson295189b2012-06-20 16:38:30 -070014148 /* If any client wait scan result through WEXT
14149 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014150 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014151 {
14152 /* The other scan request waiting for current scan finish
14153 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014154 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014155 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014156 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014157 }
14158 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014159 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014160 {
14161 struct net_device *dev = pAdapter->dev;
14162 union iwreq_data wrqu;
14163 int we_event;
14164 char *msg;
14165
14166 memset(&wrqu, '\0', sizeof(wrqu));
14167 we_event = SIOCGIWSCAN;
14168 msg = NULL;
14169 wireless_send_event(dev, we_event, &wrqu, msg);
14170 }
14171 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014172 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014173
14174 /* Get the Scan Req */
14175 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014176 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014177
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014178 /* Scan is no longer pending */
14179 pScanInfo->mScanPending = VOS_FALSE;
14180
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014181 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014182 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014183#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14184 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014185 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014186#endif
14187
14188 if (pAdapter->dev) {
14189 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14190 pAdapter->dev->name);
14191 }
mukul sharmae7041822015-12-03 15:09:21 +053014192 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014193 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014194 }
14195
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014196 /* last_scan_timestamp is used to decide if new scan
14197 * is needed or not on station interface. If last station
14198 * scan time and new station scan time is less then
14199 * last_scan_timestamp ; driver will return cached scan.
14200 */
14201 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
14202 {
14203 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14204
14205 if ( req->n_channels )
14206 {
14207 for (i = 0; i < req->n_channels ; i++ )
14208 {
14209 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
14210 }
14211 /* store no of channel scanned */
14212 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
14213 }
14214
14215 }
14216
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014217 /*
14218 * cfg80211_scan_done informing NL80211 about completion
14219 * of scanning
14220 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014221 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14222 {
14223 aborted = true;
14224 }
mukul sharmae7041822015-12-03 15:09:21 +053014225
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014226#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014227 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14228 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014229#endif
14230 cfg80211_scan_done(req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014231
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014232 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014233
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014234allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014235 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14236 ) && (pHddCtx->spoofMacAddr.isEnabled
14237 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014238 /* Generate new random mac addr for next scan */
14239 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014240
14241 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14242 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014243 }
14244
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014245 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014246 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014247
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014248 /* Acquire wakelock to handle the case where APP's tries to suspend
14249 * immediatly after the driver gets connect request(i.e after scan)
14250 * from supplicant, this result in app's is suspending and not able
14251 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014252 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014253
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014254#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014255 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014256#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014257#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014258 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014259#endif
14260
Jeff Johnson295189b2012-06-20 16:38:30 -070014261 EXIT();
14262 return 0;
14263}
14264
14265/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014266 * FUNCTION: hdd_isConnectionInProgress
14267 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014268 *
14269 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014270v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14271 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014272{
14273 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14274 hdd_station_ctx_t *pHddStaCtx = NULL;
14275 hdd_adapter_t *pAdapter = NULL;
14276 VOS_STATUS status = 0;
14277 v_U8_t staId = 0;
14278 v_U8_t *staMac = NULL;
14279
14280 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14281
14282 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14283 {
14284 pAdapter = pAdapterNode->pAdapter;
14285
14286 if( pAdapter )
14287 {
14288 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014289 "%s: Adapter with device mode %s (%d) exists",
14290 __func__, hdd_device_modetoString(pAdapter->device_mode),
14291 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014292 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014293 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14294 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14295 (eConnectionState_Connecting ==
14296 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14297 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014298 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014299 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014300 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014301 if (session_id && reason)
14302 {
14303 *session_id = pAdapter->sessionId;
14304 *reason = eHDD_CONNECTION_IN_PROGRESS;
14305 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014306 return VOS_TRUE;
14307 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014308 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014309 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014310 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014311 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014312 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014313 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014314 if (session_id && reason)
14315 {
14316 *session_id = pAdapter->sessionId;
14317 *reason = eHDD_REASSOC_IN_PROGRESS;
14318 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014319 return VOS_TRUE;
14320 }
14321 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014322 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14323 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014324 {
14325 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14326 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014327 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014328 {
14329 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014330 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014331 "%s: client " MAC_ADDRESS_STR
14332 " is in the middle of WPS/EAPOL exchange.", __func__,
14333 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014334 if (session_id && reason)
14335 {
14336 *session_id = pAdapter->sessionId;
14337 *reason = eHDD_EAPOL_IN_PROGRESS;
14338 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014339 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014340 }
14341 }
14342 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14343 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14344 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014345 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14346 ptSapContext pSapCtx = NULL;
14347 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14348 if(pSapCtx == NULL){
14349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14350 FL("psapCtx is NULL"));
14351 return VOS_FALSE;
14352 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014353 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14354 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014355 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14356 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014357 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014358 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014359
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014360 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014361 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14362 "middle of WPS/EAPOL exchange.", __func__,
14363 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014364 if (session_id && reason)
14365 {
14366 *session_id = pAdapter->sessionId;
14367 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14368 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014369 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014370 }
14371 }
14372 }
14373 }
14374 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14375 pAdapterNode = pNext;
14376 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014377 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014378}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014379
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014380/**
14381 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14382 * to the Scan request
14383 * @scanRequest: Pointer to the csr scan request
14384 * @request: Pointer to the scan request from supplicant
14385 *
14386 * Return: None
14387 */
14388#ifdef CFG80211_SCAN_BSSID
14389static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14390 struct cfg80211_scan_request *request)
14391{
14392 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14393}
14394#else
14395static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14396 struct cfg80211_scan_request *request)
14397{
14398}
14399#endif
14400
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014401/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014402 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070014403 * this scan respond to scan trigger and update cfg80211 scan database
14404 * later, scan dump command can be used to recieve scan results
14405 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014406int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014407#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14408 struct net_device *dev,
14409#endif
14410 struct cfg80211_scan_request *request)
14411{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014412 hdd_adapter_t *pAdapter = NULL;
14413 hdd_context_t *pHddCtx = NULL;
14414 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014415 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014416 tCsrScanRequest scanRequest;
14417 tANI_U8 *channelList = NULL, i;
14418 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014419 int status;
14420 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014421 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014422 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053014423 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014424 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014425 v_U8_t curr_session_id;
14426 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070014427
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014428#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
14429 struct net_device *dev = NULL;
14430 if (NULL == request)
14431 {
14432 hddLog(VOS_TRACE_LEVEL_ERROR,
14433 "%s: scan req param null", __func__);
14434 return -EINVAL;
14435 }
14436 dev = request->wdev->netdev;
14437#endif
14438
14439 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14440 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
14441 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14442
Jeff Johnson295189b2012-06-20 16:38:30 -070014443 ENTER();
14444
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014445 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
14446 __func__, hdd_device_modetoString(pAdapter->device_mode),
14447 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014448
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014449 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014450 if (0 != status)
14451 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014452 return status;
14453 }
14454
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014455 if (NULL == pwextBuf)
14456 {
14457 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
14458 __func__);
14459 return -EIO;
14460 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014461 cfg_param = pHddCtx->cfg_ini;
14462 pScanInfo = &pHddCtx->scan_info;
14463
Jeff Johnson295189b2012-06-20 16:38:30 -070014464#ifdef WLAN_BTAMP_FEATURE
14465 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014466 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070014467 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080014468 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014469 "%s: No scanning when AMP is on", __func__);
14470 return -EOPNOTSUPP;
14471 }
14472#endif
14473 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014474 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014475 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014476 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014477 "%s: Not scanning on device_mode = %s (%d)",
14478 __func__, hdd_device_modetoString(pAdapter->device_mode),
14479 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014480 return -EOPNOTSUPP;
14481 }
14482
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053014483 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
14484 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
14485 return -EOPNOTSUPP;
14486 }
14487
Jeff Johnson295189b2012-06-20 16:38:30 -070014488 if (TRUE == pScanInfo->mScanPending)
14489 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014490 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
14491 {
14492 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
14493 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014494 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014495 }
14496
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053014497 // Don't allow scan if PNO scan is going on.
14498 if (pHddCtx->isPnoEnable)
14499 {
14500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14501 FL("pno scan in progress"));
14502 return -EBUSY;
14503 }
14504
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014505 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070014506 //Channel and action frame is pending
14507 //Otherwise Cancel Remain On Channel and allow Scan
14508 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014509 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070014510 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053014511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070014512 return -EBUSY;
14513 }
14514
Jeff Johnson295189b2012-06-20 16:38:30 -070014515 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
14516 {
14517 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080014518 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014519 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014520 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014521 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
14522 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014523 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014524 "%s: MAX TM Level Scan not allowed", __func__);
14525 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014526 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070014527 }
14528 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
14529
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014530 /* Check if scan is allowed at this point of time.
14531 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053014532 if (TRUE == pHddCtx->btCoexModeSet)
14533 {
14534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14535 FL("BTCoex Mode operation in progress"));
14536 return -EBUSY;
14537 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014538 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014539 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014540
14541 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
14542 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
14543 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014544 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
14545 pHddCtx->last_scan_reject_reason != curr_reason ||
14546 !pHddCtx->last_scan_reject_timestamp)
14547 {
14548 pHddCtx->last_scan_reject_session_id = curr_session_id;
14549 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053014550 pHddCtx->last_scan_reject_timestamp =
14551 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014552 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053014553 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053014554 else
14555 {
14556 pHddCtx->scan_reject_cnt++;
14557
Abhishek Singhe4b12562017-06-20 16:53:39 +053014558 if ((pHddCtx->scan_reject_cnt >=
14559 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053014560 vos_system_time_after(jiffies_to_msecs(jiffies),
14561 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014562 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014563 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
14564 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
14565 vos_system_time_after(jiffies_to_msecs(jiffies),
14566 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014567 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014568 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014569 if (pHddCtx->cfg_ini->enableFatalEvent)
14570 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
14571 WLAN_LOG_INDICATOR_HOST_DRIVER,
14572 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
14573 FALSE, FALSE);
14574 else
14575 {
14576 hddLog(LOGE, FL("Triggering SSR"));
14577 vos_wlanRestart();
14578 }
14579 }
14580 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014581 return -EBUSY;
14582 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014583 pHddCtx->last_scan_reject_timestamp = 0;
14584 pHddCtx->last_scan_reject_session_id = 0xFF;
14585 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053014586 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014587
Jeff Johnson295189b2012-06-20 16:38:30 -070014588 vos_mem_zero( &scanRequest, sizeof(scanRequest));
14589
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014590 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
14591 * Becasue of this, driver is assuming that this is not wildcard scan and so
14592 * is not aging out the scan results.
14593 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053014594 if ((request->ssids) && (request->n_ssids == 1) &&
14595 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014596 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014597 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014598
14599 if ((request->ssids) && (0 < request->n_ssids))
14600 {
14601 tCsrSSIDInfo *SsidInfo;
14602 int j;
14603 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
14604 /* Allocate num_ssid tCsrSSIDInfo structure */
14605 SsidInfo = scanRequest.SSIDs.SSIDList =
14606 ( tCsrSSIDInfo *)vos_mem_malloc(
14607 request->n_ssids*sizeof(tCsrSSIDInfo));
14608
14609 if(NULL == scanRequest.SSIDs.SSIDList)
14610 {
14611 hddLog(VOS_TRACE_LEVEL_ERROR,
14612 "%s: memory alloc failed SSIDInfo buffer", __func__);
14613 return -ENOMEM;
14614 }
14615
14616 /* copy all the ssid's and their length */
14617 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
14618 {
14619 /* get the ssid length */
14620 SsidInfo->SSID.length = request->ssids[j].ssid_len;
14621 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
14622 SsidInfo->SSID.length);
14623 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
14624 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
14625 j, SsidInfo->SSID.ssId);
14626 }
14627 /* set the scan type to active */
14628 scanRequest.scanType = eSIR_ACTIVE_SCAN;
14629 }
14630 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014631 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014632 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14633 TRACE_CODE_HDD_CFG80211_SCAN,
14634 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070014635 /* set the scan type to active */
14636 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070014637 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014638 else
14639 {
14640 /*Set the scan type to default type, in this case it is ACTIVE*/
14641 scanRequest.scanType = pScanInfo->scan_mode;
14642 }
14643 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
14644 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070014645
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014646 csr_scan_request_assign_bssid(&scanRequest, request);
14647
Jeff Johnson295189b2012-06-20 16:38:30 -070014648 /* set BSSType to default type */
14649 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
14650
14651 /*TODO: scan the requested channels only*/
14652
14653 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014654 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070014655 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014656 hddLog(VOS_TRACE_LEVEL_WARN,
14657 "No of Scan Channels exceeded limit: %d", request->n_channels);
14658 request->n_channels = MAX_CHANNEL;
14659 }
14660
14661 hddLog(VOS_TRACE_LEVEL_INFO,
14662 "No of Scan Channels: %d", request->n_channels);
14663
14664
14665 if( request->n_channels )
14666 {
14667 char chList [(request->n_channels*5)+1];
14668 int len;
14669 channelList = vos_mem_malloc( request->n_channels );
14670 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053014671 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014672 hddLog(VOS_TRACE_LEVEL_ERROR,
14673 "%s: memory alloc failed channelList", __func__);
14674 status = -ENOMEM;
14675 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053014676 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014677
14678 for( i = 0, len = 0; i < request->n_channels ; i++ )
14679 {
14680 channelList[i] = request->channels[i]->hw_value;
14681 len += snprintf(chList+len, 5, "%d ", channelList[i]);
14682 }
14683
Nirav Shah20ac06f2013-12-12 18:14:06 +053014684 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014685 "Channel-List: %s ", chList);
14686 }
c_hpothu53512302014-04-15 18:49:53 +053014687
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014688 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
14689 scanRequest.ChannelInfo.ChannelList = channelList;
14690
14691 /* set requestType to full scan */
14692 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
14693
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014694 /* if there is back to back scan happening in driver with in
14695 * nDeferScanTimeInterval interval driver should defer new scan request
14696 * and should provide last cached scan results instead of new channel list.
14697 * This rule is not applicable if scan is p2p scan.
14698 * This condition will work only in case when last request no of channels
14699 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053014700 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053014701 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014702 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014703
Sushant Kaushik86592172015-04-27 16:35:03 +053014704 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
14705 /* if wps ie is NULL , then only defer scan */
14706 if ( pWpsIe == NULL &&
14707 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053014708 {
14709 if ( pScanInfo->last_scan_timestamp !=0 &&
14710 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
14711 {
14712 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
14713 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
14714 vos_mem_compare(pScanInfo->last_scan_channelList,
14715 channelList, pScanInfo->last_scan_numChannels))
14716 {
14717 hddLog(VOS_TRACE_LEVEL_WARN,
14718 " New and old station scan time differ is less then %u",
14719 pHddCtx->cfg_ini->nDeferScanTimeInterval);
14720
14721 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014722 pAdapter);
14723
Agarwal Ashish57e84372014-12-05 18:26:53 +053014724 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014725 "Return old cached scan as all channels and no of channels are same");
14726
Agarwal Ashish57e84372014-12-05 18:26:53 +053014727 if (0 > ret)
14728 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014729
Agarwal Ashish57e84372014-12-05 18:26:53 +053014730 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053014731
14732 status = eHAL_STATUS_SUCCESS;
14733 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053014734 }
14735 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014736 }
14737
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014738 /* Flush the scan results(only p2p beacons) for STA scan and P2P
14739 * search (Flush on both full scan and social scan but not on single
14740 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
14741 */
14742
14743 /* Supplicant does single channel scan after 8-way handshake
14744 * and in that case driver shoudnt flush scan results. If
14745 * driver flushes the scan results here and unfortunately if
14746 * the AP doesnt respond to our probe req then association
14747 * fails which is not desired
14748 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014749 if ((request->n_ssids == 1)
14750 && (request->ssids != NULL)
14751 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
14752 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014753
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053014754 if( is_p2p_scan ||
14755 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014756 {
14757 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
14758 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
14759 pAdapter->sessionId );
14760 }
14761
14762 if( request->ie_len )
14763 {
14764 /* save this for future association (join requires this) */
14765 /*TODO: Array needs to be converted to dynamic allocation,
14766 * as multiple ie.s can be sent in cfg80211_scan_request structure
14767 * CR 597966
14768 */
14769 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
14770 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
14771 pScanInfo->scanAddIE.length = request->ie_len;
14772
14773 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
14774 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14775 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014776 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014777 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070014778 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014779 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
14780 memcpy( pwextBuf->roamProfile.addIEScan,
14781 request->ie, request->ie_len);
14782 }
14783 else
14784 {
14785 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
14786 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070014787 }
14788
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014789 }
14790 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
14791 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
14792
14793 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
14794 request->ie_len);
14795 if (pP2pIe != NULL)
14796 {
14797#ifdef WLAN_FEATURE_P2P_DEBUG
14798 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
14799 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
14800 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053014801 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014802 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
14803 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14804 "Go nego completed to Connection is started");
14805 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14806 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053014807 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014808 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
14809 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070014810 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014811 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
14812 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
14813 "Disconnected state to Connection is started");
14814 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
14815 "for 4way Handshake");
14816 }
14817#endif
14818
14819 /* no_cck will be set during p2p find to disable 11b rates */
14820 if(TRUE == request->no_cck)
14821 {
14822 hddLog(VOS_TRACE_LEVEL_INFO,
14823 "%s: This is a P2P Search", __func__);
14824 scanRequest.p2pSearch = 1;
14825
14826 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053014827 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014828 /* set requestType to P2P Discovery */
14829 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
14830 }
14831
14832 /*
14833 Skip Dfs Channel in case of P2P Search
14834 if it is set in ini file
14835 */
14836 if(cfg_param->skipDfsChnlInP2pSearch)
14837 {
14838 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014839 }
14840 else
14841 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053014842 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053014843 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014844
Agarwal Ashish4f616132013-12-30 23:32:50 +053014845 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014846 }
14847 }
14848
14849 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
14850
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014851#ifdef FEATURE_WLAN_TDLS
14852 /* if tdls disagree scan right now, return immediately.
14853 tdls will schedule the scan when scan is allowed. (return SUCCESS)
14854 or will reject the scan if any TDLS is in progress. (return -EBUSY)
14855 */
14856 status = wlan_hdd_tdls_scan_callback (pAdapter,
14857 wiphy,
14858#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14859 dev,
14860#endif
14861 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014862 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014863 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053014864 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014865 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
14866 "scan rejected %d", __func__, status);
14867 else
14868 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
14869 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053014870 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053014871 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014872 }
14873#endif
14874
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014875 /* acquire the wakelock to avoid the apps suspend during the scan. To
14876 * address the following issues.
14877 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
14878 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
14879 * for long time, this result in apps running at full power for long time.
14880 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
14881 * be stuck in full power because of resume BMPS
14882 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014883 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014884
Nirav Shah20ac06f2013-12-12 18:14:06 +053014885 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
14886 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014887 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
14888 scanRequest.requestType, scanRequest.scanType,
14889 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053014890 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
14891
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014892 if (pHddCtx->spoofMacAddr.isEnabled &&
14893 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053014894 {
14895 hddLog(VOS_TRACE_LEVEL_INFO,
14896 "%s: MAC Spoofing enabled for current scan", __func__);
14897 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
14898 * to fill TxBds for probe request during current scan
14899 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014900 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053014901 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014902
14903 if(status != VOS_STATUS_SUCCESS)
14904 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014905 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014906 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053014907#ifdef FEATURE_WLAN_TDLS
14908 wlan_hdd_tdls_scan_done_callback(pAdapter);
14909#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053014910 goto free_mem;
14911 }
Siddharth Bhal76972212014-10-15 16:22:51 +053014912 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014913 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070014914 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014915 pAdapter->sessionId, &scanRequest, &scanId,
14916 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070014917
Jeff Johnson295189b2012-06-20 16:38:30 -070014918 if (eHAL_STATUS_SUCCESS != status)
14919 {
14920 hddLog(VOS_TRACE_LEVEL_ERROR,
14921 "%s: sme_ScanRequest returned error %d", __func__, status);
14922 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014923 if(eHAL_STATUS_RESOURCES == status)
14924 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
14926 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070014927 status = -EBUSY;
14928 } else {
14929 status = -EIO;
14930 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014931 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053014932
14933#ifdef FEATURE_WLAN_TDLS
14934 wlan_hdd_tdls_scan_done_callback(pAdapter);
14935#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014936 goto free_mem;
14937 }
14938
14939 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014940 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070014941 pAdapter->request = request;
14942 pScanInfo->scanId = scanId;
14943
14944 complete(&pScanInfo->scan_req_completion_event);
14945
14946free_mem:
14947 if( scanRequest.SSIDs.SSIDList )
14948 {
14949 vos_mem_free(scanRequest.SSIDs.SSIDList);
14950 }
14951
14952 if( channelList )
14953 vos_mem_free( channelList );
14954
14955 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014956 return status;
14957}
14958
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014959int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
14960#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14961 struct net_device *dev,
14962#endif
14963 struct cfg80211_scan_request *request)
14964{
14965 int ret;
14966
14967 vos_ssr_protect(__func__);
14968 ret = __wlan_hdd_cfg80211_scan(wiphy,
14969#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14970 dev,
14971#endif
14972 request);
14973 vos_ssr_unprotect(__func__);
14974
14975 return ret;
14976}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014977
14978void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
14979{
14980 v_U8_t iniDot11Mode =
14981 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
14982 eHddDot11Mode hddDot11Mode = iniDot11Mode;
14983
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014984 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
14985 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014986 switch ( iniDot11Mode )
14987 {
14988 case eHDD_DOT11_MODE_AUTO:
14989 case eHDD_DOT11_MODE_11ac:
14990 case eHDD_DOT11_MODE_11ac_ONLY:
14991#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053014992 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
14993 sme_IsFeatureSupportedByFW(DOT11AC) )
14994 hddDot11Mode = eHDD_DOT11_MODE_11ac;
14995 else
14996 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014997#else
14998 hddDot11Mode = eHDD_DOT11_MODE_11n;
14999#endif
15000 break;
15001 case eHDD_DOT11_MODE_11n:
15002 case eHDD_DOT11_MODE_11n_ONLY:
15003 hddDot11Mode = eHDD_DOT11_MODE_11n;
15004 break;
15005 default:
15006 hddDot11Mode = iniDot11Mode;
15007 break;
15008 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015009#ifdef WLAN_FEATURE_AP_HT40_24G
15010 if (operationChannel > SIR_11B_CHANNEL_END)
15011#endif
15012 {
15013 /* This call decides required channel bonding mode */
15014 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015015 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015016 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015017 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015018}
15019
Jeff Johnson295189b2012-06-20 16:38:30 -070015020/*
15021 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015022 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015023 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015024int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015025 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15026 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015027{
15028 int status = 0;
15029 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015030 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015031 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015032 v_U32_t roamId;
15033 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015034 eCsrAuthType RSNAuthType;
15035
15036 ENTER();
15037
15038 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015039 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015040 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015041
15042 status = wlan_hdd_validate_context(pHddCtx);
15043 if (status)
15044 {
Yue Mae36e3552014-03-05 17:06:20 -080015045 return status;
15046 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015047
Jeff Johnson295189b2012-06-20 16:38:30 -070015048 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15049 {
15050 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15051 return -EINVAL;
15052 }
15053
Nitesh Shah9b066282017-06-06 18:05:52 +053015054 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
15055
Jeff Johnson295189b2012-06-20 16:38:30 -070015056 pRoamProfile = &pWextState->roamProfile;
15057
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015058 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015059 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015060 hdd_station_ctx_t *pHddStaCtx;
15061 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015062 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015063
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015064 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15065
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015066 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015067 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15068 {
15069 /*QoS not enabled in cfg file*/
15070 pRoamProfile->uapsd_mask = 0;
15071 }
15072 else
15073 {
15074 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015075 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015076 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15077 }
15078
15079 pRoamProfile->SSIDs.numOfSSIDs = 1;
15080 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15081 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015082 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015083 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15084 ssid, ssid_len);
15085
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015086 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15087 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15088
Jeff Johnson295189b2012-06-20 16:38:30 -070015089 if (bssid)
15090 {
15091 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015092 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015093 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015094 /* Save BSSID in seperate variable as well, as RoamProfile
15095 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015096 case of join failure we should send valid BSSID to supplicant
15097 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015098 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015099 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015100
Jeff Johnson295189b2012-06-20 16:38:30 -070015101 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015102 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015103 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015104 /* Store bssid_hint to use in the scan filter. */
15105 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15106 WNI_CFG_BSSID_LEN);
15107 /*
15108 * Save BSSID in seperate variable as well, as RoamProfile
15109 * BSSID is getting zeroed out in the association process. And in
15110 * case of join failure we should send valid BSSID to supplicant
15111 */
15112 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15113 WNI_CFG_BSSID_LEN);
15114 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15115 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015116 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015117
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015118
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015119 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15120 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015121 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15122 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015123 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015124 /*set gen ie*/
15125 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15126 /*set auth*/
15127 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15128 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015129#ifdef FEATURE_WLAN_WAPI
15130 if (pAdapter->wapi_info.nWapiMode)
15131 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015132 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015133 switch (pAdapter->wapi_info.wapiAuthMode)
15134 {
15135 case WAPI_AUTH_MODE_PSK:
15136 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015137 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015138 pAdapter->wapi_info.wapiAuthMode);
15139 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15140 break;
15141 }
15142 case WAPI_AUTH_MODE_CERT:
15143 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015144 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015145 pAdapter->wapi_info.wapiAuthMode);
15146 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15147 break;
15148 }
15149 } // End of switch
15150 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15151 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15152 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015153 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015154 pRoamProfile->AuthType.numEntries = 1;
15155 pRoamProfile->EncryptionType.numEntries = 1;
15156 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15157 pRoamProfile->mcEncryptionType.numEntries = 1;
15158 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15159 }
15160 }
15161#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015162#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015163 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015164 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15165 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15166 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015167 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15168 sizeof (tSirGtkOffloadParams));
15169 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015170 }
15171#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015172 pRoamProfile->csrPersona = pAdapter->device_mode;
15173
Jeff Johnson32d95a32012-09-10 13:15:23 -070015174 if( operatingChannel )
15175 {
15176 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15177 pRoamProfile->ChannelInfo.numOfChannels = 1;
15178 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015179 else
15180 {
15181 pRoamProfile->ChannelInfo.ChannelList = NULL;
15182 pRoamProfile->ChannelInfo.numOfChannels = 0;
15183 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015184 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15185 {
15186 hdd_select_cbmode(pAdapter,operatingChannel);
15187 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015188
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015189 /*
15190 * Change conn_state to connecting before sme_RoamConnect(),
15191 * because sme_RoamConnect() has a direct path to call
15192 * hdd_smeRoamCallback(), which will change the conn_state
15193 * If direct path, conn_state will be accordingly changed
15194 * to NotConnected or Associated by either
15195 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15196 * in sme_RoamCallback()
15197 * if sme_RomConnect is to be queued,
15198 * Connecting state will remain until it is completed.
15199 * If connection state is not changed,
15200 * connection state will remain in eConnectionState_NotConnected state.
15201 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15202 * if conn state is eConnectionState_NotConnected.
15203 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15204 * informed of connect result indication which is an issue.
15205 */
15206
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015207 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15208 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015209 {
15210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015211 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015212 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15213 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015214 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015215 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015216 pAdapter->sessionId, pRoamProfile, &roamId);
15217
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015218 if ((eHAL_STATUS_SUCCESS != status) &&
15219 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15220 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015221
15222 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015223 hddLog(VOS_TRACE_LEVEL_ERROR,
15224 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15225 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015226 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015227 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015228 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015229 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015230
15231 pRoamProfile->ChannelInfo.ChannelList = NULL;
15232 pRoamProfile->ChannelInfo.numOfChannels = 0;
15233
Jeff Johnson295189b2012-06-20 16:38:30 -070015234 }
15235 else
15236 {
15237 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15238 return -EINVAL;
15239 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015240 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015241 return status;
15242}
15243
15244/*
15245 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15246 * This function is used to set the authentication type (OPEN/SHARED).
15247 *
15248 */
15249static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15250 enum nl80211_auth_type auth_type)
15251{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015252 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015253 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15254
15255 ENTER();
15256
15257 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015258 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015259 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015260 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015261 hddLog(VOS_TRACE_LEVEL_INFO,
15262 "%s: set authentication type to AUTOSWITCH", __func__);
15263 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15264 break;
15265
15266 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015267#ifdef WLAN_FEATURE_VOWIFI_11R
15268 case NL80211_AUTHTYPE_FT:
15269#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015270 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015271 "%s: set authentication type to OPEN", __func__);
15272 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15273 break;
15274
15275 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015276 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015277 "%s: set authentication type to SHARED", __func__);
15278 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15279 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015280#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015281 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015282 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015283 "%s: set authentication type to CCKM WPA", __func__);
15284 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15285 break;
15286#endif
15287
15288
15289 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015290 hddLog(VOS_TRACE_LEVEL_ERROR,
15291 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015292 auth_type);
15293 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15294 return -EINVAL;
15295 }
15296
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015297 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015298 pHddStaCtx->conn_info.authType;
15299 return 0;
15300}
15301
15302/*
15303 * FUNCTION: wlan_hdd_set_akm_suite
15304 * This function is used to set the key mgmt type(PSK/8021x).
15305 *
15306 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015307static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015308 u32 key_mgmt
15309 )
15310{
15311 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15312 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015313 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015314#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015315#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015316#endif
15317#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015318#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015319#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015320 /*set key mgmt type*/
15321 switch(key_mgmt)
15322 {
15323 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015324 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015325#ifdef WLAN_FEATURE_VOWIFI_11R
15326 case WLAN_AKM_SUITE_FT_PSK:
15327#endif
15328 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015329 __func__);
15330 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15331 break;
15332
15333 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015334 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015335#ifdef WLAN_FEATURE_VOWIFI_11R
15336 case WLAN_AKM_SUITE_FT_8021X:
15337#endif
15338 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015339 __func__);
15340 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15341 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015342#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015343#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15344#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15345 case WLAN_AKM_SUITE_CCKM:
15346 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15347 __func__);
15348 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15349 break;
15350#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015351#ifndef WLAN_AKM_SUITE_OSEN
15352#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15353 case WLAN_AKM_SUITE_OSEN:
15354 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15355 __func__);
15356 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15357 break;
15358#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015359
15360 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015361 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015362 __func__, key_mgmt);
15363 return -EINVAL;
15364
15365 }
15366 return 0;
15367}
15368
15369/*
15370 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015371 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015372 * (NONE/WEP40/WEP104/TKIP/CCMP).
15373 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015374static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15375 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015376 bool ucast
15377 )
15378{
15379 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015380 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015381 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15382
15383 ENTER();
15384
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015385 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015386 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015387 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015388 __func__, cipher);
15389 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15390 }
15391 else
15392 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015393
Jeff Johnson295189b2012-06-20 16:38:30 -070015394 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015395 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015396 {
15397 case IW_AUTH_CIPHER_NONE:
15398 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15399 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015400
Jeff Johnson295189b2012-06-20 16:38:30 -070015401 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015402 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070015403 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015404
Jeff Johnson295189b2012-06-20 16:38:30 -070015405 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015406 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070015407 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015408
Jeff Johnson295189b2012-06-20 16:38:30 -070015409 case WLAN_CIPHER_SUITE_TKIP:
15410 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
15411 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015412
Jeff Johnson295189b2012-06-20 16:38:30 -070015413 case WLAN_CIPHER_SUITE_CCMP:
15414 encryptionType = eCSR_ENCRYPT_TYPE_AES;
15415 break;
15416#ifdef FEATURE_WLAN_WAPI
15417 case WLAN_CIPHER_SUITE_SMS4:
15418 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
15419 break;
15420#endif
15421
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015422#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015423 case WLAN_CIPHER_SUITE_KRK:
15424 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
15425 break;
15426#endif
15427 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015428 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015429 __func__, cipher);
15430 return -EOPNOTSUPP;
15431 }
15432 }
15433
15434 if (ucast)
15435 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015436 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015437 __func__, encryptionType);
15438 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
15439 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015440 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015441 encryptionType;
15442 }
15443 else
15444 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015445 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015446 __func__, encryptionType);
15447 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
15448 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
15449 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
15450 }
15451
15452 return 0;
15453}
15454
15455
15456/*
15457 * FUNCTION: wlan_hdd_cfg80211_set_ie
15458 * This function is used to parse WPA/RSN IE's.
15459 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015460int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015461#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15462 const u8 *ie,
15463#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015464 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015465#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015466 size_t ie_len
15467 )
15468{
15469 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15471 const u8 *genie = ie;
15472#else
Jeff Johnson295189b2012-06-20 16:38:30 -070015473 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015474#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015475 v_U16_t remLen = ie_len;
15476#ifdef FEATURE_WLAN_WAPI
15477 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
15478 u16 *tmp;
15479 v_U16_t akmsuiteCount;
15480 int *akmlist;
15481#endif
15482 ENTER();
15483
15484 /* clear previous assocAddIE */
15485 pWextState->assocAddIE.length = 0;
15486 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015487 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015488
15489 while (remLen >= 2)
15490 {
15491 v_U16_t eLen = 0;
15492 v_U8_t elementId;
15493 elementId = *genie++;
15494 eLen = *genie++;
15495 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015496
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053015497 /* Sanity check on eLen */
15498 if (eLen > remLen) {
15499 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
15500 __func__, eLen, elementId);
15501 VOS_ASSERT(0);
15502 return -EINVAL;
15503 }
15504
Arif Hussain6d2a3322013-11-17 19:50:10 -080015505 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070015506 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015507
15508 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070015509 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015510 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015511 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 -070015512 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015513 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015514 "%s: Invalid WPA IE", __func__);
15515 return -EINVAL;
15516 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015517 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070015518 {
15519 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015520 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015521 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015522
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015523 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015524 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015525 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
15526 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015527 VOS_ASSERT(0);
15528 return -ENOMEM;
15529 }
15530 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15531 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15532 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015533
Jeff Johnson295189b2012-06-20 16:38:30 -070015534 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
15535 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15536 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15537 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015538 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
15539 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053015540 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15541 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
15542 __func__, eLen);
15543 VOS_ASSERT(0);
15544 return -EINVAL;
15545 }
15546
Jeff Johnson295189b2012-06-20 16:38:30 -070015547 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
15548 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15549 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
15550 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
15551 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
15552 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015553 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053015554 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070015555 {
15556 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015557 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015558 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015559
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015560 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015561 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015562 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15563 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015564 VOS_ASSERT(0);
15565 return -ENOMEM;
15566 }
15567 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
15568 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15569 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015570
Jeff Johnson295189b2012-06-20 16:38:30 -070015571 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15572 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15573 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015574#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015575 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
15576 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015577 /*Consider WFD IE, only for P2P Client */
15578 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
15579 {
15580 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015581 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070015582 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015583
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015584 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015585 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015586 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15587 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070015588 VOS_ASSERT(0);
15589 return -ENOMEM;
15590 }
15591 // WFD IE is saved to Additional IE ; it should be accumulated to handle
15592 // WPS IE + P2P IE + WFD IE
15593 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15594 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015595
Jeff Johnson295189b2012-06-20 16:38:30 -070015596 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15597 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15598 }
15599#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015600 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015601 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015602 HS20_OUI_TYPE_SIZE)) )
15603 {
15604 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015605 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015606 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015607
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015608 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015609 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015610 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15611 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015612 VOS_ASSERT(0);
15613 return -ENOMEM;
15614 }
15615 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15616 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015617
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070015618 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15619 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15620 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015621 /* Appending OSEN Information Element in Assiciation Request */
15622 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
15623 OSEN_OUI_TYPE_SIZE)) )
15624 {
15625 v_U16_t curAddIELen = pWextState->assocAddIE.length;
15626 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
15627 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015628
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015629 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070015630 {
15631 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15632 "Need bigger buffer space");
15633 VOS_ASSERT(0);
15634 return -ENOMEM;
15635 }
15636 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15637 pWextState->assocAddIE.length += eLen + 2;
15638
15639 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
15640 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15641 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15642 }
15643
Abhishek Singh4322e622015-06-10 15:42:54 +053015644 /* Update only for WPA IE */
15645 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
15646 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015647
15648 /* populating as ADDIE in beacon frames */
15649 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015650 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015651 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
15652 {
15653 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15654 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
15655 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15656 {
15657 hddLog(LOGE,
15658 "Coldn't pass "
15659 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
15660 }
15661 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
15662 else
15663 hddLog(LOGE,
15664 "Could not pass on "
15665 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
15666
15667 /* IBSS mode doesn't contain params->proberesp_ies still
15668 beaconIE's need to be populated in probe response frames */
15669 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
15670 {
15671 u16 rem_probe_resp_ie_len = eLen + 2;
15672 u8 probe_rsp_ie_len[3] = {0};
15673 u8 counter = 0;
15674
15675 /* Check Probe Resp Length if it is greater then 255 then
15676 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
15677 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
15678 not able Store More then 255 bytes into One Variable */
15679
15680 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
15681 {
15682 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
15683 {
15684 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
15685 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
15686 }
15687 else
15688 {
15689 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
15690 rem_probe_resp_ie_len = 0;
15691 }
15692 }
15693
15694 rem_probe_resp_ie_len = 0;
15695
15696 if (probe_rsp_ie_len[0] > 0)
15697 {
15698 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15699 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
15700 (tANI_U8*)(genie - 2),
15701 probe_rsp_ie_len[0], NULL,
15702 eANI_BOOLEAN_FALSE)
15703 == eHAL_STATUS_FAILURE)
15704 {
15705 hddLog(LOGE,
15706 "Could not pass"
15707 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
15708 }
15709 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
15710 }
15711
15712 if (probe_rsp_ie_len[1] > 0)
15713 {
15714 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15715 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
15716 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15717 probe_rsp_ie_len[1], NULL,
15718 eANI_BOOLEAN_FALSE)
15719 == eHAL_STATUS_FAILURE)
15720 {
15721 hddLog(LOGE,
15722 "Could not pass"
15723 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
15724 }
15725 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
15726 }
15727
15728 if (probe_rsp_ie_len[2] > 0)
15729 {
15730 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
15731 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
15732 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
15733 probe_rsp_ie_len[2], NULL,
15734 eANI_BOOLEAN_FALSE)
15735 == eHAL_STATUS_FAILURE)
15736 {
15737 hddLog(LOGE,
15738 "Could not pass"
15739 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
15740 }
15741 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
15742 }
15743
15744 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
15745 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
15746 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
15747 {
15748 hddLog(LOGE,
15749 "Could not pass"
15750 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
15751 }
15752 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070015753 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070015754 break;
15755 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053015756 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
15757 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
15758 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
15759 VOS_ASSERT(0);
15760 return -EINVAL;
15761 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015762 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
15763 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
15764 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
15765 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
15766 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
15767 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053015768
Abhishek Singhb16f3562016-01-20 11:08:32 +053015769 /* Appending extended capabilities with Interworking or
15770 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053015771 *
15772 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053015773 * interworkingService or bsstransition bit is set to 1.
15774 * Driver is only interested in interworkingService and
15775 * bsstransition capability from supplicant.
15776 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053015777 * required from supplicat, it needs to be handled while
15778 * sending Assoc Req in LIM.
15779 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015780 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015781 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015782 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015783 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015784 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015785
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015786 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015787 {
Jeff Johnson902c9832012-12-10 14:28:09 -080015788 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
15789 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015790 VOS_ASSERT(0);
15791 return -ENOMEM;
15792 }
15793 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
15794 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015795
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015796 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
15797 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
15798 break;
15799 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015800#ifdef FEATURE_WLAN_WAPI
15801 case WLAN_EID_WAPI:
15802 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015803 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070015804 pAdapter->wapi_info.nWapiMode);
15805 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015806 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070015807 akmsuiteCount = WPA_GET_LE16(tmp);
15808 tmp = tmp + 1;
15809 akmlist = (int *)(tmp);
15810 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
15811 {
15812 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
15813 }
15814 else
15815 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015816 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070015817 VOS_ASSERT(0);
15818 return -EINVAL;
15819 }
15820
15821 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
15822 {
15823 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015824 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015825 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015826 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015827 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015828 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015829 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015830 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015831 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
15832 }
15833 break;
15834#endif
15835 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015836 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015837 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070015838 /* when Unknown IE is received we should break and continue
15839 * to the next IE in the buffer instead we were returning
15840 * so changing this to break */
15841 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070015842 }
15843 genie += eLen;
15844 remLen -= eLen;
15845 }
15846 EXIT();
15847 return 0;
15848}
15849
15850/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015851 * FUNCTION: hdd_isWPAIEPresent
15852 * Parse the received IE to find the WPA IE
15853 *
15854 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015855static bool hdd_isWPAIEPresent(
15856#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
15857 const u8 *ie,
15858#else
15859 u8 *ie,
15860#endif
15861 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053015862{
15863 v_U8_t eLen = 0;
15864 v_U16_t remLen = ie_len;
15865 v_U8_t elementId = 0;
15866
15867 while (remLen >= 2)
15868 {
15869 elementId = *ie++;
15870 eLen = *ie++;
15871 remLen -= 2;
15872 if (eLen > remLen)
15873 {
15874 hddLog(VOS_TRACE_LEVEL_ERROR,
15875 "%s: IE length is wrong %d", __func__, eLen);
15876 return FALSE;
15877 }
15878 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
15879 {
15880 /* OUI - 0x00 0X50 0XF2
15881 WPA Information Element - 0x01
15882 WPA version - 0x01*/
15883 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
15884 return TRUE;
15885 }
15886 ie += eLen;
15887 remLen -= eLen;
15888 }
15889 return FALSE;
15890}
15891
15892/*
Jeff Johnson295189b2012-06-20 16:38:30 -070015893 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015894 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070015895 * parameters during connect operation.
15896 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015897int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015898 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015899 )
Jeff Johnson295189b2012-06-20 16:38:30 -070015900{
15901 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015902 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015903 ENTER();
15904
15905 /*set wpa version*/
15906 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
15907
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015908 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015909 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053015910 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070015911 {
15912 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
15913 }
15914 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
15915 {
15916 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
15917 }
15918 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015919
15920 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015921 pWextState->wpaVersion);
15922
15923 /*set authentication type*/
15924 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
15925
15926 if (0 > status)
15927 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015928 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015929 "%s: failed to set authentication type ", __func__);
15930 return status;
15931 }
15932
15933 /*set key mgmt type*/
15934 if (req->crypto.n_akm_suites)
15935 {
15936 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
15937 if (0 > status)
15938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015939 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070015940 __func__);
15941 return status;
15942 }
15943 }
15944
15945 /*set pairwise cipher type*/
15946 if (req->crypto.n_ciphers_pairwise)
15947 {
15948 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
15949 req->crypto.ciphers_pairwise[0], true);
15950 if (0 > status)
15951 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015952 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015953 "%s: failed to set unicast cipher type", __func__);
15954 return status;
15955 }
15956 }
15957 else
15958 {
15959 /*Reset previous cipher suite to none*/
15960 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
15961 if (0 > status)
15962 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015963 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015964 "%s: failed to set unicast cipher type", __func__);
15965 return status;
15966 }
15967 }
15968
15969 /*set group cipher type*/
15970 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
15971 false);
15972
15973 if (0 > status)
15974 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070015976 __func__);
15977 return status;
15978 }
15979
Chet Lanctot186b5732013-03-18 10:26:30 -070015980#ifdef WLAN_FEATURE_11W
15981 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
15982#endif
15983
Jeff Johnson295189b2012-06-20 16:38:30 -070015984 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
15985 if (req->ie_len)
15986 {
15987 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
15988 if ( 0 > status)
15989 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015990 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070015991 __func__);
15992 return status;
15993 }
15994 }
15995
15996 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015997 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070015998 {
15999 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16000 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16001 )
16002 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016003 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016004 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16005 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016006 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016007 __func__);
16008 return -EOPNOTSUPP;
16009 }
16010 else
16011 {
16012 u8 key_len = req->key_len;
16013 u8 key_idx = req->key_idx;
16014
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016015 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016016 && (CSR_MAX_NUM_KEY > key_idx)
16017 )
16018 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016019 hddLog(VOS_TRACE_LEVEL_INFO,
16020 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016021 __func__, key_idx, key_len);
16022 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016023 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016024 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016025 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016026 (u8)key_len;
16027 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16028 }
16029 }
16030 }
16031 }
16032
16033 return status;
16034}
16035
16036/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016037 * FUNCTION: wlan_hdd_try_disconnect
16038 * This function is used to disconnect from previous
16039 * connection
16040 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016041int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016042{
16043 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016044 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016045 hdd_station_ctx_t *pHddStaCtx;
16046 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016047 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016048
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016049 ret = wlan_hdd_validate_context(pHddCtx);
16050 if (0 != ret)
16051 {
16052 return ret;
16053 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016054 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16055
16056 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16057
16058 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16059 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016060 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016061 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16062 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016063 /* Indicate disconnect to SME so that in-progress connection or preauth
16064 * can be aborted
16065 */
16066 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16067 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016068 spin_lock_bh(&pAdapter->lock_for_active_session);
16069 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16070 {
16071 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16072 }
16073 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016074 hdd_connSetConnectionState(pHddStaCtx,
16075 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016076 /* Issue disconnect to CSR */
16077 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016078 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016079 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016080 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16081 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16082 hddLog(LOG1,
16083 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16084 } else if ( 0 != status ) {
16085 hddLog(LOGE,
16086 FL("csrRoamDisconnect failure, returned %d"),
16087 (int)status );
16088 result = -EINVAL;
16089 goto disconnected;
16090 }
16091 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016092 &pAdapter->disconnect_comp_var,
16093 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016094 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16095 hddLog(LOGE,
16096 "%s: Failed to disconnect, timed out", __func__);
16097 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016098 }
16099 }
16100 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16101 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016102 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016103 &pAdapter->disconnect_comp_var,
16104 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016105 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016106 {
16107 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016108 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016109 }
16110 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016111disconnected:
16112 hddLog(LOG1,
16113 FL("Set HDD connState to eConnectionState_NotConnected"));
16114 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16115 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016116}
16117
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016118/**
16119 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16120 * @adapter: Pointer to the HDD adapter
16121 * @req: Pointer to the structure cfg_connect_params receieved from user space
16122 *
16123 * This function will start reassociation if bssid hint, channel hint and
16124 * previous bssid parameters are present in the connect request
16125 *
16126 * Return: success if reassociation is happening
16127 * Error code if reassociation is not permitted or not happening
16128 */
16129#ifdef CFG80211_CONNECT_PREV_BSSID
16130static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16131 struct cfg80211_connect_params *req)
16132{
16133 int status = -EPERM;
16134 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16135 hddLog(VOS_TRACE_LEVEL_INFO,
16136 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16137 req->channel_hint->hw_value,
16138 MAC_ADDR_ARRAY(req->bssid_hint));
16139 status = hdd_reassoc(adapter, req->bssid_hint,
16140 req->channel_hint->hw_value,
16141 CONNECT_CMD_USERSPACE);
16142 }
16143 return status;
16144}
16145#else
16146static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16147 struct cfg80211_connect_params *req)
16148{
16149 return -EPERM;
16150}
16151#endif
16152
Abhishek Singhe3beee22017-07-31 15:35:40 +053016153/**
16154 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16155 * connect in HT20 mode
16156 * @hdd_ctx: hdd context
16157 * @adapter: Pointer to the HDD adapter
16158 * @req: Pointer to the structure cfg_connect_params receieved from user space
16159 *
16160 * This function will check if supplicant has indicated to to connect in HT20
16161 * mode. this is currently applicable only for 2.4Ghz mode only.
16162 * if feature is enabled and supplicant indicate HT20 set
16163 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16164 *
16165 * Return: void
16166 */
16167#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16168static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16169 hdd_adapter_t *adapter,
16170 struct cfg80211_connect_params *req)
16171{
16172 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16173 tCsrRoamProfile *roam_profile;
16174
16175 roam_profile = &wext_state->roamProfile;
16176 roam_profile->force_24ghz_in_ht20 = false;
16177 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16178 !(req->ht_capa.cap_info &
16179 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16180 roam_profile->force_24ghz_in_ht20 = true;
16181
16182 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16183 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16184}
16185#else
16186static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16187 hdd_adapter_t *adapter,
16188 struct cfg80211_connect_params *req)
16189{
16190 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16191 tCsrRoamProfile *roam_profile;
16192
16193 roam_profile = &wext_state->roamProfile;
16194 roam_profile->force_24ghz_in_ht20 = false;
16195}
16196#endif
16197
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016198/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016199 * FUNCTION: __wlan_hdd_cfg80211_connect
16200 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016201 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016202static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016203 struct net_device *ndev,
16204 struct cfg80211_connect_params *req
16205 )
16206{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016207 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016208 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016209#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16210 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016211 const u8 *bssid_hint = req->bssid_hint;
16212#else
16213 const u8 *bssid_hint = NULL;
16214#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016215 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016216 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016217 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016218
16219 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016220
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016221 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16222 TRACE_CODE_HDD_CFG80211_CONNECT,
16223 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016224 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016225 "%s: device_mode = %s (%d)", __func__,
16226 hdd_device_modetoString(pAdapter->device_mode),
16227 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016228
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016229 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016230 if (!pHddCtx)
16231 {
16232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16233 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016234 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016235 }
16236
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016237 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016238 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016239 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016240 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016241 }
16242
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016243 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16244 return -EINVAL;
16245
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016246 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16247 if (0 == status)
16248 return status;
16249
Agarwal Ashish51325b52014-06-16 16:50:49 +053016250
Jeff Johnson295189b2012-06-20 16:38:30 -070016251#ifdef WLAN_BTAMP_FEATURE
16252 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016253 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016254 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016255 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016256 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016257 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016258 }
16259#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016260
16261 //If Device Mode is Station Concurrent Sessions Exit BMps
16262 //P2P Mode will be taken care in Open/close adapter
16263 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016264 (vos_concurrent_open_sessions_running())) {
16265 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16266 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016267 }
16268
16269 /*Try disconnecting if already in connected state*/
16270 status = wlan_hdd_try_disconnect(pAdapter);
16271 if ( 0 > status)
16272 {
16273 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16274 " connection"));
16275 return -EALREADY;
16276 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016277 /* Check for max concurrent connections after doing disconnect if any*/
16278 if (vos_max_concurrent_connections_reached()) {
16279 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16280 return -ECONNREFUSED;
16281 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016282
Jeff Johnson295189b2012-06-20 16:38:30 -070016283 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016284 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016285
16286 if ( 0 > status)
16287 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016288 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016289 __func__);
16290 return status;
16291 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016292
16293 if (pHddCtx->spoofMacAddr.isEnabled)
16294 {
16295 hddLog(VOS_TRACE_LEVEL_INFO,
16296 "%s: MAC Spoofing enabled ", __func__);
16297 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16298 * to fill TxBds for probe request during SSID scan which may happen
16299 * as part of connect command
16300 */
16301 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16302 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16303 if (status != VOS_STATUS_SUCCESS)
16304 return -ECONNREFUSED;
16305 }
16306
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016307 if (req->channel)
16308 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016309 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016310 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016311
16312 /* Abort if any scan is going on */
16313 status = wlan_hdd_scan_abort(pAdapter);
16314 if (0 != status)
16315 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16316
Abhishek Singhe3beee22017-07-31 15:35:40 +053016317 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16318
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016319 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16320 req->ssid_len, req->bssid,
16321 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016322
Sushant Kaushikd7083982015-03-18 14:33:24 +053016323 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016324 {
16325 //ReEnable BMPS if disabled
16326 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16327 (NULL != pHddCtx))
16328 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016329 if (pHddCtx->hdd_wlan_suspended)
16330 {
16331 hdd_set_pwrparams(pHddCtx);
16332 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016333 //ReEnable Bmps and Imps back
16334 hdd_enable_bmps_imps(pHddCtx);
16335 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016337 return status;
16338 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016339 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016340 EXIT();
16341 return status;
16342}
16343
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016344static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16345 struct net_device *ndev,
16346 struct cfg80211_connect_params *req)
16347{
16348 int ret;
16349 vos_ssr_protect(__func__);
16350 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16351 vos_ssr_unprotect(__func__);
16352
16353 return ret;
16354}
Jeff Johnson295189b2012-06-20 16:38:30 -070016355
16356/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016357 * FUNCTION: wlan_hdd_disconnect
16358 * This function is used to issue a disconnect request to SME
16359 */
16360int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
16361{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016362 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016363 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016364 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016365 long ret;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016366 eConnectionState prev_conn_state;
Yeshwanth Sriram Guntukaae784d22017-12-06 14:20:51 +053016367 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016368
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016369 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016370
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016371 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016372 if (0 != status)
16373 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016374 return status;
16375 }
Abhishek Singh07e4a892015-11-23 11:29:57 +053016376 /* Indicate sme of disconnect so that in progress connection or preauth
16377 * can be aborted
16378 */
16379 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
Sushant Kaushikb4834d22015-07-15 15:29:05 +053016380 pAdapter->sessionId);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016381 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016382
Agarwal Ashish47d18112014-08-04 19:55:07 +053016383 /* Need to apply spin lock before decreasing active sessions
16384 * as there can be chance for double decrement if context switch
16385 * Calls hdd_DisConnectHandler.
16386 */
16387
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016388 prev_conn_state = pHddStaCtx->conn_info.connState;
16389
Agarwal Ashish47d18112014-08-04 19:55:07 +053016390 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016391 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16392 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016393 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16394 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053016395 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
16396 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singh78c691f2017-11-30 13:48:44 +053016397 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053016398
Abhishek Singhf4669da2014-05-26 15:07:49 +053016399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053016400 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
16401
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016402 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016403
Mihir Shete182a0b22014-08-18 16:08:48 +053016404 /*
16405 * stop tx queues before deleting STA/BSS context from the firmware.
16406 * tx has to be disabled because the firmware can get busy dropping
16407 * the tx frames after BSS/STA has been deleted and will not send
16408 * back a response resulting in WDI timeout
16409 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053016410 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053016411 netif_tx_disable(pAdapter->dev);
16412 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016413
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016414 wlan_hdd_check_and_stop_mon(pAdapter, true);
16415
Mihir Shete182a0b22014-08-18 16:08:48 +053016416 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016417 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
16418 pAdapter->sessionId, reason);
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016419 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
16420 prev_conn_state != eConnectionState_Connecting)
16421 {
16422 hddLog(LOG1,
16423 FL("status = %d, already disconnected"), status);
16424 result = 0;
Yeshwanth Sriram Guntukaae784d22017-12-06 14:20:51 +053016425 /*
16426 * Wait here instead of returning directly. This will block the
16427 * next connect command and allow processing of the disconnect
16428 * in SME else we might hit some race conditions leading to SME
16429 * and HDD out of sync. As disconnect is already in progress,
16430 * wait here for 1 sec instead of 5 sec.
16431 */
16432 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
16433 goto wait_for_disconnect;
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016434 }
16435 /*
16436 * Wait here instead of returning directly, this will block the next
16437 * connect command and allow processing of the scan for ssid and
16438 * the previous connect command in CSR. Else we might hit some
16439 * race conditions leading to SME and HDD out of sync.
16440 */
16441 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016442 {
16443 hddLog(LOG1,
16444 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016445 }
16446 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016447 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016448 hddLog(LOGE,
16449 FL("csrRoamDisconnect failure, returned %d"),
16450 (int)status);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016451 result = -EINVAL;
16452 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016453 }
Yeshwanth Sriram Guntukaae784d22017-12-06 14:20:51 +053016454wait_for_disconnect:
16455 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
16456 msecs_to_jiffies(wait_time));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016457 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016458 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016459 hddLog(LOGE,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053016460 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016461 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053016462 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016463disconnected:
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016464 hddLog(LOG1,
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016465 FL("Set HDD connState to eConnectionState_NotConnected"));
16466 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053016467#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
16468 /* Sending disconnect event to userspace for kernel version < 3.11
16469 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
16470 */
16471 hddLog(LOG1, FL("Send disconnected event to userspace"));
16472
Mahesh A Saptasagarf5859b12016-06-01 17:17:50 +053016473 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
Mahesh A Saptasagar936ffc32016-05-25 11:27:43 +053016474 WLAN_REASON_UNSPECIFIED);
16475#endif
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053016476
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016477 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053016478 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016479}
16480
16481
16482/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016483 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016484 * This function is used to issue a disconnect request to SME
16485 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016486static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016487 struct net_device *dev,
16488 u16 reason
16489 )
16490{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016492 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016493 tCsrRoamProfile *pRoamProfile;
16494 hdd_station_ctx_t *pHddStaCtx;
16495 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016496#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016497 tANI_U8 staIdx;
16498#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016499
Jeff Johnson295189b2012-06-20 16:38:30 -070016500 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016501
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016502 if (!pAdapter) {
16503 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16504 return -EINVAL;
16505 }
16506
16507 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16508 if (!pHddStaCtx) {
16509 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16510 return -EINVAL;
16511 }
16512
16513 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16514 status = wlan_hdd_validate_context(pHddCtx);
16515 if (0 != status)
16516 {
16517 return status;
16518 }
16519
16520 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16521
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016522 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16523 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16524 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016525 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16526 __func__, hdd_device_modetoString(pAdapter->device_mode),
16527 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016528
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016529 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
16530 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070016531
Jeff Johnson295189b2012-06-20 16:38:30 -070016532 if (NULL != pRoamProfile)
16533 {
16534 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016535 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
16536 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070016537 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016538 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070016539 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016540 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070016541 switch(reason)
16542 {
16543 case WLAN_REASON_MIC_FAILURE:
16544 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
16545 break;
16546
16547 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
16548 case WLAN_REASON_DISASSOC_AP_BUSY:
16549 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
16550 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
16551 break;
16552
16553 case WLAN_REASON_PREV_AUTH_NOT_VALID:
16554 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053016555 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070016556 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
16557 break;
16558
Jeff Johnson295189b2012-06-20 16:38:30 -070016559 default:
16560 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
16561 break;
16562 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016563 pScanInfo = &pHddCtx->scan_info;
16564 if (pScanInfo->mScanPending)
16565 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016566 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016567 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053016568 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053016569 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016570 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053016571 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016572#ifdef FEATURE_WLAN_TDLS
16573 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016574 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016575 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016576 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
16577 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016578 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016579 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016580 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016582 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080016583 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016584 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016585 status = sme_DeleteTdlsPeerSta(
16586 WLAN_HDD_GET_HAL_CTX(pAdapter),
16587 pAdapter->sessionId,
16588 mac);
16589 if (status != eHAL_STATUS_SUCCESS) {
16590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16591 return -EPERM;
16592 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016593 }
16594 }
16595#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053016596
16597 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
16598 reasonCode,
16599 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016600 status = wlan_hdd_disconnect(pAdapter, reasonCode);
16601 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070016602 {
16603 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016604 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016605 __func__, (int)status );
16606 return -EINVAL;
16607 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016608 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016609 else
16610 {
16611 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
16612 "called while in %d state", __func__,
16613 pHddStaCtx->conn_info.connState);
16614 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016615 }
16616 else
16617 {
16618 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
16619 }
16620
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016621 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016622 return status;
16623}
16624
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016625static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
16626 struct net_device *dev,
16627 u16 reason
16628 )
16629{
16630 int ret;
16631 vos_ssr_protect(__func__);
16632 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
16633 vos_ssr_unprotect(__func__);
16634
16635 return ret;
16636}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053016637
Jeff Johnson295189b2012-06-20 16:38:30 -070016638/*
16639 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016640 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016641 * settings in IBSS mode.
16642 */
16643static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016644 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016645 struct cfg80211_ibss_params *params
16646 )
16647{
16648 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016649 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016650 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16651 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016652
Jeff Johnson295189b2012-06-20 16:38:30 -070016653 ENTER();
16654
16655 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070016656 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070016657
16658 if (params->ie_len && ( NULL != params->ie) )
16659 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016660 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16661 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016662 {
16663 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16664 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16665 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016666 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070016667 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016668 tDot11fIEWPA dot11WPAIE;
16669 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016670 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016671
Wilson Yang00256342013-10-10 23:13:38 -070016672 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016673 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
16674 params->ie_len, DOT11F_EID_WPA);
16675 if ( NULL != ie )
16676 {
16677 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16678 // Unpack the WPA IE
16679 //Skip past the EID byte and length byte - and four byte WiFi OUI
16680 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
16681 &ie[2+4],
16682 ie[1] - 4,
16683 &dot11WPAIE);
16684 /*Extract the multicast cipher, the encType for unicast
16685 cipher for wpa-none is none*/
16686 encryptionType =
16687 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
16688 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016689 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070016690
Jeff Johnson295189b2012-06-20 16:38:30 -070016691 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
16692
16693 if (0 > status)
16694 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016696 __func__);
16697 return status;
16698 }
16699 }
16700
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016701 pWextState->roamProfile.AuthType.authType[0] =
16702 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070016703 eCSR_AUTH_TYPE_OPEN_SYSTEM;
16704
16705 if (params->privacy)
16706 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016707 /* Security enabled IBSS, At this time there is no information available
16708 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070016709 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016710 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070016711 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016712 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070016713 *enable privacy bit in beacons */
16714
16715 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
16716 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070016717 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
16718 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070016719 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16720 pWextState->roamProfile.EncryptionType.numEntries = 1;
16721 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070016722 return status;
16723}
16724
16725/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016726 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016727 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016728 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016729static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016730 struct net_device *dev,
16731 struct cfg80211_ibss_params *params
16732 )
16733{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016735 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16736 tCsrRoamProfile *pRoamProfile;
16737 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016738 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16739 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016740 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070016741
16742 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016743
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016744 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16745 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
16746 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016747 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016748 "%s: device_mode = %s (%d)", __func__,
16749 hdd_device_modetoString(pAdapter->device_mode),
16750 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016751
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016752 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016753 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016754 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016755 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016756 }
16757
16758 if (NULL == pWextState)
16759 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016760 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016761 __func__);
16762 return -EIO;
16763 }
16764
Agarwal Ashish51325b52014-06-16 16:50:49 +053016765 if (vos_max_concurrent_connections_reached()) {
16766 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16767 return -ECONNREFUSED;
16768 }
16769
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016770 /*Try disconnecting if already in connected state*/
16771 status = wlan_hdd_try_disconnect(pAdapter);
16772 if ( 0 > status)
16773 {
16774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16775 " IBSS connection"));
16776 return -EALREADY;
16777 }
16778
Jeff Johnson295189b2012-06-20 16:38:30 -070016779 pRoamProfile = &pWextState->roamProfile;
16780
16781 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
16782 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016783 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016784 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016785 return -EINVAL;
16786 }
16787
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016788 /* BSSID is provided by upper layers hence no need to AUTO generate */
16789 if (NULL != params->bssid) {
16790 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16791 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
16792 hddLog (VOS_TRACE_LEVEL_ERROR,
16793 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16794 return -EIO;
16795 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016796 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016797 }
krunal sonie9002db2013-11-25 14:24:17 -080016798 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
16799 {
16800 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
16801 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
16802 {
16803 hddLog (VOS_TRACE_LEVEL_ERROR,
16804 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
16805 return -EIO;
16806 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016807
16808 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080016809 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016810 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080016811 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070016812
Jeff Johnson295189b2012-06-20 16:38:30 -070016813 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070016814 if (NULL !=
16815#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16816 params->chandef.chan)
16817#else
16818 params->channel)
16819#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016820 {
16821 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016822 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16823 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
16824 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16825 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016826
16827 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016828 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070016829 ieee80211_frequency_to_channel(
16830#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
16831 params->chandef.chan->center_freq);
16832#else
16833 params->channel->center_freq);
16834#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016835
16836 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16837 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070016838 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016839 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
16840 __func__);
16841 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070016842 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016843
16844 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070016845 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016846 if (channelNum == validChan[indx])
16847 {
16848 break;
16849 }
16850 }
16851 if (indx >= numChans)
16852 {
16853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016854 __func__, channelNum);
16855 return -EINVAL;
16856 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016857 /* Set the Operational Channel */
16858 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
16859 channelNum);
16860 pRoamProfile->ChannelInfo.numOfChannels = 1;
16861 pHddStaCtx->conn_info.operationChannel = channelNum;
16862 pRoamProfile->ChannelInfo.ChannelList =
16863 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070016864 }
16865
16866 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016867 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070016868 if (status < 0)
16869 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016870 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070016871 __func__);
16872 return status;
16873 }
16874
16875 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016876 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053016877 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016878 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016879
16880 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016881 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016882
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016883 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016884 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016885}
16886
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016887static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
16888 struct net_device *dev,
16889 struct cfg80211_ibss_params *params
16890 )
16891{
16892 int ret = 0;
16893
16894 vos_ssr_protect(__func__);
16895 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
16896 vos_ssr_unprotect(__func__);
16897
16898 return ret;
16899}
16900
Jeff Johnson295189b2012-06-20 16:38:30 -070016901/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016902 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016903 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070016904 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016905static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016906 struct net_device *dev
16907 )
16908{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016909 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016910 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16911 tCsrRoamProfile *pRoamProfile;
16912 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016913 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053016914 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016915#ifdef WLAN_FEATURE_RMC
16916 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
16917#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016918
16919 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016920
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016921 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16922 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
16923 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016924 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016925 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016926 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016927 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016928 }
16929
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016930 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
16931 hdd_device_modetoString(pAdapter->device_mode),
16932 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016933 if (NULL == pWextState)
16934 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016935 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070016936 __func__);
16937 return -EIO;
16938 }
16939
16940 pRoamProfile = &pWextState->roamProfile;
16941
16942 /* Issue disconnect only if interface type is set to IBSS */
16943 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
16944 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016945 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070016946 __func__);
16947 return -EINVAL;
16948 }
16949
Abhishek Singh7cd040e2016-01-07 10:51:04 +053016950#ifdef WLAN_FEATURE_RMC
16951 /* Clearing add IE of beacon */
16952 if (ccmCfgSetStr(pHddCtx->hHal,
16953 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
16954 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
16955 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16956 {
16957 hddLog (VOS_TRACE_LEVEL_ERROR,
16958 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
16959 return -EINVAL;
16960 }
16961 if (ccmCfgSetInt(pHddCtx->hHal,
16962 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
16963 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
16964 {
16965 hddLog (VOS_TRACE_LEVEL_ERROR,
16966 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
16967 __func__);
16968 return -EINVAL;
16969 }
16970
16971 // Reset WNI_CFG_PROBE_RSP Flags
16972 wlan_hdd_reset_prob_rspies(pAdapter);
16973
16974 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16975 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
16976 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16977 {
16978 hddLog (VOS_TRACE_LEVEL_ERROR,
16979 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
16980 __func__);
16981 return -EINVAL;
16982 }
16983#endif
16984
Jeff Johnson295189b2012-06-20 16:38:30 -070016985 /* Issue Disconnect request */
16986 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053016987 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
16988 pAdapter->sessionId,
16989 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
16990 if (!HAL_STATUS_SUCCESS(hal_status)) {
16991 hddLog(LOGE,
16992 FL("sme_RoamDisconnect failed hal_status(%d)"),
16993 hal_status);
16994 return -EAGAIN;
16995 }
16996 status = wait_for_completion_timeout(
16997 &pAdapter->disconnect_comp_var,
16998 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
16999 if (!status) {
17000 hddLog(LOGE,
17001 FL("wait on disconnect_comp_var failed"));
17002 return -ETIMEDOUT;
17003 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017004
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017005 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017006 return 0;
17007}
17008
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017009static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17010 struct net_device *dev
17011 )
17012{
17013 int ret = 0;
17014
17015 vos_ssr_protect(__func__);
17016 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17017 vos_ssr_unprotect(__func__);
17018
17019 return ret;
17020}
17021
Jeff Johnson295189b2012-06-20 16:38:30 -070017022/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017023 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017024 * This function is used to set the phy parameters
17025 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17026 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017027static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017028 u32 changed)
17029{
17030 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17031 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017032 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017033
17034 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017035
17036 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017037 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17038 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017039
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017040 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017041 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017042 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017043 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017044 }
17045
Jeff Johnson295189b2012-06-20 16:38:30 -070017046 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17047 {
17048 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17049 WNI_CFG_RTS_THRESHOLD_STAMAX :
17050 wiphy->rts_threshold;
17051
17052 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017053 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017054 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017055 hddLog(VOS_TRACE_LEVEL_ERROR,
17056 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017057 __func__, rts_threshold);
17058 return -EINVAL;
17059 }
17060
17061 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17062 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017063 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017064 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017065 hddLog(VOS_TRACE_LEVEL_ERROR,
17066 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017067 __func__, rts_threshold);
17068 return -EIO;
17069 }
17070
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017071 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017072 rts_threshold);
17073 }
17074
17075 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17076 {
17077 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17078 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17079 wiphy->frag_threshold;
17080
17081 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017082 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017083 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017084 hddLog(VOS_TRACE_LEVEL_ERROR,
17085 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017086 frag_threshold);
17087 return -EINVAL;
17088 }
17089
17090 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17091 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017092 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017093 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017094 hddLog(VOS_TRACE_LEVEL_ERROR,
17095 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017096 __func__, frag_threshold);
17097 return -EIO;
17098 }
17099
17100 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17101 frag_threshold);
17102 }
17103
17104 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17105 || (changed & WIPHY_PARAM_RETRY_LONG))
17106 {
17107 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17108 wiphy->retry_short :
17109 wiphy->retry_long;
17110
17111 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17112 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17113 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017114 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017115 __func__, retry_value);
17116 return -EINVAL;
17117 }
17118
17119 if (changed & WIPHY_PARAM_RETRY_SHORT)
17120 {
17121 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17122 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017123 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017124 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017125 hddLog(VOS_TRACE_LEVEL_ERROR,
17126 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017127 __func__, retry_value);
17128 return -EIO;
17129 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017130 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017131 __func__, retry_value);
17132 }
17133 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17134 {
17135 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17136 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017137 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017138 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017139 hddLog(VOS_TRACE_LEVEL_ERROR,
17140 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017141 __func__, retry_value);
17142 return -EIO;
17143 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017144 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017145 __func__, retry_value);
17146 }
17147 }
17148
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017149 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017150 return 0;
17151}
17152
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017153static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17154 u32 changed)
17155{
17156 int ret;
17157
17158 vos_ssr_protect(__func__);
17159 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17160 vos_ssr_unprotect(__func__);
17161
17162 return ret;
17163}
17164
Jeff Johnson295189b2012-06-20 16:38:30 -070017165/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017166 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017167 * This function is used to set the txpower
17168 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017169static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017170#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17171 struct wireless_dev *wdev,
17172#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017173#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017174 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017175#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017176 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017177#endif
17178 int dbm)
17179{
17180 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017181 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017182 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17183 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017184 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017185
17186 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017187
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017188 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17189 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17190 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017191 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017192 if (0 != status)
17193 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017194 return status;
17195 }
17196
17197 hHal = pHddCtx->hHal;
17198
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017199 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17200 dbm, ccmCfgSetCallback,
17201 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017202 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017203 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017204 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17205 return -EIO;
17206 }
17207
17208 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17209 dbm);
17210
17211 switch(type)
17212 {
17213 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17214 /* Fall through */
17215 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17216 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17217 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17219 __func__);
17220 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017221 }
17222 break;
17223 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017224 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017225 __func__);
17226 return -EOPNOTSUPP;
17227 break;
17228 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017229 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17230 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017231 return -EIO;
17232 }
17233
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017234 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017235 return 0;
17236}
17237
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017238static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17239#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17240 struct wireless_dev *wdev,
17241#endif
17242#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17243 enum tx_power_setting type,
17244#else
17245 enum nl80211_tx_power_setting type,
17246#endif
17247 int dbm)
17248{
17249 int ret;
17250 vos_ssr_protect(__func__);
17251 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17252#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17253 wdev,
17254#endif
17255#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17256 type,
17257#else
17258 type,
17259#endif
17260 dbm);
17261 vos_ssr_unprotect(__func__);
17262
17263 return ret;
17264}
17265
Jeff Johnson295189b2012-06-20 16:38:30 -070017266/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017267 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017268 * This function is used to read the txpower
17269 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017270static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017271#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17272 struct wireless_dev *wdev,
17273#endif
17274 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017275{
17276
17277 hdd_adapter_t *pAdapter;
17278 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017279 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017280
Jeff Johnsone7245742012-09-05 17:12:55 -070017281 ENTER();
17282
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017283 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017284 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017285 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017286 *dbm = 0;
17287 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017288 }
17289
Jeff Johnson295189b2012-06-20 16:38:30 -070017290 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17291 if (NULL == pAdapter)
17292 {
17293 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17294 return -ENOENT;
17295 }
17296
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017297 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17298 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17299 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017300 wlan_hdd_get_classAstats(pAdapter);
17301 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17302
Jeff Johnsone7245742012-09-05 17:12:55 -070017303 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017304 return 0;
17305}
17306
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017307static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17308#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17309 struct wireless_dev *wdev,
17310#endif
17311 int *dbm)
17312{
17313 int ret;
17314
17315 vos_ssr_protect(__func__);
17316 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17317#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17318 wdev,
17319#endif
17320 dbm);
17321 vos_ssr_unprotect(__func__);
17322
17323 return ret;
17324}
17325
Dustin Brown8c1d4092017-07-28 18:08:01 +053017326/*
17327 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17328 * @stats: summary stats to use as a source
17329 * @info: kernel station_info struct to use as a destination
17330 *
17331 * Return: None
17332 */
17333static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17334 struct station_info *info)
17335{
17336 int i;
17337
17338 info->rx_packets = stats->rx_frm_cnt;
17339 info->tx_packets = 0;
17340 info->tx_retries = 0;
17341 info->tx_failed = 0;
17342
17343 for (i = 0; i < 4; ++i) {
17344 info->tx_packets += stats->tx_frm_cnt[i];
17345 info->tx_retries += stats->multiple_retry_cnt[i];
17346 info->tx_failed += stats->fail_cnt[i];
17347 }
17348
17349 info->filled |= STATION_INFO_TX_PACKETS |
17350 STATION_INFO_TX_RETRIES |
17351 STATION_INFO_TX_FAILED |
17352 STATION_INFO_RX_PACKETS;
17353}
17354
17355/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017356 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17357 * @adapter: sap adapter pointer
17358 * @staid: station id of the client
17359 * @rssi: rssi value to fill
17360 *
17361 * Return: None
17362 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017363void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017364wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17365{
17366 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17367
17368 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17369}
17370
17371/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017372 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17373 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017374 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017375 * @info: kernel station_info struct to populate
17376 *
17377 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17378 * support "station dump" and "station get" for SAP vdevs, even though they
17379 * aren't technically stations.
17380 *
17381 * Return: errno
17382 */
17383static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017384wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17385#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17386 const u8* mac,
17387#else
17388 u8* mac,
17389#endif
17390 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017391{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017392 v_MACADDR_t *peerMacAddr;
17393 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017394 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017395 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017396
17397 status = wlan_hdd_get_station_stats(adapter);
17398 if (!VOS_IS_STATUS_SUCCESS(status)) {
17399 hddLog(VOS_TRACE_LEVEL_ERROR,
17400 "Failed to get SAP stats; status:%d", status);
17401 return 0;
17402 }
17403
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017404 peerMacAddr = (v_MACADDR_t *)mac;
17405 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17406 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17407 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17408
17409 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17410 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
17411 info->filled |= STATION_INFO_SIGNAL;
17412 }
17413
Dustin Brown8c1d4092017-07-28 18:08:01 +053017414 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17415
17416 return 0;
17417}
17418
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017419static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017420#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17421 const u8* mac,
17422#else
17423 u8* mac,
17424#endif
17425 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017426{
17427 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17428 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17429 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017430 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017431
17432 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17433 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017434
17435 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17436 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17437 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17438 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17439 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17440 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17441 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017442 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017443 tANI_U16 myRate;
17444 tANI_U16 currentRate = 0;
17445 tANI_U8 maxSpeedMCS = 0;
17446 tANI_U8 maxMCSIdx = 0;
17447 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017448 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017449 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017450 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017451
Leo Chang6f8870f2013-03-26 18:11:36 -070017452#ifdef WLAN_FEATURE_11AC
17453 tANI_U32 vht_mcs_map;
17454 eDataRate11ACMaxMcs vhtMaxMcs;
17455#endif /* WLAN_FEATURE_11AC */
17456
Jeff Johnsone7245742012-09-05 17:12:55 -070017457 ENTER();
17458
Dustin Brown8c1d4092017-07-28 18:08:01 +053017459 status = wlan_hdd_validate_context(pHddCtx);
17460 if (0 != status)
17461 {
17462 return status;
17463 }
17464
17465 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017466 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017467
Jeff Johnson295189b2012-06-20 16:38:30 -070017468 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17469 (0 == ssidlen))
17470 {
17471 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17472 " Invalid ssidlen, %d", __func__, ssidlen);
17473 /*To keep GUI happy*/
17474 return 0;
17475 }
17476
Mukul Sharma811205f2014-07-09 21:07:30 +053017477 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17478 {
17479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17480 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017481 /* return a cached value */
17482 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017483 return 0;
17484 }
17485
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017486 wlan_hdd_get_station_stats(pAdapter);
17487 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017488
Kiet Lam3b17fc82013-09-27 05:24:08 +053017489 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017490 wlan_hdd_get_snr(pAdapter, &snr);
17491 pHddStaCtx->conn_info.signal = sinfo->signal;
17492 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Kiet Lam3b17fc82013-09-27 05:24:08 +053017493 sinfo->filled |= STATION_INFO_SIGNAL;
17494
c_hpothu09f19542014-05-30 21:53:31 +053017495 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017496 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17497 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017498 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017499 {
17500 rate_flags = pAdapter->maxRateFlags;
17501 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017502
Jeff Johnson295189b2012-06-20 16:38:30 -070017503 //convert to the UI units of 100kbps
17504 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
17505
17506#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070017507 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 -070017508 sinfo->signal,
17509 pCfg->reportMaxLinkSpeed,
17510 myRate,
17511 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017512 (int) pCfg->linkSpeedRssiMid,
17513 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070017514 (int) rate_flags,
17515 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070017516#endif //LINKSPEED_DEBUG_ENABLED
17517
17518 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
17519 {
17520 // we do not want to necessarily report the current speed
17521 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
17522 {
17523 // report the max possible speed
17524 rssidx = 0;
17525 }
17526 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
17527 {
17528 // report the max possible speed with RSSI scaling
17529 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
17530 {
17531 // report the max possible speed
17532 rssidx = 0;
17533 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017534 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070017535 {
17536 // report middle speed
17537 rssidx = 1;
17538 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017539 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
17540 {
17541 // report middle speed
17542 rssidx = 2;
17543 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017544 else
17545 {
17546 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017547 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070017548 }
17549 }
17550 else
17551 {
17552 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
17553 hddLog(VOS_TRACE_LEVEL_ERROR,
17554 "%s: Invalid value for reportMaxLinkSpeed: %u",
17555 __func__, pCfg->reportMaxLinkSpeed);
17556 rssidx = 0;
17557 }
17558
17559 maxRate = 0;
17560
17561 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017562 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
17563 OperationalRates, &ORLeng))
17564 {
17565 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17566 /*To keep GUI happy*/
17567 return 0;
17568 }
17569
Jeff Johnson295189b2012-06-20 16:38:30 -070017570 for (i = 0; i < ORLeng; i++)
17571 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017572 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017573 {
17574 /* Validate Rate Set */
17575 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
17576 {
17577 currentRate = supported_data_rate[j].supported_rate[rssidx];
17578 break;
17579 }
17580 }
17581 /* Update MAX rate */
17582 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17583 }
17584
17585 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017586 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
17587 ExtendedRates, &ERLeng))
17588 {
17589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17590 /*To keep GUI happy*/
17591 return 0;
17592 }
17593
Jeff Johnson295189b2012-06-20 16:38:30 -070017594 for (i = 0; i < ERLeng; i++)
17595 {
Jeff Johnsone7245742012-09-05 17:12:55 -070017596 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017597 {
17598 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
17599 {
17600 currentRate = supported_data_rate[j].supported_rate[rssidx];
17601 break;
17602 }
17603 }
17604 /* Update MAX rate */
17605 maxRate = (currentRate > maxRate)?currentRate:maxRate;
17606 }
c_hpothu79aab322014-07-14 21:11:01 +053017607
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017608 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053017609 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053017610 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053017611 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070017612 {
c_hpothu79aab322014-07-14 21:11:01 +053017613 if (rate_flags & eHAL_TX_RATE_VHT80)
17614 mode = 2;
17615 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
17616 mode = 1;
17617 else
17618 mode = 0;
17619
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053017620 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
17621 MCSRates, &MCSLeng))
17622 {
17623 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
17624 /*To keep GUI happy*/
17625 return 0;
17626 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017627 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070017628#ifdef WLAN_FEATURE_11AC
17629 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017630 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070017631 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017632 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017633 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070017634 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070017635 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017636 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017637 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017638 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070017639 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017640 maxMCSIdx = 7;
17641 }
17642 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
17643 {
17644 maxMCSIdx = 8;
17645 }
17646 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
17647 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017648 //VHT20 is supporting 0~8
17649 if (rate_flags & eHAL_TX_RATE_VHT20)
17650 maxMCSIdx = 8;
17651 else
17652 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070017653 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017654
c_hpothu79aab322014-07-14 21:11:01 +053017655 if (0 != rssidx)/*check for scaled */
17656 {
17657 //get middle rate MCS index if rssi=1/2
17658 for (i=0; i <= maxMCSIdx; i++)
17659 {
17660 if (sinfo->signal <= rssiMcsTbl[mode][i])
17661 {
17662 maxMCSIdx = i;
17663 break;
17664 }
17665 }
17666 }
17667
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017668 if (rate_flags & eHAL_TX_RATE_VHT80)
17669 {
17670 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
17671 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
17672 }
17673 else if (rate_flags & eHAL_TX_RATE_VHT40)
17674 {
17675 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
17676 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
17677 }
17678 else if (rate_flags & eHAL_TX_RATE_VHT20)
17679 {
17680 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
17681 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
17682 }
17683
Leo Chang6f8870f2013-03-26 18:11:36 -070017684 maxSpeedMCS = 1;
17685 if (currentRate > maxRate)
17686 {
17687 maxRate = currentRate;
17688 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017689
Leo Chang6f8870f2013-03-26 18:11:36 -070017690 }
17691 else
17692#endif /* WLAN_FEATURE_11AC */
17693 {
17694 if (rate_flags & eHAL_TX_RATE_HT40)
17695 {
17696 rateFlag |= 1;
17697 }
17698 if (rate_flags & eHAL_TX_RATE_SGI)
17699 {
17700 rateFlag |= 2;
17701 }
17702
Girish Gowli01abcee2014-07-31 20:18:55 +053017703 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053017704 if (rssidx == 1 || rssidx == 2)
17705 {
17706 //get middle rate MCS index if rssi=1/2
17707 for (i=0; i <= 7; i++)
17708 {
17709 if (sinfo->signal <= rssiMcsTbl[mode][i])
17710 {
17711 temp = i+1;
17712 break;
17713 }
17714 }
17715 }
c_hpothu79aab322014-07-14 21:11:01 +053017716
17717 for (i = 0; i < MCSLeng; i++)
17718 {
Leo Chang6f8870f2013-03-26 18:11:36 -070017719 for (j = 0; j < temp; j++)
17720 {
17721 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
17722 {
17723 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017724 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017725 break;
17726 }
17727 }
17728 if ((j < temp) && (currentRate > maxRate))
17729 {
17730 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070017731 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017732 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053017733 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070017734 }
17735 }
17736
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017737 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
17738 {
17739 maxRate = myRate;
17740 maxSpeedMCS = 1;
17741 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17742 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017743 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053017744 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070017745 {
17746 maxRate = myRate;
17747 if (rate_flags & eHAL_TX_RATE_LEGACY)
17748 {
17749 maxSpeedMCS = 0;
17750 }
17751 else
17752 {
17753 maxSpeedMCS = 1;
17754 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
17755 }
17756 }
17757
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017758 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070017759 {
17760 sinfo->txrate.legacy = maxRate;
17761#ifdef LINKSPEED_DEBUG_ENABLED
17762 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
17763#endif //LINKSPEED_DEBUG_ENABLED
17764 }
17765 else
17766 {
17767 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070017768#ifdef WLAN_FEATURE_11AC
17769 sinfo->txrate.nss = 1;
17770 if (rate_flags & eHAL_TX_RATE_VHT80)
17771 {
17772 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017773 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070017774 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017775 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070017776 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017777 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17778 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17779 }
17780 else if (rate_flags & eHAL_TX_RATE_VHT20)
17781 {
17782 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17783 }
17784#endif /* WLAN_FEATURE_11AC */
17785 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
17786 {
17787 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17788 if (rate_flags & eHAL_TX_RATE_HT40)
17789 {
17790 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17791 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017792 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017793 if (rate_flags & eHAL_TX_RATE_SGI)
17794 {
17795 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17796 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053017797
Jeff Johnson295189b2012-06-20 16:38:30 -070017798#ifdef LINKSPEED_DEBUG_ENABLED
17799 pr_info("Reporting MCS rate %d flags %x\n",
17800 sinfo->txrate.mcs,
17801 sinfo->txrate.flags );
17802#endif //LINKSPEED_DEBUG_ENABLED
17803 }
17804 }
17805 else
17806 {
17807 // report current rate instead of max rate
17808
17809 if (rate_flags & eHAL_TX_RATE_LEGACY)
17810 {
17811 //provide to the UI in units of 100kbps
17812 sinfo->txrate.legacy = myRate;
17813#ifdef LINKSPEED_DEBUG_ENABLED
17814 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
17815#endif //LINKSPEED_DEBUG_ENABLED
17816 }
17817 else
17818 {
17819 //must be MCS
17820 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070017821#ifdef WLAN_FEATURE_11AC
17822 sinfo->txrate.nss = 1;
17823 if (rate_flags & eHAL_TX_RATE_VHT80)
17824 {
17825 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
17826 }
17827 else
17828#endif /* WLAN_FEATURE_11AC */
17829 {
17830 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
17831 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017832 if (rate_flags & eHAL_TX_RATE_SGI)
17833 {
17834 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
17835 }
17836 if (rate_flags & eHAL_TX_RATE_HT40)
17837 {
17838 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
17839 }
Leo Chang6f8870f2013-03-26 18:11:36 -070017840#ifdef WLAN_FEATURE_11AC
17841 else if (rate_flags & eHAL_TX_RATE_VHT80)
17842 {
17843 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
17844 }
17845#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070017846#ifdef LINKSPEED_DEBUG_ENABLED
17847 pr_info("Reporting actual MCS rate %d flags %x\n",
17848 sinfo->txrate.mcs,
17849 sinfo->txrate.flags );
17850#endif //LINKSPEED_DEBUG_ENABLED
17851 }
17852 }
17853 sinfo->filled |= STATION_INFO_TX_BITRATE;
17854
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017855 sinfo->tx_packets =
17856 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
17857 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
17858 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
17859 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
17860
17861 sinfo->tx_retries =
17862 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
17863 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
17864 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
17865 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
17866
17867 sinfo->tx_failed =
17868 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
17869 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
17870 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
17871 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
17872
17873 sinfo->filled |=
17874 STATION_INFO_TX_PACKETS |
17875 STATION_INFO_TX_RETRIES |
17876 STATION_INFO_TX_FAILED;
17877
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017878 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
17879 sinfo->filled |= STATION_INFO_RX_PACKETS;
17880
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017881 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
17882 &sinfo->txrate, sizeof(sinfo->txrate));
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053017883 if (rate_flags & eHAL_TX_RATE_LEGACY)
17884 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
17885 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
17886 sinfo->rx_packets);
17887 else
17888 hddLog(LOG1,
17889 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
17890 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
17891 sinfo->tx_packets, sinfo->rx_packets);
17892
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017893 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17894 TRACE_CODE_HDD_CFG80211_GET_STA,
17895 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070017896 EXIT();
17897 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017898}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17900static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17901 const u8* mac, struct station_info *sinfo)
17902#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017903static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
17904 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017905#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017906{
17907 int ret;
17908
17909 vos_ssr_protect(__func__);
17910 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
17911 vos_ssr_unprotect(__func__);
17912
17913 return ret;
17914}
17915
17916static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070017917 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070017918{
17919 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017920 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017921 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017922 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017923
Jeff Johnsone7245742012-09-05 17:12:55 -070017924 ENTER();
17925
Jeff Johnson295189b2012-06-20 16:38:30 -070017926 if (NULL == pAdapter)
17927 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017929 return -ENODEV;
17930 }
17931
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017932 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17933 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
17934 pAdapter->sessionId, timeout));
17935
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017936 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017937 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017938 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017939 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017940 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017941 }
17942
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017943 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
17944 (TRUE == pHddCtx->hdd_wlan_suspended) &&
17945 (pHddCtx->cfg_ini->fhostArpOffload) &&
17946 (eConnectionState_Associated ==
17947 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
17948 {
Amar Singhald53568e2013-09-26 11:03:45 -070017949
17950 hddLog(VOS_TRACE_LEVEL_INFO,
17951 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053017952 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017953 if (!VOS_IS_STATUS_SUCCESS(vos_status))
17954 {
17955 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017956 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053017957 __func__, vos_status);
17958 }
17959 }
17960
Jeff Johnson295189b2012-06-20 16:38:30 -070017961 /**The get power cmd from the supplicant gets updated by the nl only
17962 *on successful execution of the function call
17963 *we are oppositely mapped w.r.t mode in the driver
17964 **/
17965 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
17966
17967 if (VOS_STATUS_E_FAILURE == vos_status)
17968 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17970 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017971 return -EINVAL;
17972 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017973 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017974 return 0;
17975}
17976
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017977static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
17978 struct net_device *dev, bool mode, int timeout)
17979{
17980 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070017981
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017982 vos_ssr_protect(__func__);
17983 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
17984 vos_ssr_unprotect(__func__);
17985
17986 return ret;
17987}
Sushant Kaushik084f6592015-09-10 13:11:56 +053017988
Jeff Johnson295189b2012-06-20 16:38:30 -070017989#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017990static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
17991 struct net_device *netdev,
17992 u8 key_index)
17993{
17994 ENTER();
17995 return 0;
17996}
17997
Jeff Johnson295189b2012-06-20 16:38:30 -070017998static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017999 struct net_device *netdev,
18000 u8 key_index)
18001{
18002 int ret;
18003 vos_ssr_protect(__func__);
18004 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18005 vos_ssr_unprotect(__func__);
18006 return ret;
18007}
18008#endif //LINUX_VERSION_CODE
18009
18010#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18011static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18012 struct net_device *dev,
18013 struct ieee80211_txq_params *params)
18014{
18015 ENTER();
18016 return 0;
18017}
18018#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18019static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18020 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018021{
Jeff Johnsone7245742012-09-05 17:12:55 -070018022 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018023 return 0;
18024}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018025#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018026
18027#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18028static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018029 struct net_device *dev,
18030 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018031{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018032 int ret;
18033
18034 vos_ssr_protect(__func__);
18035 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18036 vos_ssr_unprotect(__func__);
18037 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018038}
18039#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18040static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18041 struct ieee80211_txq_params *params)
18042{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018043 int ret;
18044
18045 vos_ssr_protect(__func__);
18046 ret = __wlan_hdd_set_txq_params(wiphy, params);
18047 vos_ssr_unprotect(__func__);
18048 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018049}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018050#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018051
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018052static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018053 struct net_device *dev,
18054 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018055{
18056 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018057 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018058 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018059 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018060 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018061 v_CONTEXT_t pVosContext = NULL;
18062 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018063
Jeff Johnsone7245742012-09-05 17:12:55 -070018064 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018065
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018066 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018067 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018068 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018069 return -EINVAL;
18070 }
18071
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018072 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18073 TRACE_CODE_HDD_CFG80211_DEL_STA,
18074 pAdapter->sessionId, pAdapter->device_mode));
18075
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018076 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18077 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018078 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018079 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018080 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018081 }
18082
Jeff Johnson295189b2012-06-20 16:38:30 -070018083 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018084 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018085 )
18086 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018087 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18088 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18089 if(pSapCtx == NULL){
18090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18091 FL("psapCtx is NULL"));
18092 return -ENOENT;
18093 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018094 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18095 {
18096 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18097 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18098 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18099 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018100 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018101 {
18102 v_U16_t i;
18103 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18104 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018105 if ((pSapCtx->aStaInfo[i].isUsed) &&
18106 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018107 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018108 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018109 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018110 ETHER_ADDR_LEN);
18111
Jeff Johnson295189b2012-06-20 16:38:30 -070018112 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018113 "%s: Delete STA with MAC::"
18114 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018115 __func__,
18116 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18117 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018118 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018119 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018120 }
18121 }
18122 }
18123 else
18124 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018125
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018126 vos_status = hdd_softap_GetStaId(pAdapter,
18127 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018128 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18129 {
18130 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018131 "%s: Skip this DEL STA as this is not used::"
18132 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018133 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018134 return -ENOENT;
18135 }
18136
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018137 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018138 {
18139 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018140 "%s: Skip this DEL STA as deauth is in progress::"
18141 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018142 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018143 return -ENOENT;
18144 }
18145
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018146 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018147
Jeff Johnson295189b2012-06-20 16:38:30 -070018148 hddLog(VOS_TRACE_LEVEL_INFO,
18149 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018150 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018151 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018152 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018153
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018154 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018155 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18156 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018157 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018158 hddLog(VOS_TRACE_LEVEL_INFO,
18159 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018160 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018161 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018162 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018163 return -ENOENT;
18164 }
18165
Jeff Johnson295189b2012-06-20 16:38:30 -070018166 }
18167 }
18168
18169 EXIT();
18170
18171 return 0;
18172}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018173
18174#ifdef CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018175int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018176 struct net_device *dev,
18177 struct station_del_parameters *param)
18178#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018179#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018180int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018181 struct net_device *dev, const u8 *mac)
18182#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018183int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018184 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018185#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018186#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018187{
18188 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018189 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018190
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018191 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018192
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018193#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018194 if (NULL == param) {
18195 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018196 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018197 return -EINVAL;
18198 }
18199
18200 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18201 param->subtype, &delStaParams);
18202
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018203#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018204 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018205 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018206#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018207 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18208
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018209 vos_ssr_unprotect(__func__);
18210
18211 return ret;
18212}
18213
18214static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018215 struct net_device *dev,
18216#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18217 const u8 *mac,
18218#else
18219 u8 *mac,
18220#endif
18221 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018222{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018223 hdd_adapter_t *pAdapter;
18224 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018225 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018226#ifdef FEATURE_WLAN_TDLS
18227 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018228
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018229 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018230
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018231 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18232 if (NULL == pAdapter)
18233 {
18234 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18235 "%s: Adapter is NULL",__func__);
18236 return -EINVAL;
18237 }
18238 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18239 status = wlan_hdd_validate_context(pHddCtx);
18240 if (0 != status)
18241 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018242 return status;
18243 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018244
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018245 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18246 TRACE_CODE_HDD_CFG80211_ADD_STA,
18247 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018248 mask = params->sta_flags_mask;
18249
18250 set = params->sta_flags_set;
18251
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018253 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18254 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018255
18256 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18257 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018258 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018259 }
18260 }
18261#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018262 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018263 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018264}
18265
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018266#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18267static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18268 struct net_device *dev, const u8 *mac,
18269 struct station_parameters *params)
18270#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018271static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18272 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018273#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018274{
18275 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018276
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018277 vos_ssr_protect(__func__);
18278 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18279 vos_ssr_unprotect(__func__);
18280
18281 return ret;
18282}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018283#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018284
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018285static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018286 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018287{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018288 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18289 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018290 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018291 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018292 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018293 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018294
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018295 ENTER();
18296
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018297 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018298 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018299 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018300 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018301 return -EINVAL;
18302 }
18303
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018304 if (!pmksa) {
18305 hddLog(LOGE, FL("pmksa is NULL"));
18306 return -EINVAL;
18307 }
18308
18309 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018310 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018311 pmksa->bssid, pmksa->pmkid);
18312 return -EINVAL;
18313 }
18314
18315 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18316 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18317
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018318 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18319 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018320 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018321 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018322 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018323 }
18324
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018325 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018326 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18327
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018328 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18329 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018330
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018331 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018332 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018333 &pmk_id, 1, FALSE);
18334
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018335 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18336 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18337 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018338
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018339 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018340 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018341}
18342
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018343static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18344 struct cfg80211_pmksa *pmksa)
18345{
18346 int ret;
18347
18348 vos_ssr_protect(__func__);
18349 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18350 vos_ssr_unprotect(__func__);
18351
18352 return ret;
18353}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018354
Wilson Yang6507c4e2013-10-01 20:11:19 -070018355
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018356static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018357 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018358{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018359 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18360 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018361 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018362 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018363
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018364 ENTER();
18365
Wilson Yang6507c4e2013-10-01 20:11:19 -070018366 /* Validate pAdapter */
18367 if (NULL == pAdapter)
18368 {
18369 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18370 return -EINVAL;
18371 }
18372
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018373 if (!pmksa) {
18374 hddLog(LOGE, FL("pmksa is NULL"));
18375 return -EINVAL;
18376 }
18377
18378 if (!pmksa->bssid) {
18379 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18380 return -EINVAL;
18381 }
18382
Kiet Lam98c46a12014-10-31 15:34:57 -070018383 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18384 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18385
Wilson Yang6507c4e2013-10-01 20:11:19 -070018386 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18387 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018388 if (0 != status)
18389 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018390 return status;
18391 }
18392
18393 /*Retrieve halHandle*/
18394 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18395
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018396 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18397 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18398 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018399 /* Delete the PMKID CSR cache */
18400 if (eHAL_STATUS_SUCCESS !=
18401 sme_RoamDelPMKIDfromCache(halHandle,
18402 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18403 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18404 MAC_ADDR_ARRAY(pmksa->bssid));
18405 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018406 }
18407
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018408 EXIT();
18409 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018410}
18411
Wilson Yang6507c4e2013-10-01 20:11:19 -070018412
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018413static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18414 struct cfg80211_pmksa *pmksa)
18415{
18416 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018417
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018418 vos_ssr_protect(__func__);
18419 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18420 vos_ssr_unprotect(__func__);
18421
18422 return ret;
18423
18424}
18425
18426static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018427{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018428 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18429 tHalHandle halHandle;
18430 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018431 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018432
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018433 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018434
18435 /* Validate pAdapter */
18436 if (NULL == pAdapter)
18437 {
18438 hddLog(VOS_TRACE_LEVEL_ERROR,
18439 "%s: Invalid Adapter" ,__func__);
18440 return -EINVAL;
18441 }
18442
18443 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18444 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018445 if (0 != status)
18446 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018447 return status;
18448 }
18449
18450 /*Retrieve halHandle*/
18451 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18452
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018453 /* Flush the PMKID cache in CSR */
18454 if (eHAL_STATUS_SUCCESS !=
18455 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18457 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018458 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018459 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018460 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018461}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018462
18463static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
18464{
18465 int ret;
18466
18467 vos_ssr_protect(__func__);
18468 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
18469 vos_ssr_unprotect(__func__);
18470
18471 return ret;
18472}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018473#endif
18474
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018475#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018476static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18477 struct net_device *dev,
18478 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018479{
18480 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18481 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018482 hdd_context_t *pHddCtx;
18483 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018485 ENTER();
18486
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018487 if (NULL == pAdapter)
18488 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018489 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018490 return -ENODEV;
18491 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018492 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18493 ret = wlan_hdd_validate_context(pHddCtx);
18494 if (0 != ret)
18495 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018496 return ret;
18497 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018498 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018499 if (NULL == pHddStaCtx)
18500 {
18501 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
18502 return -EINVAL;
18503 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018504
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018505 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18506 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
18507 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018508 // Added for debug on reception of Re-assoc Req.
18509 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
18510 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018511 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018512 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080018513 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018514 }
18515
18516#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080018517 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018518 ftie->ie_len);
18519#endif
18520
18521 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053018522 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
18523 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018524 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018525
18526 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018527 return 0;
18528}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018529
18530static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
18531 struct net_device *dev,
18532 struct cfg80211_update_ft_ies_params *ftie)
18533{
18534 int ret;
18535
18536 vos_ssr_protect(__func__);
18537 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
18538 vos_ssr_unprotect(__func__);
18539
18540 return ret;
18541}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018542#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018543
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018544#ifdef FEATURE_WLAN_SCAN_PNO
18545
18546void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
18547 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
18548{
18549 int ret;
18550 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
18551 hdd_context_t *pHddCtx;
18552
Nirav Shah80830bf2013-12-31 16:35:12 +053018553 ENTER();
18554
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018555 if (NULL == pAdapter)
18556 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018558 "%s: HDD adapter is Null", __func__);
18559 return ;
18560 }
18561
18562 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18563 if (NULL == pHddCtx)
18564 {
18565 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18566 "%s: HDD context is Null!!!", __func__);
18567 return ;
18568 }
18569
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018570 spin_lock(&pHddCtx->schedScan_lock);
18571 if (TRUE == pHddCtx->isWiphySuspended)
18572 {
18573 pHddCtx->isSchedScanUpdatePending = TRUE;
18574 spin_unlock(&pHddCtx->schedScan_lock);
18575 hddLog(VOS_TRACE_LEVEL_INFO,
18576 "%s: Update cfg80211 scan database after it resume", __func__);
18577 return ;
18578 }
18579 spin_unlock(&pHddCtx->schedScan_lock);
18580
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018581 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
18582
18583 if (0 > ret)
18584 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053018585 else
18586 {
18587 /* Acquire wakelock to handle the case where APP's tries to suspend
18588 * immediatly after the driver gets connect request(i.e after pno)
18589 * from supplicant, this result in app's is suspending and not able
18590 * to process the connect request to AP */
18591 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
18592 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018593 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18595 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018596}
18597
18598/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018599 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018600 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018601 */
18602static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
18603{
18604 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
18605 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018606 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018607 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18608 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053018609
18610 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
18611 {
18612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18613 "%s: PNO is allowed only in STA interface", __func__);
18614 return eHAL_STATUS_FAILURE;
18615 }
18616
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018617 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
18618
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018619 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053018620 * active sessions. PNO is allowed only in case when sap session
18621 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018622 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018623 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
18624 {
18625 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018626 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018627
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018628 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
18629 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
18630 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
18631 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053018632 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
18633 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053018634 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018635 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018636 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018637 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018638 }
18639 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18640 pAdapterNode = pNext;
18641 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018642 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018643}
18644
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018645void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
18646{
18647 hdd_adapter_t *pAdapter = callbackContext;
18648 hdd_context_t *pHddCtx;
18649
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018650 ENTER();
18651
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018652 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
18653 {
18654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18655 FL("Invalid adapter or adapter has invalid magic"));
18656 return;
18657 }
18658
18659 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18660 if (0 != wlan_hdd_validate_context(pHddCtx))
18661 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018662 return;
18663 }
18664
c_hpothub53c45d2014-08-18 16:53:14 +053018665 if (VOS_STATUS_SUCCESS != status)
18666 {
18667 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018668 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053018669 pHddCtx->isPnoEnable = FALSE;
18670 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018671
18672 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
18673 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018674 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018675}
18676
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018677#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
18678 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
18679/**
18680 * hdd_config_sched_scan_plan() - configures the sched scan plans
18681 * from the framework.
18682 * @pno_req: pointer to PNO scan request
18683 * @request: pointer to scan request from framework
18684 *
18685 * Return: None
18686 */
18687static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
18688 struct cfg80211_sched_scan_request *request,
18689 hdd_context_t *hdd_ctx)
18690{
18691 v_U32_t i = 0;
18692
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018693 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018694 for (i = 0; i < request->n_scan_plans; i++)
18695 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018696 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
18697 request->scan_plans[i].iterations;
18698 pno_req->scanTimers.aTimerValues[i].uTimerValue =
18699 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018700 }
18701}
18702#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018703static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018704 struct cfg80211_sched_scan_request *request,
18705 hdd_context_t *hdd_ctx)
18706{
18707 v_U32_t i, temp_int;
18708 /* Driver gets only one time interval which is hardcoded in
18709 * supplicant for 10000ms. Taking power consumption into account 6
18710 * timers will be used, Timervalue is increased exponentially
18711 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
18712 * timer is configurable through INI param gPNOScanTimerRepeatValue.
18713 * If it is set to 0 only one timer will be used and PNO scan cycle
18714 * will be repeated after each interval specified by supplicant
18715 * till PNO is disabled.
18716 */
18717 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018718 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018719 HDD_PNO_SCAN_TIMERS_SET_ONE;
18720 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018721 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018722 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
18723
18724 temp_int = (request->interval)/1000;
18725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18726 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
18727 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018728 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018729 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018730 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018731 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018732 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018733 temp_int *= 2;
18734 }
18735 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018736 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018737}
18738#endif
18739
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018740/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018741 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
18742 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018743 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053018744static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018745 struct net_device *dev, struct cfg80211_sched_scan_request *request)
18746{
18747 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018748 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018749 hdd_context_t *pHddCtx;
18750 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053018751 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053018752 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
18753 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018754 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
18755 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018756 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018757 hdd_config_t *pConfig = NULL;
18758 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018759
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018760 ENTER();
18761
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018762 if (NULL == pAdapter)
18763 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018765 "%s: HDD adapter is Null", __func__);
18766 return -ENODEV;
18767 }
18768
18769 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018770 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018771
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018772 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018773 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018774 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018775 }
18776
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018777 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018778 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18779 if (NULL == hHal)
18780 {
18781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18782 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018783 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018784 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018785 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18786 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
18787 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018788 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053018789 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053018790 {
18791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18792 "%s: aborting the existing scan is unsuccessfull", __func__);
18793 return -EBUSY;
18794 }
18795
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018796 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018797 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053018798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053018799 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053018800 return -EBUSY;
18801 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018802
c_hpothu37f21312014-04-09 21:49:54 +053018803 if (TRUE == pHddCtx->isPnoEnable)
18804 {
18805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18806 FL("already PNO is enabled"));
18807 return -EBUSY;
18808 }
c_hpothu225aa7c2014-10-22 17:45:13 +053018809
18810 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
18811 {
18812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18813 "%s: abort ROC failed ", __func__);
18814 return -EBUSY;
18815 }
18816
c_hpothu37f21312014-04-09 21:49:54 +053018817 pHddCtx->isPnoEnable = TRUE;
18818
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018819 pnoRequest.enable = 1; /*Enable PNO */
18820 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018821
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018822 if (( !pnoRequest.ucNetworksCount ) ||
18823 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018824 {
18825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018826 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018827 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018828 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018829 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018830 goto error;
18831 }
18832
18833 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
18834 {
18835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018836 "%s: Incorrect number of channels %d",
18837 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018838 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018839 goto error;
18840 }
18841
18842 /* Framework provides one set of channels(all)
18843 * common for all saved profile */
18844 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
18845 channels_allowed, &num_channels_allowed))
18846 {
18847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18848 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018849 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018850 goto error;
18851 }
18852 /* Checking each channel against allowed channel list */
18853 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053018854 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018855 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018856 char chList [(request->n_channels*5)+1];
18857 int len;
18858 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018859 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018860 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018861 {
Nirav Shah80830bf2013-12-31 16:35:12 +053018862 if (request->channels[i]->hw_value == channels_allowed[indx])
18863 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018864 if ((!pConfig->enableDFSPnoChnlScan) &&
18865 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
18866 {
18867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18868 "%s : Dropping DFS channel : %d",
18869 __func__,channels_allowed[indx]);
18870 num_ignore_dfs_ch++;
18871 break;
18872 }
18873
Nirav Shah80830bf2013-12-31 16:35:12 +053018874 valid_ch[num_ch++] = request->channels[i]->hw_value;
18875 len += snprintf(chList+len, 5, "%d ",
18876 request->channels[i]->hw_value);
18877 break ;
18878 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018879 }
18880 }
Nirav Shah80830bf2013-12-31 16:35:12 +053018881 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018882
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053018883 /*If all channels are DFS and dropped, then ignore the PNO request*/
18884 if (num_ignore_dfs_ch == request->n_channels)
18885 {
18886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18887 "%s : All requested channels are DFS channels", __func__);
18888 ret = -EINVAL;
18889 goto error;
18890 }
18891 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018892
18893 pnoRequest.aNetworks =
18894 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18895 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018896 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018897 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18898 FL("failed to allocate memory aNetworks %u"),
18899 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18900 goto error;
18901 }
18902 vos_mem_zero(pnoRequest.aNetworks,
18903 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
18904
18905 /* Filling per profile params */
18906 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
18907 {
18908 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018909 request->match_sets[i].ssid.ssid_len;
18910
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018911 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
18912 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018913 {
18914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053018915 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018916 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053018917 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018918 goto error;
18919 }
18920
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018921 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018922 request->match_sets[i].ssid.ssid,
18923 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053018924 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18925 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018926 i, pnoRequest.aNetworks[i].ssId.ssId);
18927 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
18928 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
18929 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018930
18931 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018932 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
18933 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018934
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018935 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018936 }
18937
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018938 for (i = 0; i < request->n_ssids; i++)
18939 {
18940 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018941 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018942 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018943 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018944 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018945 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018946 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018947 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018948 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018949 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053018950 break;
18951 }
18952 j++;
18953 }
18954 }
18955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18956 "Number of hidden networks being Configured = %d",
18957 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080018959 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018960
18961 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18962 if (pnoRequest.p24GProbeTemplate == NULL)
18963 {
18964 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18965 FL("failed to allocate memory p24GProbeTemplate %u"),
18966 SIR_PNO_MAX_PB_REQ_SIZE);
18967 goto error;
18968 }
18969
18970 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
18971 if (pnoRequest.p5GProbeTemplate == NULL)
18972 {
18973 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
18974 FL("failed to allocate memory p5GProbeTemplate %u"),
18975 SIR_PNO_MAX_PB_REQ_SIZE);
18976 goto error;
18977 }
18978
18979 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18980 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
18981
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053018982 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
18983 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018984 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018985 pnoRequest.us24GProbeTemplateLen = request->ie_len;
18986 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
18987 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018988
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018989 pnoRequest.us5GProbeTemplateLen = request->ie_len;
18990 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
18991 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053018992 }
18993
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053018994 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053018995
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018996 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018997
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053018998 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053018999 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19000 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019001 pAdapter->pno_req_status = 0;
19002
Nirav Shah80830bf2013-12-31 16:35:12 +053019003 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19004 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019005 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19006 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019007
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019008 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019009 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019010 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19011 if (eHAL_STATUS_SUCCESS != status)
19012 {
19013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019014 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019015 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019016 goto error;
19017 }
19018
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019019 ret = wait_for_completion_timeout(
19020 &pAdapter->pno_comp_var,
19021 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19022 if (0 >= ret)
19023 {
19024 // Did not receive the response for PNO enable in time.
19025 // Assuming the PNO enable was success.
19026 // Returning error from here, because we timeout, results
19027 // in side effect of Wifi (Wifi Setting) not to work.
19028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19029 FL("Timed out waiting for PNO to be Enabled"));
19030 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019031 }
19032
19033 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019034 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019035
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019036error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19038 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019039 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019040 if (pnoRequest.aNetworks)
19041 vos_mem_free(pnoRequest.aNetworks);
19042 if (pnoRequest.p24GProbeTemplate)
19043 vos_mem_free(pnoRequest.p24GProbeTemplate);
19044 if (pnoRequest.p5GProbeTemplate)
19045 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019046
19047 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019048 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019049}
19050
19051/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019052 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19053 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019054 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019055static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19056 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19057{
19058 int ret;
19059
19060 vos_ssr_protect(__func__);
19061 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19062 vos_ssr_unprotect(__func__);
19063
19064 return ret;
19065}
19066
19067/*
19068 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19069 * Function to disable PNO
19070 */
19071static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019072 struct net_device *dev)
19073{
19074 eHalStatus status = eHAL_STATUS_FAILURE;
19075 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19076 hdd_context_t *pHddCtx;
19077 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019078 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019079 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019080
19081 ENTER();
19082
19083 if (NULL == pAdapter)
19084 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019086 "%s: HDD adapter is Null", __func__);
19087 return -ENODEV;
19088 }
19089
19090 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019091
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019092 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019093 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019095 "%s: HDD context is Null", __func__);
19096 return -ENODEV;
19097 }
19098
19099 /* The return 0 is intentional when isLogpInProgress and
19100 * isLoadUnloadInProgress. We did observe a crash due to a return of
19101 * failure in sched_scan_stop , especially for a case where the unload
19102 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19103 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19104 * success. If it returns a failure , then its next invocation due to the
19105 * clean up of the second interface will have the dev pointer corresponding
19106 * to the first one leading to a crash.
19107 */
19108 if (pHddCtx->isLogpInProgress)
19109 {
19110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19111 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019112 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019113 return ret;
19114 }
19115
Mihir Shete18156292014-03-11 15:38:30 +053019116 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019117 {
19118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19119 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19120 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019121 }
19122
19123 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19124 if (NULL == hHal)
19125 {
19126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19127 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019128 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019129 }
19130
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019131 pnoRequest.enable = 0; /* Disable PNO */
19132 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019133
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019134 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19135 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19136 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019137
19138 INIT_COMPLETION(pAdapter->pno_comp_var);
19139 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19140 pnoRequest.callbackContext = pAdapter;
19141 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019142 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019143 pAdapter->sessionId,
19144 NULL, pAdapter);
19145 if (eHAL_STATUS_SUCCESS != status)
19146 {
19147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19148 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019149 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019150 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019151 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019152 ret = wait_for_completion_timeout(
19153 &pAdapter->pno_comp_var,
19154 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19155 if (0 >= ret)
19156 {
19157 // Did not receive the response for PNO disable in time.
19158 // Assuming the PNO disable was success.
19159 // Returning error from here, because we timeout, results
19160 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019162 FL("Timed out waiting for PNO to be disabled"));
19163 ret = 0;
19164 }
19165
19166 ret = pAdapter->pno_req_status;
19167 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019168
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019169error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019171 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019172
19173 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019174 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019175}
19176
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019177/*
19178 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19179 * NL interface to disable PNO
19180 */
19181static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19182 struct net_device *dev)
19183{
19184 int ret;
19185
19186 vos_ssr_protect(__func__);
19187 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19188 vos_ssr_unprotect(__func__);
19189
19190 return ret;
19191}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019192#endif /*FEATURE_WLAN_SCAN_PNO*/
19193
19194
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019195#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019196#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019197static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19198 struct net_device *dev,
19199 u8 *peer, u8 action_code,
19200 u8 dialog_token,
19201 u16 status_code, u32 peer_capability,
19202 const u8 *buf, size_t len)
19203#else /* TDLS_MGMT_VERSION2 */
19204#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19205static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19206 struct net_device *dev,
19207 const u8 *peer, u8 action_code,
19208 u8 dialog_token, u16 status_code,
19209 u32 peer_capability, bool initiator,
19210 const u8 *buf, size_t len)
19211#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19212static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19213 struct net_device *dev,
19214 const u8 *peer, u8 action_code,
19215 u8 dialog_token, u16 status_code,
19216 u32 peer_capability, const u8 *buf,
19217 size_t len)
19218#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19219static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19220 struct net_device *dev,
19221 u8 *peer, u8 action_code,
19222 u8 dialog_token,
19223 u16 status_code, u32 peer_capability,
19224 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019225#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019226static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19227 struct net_device *dev,
19228 u8 *peer, u8 action_code,
19229 u8 dialog_token,
19230 u16 status_code, const u8 *buf,
19231 size_t len)
19232#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019233#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019234{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019235 hdd_adapter_t *pAdapter;
19236 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019237 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019238 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019239 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019240 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019241 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019242 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019243#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019244 u32 peer_capability = 0;
19245#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019246 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019247 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019248 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019249
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019250 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19251 if (NULL == pAdapter)
19252 {
19253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19254 "%s: Adapter is NULL",__func__);
19255 return -EINVAL;
19256 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019257 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19258 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19259 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019260
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019261 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019262 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019263 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019265 "Invalid arguments");
19266 return -EINVAL;
19267 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019268
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019269 if (pHddCtx->isLogpInProgress)
19270 {
19271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19272 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019273 wlan_hdd_tdls_set_link_status(pAdapter,
19274 peer,
19275 eTDLS_LINK_IDLE,
19276 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019277 return -EBUSY;
19278 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019279
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019280 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19281 {
19282 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19283 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19284 return -EAGAIN;
19285 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019286
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019287 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19288 if (!pHddTdlsCtx) {
19289 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19290 "%s: pHddTdlsCtx not valid.", __func__);
19291 }
19292
Hoonki Lee27511902013-03-14 18:19:06 -070019293 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019294 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019295 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019296 "%s: TDLS mode is disabled OR not enabled in FW."
19297 MAC_ADDRESS_STR " action %d declined.",
19298 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019299 return -ENOTSUPP;
19300 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019301
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019302 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19303
19304 if( NULL == pHddStaCtx )
19305 {
19306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19307 "%s: HDD station context NULL ",__func__);
19308 return -EINVAL;
19309 }
19310
19311 /* STA should be connected and authenticated
19312 * before sending any TDLS frames
19313 */
19314 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19315 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19316 {
19317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19318 "STA is not connected or unauthenticated. "
19319 "connState %u, uIsAuthenticated %u",
19320 pHddStaCtx->conn_info.connState,
19321 pHddStaCtx->conn_info.uIsAuthenticated);
19322 return -EAGAIN;
19323 }
19324
Hoonki Lee27511902013-03-14 18:19:06 -070019325 /* other than teardown frame, other mgmt frames are not sent if disabled */
19326 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19327 {
19328 /* if tdls_mode is disabled to respond to peer's request */
19329 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19330 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019331 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019332 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019333 " TDLS mode is disabled. action %d declined.",
19334 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019335
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019336 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019337 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019338
19339 if (vos_max_concurrent_connections_reached())
19340 {
19341 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19342 return -EINVAL;
19343 }
Hoonki Lee27511902013-03-14 18:19:06 -070019344 }
19345
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019346 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19347 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019348 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019349 {
19350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019351 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019352 " TDLS setup is ongoing. action %d declined.",
19353 __func__, MAC_ADDR_ARRAY(peer), action_code);
19354 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019355 }
19356 }
19357
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019358 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19359 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019360 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019361 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19362 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019363 {
19364 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19365 we return error code at 'add_station()'. Hence we have this
19366 check again in addtion to add_station().
19367 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019368 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019369 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019370 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19371 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019372 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19373 __func__, MAC_ADDR_ARRAY(peer), action_code,
19374 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019375 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019376 }
19377 else
19378 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019379 /* maximum reached. tweak to send error code to peer and return
19380 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019381 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19383 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019384 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19385 __func__, MAC_ADDR_ARRAY(peer), status_code,
19386 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019387 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019388 /* fall through to send setup resp with failure status
19389 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019390 }
19391 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019392 else
19393 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019394 mutex_lock(&pHddCtx->tdls_lock);
19395 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019396 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019397 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019398 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019400 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19401 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019402 return -EPERM;
19403 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019404 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019405 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019406 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019407
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019408 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019409 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019410 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19411 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019412
Hoonki Leea34dd892013-02-05 22:56:02 -080019413 /*Except teardown responder will not be used so just make 0*/
19414 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019415 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019416 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019417
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019418 mutex_lock(&pHddCtx->tdls_lock);
19419 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019420
19421 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19422 responder = pTdlsPeer->is_responder;
19423 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019424 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019426 "%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 -070019427 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19428 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019429 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019430 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019431 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019432 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019433 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019434
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019435 /* Discard TDLS setup if peer is removed by user app */
19436 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19437 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19438 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19439 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19440
19441 mutex_lock(&pHddCtx->tdls_lock);
19442 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19443 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19444 mutex_unlock(&pHddCtx->tdls_lock);
19445 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19446 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19447 MAC_ADDR_ARRAY(peer), action_code);
19448 return -EINVAL;
19449 }
19450 mutex_unlock(&pHddCtx->tdls_lock);
19451 }
19452
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019453 /* For explicit trigger of DIS_REQ come out of BMPS for
19454 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019455 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019456 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019457 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19458 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019459 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019460 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019461 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019462 "%s: Sending frame action_code %u.Disable BMPS", __func__,
19463 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019464 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
19465 if (status != VOS_STATUS_SUCCESS) {
19466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019467 } else {
19468 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019469 }
Hoonki Lee14621352013-04-16 17:51:19 -070019470 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019471 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019472 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019473 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
19474 }
19475 }
Hoonki Lee14621352013-04-16 17:51:19 -070019476 }
19477
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019478 /* make sure doesn't call send_mgmt() while it is pending */
19479 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
19480 {
19481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080019482 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019483 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019484 ret = -EBUSY;
19485 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019486 }
19487
19488 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019489 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
19490
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019491 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
19492 pAdapter->sessionId, peer, action_code, dialog_token,
19493 status_code, peer_capability, (tANI_U8 *)buf, len,
19494 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019495
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019496 if (VOS_STATUS_SUCCESS != status)
19497 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019498 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19499 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019500 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019501 ret = -EINVAL;
19502 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019503 }
19504
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19506 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
19507 WAIT_TIME_TDLS_MGMT);
19508
Hoonki Leed37cbb32013-04-20 00:31:14 -070019509 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
19510 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
19511
19512 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019513 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070019514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070019515 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070019516 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019517 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080019518
19519 if (pHddCtx->isLogpInProgress)
19520 {
19521 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19522 "%s: LOGP in Progress. Ignore!!!", __func__);
19523 return -EAGAIN;
19524 }
Abhishek Singh837adf22015-10-01 17:37:37 +053019525 if (rc <= 0)
19526 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
19527 WLAN_LOG_INDICATOR_HOST_DRIVER,
19528 WLAN_LOG_REASON_HDD_TIME_OUT,
19529 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080019530
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019531 ret = -EINVAL;
19532 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019533 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019534 else
19535 {
19536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19537 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
19538 __func__, rc, pAdapter->mgmtTxCompletionStatus);
19539 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019540
Gopichand Nakkala05922802013-03-14 12:23:19 -070019541 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070019542 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019543 ret = max_sta_failed;
19544 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070019545 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019546
Hoonki Leea34dd892013-02-05 22:56:02 -080019547 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
19548 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019549 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19551 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019552 }
19553 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
19554 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019555 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
19557 }
Hoonki Leea34dd892013-02-05 22:56:02 -080019558 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019559
19560 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019561
19562tx_failed:
19563 /* add_station will be called before sending TDLS_SETUP_REQ and
19564 * TDLS_SETUP_RSP and as part of add_station driver will enable
19565 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
19566 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
19567 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
19568 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
19569 */
19570
19571 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19572 (SIR_MAC_TDLS_SETUP_RSP == action_code))
19573 wlan_hdd_tdls_check_bmps(pAdapter);
19574 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019575}
19576
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019577#if TDLS_MGMT_VERSION2
19578static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19579 u8 *peer, u8 action_code, u8 dialog_token,
19580 u16 status_code, u32 peer_capability,
19581 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019582#else /* TDLS_MGMT_VERSION2 */
19583#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
19584static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19585 struct net_device *dev,
19586 const u8 *peer, u8 action_code,
19587 u8 dialog_token, u16 status_code,
19588 u32 peer_capability, bool initiator,
19589 const u8 *buf, size_t len)
19590#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19591static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19592 struct net_device *dev,
19593 const u8 *peer, u8 action_code,
19594 u8 dialog_token, u16 status_code,
19595 u32 peer_capability, const u8 *buf,
19596 size_t len)
19597#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
19598static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19599 struct net_device *dev,
19600 u8 *peer, u8 action_code,
19601 u8 dialog_token,
19602 u16 status_code, u32 peer_capability,
19603 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019604#else
19605static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
19606 u8 *peer, u8 action_code, u8 dialog_token,
19607 u16 status_code, const u8 *buf, size_t len)
19608#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019609#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019610{
19611 int ret;
19612
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019613 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019614#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019615 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19616 dialog_token, status_code,
19617 peer_capability, buf, len);
19618#else /* TDLS_MGMT_VERSION2 */
19619#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
19620 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19621 dialog_token, status_code,
19622 peer_capability, initiator,
19623 buf, len);
19624#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19625 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19626 dialog_token, status_code,
19627 peer_capability, buf, len);
19628#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19629 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19630 dialog_token, status_code,
19631 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019632#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019633 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
19634 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019635#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019636#endif
19637 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019638
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019639 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019640}
Atul Mittal115287b2014-07-08 13:26:33 +053019641
19642int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019643#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19644 const u8 *peer,
19645#else
Atul Mittal115287b2014-07-08 13:26:33 +053019646 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019647#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019648 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053019649 cfg80211_exttdls_callback callback)
19650{
19651
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019652 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053019653 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019654 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053019655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19656 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
19657 __func__, MAC_ADDR_ARRAY(peer));
19658
19659 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19660 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19661
19662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019663 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19664 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19665 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019666 return -ENOTSUPP;
19667 }
19668
19669 /* To cater the requirement of establishing the TDLS link
19670 * irrespective of the data traffic , get an entry of TDLS peer.
19671 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019672 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019673 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
19674 if (pTdlsPeer == NULL) {
19675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19676 "%s: peer " MAC_ADDRESS_STR " not existing",
19677 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053019678 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019679 return -EINVAL;
19680 }
19681
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019682 /* check FW TDLS Off Channel capability */
19683 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019684 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053019685 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019686 {
19687 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
19688 pTdlsPeer->peerParams.global_operating_class =
19689 tdls_peer_params->global_operating_class;
19690 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
19691 pTdlsPeer->peerParams.min_bandwidth_kbps =
19692 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019693 /* check configured channel is valid, non dfs and
19694 * not current operating channel */
19695 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
19696 tdls_peer_params->channel)) &&
19697 (pHddStaCtx) &&
19698 (tdls_peer_params->channel !=
19699 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019700 {
19701 pTdlsPeer->isOffChannelConfigured = TRUE;
19702 }
19703 else
19704 {
19705 pTdlsPeer->isOffChannelConfigured = FALSE;
19706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19707 "%s: Configured Tdls Off Channel is not valid", __func__);
19708
19709 }
19710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019711 "%s: tdls_off_channel %d isOffChannelConfigured %d "
19712 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019713 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053019714 pTdlsPeer->isOffChannelConfigured,
19715 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019716 }
19717 else
19718 {
19719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053019720 "%s: TDLS off channel FW capability %d, "
19721 "host capab %d or Invalid TDLS Peer Params", __func__,
19722 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
19723 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019724 }
19725
Atul Mittal115287b2014-07-08 13:26:33 +053019726 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
19727
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019728 mutex_unlock(&pHddCtx->tdls_lock);
19729
Atul Mittal115287b2014-07-08 13:26:33 +053019730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19731 " %s TDLS Add Force Peer Failed",
19732 __func__);
19733 return -EINVAL;
19734 }
19735 /*EXT TDLS*/
19736
19737 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019738 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19740 " %s TDLS set callback Failed",
19741 __func__);
19742 return -EINVAL;
19743 }
19744
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019745 mutex_unlock(&pHddCtx->tdls_lock);
19746
Atul Mittal115287b2014-07-08 13:26:33 +053019747 return(0);
19748
19749}
19750
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019751int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
19752#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19753 const u8 *peer
19754#else
19755 u8 *peer
19756#endif
19757)
Atul Mittal115287b2014-07-08 13:26:33 +053019758{
19759
19760 hddTdlsPeer_t *pTdlsPeer;
19761 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019762
Atul Mittal115287b2014-07-08 13:26:33 +053019763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19764 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
19765 __func__, MAC_ADDR_ARRAY(peer));
19766
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019767 if (0 != wlan_hdd_validate_context(pHddCtx)) {
19768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
19769 return -EINVAL;
19770 }
19771
Atul Mittal115287b2014-07-08 13:26:33 +053019772 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
19773 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
19774
19775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019776 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
19777 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
19778 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053019779 return -ENOTSUPP;
19780 }
19781
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019782 mutex_lock(&pHddCtx->tdls_lock);
19783 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053019784
19785 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019786 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019787 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019788 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053019789 __func__, MAC_ADDR_ARRAY(peer));
19790 return -EINVAL;
19791 }
19792 else {
19793 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
19794 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053019795 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
19796 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019797 /* if channel switch is configured, reset
19798 the channel for this peer */
19799 if (TRUE == pTdlsPeer->isOffChannelConfigured)
19800 {
19801 pTdlsPeer->peerParams.channel = 0;
19802 pTdlsPeer->isOffChannelConfigured = FALSE;
19803 }
Atul Mittal115287b2014-07-08 13:26:33 +053019804 }
19805
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019806 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019807 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053019809 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019810 }
Atul Mittal115287b2014-07-08 13:26:33 +053019811
19812 /*EXT TDLS*/
19813
19814 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019815 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053019816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19817 " %s TDLS set callback Failed",
19818 __func__);
19819 return -EINVAL;
19820 }
Atul Mittal115287b2014-07-08 13:26:33 +053019821
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019822 mutex_unlock(&pHddCtx->tdls_lock);
19823
19824 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053019825}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019826static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019827#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19828 const u8 *peer,
19829#else
19830 u8 *peer,
19831#endif
19832 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019833{
19834 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19835 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019836 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070019837 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019838
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019839 ENTER();
19840
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053019841 if (!pAdapter) {
19842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
19843 return -EINVAL;
19844 }
19845
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019846 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19847 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
19848 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019849 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019850 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019851 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070019852 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019853 return -EINVAL;
19854 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019855
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019856 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019857 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019858 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019859 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019860 }
19861
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019862
19863 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019864 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019865 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080019866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019867 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
19868 "Cannot process TDLS commands",
19869 pHddCtx->cfg_ini->fEnableTDLSSupport,
19870 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019871 return -ENOTSUPP;
19872 }
19873
19874 switch (oper) {
19875 case NL80211_TDLS_ENABLE_LINK:
19876 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019877 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019878 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053019879 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
19880 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053019881 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019882 tANI_U16 numCurrTdlsPeers = 0;
19883 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053019884 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019885 tSirMacAddr peerMac;
19886 int channel;
19887 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019888
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19890 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
19891 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019892
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019893 mutex_lock(&pHddCtx->tdls_lock);
19894 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053019895 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053019896 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019897 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053019898 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
19899 " (oper %d) not exsting. ignored",
19900 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19901 return -EINVAL;
19902 }
19903
19904 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19905 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
19906 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
19907 "NL80211_TDLS_ENABLE_LINK");
19908
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019909 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
19910 {
19911 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
19912 MAC_ADDRESS_STR " failed",
19913 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019914 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070019915 return -EINVAL;
19916 }
19917
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053019918 /* before starting tdls connection, set tdls
19919 * off channel established status to default value */
19920 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019921
19922 mutex_unlock(&pHddCtx->tdls_lock);
19923
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053019924 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019925 /* TDLS Off Channel, Disable tdls channel switch,
19926 when there are more than one tdls link */
19927 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053019928 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019929 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019930 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019931 /* get connected peer and send disable tdls off chan */
19932 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019933 if ((connPeer) &&
19934 (connPeer->isOffChannelSupported == TRUE) &&
19935 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019936 {
19937 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19938 "%s: More then one peer connected, Disable "
19939 "TDLS channel switch", __func__);
19940
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053019941 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019942 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
19943 channel = connPeer->peerParams.channel;
19944
19945 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019946
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019947 ret = sme_SendTdlsChanSwitchReq(
19948 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019949 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019950 peerMac,
19951 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019952 TDLS_OFF_CHANNEL_BW_OFFSET,
19953 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019954 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053019955 hddLog(VOS_TRACE_LEVEL_ERROR,
19956 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019957 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019958 }
19959 else
19960 {
19961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19962 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019963 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019964 "isOffChannelConfigured %d",
19965 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053019966 (connPeer ? (connPeer->isOffChannelSupported)
19967 : -1),
19968 (connPeer ? (connPeer->isOffChannelConfigured)
19969 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019970 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053019971 }
19972 }
19973
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053019974 mutex_lock(&pHddCtx->tdls_lock);
19975 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19976 if ( NULL == pTdlsPeer ) {
19977 mutex_unlock(&pHddCtx->tdls_lock);
19978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19979 "%s: " MAC_ADDRESS_STR
19980 " (oper %d) peer got freed in other context. ignored",
19981 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
19982 return -EINVAL;
19983 }
19984 peer_status = pTdlsPeer->link_status;
19985 mutex_unlock(&pHddCtx->tdls_lock);
19986
19987 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019988 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019989 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053019990
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019991 if (0 != wlan_hdd_tdls_get_link_establish_params(
19992 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053019994 return -EINVAL;
19995 }
19996 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053019997
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019998 ret = sme_SendTdlsLinkEstablishParams(
19999 WLAN_HDD_GET_HAL_CTX(pAdapter),
20000 pAdapter->sessionId, peer,
20001 &tdlsLinkEstablishParams);
20002 if (ret != VOS_STATUS_SUCCESS) {
20003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20004 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020005 /* Send TDLS peer UAPSD capabilities to the firmware and
20006 * register with the TL on after the response for this operation
20007 * is received .
20008 */
20009 ret = wait_for_completion_interruptible_timeout(
20010 &pAdapter->tdls_link_establish_req_comp,
20011 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020012
20013 mutex_lock(&pHddCtx->tdls_lock);
20014 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20015 if ( NULL == pTdlsPeer ) {
20016 mutex_unlock(&pHddCtx->tdls_lock);
20017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20018 "%s %d: " MAC_ADDRESS_STR
20019 " (oper %d) peer got freed in other context. ignored",
20020 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20021 (int)oper);
20022 return -EINVAL;
20023 }
20024 peer_status = pTdlsPeer->link_status;
20025 mutex_unlock(&pHddCtx->tdls_lock);
20026
20027 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020028 {
20029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020030 FL("Link Establish Request Failed Status %ld"),
20031 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020032 return -EINVAL;
20033 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020034 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020035
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020036 mutex_lock(&pHddCtx->tdls_lock);
20037 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20038 if ( NULL == pTdlsPeer ) {
20039 mutex_unlock(&pHddCtx->tdls_lock);
20040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20041 "%s: " MAC_ADDRESS_STR
20042 " (oper %d) peer got freed in other context. ignored",
20043 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20044 return -EINVAL;
20045 }
20046
Atul Mittal115287b2014-07-08 13:26:33 +053020047 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20048 eTDLS_LINK_CONNECTED,
20049 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020050 staDesc.ucSTAId = pTdlsPeer->staId;
20051 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020052
20053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20054 "%s: tdlsLinkEstablishParams of peer "
20055 MAC_ADDRESS_STR "uapsdQueues: %d"
20056 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20057 "isResponder: %d peerstaId: %d",
20058 __func__,
20059 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20060 tdlsLinkEstablishParams.uapsdQueues,
20061 tdlsLinkEstablishParams.qos,
20062 tdlsLinkEstablishParams.maxSp,
20063 tdlsLinkEstablishParams.isBufSta,
20064 tdlsLinkEstablishParams.isOffChannelSupported,
20065 tdlsLinkEstablishParams.isResponder,
20066 pTdlsPeer->staId);
20067
20068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20069 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20070 __func__,
20071 staDesc.ucSTAId,
20072 staDesc.ucQosEnabled);
20073
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020074 ret = WLANTL_UpdateTdlsSTAClient(
20075 pHddCtx->pvosContext,
20076 &staDesc);
20077 if (ret != VOS_STATUS_SUCCESS) {
20078 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20079 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020080
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020081 /* Mark TDLS client Authenticated .*/
20082 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20083 pTdlsPeer->staId,
20084 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020085 if (VOS_STATUS_SUCCESS == status)
20086 {
Hoonki Lee14621352013-04-16 17:51:19 -070020087 if (pTdlsPeer->is_responder == 0)
20088 {
20089 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020090 tdlsConnInfo_t *tdlsInfo;
20091
20092 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20093
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020094 if (!vos_timer_is_initialized(
20095 &pTdlsPeer->initiatorWaitTimeoutTimer))
20096 {
20097 /* Initialize initiator wait callback */
20098 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020099 &pTdlsPeer->initiatorWaitTimeoutTimer,
20100 VOS_TIMER_TYPE_SW,
20101 wlan_hdd_tdls_initiator_wait_cb,
20102 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020103 }
Hoonki Lee14621352013-04-16 17:51:19 -070020104 wlan_hdd_tdls_timer_restart(pAdapter,
20105 &pTdlsPeer->initiatorWaitTimeoutTimer,
20106 WAIT_TIME_TDLS_INITIATOR);
20107 /* suspend initiator TX until it receives direct packet from the
20108 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020109 ret = WLANTL_SuspendDataTx(
20110 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20111 &staId, NULL);
20112 if (ret != VOS_STATUS_SUCCESS) {
20113 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20114 }
Hoonki Lee14621352013-04-16 17:51:19 -070020115 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020116
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020117 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020118 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020119 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020120 suppChannelLen =
20121 tdlsLinkEstablishParams.supportedChannelsLen;
20122
20123 if ((suppChannelLen > 0) &&
20124 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20125 {
20126 tANI_U8 suppPeerChannel = 0;
20127 int i = 0;
20128 for (i = 0U; i < suppChannelLen; i++)
20129 {
20130 suppPeerChannel =
20131 tdlsLinkEstablishParams.supportedChannels[i];
20132
20133 pTdlsPeer->isOffChannelSupported = FALSE;
20134 if (suppPeerChannel ==
20135 pTdlsPeer->peerParams.channel)
20136 {
20137 pTdlsPeer->isOffChannelSupported = TRUE;
20138 break;
20139 }
20140 }
20141 }
20142 else
20143 {
20144 pTdlsPeer->isOffChannelSupported = FALSE;
20145 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020146 }
20147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20148 "%s: TDLS channel switch request for channel "
20149 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020150 "%d isOffChannelSupported %d", __func__,
20151 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020152 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020153 suppChannelLen,
20154 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020155
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020156 /* TDLS Off Channel, Enable tdls channel switch,
20157 when their is only one tdls link and it supports */
20158 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20159 if ((numCurrTdlsPeers == 1) &&
20160 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20161 (TRUE == pTdlsPeer->isOffChannelConfigured))
20162 {
20163 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20164 "%s: Send TDLS channel switch request for channel %d",
20165 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020166
20167 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020168 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20169 channel = pTdlsPeer->peerParams.channel;
20170
20171 mutex_unlock(&pHddCtx->tdls_lock);
20172
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020173 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20174 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020175 peerMac,
20176 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020177 TDLS_OFF_CHANNEL_BW_OFFSET,
20178 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020179 if (ret != VOS_STATUS_SUCCESS) {
20180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20181 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020182 }
20183 else
20184 {
20185 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20186 "%s: TDLS channel switch request not sent"
20187 " numCurrTdlsPeers %d "
20188 "isOffChannelSupported %d "
20189 "isOffChannelConfigured %d",
20190 __func__, numCurrTdlsPeers,
20191 pTdlsPeer->isOffChannelSupported,
20192 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020193 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020194 }
20195
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020196 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020197 else
20198 mutex_unlock(&pHddCtx->tdls_lock);
20199
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020200 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020201
20202 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020203 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20204 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020205 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020206 int ac;
20207 uint8 ucAc[4] = { WLANTL_AC_VO,
20208 WLANTL_AC_VI,
20209 WLANTL_AC_BK,
20210 WLANTL_AC_BE };
20211 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20212 for(ac=0; ac < 4; ac++)
20213 {
20214 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20215 pTdlsPeer->staId, ucAc[ac],
20216 tlTid[ac], tlTid[ac], 0, 0,
20217 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020218 if (status != VOS_STATUS_SUCCESS) {
20219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20220 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020221 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020222 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020223 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020224
Bhargav Shah66896792015-10-01 18:17:37 +053020225 /* stop TCP delack timer if TDLS is enable */
20226 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20227 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020228 hdd_wlan_tdls_enable_link_event(peer,
20229 pTdlsPeer->isOffChannelSupported,
20230 pTdlsPeer->isOffChannelConfigured,
20231 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020232 }
20233 break;
20234 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020235 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020236 tANI_U16 numCurrTdlsPeers = 0;
20237 hddTdlsPeer_t *connPeer = NULL;
20238
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020239 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20240 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20241 __func__, MAC_ADDR_ARRAY(peer));
20242
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020243 mutex_lock(&pHddCtx->tdls_lock);
20244 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020245
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020246
Sunil Dutt41de4e22013-11-14 18:09:02 +053020247 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020248 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020249 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20250 " (oper %d) not exsting. ignored",
20251 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20252 return -EINVAL;
20253 }
20254
20255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20256 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20257 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20258 "NL80211_TDLS_DISABLE_LINK");
20259
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020260 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020261 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020262 long status;
20263
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020264 /* set tdls off channel status to false for this peer */
20265 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020266 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20267 eTDLS_LINK_TEARING,
20268 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20269 eTDLS_LINK_UNSPECIFIED:
20270 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020271 mutex_unlock(&pHddCtx->tdls_lock);
20272
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020273 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20274
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020275 status = sme_DeleteTdlsPeerSta(
20276 WLAN_HDD_GET_HAL_CTX(pAdapter),
20277 pAdapter->sessionId, peer );
20278 if (status != VOS_STATUS_SUCCESS) {
20279 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20280 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020281
20282 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20283 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020284
20285 mutex_lock(&pHddCtx->tdls_lock);
20286 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20287 if ( NULL == pTdlsPeer ) {
20288 mutex_unlock(&pHddCtx->tdls_lock);
20289 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20290 " peer was freed in other context",
20291 __func__, MAC_ADDR_ARRAY(peer));
20292 return -EINVAL;
20293 }
20294
Atul Mittal271a7652014-09-12 13:18:22 +053020295 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020296 eTDLS_LINK_IDLE,
20297 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020298 mutex_unlock(&pHddCtx->tdls_lock);
20299
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020300 if (status <= 0)
20301 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20303 "%s: Del station failed status %ld",
20304 __func__, status);
20305 return -EPERM;
20306 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020307
20308 /* TDLS Off Channel, Enable tdls channel switch,
20309 when their is only one tdls link and it supports */
20310 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20311 if (numCurrTdlsPeers == 1)
20312 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020313 tSirMacAddr peerMac;
20314 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020315
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020316 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020317 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020318
20319 if (connPeer == NULL) {
20320 mutex_unlock(&pHddCtx->tdls_lock);
20321 hddLog(VOS_TRACE_LEVEL_ERROR,
20322 "%s connPeer is NULL", __func__);
20323 return -EINVAL;
20324 }
20325
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020326 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20327 channel = connPeer->peerParams.channel;
20328
20329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20330 "%s: TDLS channel switch "
20331 "isOffChannelSupported %d "
20332 "isOffChannelConfigured %d "
20333 "isOffChannelEstablished %d",
20334 __func__,
20335 (connPeer ? connPeer->isOffChannelSupported : -1),
20336 (connPeer ? connPeer->isOffChannelConfigured : -1),
20337 (connPeer ? connPeer->isOffChannelEstablished : -1));
20338
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020339 if ((connPeer) &&
20340 (connPeer->isOffChannelSupported == TRUE) &&
20341 (connPeer->isOffChannelConfigured == TRUE))
20342 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020343 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020344 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020345 status = sme_SendTdlsChanSwitchReq(
20346 WLAN_HDD_GET_HAL_CTX(pAdapter),
20347 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020348 peerMac,
20349 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020350 TDLS_OFF_CHANNEL_BW_OFFSET,
20351 TDLS_CHANNEL_SWITCH_ENABLE);
20352 if (status != VOS_STATUS_SUCCESS) {
20353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20354 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020355 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020356 else
20357 mutex_unlock(&pHddCtx->tdls_lock);
20358 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020359 else
20360 {
20361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20362 "%s: TDLS channel switch request not sent "
20363 "numCurrTdlsPeers %d ",
20364 __func__, numCurrTdlsPeers);
20365 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020366 }
20367 else
20368 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020369 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20371 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020372 }
Bhargav Shah66896792015-10-01 18:17:37 +053020373 if (numCurrTdlsPeers == 0) {
20374 /* start TCP delack timer if TDLS is disable */
20375 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20376 hdd_manage_delack_timer(pHddCtx);
20377 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020378 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020379 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020380 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020381 {
Atul Mittal115287b2014-07-08 13:26:33 +053020382 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020383
Atul Mittal115287b2014-07-08 13:26:33 +053020384 if (0 != status)
20385 {
20386 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020387 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020388 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020389 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020390 break;
20391 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020392 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020393 {
Atul Mittal115287b2014-07-08 13:26:33 +053020394 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20395 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020396 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020397 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020398
Atul Mittal115287b2014-07-08 13:26:33 +053020399 if (0 != status)
20400 {
20401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020402 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020403 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020404 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020405 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020406 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020407 case NL80211_TDLS_DISCOVERY_REQ:
20408 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020410 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020411 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020412 return -ENOTSUPP;
20413 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020414 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20415 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020416 return -ENOTSUPP;
20417 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020418
20419 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020420 return 0;
20421}
Chilam NG571c65a2013-01-19 12:27:36 +053020422
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020423static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020424#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20425 const u8 *peer,
20426#else
20427 u8 *peer,
20428#endif
20429 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020430{
20431 int ret;
20432
20433 vos_ssr_protect(__func__);
20434 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20435 vos_ssr_unprotect(__func__);
20436
20437 return ret;
20438}
20439
Chilam NG571c65a2013-01-19 12:27:36 +053020440int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20441 struct net_device *dev, u8 *peer)
20442{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020443 hddLog(VOS_TRACE_LEVEL_INFO,
20444 "tdls send discover req: "MAC_ADDRESS_STR,
20445 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020446#if TDLS_MGMT_VERSION2
20447 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20448 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20449#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020450#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20451 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20452 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20453#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20454 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20455 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20456#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20457 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20458 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20459#else
Chilam NG571c65a2013-01-19 12:27:36 +053020460 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20461 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020462#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020463#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053020464}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020465#endif
20466
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020467#ifdef WLAN_FEATURE_GTK_OFFLOAD
20468/*
20469 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
20470 * Callback rountine called upon receiving response for
20471 * get offload info
20472 */
20473void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
20474 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
20475{
20476
20477 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020478 tANI_U8 tempReplayCounter[8];
20479 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020480
20481 ENTER();
20482
20483 if (NULL == pAdapter)
20484 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053020485 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020486 "%s: HDD adapter is Null", __func__);
20487 return ;
20488 }
20489
20490 if (NULL == pGtkOffloadGetInfoRsp)
20491 {
20492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20493 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
20494 return ;
20495 }
20496
20497 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
20498 {
20499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20500 "%s: wlan Failed to get replay counter value",
20501 __func__);
20502 return ;
20503 }
20504
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020505 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20506 /* Update replay counter */
20507 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
20508 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20509
20510 {
20511 /* changing from little to big endian since supplicant
20512 * works on big endian format
20513 */
20514 int i;
20515 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
20516
20517 for (i = 0; i < 8; i++)
20518 {
20519 tempReplayCounter[7-i] = (tANI_U8)p[i];
20520 }
20521 }
20522
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020523 /* Update replay counter to NL */
20524 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020525 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020526}
20527
20528/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020529 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020530 * This function is used to offload GTK rekeying job to the firmware.
20531 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020532int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020533 struct cfg80211_gtk_rekey_data *data)
20534{
20535 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20536 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
20537 hdd_station_ctx_t *pHddStaCtx;
20538 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020539 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020540 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020541 eHalStatus status = eHAL_STATUS_FAILURE;
20542
20543 ENTER();
20544
20545 if (NULL == pAdapter)
20546 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020548 "%s: HDD adapter is Null", __func__);
20549 return -ENODEV;
20550 }
20551
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020552 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20553 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
20554 pAdapter->sessionId, pAdapter->device_mode));
20555
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020556 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020557 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020558 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020559 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020560 }
20561
20562 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20563 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20564 if (NULL == hHal)
20565 {
20566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20567 "%s: HAL context is Null!!!", __func__);
20568 return -EAGAIN;
20569 }
20570
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020571 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
20572 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
20573 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
20574 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020575 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020576 {
20577 /* changing from big to little endian since driver
20578 * works on little endian format
20579 */
20580 tANI_U8 *p =
20581 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
20582 int i;
20583
20584 for (i = 0; i < 8; i++)
20585 {
20586 p[7-i] = data->replay_ctr[i];
20587 }
20588 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020589
20590 if (TRUE == pHddCtx->hdd_wlan_suspended)
20591 {
20592 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020593 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
20594 sizeof (tSirGtkOffloadParams));
20595 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020596 pAdapter->sessionId);
20597
20598 if (eHAL_STATUS_SUCCESS != status)
20599 {
20600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20601 "%s: sme_SetGTKOffload failed, returned %d",
20602 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020603
20604 /* Need to clear any trace of key value in the memory.
20605 * Thus zero out the memory even though it is local
20606 * variable.
20607 */
20608 vos_mem_zero(&hddGtkOffloadReqParams,
20609 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020610 return status;
20611 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20613 "%s: sme_SetGTKOffload successfull", __func__);
20614 }
20615 else
20616 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20618 "%s: wlan not suspended GTKOffload request is stored",
20619 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020620 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020621
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053020622 /* Need to clear any trace of key value in the memory.
20623 * Thus zero out the memory even though it is local
20624 * variable.
20625 */
20626 vos_mem_zero(&hddGtkOffloadReqParams,
20627 sizeof(hddGtkOffloadReqParams));
20628
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020629 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053020630 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020631}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020632
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020633int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
20634 struct cfg80211_gtk_rekey_data *data)
20635{
20636 int ret;
20637
20638 vos_ssr_protect(__func__);
20639 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
20640 vos_ssr_unprotect(__func__);
20641
20642 return ret;
20643}
20644#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020645/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020646 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020647 * This function is used to set access control policy
20648 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020649static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20650 struct net_device *dev,
20651 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020652{
20653 int i;
20654 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20655 hdd_hostapd_state_t *pHostapdState;
20656 tsap_Config_t *pConfig;
20657 v_CONTEXT_t pVosContext = NULL;
20658 hdd_context_t *pHddCtx;
20659 int status;
20660
20661 ENTER();
20662
20663 if (NULL == pAdapter)
20664 {
20665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20666 "%s: HDD adapter is Null", __func__);
20667 return -ENODEV;
20668 }
20669
20670 if (NULL == params)
20671 {
20672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20673 "%s: params is Null", __func__);
20674 return -EINVAL;
20675 }
20676
20677 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
20678 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020679 if (0 != status)
20680 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020681 return status;
20682 }
20683
20684 pVosContext = pHddCtx->pvosContext;
20685 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
20686
20687 if (NULL == pHostapdState)
20688 {
20689 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20690 "%s: pHostapdState is Null", __func__);
20691 return -EINVAL;
20692 }
20693
20694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
20695 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020696 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20697 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
20698 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020699
20700 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
20701 {
20702 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
20703
20704 /* default value */
20705 pConfig->num_accept_mac = 0;
20706 pConfig->num_deny_mac = 0;
20707
20708 /**
20709 * access control policy
20710 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20711 * listed in hostapd.deny file.
20712 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20713 * listed in hostapd.accept file.
20714 */
20715 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
20716 {
20717 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
20718 }
20719 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
20720 {
20721 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
20722 }
20723 else
20724 {
20725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20726 "%s:Acl Policy : %d is not supported",
20727 __func__, params->acl_policy);
20728 return -ENOTSUPP;
20729 }
20730
20731 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
20732 {
20733 pConfig->num_accept_mac = params->n_acl_entries;
20734 for (i = 0; i < params->n_acl_entries; i++)
20735 {
20736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20737 "** Add ACL MAC entry %i in WhiletList :"
20738 MAC_ADDRESS_STR, i,
20739 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20740
20741 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
20742 sizeof(qcmacaddr));
20743 }
20744 }
20745 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
20746 {
20747 pConfig->num_deny_mac = params->n_acl_entries;
20748 for (i = 0; i < params->n_acl_entries; i++)
20749 {
20750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20751 "** Add ACL MAC entry %i in BlackList :"
20752 MAC_ADDRESS_STR, i,
20753 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
20754
20755 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
20756 sizeof(qcmacaddr));
20757 }
20758 }
20759
20760 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
20761 {
20762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20763 "%s: SAP Set Mac Acl fail", __func__);
20764 return -EINVAL;
20765 }
20766 }
20767 else
20768 {
20769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053020770 "%s: Invalid device_mode = %s (%d)",
20771 __func__, hdd_device_modetoString(pAdapter->device_mode),
20772 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020773 return -EINVAL;
20774 }
20775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020776 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020777 return 0;
20778}
20779
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020780static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20781 struct net_device *dev,
20782 const struct cfg80211_acl_data *params)
20783{
20784 int ret;
20785 vos_ssr_protect(__func__);
20786 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
20787 vos_ssr_unprotect(__func__);
20788
20789 return ret;
20790}
20791
Leo Chang9056f462013-08-01 19:21:11 -070020792#ifdef WLAN_NL80211_TESTMODE
20793#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070020794void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070020795(
20796 void *pAdapter,
20797 void *indCont
20798)
20799{
Leo Changd9df8aa2013-09-26 13:32:26 -070020800 tSirLPHBInd *lphbInd;
20801 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053020802 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070020803
20804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020805 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070020806
c_hpothu73f35e62014-04-18 13:40:08 +053020807 if (pAdapter == NULL)
20808 {
20809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20810 "%s: pAdapter is NULL\n",__func__);
20811 return;
20812 }
20813
Leo Chang9056f462013-08-01 19:21:11 -070020814 if (NULL == indCont)
20815 {
20816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070020817 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070020818 return;
20819 }
20820
c_hpothu73f35e62014-04-18 13:40:08 +053020821 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070020822 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070020823 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053020824 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070020825 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070020826 GFP_ATOMIC);
20827 if (!skb)
20828 {
20829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20830 "LPHB timeout, NL buffer alloc fail");
20831 return;
20832 }
20833
Leo Changac3ba772013-10-07 09:47:04 -070020834 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070020835 {
20836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20837 "WLAN_HDD_TM_ATTR_CMD put fail");
20838 goto nla_put_failure;
20839 }
Leo Changac3ba772013-10-07 09:47:04 -070020840 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070020841 {
20842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20843 "WLAN_HDD_TM_ATTR_TYPE put fail");
20844 goto nla_put_failure;
20845 }
Leo Changac3ba772013-10-07 09:47:04 -070020846 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070020847 sizeof(tSirLPHBInd), lphbInd))
20848 {
20849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20850 "WLAN_HDD_TM_ATTR_DATA put fail");
20851 goto nla_put_failure;
20852 }
Leo Chang9056f462013-08-01 19:21:11 -070020853 cfg80211_testmode_event(skb, GFP_ATOMIC);
20854 return;
20855
20856nla_put_failure:
20857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20858 "NLA Put fail");
20859 kfree_skb(skb);
20860
20861 return;
20862}
20863#endif /* FEATURE_WLAN_LPHB */
20864
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020865static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070020866{
20867 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20868 int err = 0;
20869#ifdef FEATURE_WLAN_LPHB
20870 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070020871 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020872
20873 ENTER();
20874
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020875 err = wlan_hdd_validate_context(pHddCtx);
20876 if (0 != err)
20877 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053020878 return err;
20879 }
Leo Chang9056f462013-08-01 19:21:11 -070020880#endif /* FEATURE_WLAN_LPHB */
20881
20882 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
20883 if (err)
20884 {
20885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20886 "%s Testmode INV ATTR", __func__);
20887 return err;
20888 }
20889
20890 if (!tb[WLAN_HDD_TM_ATTR_CMD])
20891 {
20892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20893 "%s Testmode INV CMD", __func__);
20894 return -EINVAL;
20895 }
20896
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020897 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20898 TRACE_CODE_HDD_CFG80211_TESTMODE,
20899 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070020900 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
20901 {
20902#ifdef FEATURE_WLAN_LPHB
20903 /* Low Power Heartbeat configuration request */
20904 case WLAN_HDD_TM_CMD_WLAN_HB:
20905 {
20906 int buf_len;
20907 void *buf;
20908 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080020909 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070020910
20911 if (!tb[WLAN_HDD_TM_ATTR_DATA])
20912 {
20913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20914 "%s Testmode INV DATA", __func__);
20915 return -EINVAL;
20916 }
20917
20918 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20919 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080020920
Manjeet Singh3c577442017-02-10 19:03:38 +053020921 if (buf_len > sizeof(*hb_params)) {
20922 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
20923 buf_len);
20924 return -ERANGE;
20925 }
20926
Amar Singhal05852702014-02-04 14:40:00 -080020927 hb_params_temp =(tSirLPHBReq *)buf;
20928 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
20929 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
20930 return -EINVAL;
20931
Leo Chang9056f462013-08-01 19:21:11 -070020932 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
20933 if (NULL == hb_params)
20934 {
20935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20936 "%s Request Buffer Alloc Fail", __func__);
20937 return -EINVAL;
20938 }
20939
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053020940 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070020941 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070020942 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
20943 hb_params,
20944 wlan_hdd_cfg80211_lphb_ind_handler);
20945 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070020946 {
Leo Changd9df8aa2013-09-26 13:32:26 -070020947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20948 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070020949 vos_mem_free(hb_params);
20950 }
Leo Chang9056f462013-08-01 19:21:11 -070020951 return 0;
20952 }
20953#endif /* FEATURE_WLAN_LPHB */
20954 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20956 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070020957 return -EOPNOTSUPP;
20958 }
20959
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020960 EXIT();
20961 return err;
Leo Chang9056f462013-08-01 19:21:11 -070020962}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020963
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053020964static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20965#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
20966 struct wireless_dev *wdev,
20967#endif
20968 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020969{
20970 int ret;
20971
20972 vos_ssr_protect(__func__);
20973 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
20974 vos_ssr_unprotect(__func__);
20975
20976 return ret;
20977}
Leo Chang9056f462013-08-01 19:21:11 -070020978#endif /* CONFIG_NL80211_TESTMODE */
20979
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053020980extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020981static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020982 struct net_device *dev,
20983 int idx, struct survey_info *survey)
20984{
20985 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20986 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053020987 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020988 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053020989 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020990 v_S7_t snr,rssi;
20991 int status, i, j, filled = 0;
20992
20993 ENTER();
20994
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053020995 if (NULL == pAdapter)
20996 {
20997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
20998 "%s: HDD adapter is Null", __func__);
20999 return -ENODEV;
21000 }
21001
21002 if (NULL == wiphy)
21003 {
21004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21005 "%s: wiphy is Null", __func__);
21006 return -ENODEV;
21007 }
21008
21009 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21010 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021011 if (0 != status)
21012 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021013 return status;
21014 }
21015
Mihir Sheted9072e02013-08-21 17:02:29 +053021016 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21017
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021018 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021019 0 != pAdapter->survey_idx ||
21020 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021021 {
21022 /* The survey dump ops when implemented completely is expected to
21023 * return a survey of all channels and the ops is called by the
21024 * kernel with incremental values of the argument 'idx' till it
21025 * returns -ENONET. But we can only support the survey for the
21026 * operating channel for now. survey_idx is used to track
21027 * that the ops is called only once and then return -ENONET for
21028 * the next iteration
21029 */
21030 pAdapter->survey_idx = 0;
21031 return -ENONET;
21032 }
21033
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021034 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21035 {
21036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21037 "%s: Roaming in progress, hence return ", __func__);
21038 return -ENONET;
21039 }
21040
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021041 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21042
21043 wlan_hdd_get_snr(pAdapter, &snr);
21044 wlan_hdd_get_rssi(pAdapter, &rssi);
21045
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021046 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21047 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21048 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021049 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21050 hdd_wlan_get_freq(channel, &freq);
21051
21052
21053 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
21054 {
21055 if (NULL == wiphy->bands[i])
21056 {
21057 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21058 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21059 continue;
21060 }
21061
21062 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21063 {
21064 struct ieee80211_supported_band *band = wiphy->bands[i];
21065
21066 if (band->channels[j].center_freq == (v_U16_t)freq)
21067 {
21068 survey->channel = &band->channels[j];
21069 /* The Rx BDs contain SNR values in dB for the received frames
21070 * while the supplicant expects noise. So we calculate and
21071 * return the value of noise (dBm)
21072 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21073 */
21074 survey->noise = rssi - snr;
21075 survey->filled = SURVEY_INFO_NOISE_DBM;
21076 filled = 1;
21077 }
21078 }
21079 }
21080
21081 if (filled)
21082 pAdapter->survey_idx = 1;
21083 else
21084 {
21085 pAdapter->survey_idx = 0;
21086 return -ENONET;
21087 }
21088
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021089 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021090 return 0;
21091}
21092
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021093static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21094 struct net_device *dev,
21095 int idx, struct survey_info *survey)
21096{
21097 int ret;
21098
21099 vos_ssr_protect(__func__);
21100 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21101 vos_ssr_unprotect(__func__);
21102
21103 return ret;
21104}
21105
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021106/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021107 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021108 * this is called when cfg80211 driver resume
21109 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21110 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021111int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021112{
21113 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21114 hdd_adapter_t *pAdapter;
21115 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21116 VOS_STATUS status = VOS_STATUS_SUCCESS;
21117
21118 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021119
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021120 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021121 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021122 return 0;
21123 }
21124
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021125 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21126 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021127
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021128 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021129 {
21130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21131 "%s: Resume SoftAP", __func__);
21132 hdd_set_wlan_suspend_mode(false);
21133 }
21134
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021135 spin_lock(&pHddCtx->schedScan_lock);
21136 pHddCtx->isWiphySuspended = FALSE;
21137 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21138 {
21139 spin_unlock(&pHddCtx->schedScan_lock);
21140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21141 "%s: Return resume is not due to PNO indication", __func__);
21142 return 0;
21143 }
21144 // Reset flag to avoid updatating cfg80211 data old results again
21145 pHddCtx->isSchedScanUpdatePending = FALSE;
21146 spin_unlock(&pHddCtx->schedScan_lock);
21147
21148 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21149
21150 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21151 {
21152 pAdapter = pAdapterNode->pAdapter;
21153 if ( (NULL != pAdapter) &&
21154 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21155 {
21156 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021157 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021158 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21159 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021160 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021161 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021162 {
21163 /* Acquire wakelock to handle the case where APP's tries to
21164 * suspend immediately after updating the scan results. Whis
21165 * results in app's is in suspended state and not able to
21166 * process the connect request to AP
21167 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021168 hdd_prevent_suspend_timeout(2000,
21169 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021170 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021171 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021172
21173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21174 "%s : cfg80211 scan result database updated", __func__);
21175
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021176 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021177 return 0;
21178
21179 }
21180 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21181 pAdapterNode = pNext;
21182 }
21183
21184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21185 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021186 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021187 return 0;
21188}
21189
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021190int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21191{
21192 int ret;
21193
21194 vos_ssr_protect(__func__);
21195 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21196 vos_ssr_unprotect(__func__);
21197
21198 return ret;
21199}
21200
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021201/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021202 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021203 * this is called when cfg80211 driver suspends
21204 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021205int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021206 struct cfg80211_wowlan *wow)
21207{
21208 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021209 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021210
21211 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021212
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021213 ret = wlan_hdd_validate_context(pHddCtx);
21214 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021215 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021216 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021217 }
21218
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021219 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21221 "%s: Suspend SoftAP", __func__);
21222 hdd_set_wlan_suspend_mode(true);
21223 }
21224
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021225
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021226 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21227 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21228 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021229 pHddCtx->isWiphySuspended = TRUE;
21230
21231 EXIT();
21232
21233 return 0;
21234}
21235
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021236int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21237 struct cfg80211_wowlan *wow)
21238{
21239 int ret;
21240
21241 vos_ssr_protect(__func__);
21242 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21243 vos_ssr_unprotect(__func__);
21244
21245 return ret;
21246}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021247
21248#ifdef FEATURE_OEM_DATA_SUPPORT
21249static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021250 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021251{
21252 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21253
21254 ENTER();
21255
21256 if (wlan_hdd_validate_context(pHddCtx)) {
21257 return;
21258 }
21259 if (!pMsg)
21260 {
21261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21262 return;
21263 }
21264
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021265 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021266
21267 EXIT();
21268 return;
21269
21270}
21271
21272void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021273 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021274{
21275 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21276
21277 ENTER();
21278
21279 if (wlan_hdd_validate_context(pHddCtx)) {
21280 return;
21281 }
21282
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021283 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021284
21285 switch(evType) {
21286 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021287 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021288 break;
21289 default:
21290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21291 break;
21292 }
21293 EXIT();
21294}
21295#endif
21296
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021297#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21298 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021299/**
21300 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21301 * @wiphy: Pointer to wiphy
21302 * @wdev: Pointer to wireless device structure
21303 *
21304 * This function is used to abort an ongoing scan
21305 *
21306 * Return: None
21307 */
21308static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21309 struct wireless_dev *wdev)
21310{
21311 struct net_device *dev = wdev->netdev;
21312 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21313 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21314 int ret;
21315
21316 ENTER();
21317
21318 if (NULL == adapter) {
21319 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21320 return;
21321 }
21322
21323 ret = wlan_hdd_validate_context(hdd_ctx);
21324 if (0 != ret)
21325 return;
21326
21327 wlan_hdd_scan_abort(adapter);
21328
21329 return;
21330}
21331
21332/**
21333 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21334 * @wiphy: Pointer to wiphy
21335 * @wdev: Pointer to wireless device structure
21336 *
21337 * Return: None
21338 */
21339void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21340 struct wireless_dev *wdev)
21341{
21342 vos_ssr_protect(__func__);
21343 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21344 vos_ssr_unprotect(__func__);
21345
21346 return;
21347}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021348#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021349
Abhishek Singh936c6932017-11-07 17:28:23 +053021350#ifdef CHANNEL_SWITCH_SUPPORTED
21351/**
21352 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21353 * channel in SAP/GO
21354 * @wiphy: wiphy pointer
21355 * @dev: dev pointer.
21356 * @csa_params: Change channel params
21357 *
21358 * This function is called to switch channel in SAP/GO
21359 *
21360 * Return: 0 if success else return non zero
21361 */
21362static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21363 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21364{
21365 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21366 hdd_context_t *hdd_ctx;
21367 uint8_t channel;
21368 int ret;
21369 v_CONTEXT_t vos_ctx;
21370
21371 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21372
21373 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21374 ret = wlan_hdd_validate_context(hdd_ctx);
21375 if (ret)
21376 return ret;
21377
21378 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21379 if (!vos_ctx) {
21380 hddLog(LOGE, FL("Vos ctx is null"));
21381 return -EINVAL;
21382 }
21383
21384 if ((WLAN_HDD_SOFTAP != adapter->device_mode) &&
21385 (WLAN_HDD_P2P_GO != adapter->device_mode))
21386 return -ENOTSUPP;
21387
21388 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021389 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021390
21391 return ret;
21392}
21393
21394/**
21395 * wlan_hdd_cfg80211_channel_switch()- function to switch
21396 * channel in SAP/GO
21397 * @wiphy: wiphy pointer
21398 * @dev: dev pointer.
21399 * @csa_params: Change channel params
21400 *
21401 * This function is called to switch channel in SAP/GO
21402 *
21403 * Return: 0 if success else return non zero
21404 */
21405static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21406 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21407{
21408 int ret;
21409
21410 vos_ssr_protect(__func__);
21411 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21412 vos_ssr_unprotect(__func__);
21413
21414 return ret;
21415}
21416#endif
21417
Jeff Johnson295189b2012-06-20 16:38:30 -070021418/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021419static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021420{
21421 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21422 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21423 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21424 .change_station = wlan_hdd_change_station,
21425#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21426 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21427 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21428 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021429#else
21430 .start_ap = wlan_hdd_cfg80211_start_ap,
21431 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21432 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021433#endif
21434 .change_bss = wlan_hdd_cfg80211_change_bss,
21435 .add_key = wlan_hdd_cfg80211_add_key,
21436 .get_key = wlan_hdd_cfg80211_get_key,
21437 .del_key = wlan_hdd_cfg80211_del_key,
21438 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021439#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021440 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021441#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021442 .scan = wlan_hdd_cfg80211_scan,
21443 .connect = wlan_hdd_cfg80211_connect,
21444 .disconnect = wlan_hdd_cfg80211_disconnect,
21445 .join_ibss = wlan_hdd_cfg80211_join_ibss,
21446 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
21447 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
21448 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
21449 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070021450 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
21451 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053021452 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070021453#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
21454 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
21455 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
21456 .set_txq_params = wlan_hdd_set_txq_params,
21457#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021458 .get_station = wlan_hdd_cfg80211_get_station,
21459 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
21460 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021461 .add_station = wlan_hdd_cfg80211_add_station,
21462#ifdef FEATURE_WLAN_LFR
21463 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
21464 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
21465 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
21466#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070021467#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
21468 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
21469#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021470#ifdef FEATURE_WLAN_TDLS
21471 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
21472 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
21473#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021474#ifdef WLAN_FEATURE_GTK_OFFLOAD
21475 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
21476#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053021477#ifdef FEATURE_WLAN_SCAN_PNO
21478 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
21479 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
21480#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021481 .resume = wlan_hdd_cfg80211_resume_wlan,
21482 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021483 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070021484#ifdef WLAN_NL80211_TESTMODE
21485 .testmode_cmd = wlan_hdd_cfg80211_testmode,
21486#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021487 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21489 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021490 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021491#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053021492#ifdef CHANNEL_SWITCH_SUPPORTED
21493 .channel_switch = wlan_hdd_cfg80211_channel_switch,
21494#endif
21495
Jeff Johnson295189b2012-06-20 16:38:30 -070021496};
21497