blob: c59338cf2546f6ada38ec611e1011391927207a2 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +05302 * Copyright (c) 2012-2019 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>
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053066#include <linux/etherdevice.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <wlan_hdd_includes.h>
68#include <net/arp.h>
69#include <net/cfg80211.h>
70#include <linux/wireless.h>
71#include <wlan_hdd_wowl.h>
72#include <aniGlobal.h>
73#include "ccmApi.h"
74#include "sirParams.h"
75#include "dot11f.h"
76#include "wlan_hdd_assoc.h"
77#include "wlan_hdd_wext.h"
78#include "sme_Api.h"
79#include "wlan_hdd_p2p.h"
80#include "wlan_hdd_cfg80211.h"
81#include "wlan_hdd_hostapd.h"
82#include "sapInternal.h"
83#include "wlan_hdd_softap_tx_rx.h"
84#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053085#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053086#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070090#ifdef WLAN_BTAMP_FEATURE
91#include "bap_hdd_misc.h"
92#endif
93#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080094#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053099#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +0530100#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530101#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103
104#define g_mode_rates_size (12)
105#define a_mode_rates_size (8)
106#define FREQ_BASE_80211G (2407)
107#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700108#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530109#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800111 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700112
113#define HDD2GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530114 .band = HDD_NL80211_BAND_2GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700115 .center_freq = (freq), \
116 .hw_value = (chan),\
117 .flags = (flag), \
118 .max_antenna_gain = 0 ,\
119 .max_power = 30, \
120}
121
122#define HDD5GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530123 .band = HDD_NL80211_BAND_5GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700124 .center_freq = (freq), \
125 .hw_value = (chan),\
126 .flags = (flag), \
127 .max_antenna_gain = 0 ,\
128 .max_power = 30, \
129}
130
131#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
132{\
133 .bitrate = rate, \
134 .hw_value = rate_id, \
135 .flags = flag, \
136}
137
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530138#ifdef WLAN_FEATURE_VOWIFI_11R
139#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
140#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
141#endif
142
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530144#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Atul Mittal115287b2014-07-08 13:26:33 +0530168/*EXT TDLS*/
169/*
170 * Used to allocate the size of 4096 for the TDLS.
171 * The size of 4096 is considered assuming that all data per
172 * respective event fit with in the limit.Please take a call
173 * on the limit based on the data requirements on link layer
174 * statistics.
175 */
176#define EXTTDLS_EVENT_BUF_SIZE 4096
177
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530178/*
179 * Values for Mac spoofing feature
180 *
181 */
182#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
183#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
184#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530185#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
186
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530187/*
188 * max_sched_scan_plans defined to 10
189 */
190#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530191
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530192static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700193{
194 WLAN_CIPHER_SUITE_WEP40,
195 WLAN_CIPHER_SUITE_WEP104,
196 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800197#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
199 WLAN_CIPHER_SUITE_KRK,
200 WLAN_CIPHER_SUITE_CCMP,
201#else
202 WLAN_CIPHER_SUITE_CCMP,
203#endif
204#ifdef FEATURE_WLAN_WAPI
205 WLAN_CIPHER_SUITE_SMS4,
206#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700207#ifdef WLAN_FEATURE_11W
208 WLAN_CIPHER_SUITE_AES_CMAC,
209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700210};
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530300 .band = HDD_NL80211_BAND_2GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
Abhinav Kumar1ac5cb42018-09-21 16:11:03 +0530307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
308 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
Jeff Johnson295189b2012-06-20 16:38:30 -0700309 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
310 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
311 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
312 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
313 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
Abhinav Kumar73d67c02019-02-22 12:42:41 +0530314 .vht_cap.vht_supported = 1,
315 .vht_cap.cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454
316 | IEEE80211_VHT_CAP_SHORT_GI_80,
Jeff Johnson295189b2012-06-20 16:38:30 -0700317};
318
Jeff Johnson295189b2012-06-20 16:38:30 -0700319static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
320{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530321 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700322 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530323 .band = HDD_NL80211_BAND_5GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700324 .bitrates = a_mode_rates,
325 .n_bitrates = a_mode_rates_size,
326 .ht_cap.ht_supported = 1,
327 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
328 | IEEE80211_HT_CAP_GRN_FLD
329 | IEEE80211_HT_CAP_DSSSCCK40
330 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
331 | IEEE80211_HT_CAP_SGI_40
332 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
333 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
334 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
335 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
336 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
337 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
Abhinav Kumar73d67c02019-02-22 12:42:41 +0530338 .vht_cap.vht_supported = 1,
339 .vht_cap.cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454
340 | IEEE80211_VHT_CAP_SHORT_GI_80,
Jeff Johnson295189b2012-06-20 16:38:30 -0700341};
342
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530343/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700344 TX/RX direction for each kind of interface */
345static const struct ieee80211_txrx_stypes
346wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
347 [NL80211_IFTYPE_STATION] = {
348 .tx = 0xffff,
349 .rx = BIT(SIR_MAC_MGMT_ACTION) |
Abhinav Kumard5eacfa2019-08-05 14:56:21 +0530350 BIT(SIR_MAC_MGMT_AUTH) |
Jeff Johnson295189b2012-06-20 16:38:30 -0700351 BIT(SIR_MAC_MGMT_PROBE_REQ),
352 },
353 [NL80211_IFTYPE_AP] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
356 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
357 BIT(SIR_MAC_MGMT_PROBE_REQ) |
358 BIT(SIR_MAC_MGMT_DISASSOC) |
359 BIT(SIR_MAC_MGMT_AUTH) |
360 BIT(SIR_MAC_MGMT_DEAUTH) |
361 BIT(SIR_MAC_MGMT_ACTION),
362 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700363 [NL80211_IFTYPE_ADHOC] = {
364 .tx = 0xffff,
365 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
366 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
367 BIT(SIR_MAC_MGMT_PROBE_REQ) |
368 BIT(SIR_MAC_MGMT_DISASSOC) |
369 BIT(SIR_MAC_MGMT_AUTH) |
370 BIT(SIR_MAC_MGMT_DEAUTH) |
371 BIT(SIR_MAC_MGMT_ACTION),
372 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700373 [NL80211_IFTYPE_P2P_CLIENT] = {
374 .tx = 0xffff,
375 .rx = BIT(SIR_MAC_MGMT_ACTION) |
376 BIT(SIR_MAC_MGMT_PROBE_REQ),
377 },
378 [NL80211_IFTYPE_P2P_GO] = {
379 /* This is also same as for SoftAP */
380 .tx = 0xffff,
381 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
382 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
383 BIT(SIR_MAC_MGMT_PROBE_REQ) |
384 BIT(SIR_MAC_MGMT_DISASSOC) |
385 BIT(SIR_MAC_MGMT_AUTH) |
386 BIT(SIR_MAC_MGMT_DEAUTH) |
387 BIT(SIR_MAC_MGMT_ACTION),
388 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700389};
390
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800391#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800392static const struct ieee80211_iface_limit
393wlan_hdd_iface_limit[] = {
394 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800395 /* max = 3 ; Our driver create two interfaces during driver init
396 * wlan0 and p2p0 interfaces. p2p0 is considered as station
397 * interface until a group is formed. In JB architecture, once the
398 * group is formed, interface type of p2p0 is changed to P2P GO or
399 * Client.
400 * When supplicant remove the group, it first issue a set interface
401 * cmd to change the mode back to Station. In JB this works fine as
402 * we advertize two station type interface during driver init.
403 * Some vendors create separate interface for P2P GO/Client,
404 * after group formation(Third one). But while group remove
405 * supplicant first tries to change the mode(3rd interface) to STATION
406 * But as we advertized only two sta type interfaces nl80211 was
407 * returning error for the third one which was leading to failure in
408 * delete interface. Ideally while removing the group, supplicant
409 * should not try to change the 3rd interface mode to Station type.
410 * Till we get a fix in wpa_supplicant, we advertize max STA
411 * interface type to 3
412 */
413 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800414 .types = BIT(NL80211_IFTYPE_STATION),
415 },
416 {
417 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700418 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800419 },
420 {
421 .max = 1,
422 .types = BIT(NL80211_IFTYPE_P2P_GO) |
423 BIT(NL80211_IFTYPE_P2P_CLIENT),
424 },
425};
426
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530427/* interface limits for sta + monitor SCC */
428static const struct ieee80211_iface_limit
429wlan_hdd_iface_sta_mon_limit[] = {
430 {
431 .max = 1,
432 .types = BIT(NL80211_IFTYPE_STATION),
433 },
434 {
435 .max = 1, /* Monitor interface */
436 .types = BIT(NL80211_IFTYPE_MONITOR),
437 },
438};
439
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800440/* By default, only single channel concurrency is allowed */
441static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530442wlan_hdd_iface_combination[] = {
443 {
444 .limits = wlan_hdd_iface_limit,
445 .num_different_channels = 1,
446 /*
447 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
448 * and p2p0 interfaces during driver init
449 * Some vendors create separate interface for P2P operations.
450 * wlan0: STA interface
451 * p2p0: P2P Device interface, action frames goes
452 * through this interface.
453 * p2p-xx: P2P interface, After GO negotiation this interface is
454 * created for p2p operations(GO/CLIENT interface).
455 */
456 .max_interfaces = WLAN_MAX_INTERFACES,
457 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
458 .beacon_int_infra_match = false,
459 },
460 {
461 .limits = wlan_hdd_iface_sta_mon_limit,
462 .num_different_channels = 1,
463 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
464 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
465 .beacon_int_infra_match = false,
466 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800467};
468#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800469
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
471static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +0530472 .flags = WIPHY_WOWLAN_ANY |
473 WIPHY_WOWLAN_MAGIC_PKT,
Nachiket Kukade5b2e7332018-04-06 14:40:22 +0530474 .n_patterns = WOWL_MAX_PTRNS_ALLOWED,
475 .pattern_min_len = 1,
476 .pattern_max_len = WOWL_PTRN_MAX_SIZE,
477};
478#endif
479
Jeff Johnson295189b2012-06-20 16:38:30 -0700480static struct cfg80211_ops wlan_hdd_cfg80211_ops;
481
482/* Data rate 100KBPS based on IE Index */
483struct index_data_rate_type
484{
485 v_U8_t beacon_rate_index;
486 v_U16_t supported_rate[4];
487};
488
489/* 11B, 11G Rate table include Basic rate and Extended rate
490 The IDX field is the rate index
491 The HI field is the rate when RSSI is strong or being ignored
492 (in this case we report actual rate)
493 The MID field is the rate when RSSI is moderate
494 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
495 The LO field is the rate when RSSI is low
496 (in this case we don't report rates, actual current rate used)
497 */
498static const struct
499{
500 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700501 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700502} supported_data_rate[] =
503{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700504/* IDX HI HM LM LO (RSSI-based index */
505 {2, { 10, 10, 10, 0}},
506 {4, { 20, 20, 10, 0}},
507 {11, { 55, 20, 10, 0}},
508 {12, { 60, 55, 20, 0}},
509 {18, { 90, 55, 20, 0}},
510 {22, {110, 55, 20, 0}},
511 {24, {120, 90, 60, 0}},
512 {36, {180, 120, 60, 0}},
513 {44, {220, 180, 60, 0}},
514 {48, {240, 180, 90, 0}},
515 {66, {330, 180, 90, 0}},
516 {72, {360, 240, 90, 0}},
517 {96, {480, 240, 120, 0}},
518 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700519};
520
521/* MCS Based rate table */
522static struct index_data_rate_type supported_mcs_rate[] =
523{
524/* MCS L20 L40 S20 S40 */
525 {0, {65, 135, 72, 150}},
526 {1, {130, 270, 144, 300}},
527 {2, {195, 405, 217, 450}},
528 {3, {260, 540, 289, 600}},
529 {4, {390, 810, 433, 900}},
530 {5, {520, 1080, 578, 1200}},
531 {6, {585, 1215, 650, 1350}},
532 {7, {650, 1350, 722, 1500}}
533};
534
Leo Chang6f8870f2013-03-26 18:11:36 -0700535#ifdef WLAN_FEATURE_11AC
536
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530537#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700538
539struct index_vht_data_rate_type
540{
541 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530542 v_U16_t supported_VHT80_rate[2];
543 v_U16_t supported_VHT40_rate[2];
544 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700545};
546
547typedef enum
548{
549 DATA_RATE_11AC_MAX_MCS_7,
550 DATA_RATE_11AC_MAX_MCS_8,
551 DATA_RATE_11AC_MAX_MCS_9,
552 DATA_RATE_11AC_MAX_MCS_NA
553} eDataRate11ACMaxMcs;
554
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530555/* SSID broadcast type */
556typedef enum eSSIDBcastType
557{
558 eBCAST_UNKNOWN = 0,
559 eBCAST_NORMAL = 1,
560 eBCAST_HIDDEN = 2,
561} tSSIDBcastType;
562
Leo Chang6f8870f2013-03-26 18:11:36 -0700563/* MCS Based VHT rate table */
564static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
565{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530566/* MCS L80 S80 L40 S40 L20 S40*/
567 {0, {293, 325}, {135, 150}, {65, 72}},
568 {1, {585, 650}, {270, 300}, {130, 144}},
569 {2, {878, 975}, {405, 450}, {195, 217}},
570 {3, {1170, 1300}, {540, 600}, {260, 289}},
571 {4, {1755, 1950}, {810, 900}, {390, 433}},
572 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
573 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
574 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
575 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
576 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700577};
578#endif /* WLAN_FEATURE_11AC */
579
c_hpothu79aab322014-07-14 21:11:01 +0530580/*array index points to MCS and array value points respective rssi*/
581static int rssiMcsTbl[][10] =
582{
583/*MCS 0 1 2 3 4 5 6 7 8 9*/
584 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
585 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
586 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
587};
588
Jeff Johnson295189b2012-06-20 16:38:30 -0700589extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530590#ifdef FEATURE_WLAN_SCAN_PNO
591static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
592#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700593
Leo Chang9056f462013-08-01 19:21:11 -0700594#ifdef WLAN_NL80211_TESTMODE
595enum wlan_hdd_tm_attr
596{
597 WLAN_HDD_TM_ATTR_INVALID = 0,
598 WLAN_HDD_TM_ATTR_CMD = 1,
599 WLAN_HDD_TM_ATTR_DATA = 2,
600 WLAN_HDD_TM_ATTR_TYPE = 3,
601 /* keep last */
602 WLAN_HDD_TM_ATTR_AFTER_LAST,
603 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
604};
605
606enum wlan_hdd_tm_cmd
607{
608 WLAN_HDD_TM_CMD_WLAN_HB = 1,
609};
610
611#define WLAN_HDD_TM_DATA_MAX_LEN 5000
612
613static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
614{
615 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
616 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
617 .len = WLAN_HDD_TM_DATA_MAX_LEN },
618};
619#endif /* WLAN_NL80211_TESTMODE */
620
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800621#ifdef FEATURE_WLAN_CH_AVOID
622/*
623 * FUNCTION: wlan_hdd_send_avoid_freq_event
624 * This is called when wlan driver needs to send vendor specific
625 * avoid frequency range event to userspace
626 */
627int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
628 tHddAvoidFreqList *pAvoidFreqList)
629{
630 struct sk_buff *vendor_event;
631
632 ENTER();
633
634 if (!pHddCtx)
635 {
636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
637 "%s: HDD context is null", __func__);
638 return -1;
639 }
640
641 if (!pAvoidFreqList)
642 {
643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
644 "%s: pAvoidFreqList is null", __func__);
645 return -1;
646 }
647
648 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530649#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
650 NULL,
651#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800652 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530653 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800654 GFP_KERNEL);
655 if (!vendor_event)
656 {
657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
658 "%s: cfg80211_vendor_event_alloc failed", __func__);
659 return -1;
660 }
661
662 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
663 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
664
665 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
666
667 EXIT();
668 return 0;
669}
670#endif /* FEATURE_WLAN_CH_AVOID */
671
Srinivas Dasari030bad32015-02-18 23:23:54 +0530672/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530673 * define short names for the global vendor params
674 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
675 */
676#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
677
678/**
679 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
680 * hang reason
681 * @reason: cds recovery reason
682 *
683 * Return: Vendor specific reason code
684 */
685static enum qca_wlan_vendor_hang_reason
686hdd_convert_hang_reason(enum vos_hang_reason reason)
687{
688 unsigned int ret_val;
689
690 switch (reason) {
691 case VOS_GET_MSG_BUFF_FAILURE:
692 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
693 break;
694 case VOS_ACTIVE_LIST_TIMEOUT:
695 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
696 break;
697 case VOS_SCAN_REQ_EXPIRED:
698 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
699 break;
700 case VOS_TRANSMISSIONS_TIMEOUT:
701 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
702 break;
703 case VOS_DXE_FAILURE:
704 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
705 break;
706 case VOS_WDI_FAILURE:
707 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
708 break;
709 case VOS_REASON_UNSPECIFIED:
710 default:
711 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
712 }
713 return ret_val;
714}
715
716/**
717 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
718 * @hdd_ctx: Pointer to hdd context
719 * @reason: cds recovery reason
720 *
721 * Return: 0 on success or failure reason
722 */
723int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
724 enum vos_hang_reason reason)
725{
726 struct sk_buff *vendor_event;
727 enum qca_wlan_vendor_hang_reason hang_reason;
728
729 ENTER();
730
731 if (!hdd_ctx) {
732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 "HDD context is null");
734 return -EINVAL;
735 }
736
737 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
738#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
739 NULL,
740#endif
741 sizeof(unsigned int),
742 HANG_REASON_INDEX,
743 GFP_KERNEL);
744 if (!vendor_event) {
745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
746 "cfg80211_vendor_event_alloc failed");
747 return -ENOMEM;
748 }
749
750 hang_reason = hdd_convert_hang_reason(reason);
751
752 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
753 (unsigned int) hang_reason)) {
754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
755 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
756 kfree_skb(vendor_event);
757 return -EINVAL;
758 }
759
760 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
761
762 EXIT();
763 return 0;
764}
765#undef HANG_REASON_INDEX
766
767/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530768 * FUNCTION: __wlan_hdd_cfg80211_nan_request
769 * This is called when wlan driver needs to send vendor specific
770 * nan request event.
771 */
772static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
773 struct wireless_dev *wdev,
774 const void *data, int data_len)
775{
776 tNanRequestReq nan_req;
777 VOS_STATUS status;
778 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530779 struct net_device *dev = wdev->netdev;
780 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
781 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530782 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
783
784 if (0 == data_len)
785 {
786 hddLog(VOS_TRACE_LEVEL_ERROR,
787 FL("NAN - Invalid Request, length = 0"));
788 return ret_val;
789 }
790
791 if (NULL == data)
792 {
793 hddLog(VOS_TRACE_LEVEL_ERROR,
794 FL("NAN - Invalid Request, data is NULL"));
795 return ret_val;
796 }
797
798 status = wlan_hdd_validate_context(pHddCtx);
799 if (0 != status)
800 {
801 hddLog(VOS_TRACE_LEVEL_ERROR,
802 FL("HDD context is not valid"));
803 return -EINVAL;
804 }
805
806 hddLog(LOG1, FL("Received NAN command"));
807 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
808 (tANI_U8 *)data, data_len);
809
810 /* check the NAN Capability */
811 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
812 {
813 hddLog(VOS_TRACE_LEVEL_ERROR,
814 FL("NAN is not supported by Firmware"));
815 return -EINVAL;
816 }
817
818 nan_req.request_data_len = data_len;
819 nan_req.request_data = data;
820
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530821 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530822 if (VOS_STATUS_SUCCESS == status)
823 {
824 ret_val = 0;
825 }
826 return ret_val;
827}
828
829/*
830 * FUNCTION: wlan_hdd_cfg80211_nan_request
831 * Wrapper to protect the nan vendor command from ssr
832 */
833static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
834 struct wireless_dev *wdev,
835 const void *data, int data_len)
836{
837 int ret;
838
839 vos_ssr_protect(__func__);
840 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
841 vos_ssr_unprotect(__func__);
842
843 return ret;
844}
845
846/*
847 * FUNCTION: wlan_hdd_cfg80211_nan_callback
848 * This is a callback function and it gets called
849 * when we need to report nan response event to
850 * upper layers.
851 */
852static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
853{
854 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
855 struct sk_buff *vendor_event;
856 int status;
857 tSirNanEvent *data;
858
859 ENTER();
860 if (NULL == msg)
861 {
862 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
863 FL(" msg received here is null"));
864 return;
865 }
866 data = msg;
867
868 status = wlan_hdd_validate_context(pHddCtx);
869
870 if (0 != status)
871 {
872 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
873 FL("HDD context is not valid"));
874 return;
875 }
876
877 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
879 NULL,
880#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530881 data->event_data_len +
882 NLMSG_HDRLEN,
883 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
884 GFP_KERNEL);
885
886 if (!vendor_event)
887 {
888 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
889 FL("cfg80211_vendor_event_alloc failed"));
890 return;
891 }
892 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
893 data->event_data_len, data->event_data))
894 {
895 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
896 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
897 kfree_skb(vendor_event);
898 return;
899 }
900 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
901 EXIT();
902}
903
904/*
905 * FUNCTION: wlan_hdd_cfg80211_nan_init
906 * This function is called to register the callback to sme layer
907 */
908inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
909{
910 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
911}
912
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530913/*
914 * define short names for the global vendor params
915 * used by __wlan_hdd_cfg80211_get_station_cmd()
916 */
917#define STATION_INVALID \
918 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
919#define STATION_INFO \
920 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
921#define STATION_ASSOC_FAIL_REASON \
922 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530923#define STATION_REMOTE \
924 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530925#define STATION_MAX \
926 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
927
928static const struct nla_policy
929hdd_get_station_policy[STATION_MAX + 1] = {
930 [STATION_INFO] = {.type = NLA_FLAG},
931 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
932};
933
934/**
935 * hdd_get_station_assoc_fail() - Handle get station assoc fail
936 * @hdd_ctx: HDD context within host driver
937 * @wdev: wireless device
938 *
939 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
940 * Validate cmd attributes and send the station info to upper layers.
941 *
942 * Return: Success(0) or reason code for failure
943 */
944static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
945 hdd_adapter_t *adapter)
946{
947 struct sk_buff *skb = NULL;
948 uint32_t nl_buf_len;
949 hdd_station_ctx_t *hdd_sta_ctx;
950
951 nl_buf_len = NLMSG_HDRLEN;
952 nl_buf_len += sizeof(uint32_t);
953 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
954
955 if (!skb) {
956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
957 return -ENOMEM;
958 }
959
960 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
961
962 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
963 hdd_sta_ctx->conn_info.assoc_status_code)) {
964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
965 goto fail;
966 }
967 return cfg80211_vendor_cmd_reply(skb);
968fail:
969 if (skb)
970 kfree_skb(skb);
971 return -EINVAL;
972}
973
974/**
975 * hdd_map_auth_type() - transform auth type specific to
976 * vendor command
977 * @auth_type: csr auth type
978 *
979 * Return: Success(0) or reason code for failure
980 */
981static int hdd_convert_auth_type(uint32_t auth_type)
982{
983 uint32_t ret_val;
984
985 switch (auth_type) {
986 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
987 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
988 break;
989 case eCSR_AUTH_TYPE_SHARED_KEY:
990 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
991 break;
992 case eCSR_AUTH_TYPE_WPA:
993 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
994 break;
995 case eCSR_AUTH_TYPE_WPA_PSK:
996 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
997 break;
998 case eCSR_AUTH_TYPE_AUTOSWITCH:
999 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
1000 break;
1001 case eCSR_AUTH_TYPE_WPA_NONE:
1002 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
1003 break;
1004 case eCSR_AUTH_TYPE_RSN:
1005 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
1006 break;
1007 case eCSR_AUTH_TYPE_RSN_PSK:
1008 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
1009 break;
1010 case eCSR_AUTH_TYPE_FT_RSN:
1011 ret_val = QCA_WLAN_AUTH_TYPE_FT;
1012 break;
1013 case eCSR_AUTH_TYPE_FT_RSN_PSK:
1014 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
1015 break;
1016 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
1017 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1018 break;
1019 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1020 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1021 break;
1022#ifdef FEATURE_WLAN_ESE
1023 case eCSR_AUTH_TYPE_CCKM_WPA:
1024 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1025 break;
1026 case eCSR_AUTH_TYPE_CCKM_RSN:
1027 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1028 break;
1029#endif
1030 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1031 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1032 break;
1033 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1034 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1035 break;
1036 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1037 case eCSR_AUTH_TYPE_FAILED:
1038 case eCSR_AUTH_TYPE_NONE:
1039 default:
1040 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1041 break;
1042 }
1043 return ret_val;
1044}
1045
1046/**
1047 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1048 * vendor command
1049 * @dot11mode: dot11mode
1050 *
1051 * Return: Success(0) or reason code for failure
1052 */
1053static int hdd_convert_dot11mode(uint32_t dot11mode)
1054{
1055 uint32_t ret_val;
1056
1057 switch (dot11mode) {
1058 case eCSR_CFG_DOT11_MODE_11A:
1059 ret_val = QCA_WLAN_802_11_MODE_11A;
1060 break;
1061 case eCSR_CFG_DOT11_MODE_11B:
1062 ret_val = QCA_WLAN_802_11_MODE_11B;
1063 break;
1064 case eCSR_CFG_DOT11_MODE_11G:
1065 ret_val = QCA_WLAN_802_11_MODE_11G;
1066 break;
1067 case eCSR_CFG_DOT11_MODE_11N:
1068 ret_val = QCA_WLAN_802_11_MODE_11N;
1069 break;
1070 case eCSR_CFG_DOT11_MODE_11AC:
1071 ret_val = QCA_WLAN_802_11_MODE_11AC;
1072 break;
1073 case eCSR_CFG_DOT11_MODE_AUTO:
1074 case eCSR_CFG_DOT11_MODE_ABG:
1075 default:
1076 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1077 }
1078 return ret_val;
1079}
1080
1081/**
1082 * hdd_add_tx_bitrate() - add tx bitrate attribute
1083 * @skb: pointer to sk buff
1084 * @hdd_sta_ctx: pointer to hdd station context
1085 * @idx: attribute index
1086 *
1087 * Return: Success(0) or reason code for failure
1088 */
1089static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1090 hdd_station_ctx_t *hdd_sta_ctx,
1091 int idx)
1092{
1093 struct nlattr *nla_attr;
1094 uint32_t bitrate, bitrate_compat;
1095
1096 nla_attr = nla_nest_start(skb, idx);
1097 if (!nla_attr)
1098 goto fail;
1099 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301100 bitrate = cfg80211_calculate_bitrate(
1101 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301102
1103 /* report 16-bit bitrate only if we can */
1104 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1105 if (bitrate > 0 &&
1106 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1108 goto fail;
1109 }
1110 if (bitrate_compat > 0 &&
1111 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1113 goto fail;
1114 }
1115 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301116 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1118 goto fail;
1119 }
1120 nla_nest_end(skb, nla_attr);
1121 return 0;
1122fail:
1123 return -EINVAL;
1124}
1125
1126/**
1127 * hdd_add_sta_info() - add station info attribute
1128 * @skb: pointer to sk buff
1129 * @hdd_sta_ctx: pointer to hdd station context
1130 * @idx: attribute index
1131 *
1132 * Return: Success(0) or reason code for failure
1133 */
1134static int32_t hdd_add_sta_info(struct sk_buff *skb,
1135 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1136{
1137 struct nlattr *nla_attr;
1138
1139 nla_attr = nla_nest_start(skb, idx);
1140 if (!nla_attr)
1141 goto fail;
1142 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301143 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301144 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1145 goto fail;
1146 }
1147 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1148 goto fail;
1149 nla_nest_end(skb, nla_attr);
1150 return 0;
1151fail:
1152 return -EINVAL;
1153}
1154
1155/**
1156 * hdd_add_survey_info() - add survey info attribute
1157 * @skb: pointer to sk buff
1158 * @hdd_sta_ctx: pointer to hdd station context
1159 * @idx: attribute index
1160 *
1161 * Return: Success(0) or reason code for failure
1162 */
1163static int32_t hdd_add_survey_info(struct sk_buff *skb,
1164 hdd_station_ctx_t *hdd_sta_ctx,
1165 int idx)
1166{
1167 struct nlattr *nla_attr;
1168
1169 nla_attr = nla_nest_start(skb, idx);
1170 if (!nla_attr)
1171 goto fail;
1172 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301173 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301174 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301175 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1177 goto fail;
1178 }
1179 nla_nest_end(skb, nla_attr);
1180 return 0;
1181fail:
1182 return -EINVAL;
1183}
1184
1185/**
1186 * hdd_add_link_standard_info() - add link info attribute
1187 * @skb: pointer to sk buff
1188 * @hdd_sta_ctx: pointer to hdd station context
1189 * @idx: attribute index
1190 *
1191 * Return: Success(0) or reason code for failure
1192 */
1193static int32_t
1194hdd_add_link_standard_info(struct sk_buff *skb,
1195 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1196{
1197 struct nlattr *nla_attr;
1198
1199 nla_attr = nla_nest_start(skb, idx);
1200 if (!nla_attr)
1201 goto fail;
1202 if (nla_put(skb,
1203 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301204 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1205 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301206 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1207 goto fail;
1208 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301209 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1210 hdd_sta_ctx->cache_conn_info.bssId))
1211 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301212 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1213 goto fail;
1214 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1215 goto fail;
1216 nla_nest_end(skb, nla_attr);
1217 return 0;
1218fail:
1219 return -EINVAL;
1220}
1221
1222/**
1223 * hdd_add_ap_standard_info() - add ap info attribute
1224 * @skb: pointer to sk buff
1225 * @hdd_sta_ctx: pointer to hdd station context
1226 * @idx: attribute index
1227 *
1228 * Return: Success(0) or reason code for failure
1229 */
1230static int32_t
1231hdd_add_ap_standard_info(struct sk_buff *skb,
1232 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1233{
1234 struct nlattr *nla_attr;
1235
1236 nla_attr = nla_nest_start(skb, idx);
1237 if (!nla_attr)
1238 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301239 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301240 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301241 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1242 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1244 goto fail;
1245 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301246 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301247 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301248 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1249 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1251 goto fail;
1252 }
1253 nla_nest_end(skb, nla_attr);
1254 return 0;
1255fail:
1256 return -EINVAL;
1257}
1258
1259/**
1260 * hdd_get_station_info() - send BSS information to supplicant
1261 * @hdd_ctx: pointer to hdd context
1262 * @adapter: pointer to adapter
1263 *
1264 * Return: 0 if success else error status
1265 */
1266static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1267 hdd_adapter_t *adapter)
1268{
1269 struct sk_buff *skb = NULL;
1270 uint8_t *tmp_hs20 = NULL;
1271 uint32_t nl_buf_len;
1272 hdd_station_ctx_t *hdd_sta_ctx;
1273
1274 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1275
1276 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301277
1278 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1279 VOS_MAC_ADDR_SIZE +
1280 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1281 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1282 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301283 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301284 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1285 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1286 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1287 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1288 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1289 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1290 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1291 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1292 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1293 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1294 cache_conn_info.hs20vendor_ie);
1295 nl_buf_len +=
1296 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301297 1);
1298 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301299 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1300 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1301 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1302 nl_buf_len +=
1303 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301304
1305
1306 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1307 if (!skb) {
1308 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1309 __func__, __LINE__);
1310 return -ENOMEM;
1311 }
1312
1313 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1314 LINK_INFO_STANDARD_NL80211_ATTR)) {
1315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1316 goto fail;
1317 }
1318 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1319 AP_INFO_STANDARD_NL80211_ATTR)) {
1320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1321 goto fail;
1322 }
1323 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301324 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301325 nla_put_u32(skb, INFO_AKM,
1326 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301327 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301328 nla_put_u32(skb, WLAN802_11_MODE,
1329 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301330 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1332 goto fail;
1333 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301334 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301335 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301336 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1337 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1339 goto fail;
1340 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301341 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301342 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301343 (sizeof(hdd_sta_ctx->
1344 cache_conn_info.vht_operation)),
1345 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1347 goto fail;
1348 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301349 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301350 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301351 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1352 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1354 goto fail;
1355 }
1356
1357 return cfg80211_vendor_cmd_reply(skb);
1358fail:
1359 if (skb)
1360 kfree_skb(skb);
1361 return -EINVAL;
1362}
1363
1364/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301365 * hdd_add_survey_info_sap_get_len - get data length used in
1366 * hdd_add_survey_info_sap()
1367 *
1368 * This function calculates the data length used in hdd_add_survey_info_sap()
1369 *
1370 * Return: total data length used in hdd_add_survey_info_sap()
1371 */
1372static uint32_t hdd_add_survey_info_sap_get_len(void)
1373{
1374 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1375}
1376
1377/**
1378 * hdd_add_survey_info - add survey info attribute
1379 * @skb: pointer to response skb buffer
1380 * @stainfo: station information
1381 * @idx: attribute type index for nla_next_start()
1382 *
1383 * This function adds survey info attribute to response skb buffer
1384 *
1385 * Return : 0 on success and errno on failure
1386 */
1387static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1388 struct hdd_cache_sta_info *stainfo,
1389 int idx)
1390{
1391 struct nlattr *nla_attr;
1392
1393 nla_attr = nla_nest_start(skb, idx);
1394 if (!nla_attr)
1395 goto fail;
1396 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1397 stainfo->freq)) {
1398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1399 FL("put fail"));
1400 goto fail;
1401 }
1402 nla_nest_end(skb, nla_attr);
1403 return 0;
1404fail:
1405 return -EINVAL;
1406}
1407
1408/**
1409 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1410 * hdd_add_tx_bitrate_sap()
1411 *
1412 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1413 *
1414 * Return: total data length used in hdd_add_tx_bitrate_sap()
1415 */
1416static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1417{
1418 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1419}
1420
1421/**
1422 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1423 * @skb: pointer to response skb buffer
1424 * @stainfo: station information
1425 * @idx: attribute type index for nla_next_start()
1426 *
1427 * This function adds vht nss attribute to response skb buffer
1428 *
1429 * Return : 0 on success and errno on failure
1430 */
1431static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1432 struct hdd_cache_sta_info *stainfo,
1433 int idx)
1434{
1435 struct nlattr *nla_attr;
1436
1437 nla_attr = nla_nest_start(skb, idx);
1438 if (!nla_attr)
1439 goto fail;
1440
1441 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1442 stainfo->nss)) {
1443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1444 FL("put fail"));
1445 goto fail;
1446 }
1447 nla_nest_end(skb, nla_attr);
1448 return 0;
1449fail:
1450 return -EINVAL;
1451}
1452
1453/**
1454 * hdd_add_sta_info_sap_get_len - get data length used in
1455 * hdd_add_sta_info_sap()
1456 *
1457 * This function calculates the data length used in hdd_add_sta_info_sap()
1458 *
1459 * Return: total data length used in hdd_add_sta_info_sap()
1460 */
1461static uint32_t hdd_add_sta_info_sap_get_len(void)
1462{
1463 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1464 hdd_add_tx_bitrate_sap_get_len());
1465}
1466
1467/**
1468 * hdd_add_sta_info_sap - add sta signal info attribute
1469 * @skb: pointer to response skb buffer
1470 * @rssi: peer rssi value
1471 * @stainfo: station information
1472 * @idx: attribute type index for nla_next_start()
1473 *
1474 * This function adds sta signal attribute to response skb buffer
1475 *
1476 * Return : 0 on success and errno on failure
1477 */
1478static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1479 struct hdd_cache_sta_info *stainfo, int idx)
1480{
1481 struct nlattr *nla_attr;
1482
1483 nla_attr = nla_nest_start(skb, idx);
1484 if (!nla_attr)
1485 goto fail;
1486
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301487 /* upperlayer expects positive rssi value */
1488 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1490 FL("put fail"));
1491 goto fail;
1492 }
1493 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1494 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1495 FL("put fail"));
1496 goto fail;
1497 }
1498
1499 nla_nest_end(skb, nla_attr);
1500 return 0;
1501fail:
1502 return -EINVAL;
1503}
1504
1505/**
1506 * hdd_add_link_standard_info_sap_get_len - get data length used in
1507 * hdd_add_link_standard_info_sap()
1508 *
1509 * This function calculates the data length used in
1510 * hdd_add_link_standard_info_sap()
1511 *
1512 * Return: total data length used in hdd_add_link_standard_info_sap()
1513 */
1514static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1515{
1516 return ((NLA_HDRLEN) +
1517 hdd_add_survey_info_sap_get_len() +
1518 hdd_add_sta_info_sap_get_len() +
1519 (sizeof(uint32_t) + NLA_HDRLEN));
1520}
1521
1522/**
1523 * hdd_add_link_standard_info_sap - add add link info attribut
1524 * @skb: pointer to response skb buffer
1525 * @stainfo: station information
1526 * @idx: attribute type index for nla_next_start()
1527 *
1528 * This function adds link info attribut to response skb buffer
1529 *
1530 * Return : 0 on success and errno on failure
1531 */
1532static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1533 struct hdd_cache_sta_info *stainfo,
1534 int idx)
1535{
1536 struct nlattr *nla_attr;
1537
1538 nla_attr = nla_nest_start(skb, idx);
1539 if (!nla_attr)
1540 goto fail;
1541 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1542 goto fail;
1543 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1544 goto fail;
1545
1546 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1547 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1548 FL("put fail"));
1549 goto fail;
1550 }
1551
1552 nla_nest_end(skb, nla_attr);
1553 return 0;
1554fail:
1555 return -EINVAL;
1556}
1557
1558/**
1559 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1560 * hdd_add_ap_standard_info_sap()
1561 * @stainfo: station information
1562 *
1563 * This function calculates the data length used in
1564 * hdd_add_ap_standard_info_sap()
1565 *
1566 * Return: total data length used in hdd_add_ap_standard_info_sap()
1567 */
1568static uint32_t hdd_add_ap_standard_info_sap_get_len(
1569 struct hdd_cache_sta_info *stainfo)
1570{
1571 uint32_t len;
1572
1573 len = NLA_HDRLEN;
1574 if (stainfo->vht_present)
1575 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1576 if (stainfo->ht_present)
1577 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1578
1579 return len;
1580}
1581
1582/**
1583 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1584 * @skb: pointer to response skb buffer
1585 * @stainfo: station information
1586 * @idx: attribute type index for nla_next_start()
1587 *
1588 * This function adds HT and VHT info attributes to response skb buffer
1589 *
1590 * Return : 0 on success and errno on failure
1591 */
1592static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1593 struct hdd_cache_sta_info *stainfo,
1594 int idx)
1595{
1596 struct nlattr *nla_attr;
1597
1598 nla_attr = nla_nest_start(skb, idx);
1599 if (!nla_attr)
1600 goto fail;
1601
1602 if (stainfo->vht_present) {
1603 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1604 sizeof(stainfo->vht_caps),
1605 &stainfo->vht_caps)) {
1606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1607 FL("put fail"));
1608 goto fail;
1609 }
1610 }
1611 if (stainfo->ht_present) {
1612 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1613 sizeof(stainfo->ht_caps),
1614 &stainfo->ht_caps)) {
1615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1616 FL("put fail"));
1617 goto fail;
1618 }
1619 }
1620 nla_nest_end(skb, nla_attr);
1621 return 0;
1622fail:
1623 return -EINVAL;
1624}
1625
1626/**
1627 * hdd_decode_ch_width - decode channel band width based
1628 * @ch_width: encoded enum value holding channel band width
1629 *
1630 * This function decodes channel band width from the given encoded enum value.
1631 *
1632 * Returns: decoded channel band width.
1633 */
1634static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1635{
1636 switch (ch_width) {
1637 case 0:
1638 return 20;
1639 case 1:
1640 return 40;
1641 case 2:
1642 return 80;
1643 default:
1644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1645 "invalid enum: %d", ch_width);
1646 return 20;
1647 }
1648}
1649
1650/**
1651 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1652 * @hdd_ctx: hdd context
1653 * @adapter: hostapd interface
1654 * @mac_addr: mac address of requested peer
1655 *
1656 * This function collect and indicate the cached(deleted) peer's info
1657 *
1658 * Return: 0 on success, otherwise error value
1659 */
1660static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1661 hdd_adapter_t *adapter,
1662 v_MACADDR_t mac_addr)
1663{
1664 struct hdd_cache_sta_info *stainfo;
1665 struct sk_buff *skb = NULL;
1666 uint32_t nl_buf_len;
1667 uint8_t cw;
1668 ptSapContext sap_ctx;
1669 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1670
1671 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1672 if(sap_ctx == NULL){
1673 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1674 FL("psapCtx is NULL"));
1675 return -ENOENT;
1676 }
1677
1678 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1679 mac_addr.bytes);
1680 if (!stainfo) {
1681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1682 "peer " MAC_ADDRESS_STR " not found",
1683 MAC_ADDR_ARRAY(mac_addr.bytes));
1684 return -EINVAL;
1685 }
Bala Venkatesha3fe9262019-08-14 11:36:53 +05301686 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE &&
1687 !sap_ctx->aStaInfo[stainfo->ucSTAId].isDeauthInProgress) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1689 "peer " MAC_ADDRESS_STR " is in connected state",
1690 MAC_ADDR_ARRAY(mac_addr.bytes));
1691 return -EINVAL;
1692 }
1693
1694
1695 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1696 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1697 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1698 (sizeof(cw) + NLA_HDRLEN) +
1699 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1700
1701 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1702 if (!skb) {
1703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1704 return -ENOMEM;
1705 }
1706
1707 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1708 LINK_INFO_STANDARD_NL80211_ATTR)) {
1709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1710 goto fail;
1711 }
1712
1713 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1714 AP_INFO_STANDARD_NL80211_ATTR)) {
1715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1716 goto fail;
1717 }
1718
1719 /* upper layer expects decoded channel BW */
1720 cw = hdd_decode_ch_width(stainfo->ch_width);
1721 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1722 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1724 goto fail;
1725 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301726 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1728 goto fail;
1729 }
1730
1731 vos_mem_zero(stainfo, sizeof(*stainfo));
1732
1733 return cfg80211_vendor_cmd_reply(skb);
1734fail:
1735 if (skb)
1736 kfree_skb(skb);
1737
1738 return -EINVAL;
1739}
1740
1741/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301742 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1743 * @wiphy: corestack handler
1744 * @wdev: wireless device
1745 * @data: data
1746 * @data_len: data length
1747 *
1748 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1749 * Validate cmd attributes and send the station info to upper layers.
1750 *
1751 * Return: Success(0) or reason code for failure
1752 */
1753static int32_t
1754__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1755 struct wireless_dev *wdev,
1756 const void *data,
1757 int data_len)
1758{
1759 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1760 struct net_device *dev = wdev->netdev;
1761 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1762 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1763 int32_t status;
1764
1765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1766 if (VOS_FTM_MODE == hdd_get_conparam()) {
1767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1768 status = -EPERM;
1769 goto out;
1770 }
1771
1772 status = wlan_hdd_validate_context(hdd_ctx);
1773 if (0 != status)
1774 goto out;
1775
1776
1777 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1778 data, data_len, NULL);
1779 if (status) {
1780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1781 goto out;
1782 }
1783
1784 /* Parse and fetch Command Type*/
1785 if (tb[STATION_INFO]) {
1786 status = hdd_get_station_info(hdd_ctx, adapter);
1787 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1788 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301789 } else if (tb[STATION_REMOTE]) {
1790 v_MACADDR_t mac_addr;
1791
1792 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1793 adapter->device_mode != WLAN_HDD_P2P_GO) {
1794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1795 adapter->device_mode);
1796 status = -EINVAL;
1797 goto out;
1798 }
1799
1800 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1801 VOS_MAC_ADDRESS_LEN);
1802
1803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1804 MAC_ADDR_ARRAY(mac_addr.bytes));
1805
1806 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1807 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301808 } else {
1809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1810 status = -EINVAL;
1811 goto out;
1812 }
1813 EXIT();
1814out:
1815 return status;
1816}
1817
1818/**
1819 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1820 * @wiphy: corestack handler
1821 * @wdev: wireless device
1822 * @data: data
1823 * @data_len: data length
1824 *
1825 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1826 * Validate cmd attributes and send the station info to upper layers.
1827 *
1828 * Return: Success(0) or reason code for failure
1829 */
1830static int32_t
1831hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1832 struct wireless_dev *wdev,
1833 const void *data,
1834 int data_len)
1835{
1836 int ret;
1837
1838 vos_ssr_protect(__func__);
1839 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1840 vos_ssr_unprotect(__func__);
1841
1842 return ret;
1843}
1844
1845/*
1846 * undef short names defined for get station command
1847 * used by __wlan_hdd_cfg80211_get_station_cmd()
1848 */
1849#undef STATION_INVALID
1850#undef STATION_INFO
1851#undef STATION_ASSOC_FAIL_REASON
1852#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301853
Sunil Duttc69bccb2014-05-26 21:30:20 +05301854#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1855
1856static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1857 struct sk_buff *vendor_event)
1858{
1859 if (nla_put_u8(vendor_event,
1860 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1861 stats->rate.preamble) ||
1862 nla_put_u8(vendor_event,
1863 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1864 stats->rate.nss) ||
1865 nla_put_u8(vendor_event,
1866 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1867 stats->rate.bw) ||
1868 nla_put_u8(vendor_event,
1869 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1870 stats->rate.rateMcsIdx) ||
1871 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1872 stats->rate.bitrate ) ||
1873 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1874 stats->txMpdu ) ||
1875 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1876 stats->rxMpdu ) ||
1877 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1878 stats->mpduLost ) ||
1879 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1880 stats->retries) ||
1881 nla_put_u32(vendor_event,
1882 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1883 stats->retriesShort ) ||
1884 nla_put_u32(vendor_event,
1885 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1886 stats->retriesLong))
1887 {
1888 hddLog(VOS_TRACE_LEVEL_ERROR,
1889 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1890 return FALSE;
1891 }
1892 return TRUE;
1893}
1894
1895static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1896 struct sk_buff *vendor_event)
1897{
1898 u32 i = 0;
1899 struct nlattr *rateInfo;
1900 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1901 stats->type) ||
1902 nla_put(vendor_event,
1903 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1904 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1905 nla_put_u32(vendor_event,
1906 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1907 stats->capabilities) ||
1908 nla_put_u32(vendor_event,
1909 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1910 stats->numRate))
1911 {
1912 hddLog(VOS_TRACE_LEVEL_ERROR,
1913 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1914 goto error;
1915 }
1916
1917 rateInfo = nla_nest_start(vendor_event,
1918 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301919 if(!rateInfo)
1920 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301921 for (i = 0; i < stats->numRate; i++)
1922 {
1923 struct nlattr *rates;
1924 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1925 stats->rateStats +
1926 (i * sizeof(tSirWifiRateStat)));
1927 rates = nla_nest_start(vendor_event, i);
Sourav Mohapatra37aa80a2018-10-31 10:57:00 +05301928
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301929 if(!rates)
1930 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301931
1932 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1933 {
1934 hddLog(VOS_TRACE_LEVEL_ERROR,
1935 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1936 return FALSE;
1937 }
1938 nla_nest_end(vendor_event, rates);
1939 }
1940 nla_nest_end(vendor_event, rateInfo);
1941
1942 return TRUE;
1943error:
1944 return FALSE;
1945}
1946
1947static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1948 struct sk_buff *vendor_event)
1949{
1950 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1951 stats->ac ) ||
1952 nla_put_u32(vendor_event,
1953 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1954 stats->txMpdu ) ||
1955 nla_put_u32(vendor_event,
1956 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1957 stats->rxMpdu ) ||
1958 nla_put_u32(vendor_event,
1959 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1960 stats->txMcast ) ||
1961 nla_put_u32(vendor_event,
1962 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1963 stats->rxMcast ) ||
1964 nla_put_u32(vendor_event,
1965 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1966 stats->rxAmpdu ) ||
1967 nla_put_u32(vendor_event,
1968 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1969 stats->txAmpdu ) ||
1970 nla_put_u32(vendor_event,
1971 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1972 stats->mpduLost )||
1973 nla_put_u32(vendor_event,
1974 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1975 stats->retries ) ||
1976 nla_put_u32(vendor_event,
1977 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1978 stats->retriesShort ) ||
1979 nla_put_u32(vendor_event,
1980 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1981 stats->retriesLong ) ||
1982 nla_put_u32(vendor_event,
1983 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1984 stats->contentionTimeMin ) ||
1985 nla_put_u32(vendor_event,
1986 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1987 stats->contentionTimeMax ) ||
1988 nla_put_u32(vendor_event,
1989 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1990 stats->contentionTimeAvg ) ||
1991 nla_put_u32(vendor_event,
1992 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1993 stats->contentionNumSamples ))
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR,
1996 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1997 return FALSE;
1998 }
1999 return TRUE;
2000}
2001
2002static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
2003 struct sk_buff *vendor_event)
2004{
Dino Myclec8f3f332014-07-21 16:48:27 +05302005 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
2007 nla_put(vendor_event,
2008 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
2009 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
2010 nla_put_u32(vendor_event,
2011 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
2012 stats->state ) ||
2013 nla_put_u32(vendor_event,
2014 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
2015 stats->roaming ) ||
2016 nla_put_u32(vendor_event,
2017 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
2018 stats->capabilities ) ||
2019 nla_put(vendor_event,
2020 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2021 strlen(stats->ssid), stats->ssid) ||
2022 nla_put(vendor_event,
2023 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2024 WNI_CFG_BSSID_LEN, stats->bssid) ||
2025 nla_put(vendor_event,
2026 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2027 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2028 nla_put(vendor_event,
2029 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2030 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2031 )
2032 {
2033 hddLog(VOS_TRACE_LEVEL_ERROR,
2034 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2035 return FALSE;
2036 }
2037 return TRUE;
2038}
2039
Dino Mycle3b9536d2014-07-09 22:05:24 +05302040static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2041 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302042 struct sk_buff *vendor_event)
2043{
2044 int i = 0;
2045 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302046 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2047 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302048 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302049
Sunil Duttc69bccb2014-05-26 21:30:20 +05302050 if (FALSE == put_wifi_interface_info(
2051 &pWifiIfaceStat->info,
2052 vendor_event))
2053 {
2054 hddLog(VOS_TRACE_LEVEL_ERROR,
2055 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2056 return FALSE;
2057
2058 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302059 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2060 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2061 if (NULL == pWifiIfaceStatTL)
2062 {
2063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2064 return FALSE;
2065 }
2066
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302067 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2068 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2069 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2070 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2071
2072 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2073 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2074 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2075 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302076
2077 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2078 {
2079 if (VOS_STATUS_SUCCESS ==
2080 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2081 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2082 {
2083 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2084 * obtained from TL structure
2085 */
2086
2087 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2088 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302089 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2090
Srinivas Dasari98947432014-11-07 19:41:24 +05302091 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2092 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2093 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2094 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2095 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2096 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2097 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2098 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302099
Srinivas Dasari98947432014-11-07 19:41:24 +05302100 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2101 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2102 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2103 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2104 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2105 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2106 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2107 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302108
Srinivas Dasari98947432014-11-07 19:41:24 +05302109 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2110 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2111 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2112 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2113 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2114 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2115 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2116 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302117 }
2118 else
2119 {
2120 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2121 }
2122
Dino Mycle3b9536d2014-07-09 22:05:24 +05302123 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2124 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2125 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2126 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2127 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2128 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2129 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2130 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2131 }
2132 else
2133 {
2134 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2135 }
2136
2137
Sunil Duttc69bccb2014-05-26 21:30:20 +05302138
2139 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302140 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2141 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2142 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302143 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2144 pWifiIfaceStat->beaconRx) ||
2145 nla_put_u32(vendor_event,
2146 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2147 pWifiIfaceStat->mgmtRx) ||
2148 nla_put_u32(vendor_event,
2149 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2150 pWifiIfaceStat->mgmtActionRx) ||
2151 nla_put_u32(vendor_event,
2152 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2153 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302154 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302155 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2156 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302157 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302158 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2159 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302160 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302161 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2162 pWifiIfaceStat->rssiAck))
2163 {
2164 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302165 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2166 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302167 return FALSE;
2168 }
2169
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302170#ifdef FEATURE_EXT_LL_STAT
2171 /*
2172 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2173 * then host should send Leaky AP stats to upper layer,
2174 * otherwise no need to send these stats.
2175 */
2176 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2177 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2178 )
2179 {
2180 hddLog(VOS_TRACE_LEVEL_INFO,
2181 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2182 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2183 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2184 pWifiIfaceStat->leakyApStat.rx_leak_window,
2185 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2186 if (nla_put_u32(vendor_event,
2187 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2188 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2189 nla_put_u32(vendor_event,
2190 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2191 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2192 nla_put_u32(vendor_event,
2193 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2194 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302195 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302196 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2197 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2198 {
2199 hddLog(VOS_TRACE_LEVEL_ERROR,
2200 FL("EXT_LL_STAT put fail"));
2201 vos_mem_free(pWifiIfaceStatTL);
2202 return FALSE;
2203 }
2204 }
2205#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302206 wmmInfo = nla_nest_start(vendor_event,
2207 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302208 if(!wmmInfo)
2209 {
2210 vos_mem_free(pWifiIfaceStatTL);
2211 return FALSE;
2212 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302213 for (i = 0; i < WIFI_AC_MAX; i++)
2214 {
2215 struct nlattr *wmmStats;
2216 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302217 if(!wmmStats)
2218 {
2219 vos_mem_free(pWifiIfaceStatTL);
2220 return FALSE;
2221 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302222 if (FALSE == put_wifi_wmm_ac_stat(
2223 &pWifiIfaceStat->AccessclassStats[i],
2224 vendor_event))
2225 {
2226 hddLog(VOS_TRACE_LEVEL_ERROR,
2227 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302228 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302229 return FALSE;
2230 }
2231
2232 nla_nest_end(vendor_event, wmmStats);
2233 }
2234 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302235 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302236 return TRUE;
2237}
2238
2239static tSirWifiInterfaceMode
2240 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2241{
2242 switch (deviceMode)
2243 {
2244 case WLAN_HDD_INFRA_STATION:
2245 return WIFI_INTERFACE_STA;
2246 case WLAN_HDD_SOFTAP:
2247 return WIFI_INTERFACE_SOFTAP;
2248 case WLAN_HDD_P2P_CLIENT:
2249 return WIFI_INTERFACE_P2P_CLIENT;
2250 case WLAN_HDD_P2P_GO:
2251 return WIFI_INTERFACE_P2P_GO;
2252 case WLAN_HDD_IBSS:
2253 return WIFI_INTERFACE_IBSS;
2254 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302255 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302256 }
2257}
2258
2259static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2260 tpSirWifiInterfaceInfo pInfo)
2261{
2262 v_U8_t *staMac = NULL;
2263 hdd_station_ctx_t *pHddStaCtx;
2264 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2265 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2266
2267 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2268
2269 vos_mem_copy(pInfo->macAddr,
2270 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2271
2272 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2273 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2274 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2275 {
2276 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2277 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2278 {
2279 pInfo->state = WIFI_DISCONNECTED;
2280 }
2281 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2282 {
2283 hddLog(VOS_TRACE_LEVEL_ERROR,
2284 "%s: Session ID %d, Connection is in progress", __func__,
2285 pAdapter->sessionId);
2286 pInfo->state = WIFI_ASSOCIATING;
2287 }
2288 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2289 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2290 {
2291 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2292 hddLog(VOS_TRACE_LEVEL_ERROR,
2293 "%s: client " MAC_ADDRESS_STR
2294 " is in the middle of WPS/EAPOL exchange.", __func__,
2295 MAC_ADDR_ARRAY(staMac));
2296 pInfo->state = WIFI_AUTHENTICATING;
2297 }
2298 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2299 {
2300 pInfo->state = WIFI_ASSOCIATED;
2301 vos_mem_copy(pInfo->bssid,
2302 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2303 vos_mem_copy(pInfo->ssid,
2304 pHddStaCtx->conn_info.SSID.SSID.ssId,
2305 pHddStaCtx->conn_info.SSID.SSID.length);
2306 //NULL Terminate the string.
2307 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2308 }
2309 }
2310 vos_mem_copy(pInfo->countryStr,
2311 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2312
2313 vos_mem_copy(pInfo->apCountryStr,
2314 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2315
2316 return TRUE;
2317}
2318
2319/*
2320 * hdd_link_layer_process_peer_stats () - This function is called after
2321 * receiving Link Layer Peer statistics from FW.This function converts
2322 * the firmware data to the NL data and sends the same to the kernel/upper
2323 * layers.
2324 */
2325static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2326 v_VOID_t *pData)
2327{
2328 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302329 tpSirWifiPeerStat pWifiPeerStat;
2330 tpSirWifiPeerInfo pWifiPeerInfo;
2331 struct nlattr *peerInfo;
2332 struct sk_buff *vendor_event;
2333 int status, i;
2334
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302335 ENTER();
2336
Sunil Duttc69bccb2014-05-26 21:30:20 +05302337 status = wlan_hdd_validate_context(pHddCtx);
2338 if (0 != status)
2339 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302340 return;
2341 }
2342
2343 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2344
2345 hddLog(VOS_TRACE_LEVEL_INFO,
2346 "LL_STATS_PEER_ALL : numPeers %u",
2347 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302348 /*
2349 * Allocate a size of 4096 for the peer stats comprising
2350 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2351 * sizeof (tSirWifiRateStat).Each field is put with an
2352 * NL attribute.The size of 4096 is considered assuming
2353 * that number of rates shall not exceed beyond 50 with
2354 * the sizeof (tSirWifiRateStat) being 32.
2355 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302356 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2357 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302358 if (!vendor_event)
2359 {
2360 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302361 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302362 __func__);
2363 return;
2364 }
2365 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302366 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2367 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2368 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302369 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2370 pWifiPeerStat->numPeers))
2371 {
2372 hddLog(VOS_TRACE_LEVEL_ERROR,
2373 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2374 kfree_skb(vendor_event);
2375 return;
2376 }
2377
2378 peerInfo = nla_nest_start(vendor_event,
2379 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302380 if(!peerInfo)
2381 {
2382 hddLog(VOS_TRACE_LEVEL_ERROR,
2383 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2384 __func__);
2385 kfree_skb(vendor_event);
2386 return;
2387 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302388
2389 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2390 pWifiPeerStat->peerInfo);
2391
2392 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2393 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302394 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302395 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302396
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302397 if(!peers)
2398 {
2399 hddLog(VOS_TRACE_LEVEL_ERROR,
2400 "%s: peer stats put fail",
2401 __func__);
2402 kfree_skb(vendor_event);
2403 return;
2404 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302405 if (FALSE == put_wifi_peer_info(
2406 pWifiPeerInfo, vendor_event))
2407 {
2408 hddLog(VOS_TRACE_LEVEL_ERROR,
2409 "%s: put_wifi_peer_info put fail", __func__);
2410 kfree_skb(vendor_event);
2411 return;
2412 }
2413
Sourav Mohapatra37aa80a2018-10-31 10:57:00 +05302414 pWifiPeerInfo = (tpSirWifiPeerInfo)((uint8 *)pWifiPeerInfo +
2415 (sizeof(tSirWifiPeerInfo) - sizeof(tSirWifiRateStat)) +
2416 (numRate * sizeof(tSirWifiRateStat)));
2417
Sunil Duttc69bccb2014-05-26 21:30:20 +05302418 nla_nest_end(vendor_event, peers);
2419 }
2420 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302421 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302422 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302423}
2424
2425/*
2426 * hdd_link_layer_process_iface_stats () - This function is called after
2427 * receiving Link Layer Interface statistics from FW.This function converts
2428 * the firmware data to the NL data and sends the same to the kernel/upper
2429 * layers.
2430 */
2431static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2432 v_VOID_t *pData)
2433{
2434 tpSirWifiIfaceStat pWifiIfaceStat;
2435 struct sk_buff *vendor_event;
2436 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2437 int status;
2438
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302439 ENTER();
2440
Sunil Duttc69bccb2014-05-26 21:30:20 +05302441 status = wlan_hdd_validate_context(pHddCtx);
2442 if (0 != status)
2443 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302444 return;
2445 }
2446 /*
2447 * Allocate a size of 4096 for the interface stats comprising
2448 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2449 * assuming that all these fit with in the limit.Please take
2450 * a call on the limit based on the data requirements on
2451 * interface statistics.
2452 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302453 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2454 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302455 if (!vendor_event)
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302458 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302459 return;
2460 }
2461
2462 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2463
Dino Mycle3b9536d2014-07-09 22:05:24 +05302464
2465 if (FALSE == hdd_get_interface_info( pAdapter,
2466 &pWifiIfaceStat->info))
2467 {
2468 hddLog(VOS_TRACE_LEVEL_ERROR,
2469 FL("hdd_get_interface_info get fail") );
2470 kfree_skb(vendor_event);
2471 return;
2472 }
2473
2474 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2475 vendor_event))
2476 {
2477 hddLog(VOS_TRACE_LEVEL_ERROR,
2478 FL("put_wifi_iface_stats fail") );
2479 kfree_skb(vendor_event);
2480 return;
2481 }
2482
Sunil Duttc69bccb2014-05-26 21:30:20 +05302483 hddLog(VOS_TRACE_LEVEL_INFO,
2484 "WMI_LINK_STATS_IFACE Data");
2485
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302486 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302487
2488 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302489}
2490
2491/*
2492 * hdd_link_layer_process_radio_stats () - This function is called after
2493 * receiving Link Layer Radio statistics from FW.This function converts
2494 * the firmware data to the NL data and sends the same to the kernel/upper
2495 * layers.
2496 */
2497static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2498 v_VOID_t *pData)
2499{
2500 int status, i;
2501 tpSirWifiRadioStat pWifiRadioStat;
2502 tpSirWifiChannelStats pWifiChannelStats;
2503 struct sk_buff *vendor_event;
2504 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2505 struct nlattr *chList;
2506
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302507 ENTER();
2508
Sunil Duttc69bccb2014-05-26 21:30:20 +05302509 status = wlan_hdd_validate_context(pHddCtx);
2510 if (0 != status)
2511 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302512 return;
2513 }
2514 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2515
2516 hddLog(VOS_TRACE_LEVEL_INFO,
2517 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302518 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302519 " radio is %d onTime is %u "
2520 " txTime is %u rxTime is %u "
2521 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302522 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302523 " onTimePnoScan is %u onTimeHs20 is %u "
2524 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302525 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302526 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2527 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2528 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302529 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302530 pWifiRadioStat->onTimeRoamScan,
2531 pWifiRadioStat->onTimePnoScan,
2532 pWifiRadioStat->onTimeHs20,
2533 pWifiRadioStat->numChannels);
2534 /*
2535 * Allocate a size of 4096 for the Radio stats comprising
2536 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2537 * (tSirWifiChannelStats).Each channel data is put with an
2538 * NL attribute.The size of 4096 is considered assuming that
2539 * number of channels shall not exceed beyond 60 with the
2540 * sizeof (tSirWifiChannelStats) being 24 bytes.
2541 */
2542
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302543 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2544 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302545 if (!vendor_event)
2546 {
2547 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302548 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302549 return;
2550 }
2551
2552 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302553 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2554 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2555 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302556 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2557 pWifiRadioStat->radio) ||
2558 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302559 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2560 NUM_RADIOS) ||
2561 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302562 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2563 pWifiRadioStat->onTime) ||
2564 nla_put_u32(vendor_event,
2565 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2566 pWifiRadioStat->txTime) ||
2567 nla_put_u32(vendor_event,
2568 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2569 pWifiRadioStat->rxTime) ||
2570 nla_put_u32(vendor_event,
2571 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2572 pWifiRadioStat->onTimeScan) ||
2573 nla_put_u32(vendor_event,
2574 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2575 pWifiRadioStat->onTimeNbd) ||
2576 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302577 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2578 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302579 nla_put_u32(vendor_event,
2580 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2581 pWifiRadioStat->onTimeRoamScan) ||
2582 nla_put_u32(vendor_event,
2583 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2584 pWifiRadioStat->onTimePnoScan) ||
2585 nla_put_u32(vendor_event,
2586 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2587 pWifiRadioStat->onTimeHs20) ||
2588 nla_put_u32(vendor_event,
2589 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2590 pWifiRadioStat->numChannels))
2591 {
2592 hddLog(VOS_TRACE_LEVEL_ERROR,
2593 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2594 kfree_skb(vendor_event);
2595 return ;
2596 }
2597
2598 chList = nla_nest_start(vendor_event,
2599 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302600 if(!chList)
2601 {
2602 hddLog(VOS_TRACE_LEVEL_ERROR,
2603 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2604 __func__);
2605 kfree_skb(vendor_event);
2606 return;
2607 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302608 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2609 {
2610 struct nlattr *chInfo;
2611
2612 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2613 pWifiRadioStat->channels +
2614 (i * sizeof(tSirWifiChannelStats)));
2615
Sunil Duttc69bccb2014-05-26 21:30:20 +05302616 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302617 if(!chInfo)
2618 {
2619 hddLog(VOS_TRACE_LEVEL_ERROR,
2620 "%s: failed to put chInfo",
2621 __func__);
2622 kfree_skb(vendor_event);
2623 return;
2624 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302625
2626 if (nla_put_u32(vendor_event,
2627 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2628 pWifiChannelStats->channel.width) ||
2629 nla_put_u32(vendor_event,
2630 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2631 pWifiChannelStats->channel.centerFreq) ||
2632 nla_put_u32(vendor_event,
2633 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2634 pWifiChannelStats->channel.centerFreq0) ||
2635 nla_put_u32(vendor_event,
2636 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2637 pWifiChannelStats->channel.centerFreq1) ||
2638 nla_put_u32(vendor_event,
2639 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2640 pWifiChannelStats->onTime) ||
2641 nla_put_u32(vendor_event,
2642 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2643 pWifiChannelStats->ccaBusyTime))
2644 {
2645 hddLog(VOS_TRACE_LEVEL_ERROR,
2646 FL("cfg80211_vendor_event_alloc failed") );
2647 kfree_skb(vendor_event);
2648 return ;
2649 }
2650 nla_nest_end(vendor_event, chInfo);
2651 }
2652 nla_nest_end(vendor_event, chList);
2653
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302654 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302655
2656 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302657 return;
2658}
2659
2660/*
2661 * hdd_link_layer_stats_ind_callback () - This function is called after
2662 * receiving Link Layer indications from FW.This callback converts the firmware
2663 * data to the NL data and send the same to the kernel/upper layers.
2664 */
2665static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2666 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302667 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302668{
Dino Mycled3d50022014-07-07 12:58:25 +05302669 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2670 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302671 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302672 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302673 int status;
2674
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302675 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302676
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302677 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302678 if (0 != status)
2679 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302680 return;
2681 }
2682
Dino Mycled3d50022014-07-07 12:58:25 +05302683 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2684 if (NULL == pAdapter)
2685 {
2686 hddLog(VOS_TRACE_LEVEL_ERROR,
2687 FL(" MAC address %pM does not exist with host"),
2688 macAddr);
2689 return;
2690 }
2691
Sunil Duttc69bccb2014-05-26 21:30:20 +05302692 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302693 "%s: Interface: %s LLStats indType: %d", __func__,
2694 pAdapter->dev->name, indType);
2695
Sunil Duttc69bccb2014-05-26 21:30:20 +05302696 switch (indType)
2697 {
2698 case SIR_HAL_LL_STATS_RESULTS_RSP:
2699 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302700 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302701 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2702 "respId = %u, moreResultToFollow = %u",
2703 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2704 macAddr, linkLayerStatsResults->respId,
2705 linkLayerStatsResults->moreResultToFollow);
2706
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302707 spin_lock(&hdd_context_lock);
2708 context = &pHddCtx->ll_stats_context;
2709 /* validate response received from target */
2710 if ((context->request_id != linkLayerStatsResults->respId) ||
2711 !(context->request_bitmap & linkLayerStatsResults->paramId))
2712 {
2713 spin_unlock(&hdd_context_lock);
2714 hddLog(LOGE,
2715 FL("Error : Request id %d response id %d request bitmap 0x%x"
2716 "response bitmap 0x%x"),
2717 context->request_id, linkLayerStatsResults->respId,
2718 context->request_bitmap, linkLayerStatsResults->paramId);
2719 return;
2720 }
2721 spin_unlock(&hdd_context_lock);
2722
Sunil Duttc69bccb2014-05-26 21:30:20 +05302723 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2724 {
2725 hdd_link_layer_process_radio_stats(pAdapter,
2726 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302727 spin_lock(&hdd_context_lock);
2728 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2729 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302730 }
2731 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2732 {
2733 hdd_link_layer_process_iface_stats(pAdapter,
2734 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302735 spin_lock(&hdd_context_lock);
2736 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2737 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302738 }
2739 else if ( linkLayerStatsResults->paramId &
2740 WMI_LINK_STATS_ALL_PEER )
2741 {
2742 hdd_link_layer_process_peer_stats(pAdapter,
2743 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302744 spin_lock(&hdd_context_lock);
2745 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2746 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302747 } /* WMI_LINK_STATS_ALL_PEER */
2748 else
2749 {
2750 hddLog(VOS_TRACE_LEVEL_ERROR,
2751 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2752 }
2753
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302754 spin_lock(&hdd_context_lock);
2755 /* complete response event if all requests are completed */
2756 if (0 == context->request_bitmap)
2757 complete(&context->response_event);
2758 spin_unlock(&hdd_context_lock);
2759
Sunil Duttc69bccb2014-05-26 21:30:20 +05302760 break;
2761 }
2762 default:
2763 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2764 break;
2765 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302766
2767 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302768 return;
2769}
2770
2771const struct
2772nla_policy
2773qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2774{
2775 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2776 { .type = NLA_U32 },
2777 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2778 { .type = NLA_U32 },
2779};
2780
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302781static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2782 struct wireless_dev *wdev,
2783 const void *data,
2784 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302785{
2786 int status;
2787 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302788 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302789 struct net_device *dev = wdev->netdev;
2790 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2791 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2792
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302793 ENTER();
2794
Sunil Duttc69bccb2014-05-26 21:30:20 +05302795 status = wlan_hdd_validate_context(pHddCtx);
2796 if (0 != status)
2797 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302798 return -EINVAL;
2799 }
2800
2801 if (NULL == pAdapter)
2802 {
2803 hddLog(VOS_TRACE_LEVEL_ERROR,
2804 FL("HDD adapter is Null"));
2805 return -ENODEV;
2806 }
Ashish Kumar Dhanotiyabdcafda2018-12-11 18:54:41 +05302807
2808 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION) {
2809 hddLog(VOS_TRACE_LEVEL_DEBUG,
2810 "Cannot set LL_STATS for device mode %d",
2811 pAdapter->device_mode);
2812 return -EINVAL;
2813 }
2814
Dino Mycledf0a5d92014-07-04 09:41:55 +05302815 /* check the LLStats Capability */
2816 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2817 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2818 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302819 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302820 FL("Link Layer Statistics not supported by Firmware"));
2821 return -EINVAL;
2822 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302823
2824 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2825 (struct nlattr *)data,
2826 data_len, qca_wlan_vendor_ll_set_policy))
2827 {
2828 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2829 return -EINVAL;
2830 }
2831 if (!tb_vendor
2832 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2833 {
2834 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2835 return -EINVAL;
2836 }
2837 if (!tb_vendor[
2838 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2839 {
2840 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2841 return -EINVAL;
2842 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302843 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302844 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302845
Dino Mycledf0a5d92014-07-04 09:41:55 +05302846 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302847 nla_get_u32(
2848 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2849
Dino Mycledf0a5d92014-07-04 09:41:55 +05302850 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302851 nla_get_u32(
2852 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2853
Dino Mycled3d50022014-07-07 12:58:25 +05302854 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2855 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302856
2857
2858 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302859 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2860 "Statistics Gathering = %d ",
2861 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2862 linkLayerStatsSetReq.mpduSizeThreshold,
2863 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302864
2865 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2866 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302867 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302868 {
2869 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2870 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302871 return -EINVAL;
2872
2873 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302874
Sunil Duttc69bccb2014-05-26 21:30:20 +05302875 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302876 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302877 {
2878 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2879 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302880 return -EINVAL;
2881 }
2882
2883 pAdapter->isLinkLayerStatsSet = 1;
2884
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302885 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302886 return 0;
2887}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302888static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2889 struct wireless_dev *wdev,
2890 const void *data,
2891 int data_len)
2892{
2893 int ret = 0;
2894
2895 vos_ssr_protect(__func__);
2896 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2897 vos_ssr_unprotect(__func__);
2898
2899 return ret;
2900}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302901
2902const struct
2903nla_policy
2904qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2905{
2906 /* Unsigned 32bit value provided by the caller issuing the GET stats
2907 * command. When reporting
2908 * the stats results, the driver uses the same value to indicate
2909 * which GET request the results
2910 * correspond to.
2911 */
2912 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2913
2914 /* Unsigned 32bit value . bit mask to identify what statistics are
2915 requested for retrieval */
2916 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2917};
2918
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302919static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2920 struct wireless_dev *wdev,
2921 const void *data,
2922 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302923{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302924 unsigned long rc;
2925 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302926 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2927 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302928 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302929 struct net_device *dev = wdev->netdev;
2930 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302931 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302932 int status;
2933
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302934 ENTER();
2935
Sunil Duttc69bccb2014-05-26 21:30:20 +05302936 status = wlan_hdd_validate_context(pHddCtx);
2937 if (0 != status)
2938 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302939 return -EINVAL ;
2940 }
2941
2942 if (NULL == pAdapter)
2943 {
2944 hddLog(VOS_TRACE_LEVEL_FATAL,
2945 "%s: HDD adapter is Null", __func__);
2946 return -ENODEV;
2947 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302948
2949 if (pHddStaCtx == NULL)
2950 {
2951 hddLog(VOS_TRACE_LEVEL_FATAL,
2952 "%s: HddStaCtx is Null", __func__);
2953 return -ENODEV;
2954 }
2955
Dino Mycledf0a5d92014-07-04 09:41:55 +05302956 /* check the LLStats Capability */
2957 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2958 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2959 {
2960 hddLog(VOS_TRACE_LEVEL_ERROR,
2961 FL("Link Layer Statistics not supported by Firmware"));
2962 return -EINVAL;
2963 }
2964
Sunil Duttc69bccb2014-05-26 21:30:20 +05302965
2966 if (!pAdapter->isLinkLayerStatsSet)
2967 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302968 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302969 "%s: isLinkLayerStatsSet : %d",
2970 __func__, pAdapter->isLinkLayerStatsSet);
2971 return -EINVAL;
2972 }
2973
Mukul Sharma10313ba2015-07-29 19:14:39 +05302974 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2975 {
2976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2977 "%s: Roaming in progress, so unable to proceed this request", __func__);
2978 return -EBUSY;
2979 }
2980
Sunil Duttc69bccb2014-05-26 21:30:20 +05302981 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2982 (struct nlattr *)data,
2983 data_len, qca_wlan_vendor_ll_get_policy))
2984 {
2985 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2986 return -EINVAL;
2987 }
2988
2989 if (!tb_vendor
2990 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2991 {
2992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2993 return -EINVAL;
2994 }
2995
2996 if (!tb_vendor
2997 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2998 {
2999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
3000 return -EINVAL;
3001 }
3002
Sunil Duttc69bccb2014-05-26 21:30:20 +05303003
Dino Mycledf0a5d92014-07-04 09:41:55 +05303004 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303005 nla_get_u32( tb_vendor[
3006 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05303007 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303008 nla_get_u32( tb_vendor[
3009 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
3010
Dino Mycled3d50022014-07-07 12:58:25 +05303011 vos_mem_copy(linkLayerStatsGetReq.macAddr,
3012 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303013
3014 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303015 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
3016 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303017 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303018
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303019 spin_lock(&hdd_context_lock);
3020 context = &pHddCtx->ll_stats_context;
3021 context->request_id = linkLayerStatsGetReq.reqId;
3022 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
3023 INIT_COMPLETION(context->response_event);
3024 spin_unlock(&hdd_context_lock);
3025
Sunil Duttc69bccb2014-05-26 21:30:20 +05303026 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303027 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303028 {
3029 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3030 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303031 return -EINVAL;
3032 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303033
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303034 rc = wait_for_completion_timeout(&context->response_event,
3035 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3036 if (!rc)
3037 {
3038 hddLog(LOGE,
3039 FL("Target response timed out request id %d request bitmap 0x%x"),
3040 context->request_id, context->request_bitmap);
3041 return -ETIMEDOUT;
3042 }
3043
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303044 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303045 return 0;
3046}
3047
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303048static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3049 struct wireless_dev *wdev,
3050 const void *data,
3051 int data_len)
3052{
3053 int ret = 0;
3054
3055 vos_ssr_protect(__func__);
3056 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3057 vos_ssr_unprotect(__func__);
3058
3059 return ret;
3060}
3061
Sunil Duttc69bccb2014-05-26 21:30:20 +05303062const struct
3063nla_policy
3064qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3065{
3066 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3067 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3068 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3069 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3070};
3071
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303072static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3073 struct wireless_dev *wdev,
3074 const void *data,
3075 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303076{
3077 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3078 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303079 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303080 struct net_device *dev = wdev->netdev;
3081 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3082 u32 statsClearReqMask;
3083 u8 stopReq;
3084 int status;
3085
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303086 ENTER();
3087
Sunil Duttc69bccb2014-05-26 21:30:20 +05303088 status = wlan_hdd_validate_context(pHddCtx);
3089 if (0 != status)
3090 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303091 return -EINVAL;
3092 }
3093
3094 if (NULL == pAdapter)
3095 {
3096 hddLog(VOS_TRACE_LEVEL_FATAL,
3097 "%s: HDD adapter is Null", __func__);
3098 return -ENODEV;
3099 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303100 /* check the LLStats Capability */
3101 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3102 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3103 {
3104 hddLog(VOS_TRACE_LEVEL_ERROR,
3105 FL("Enable LLStats Capability"));
3106 return -EINVAL;
3107 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303108
3109 if (!pAdapter->isLinkLayerStatsSet)
3110 {
3111 hddLog(VOS_TRACE_LEVEL_FATAL,
3112 "%s: isLinkLayerStatsSet : %d",
3113 __func__, pAdapter->isLinkLayerStatsSet);
3114 return -EINVAL;
3115 }
3116
3117 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3118 (struct nlattr *)data,
3119 data_len, qca_wlan_vendor_ll_clr_policy))
3120 {
3121 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3122 return -EINVAL;
3123 }
3124
3125 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3126
3127 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3128 {
3129 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3130 return -EINVAL;
3131
3132 }
3133
Sunil Duttc69bccb2014-05-26 21:30:20 +05303134
Dino Mycledf0a5d92014-07-04 09:41:55 +05303135 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303136 nla_get_u32(
3137 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3138
Dino Mycledf0a5d92014-07-04 09:41:55 +05303139 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303140 nla_get_u8(
3141 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3142
3143 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303144 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303145
Dino Mycled3d50022014-07-07 12:58:25 +05303146 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3147 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303148
3149 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303150 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3151 "statsClearReqMask = 0x%X, stopReq = %d",
3152 linkLayerStatsClearReq.reqId,
3153 linkLayerStatsClearReq.macAddr,
3154 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303155 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303156
3157 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303158 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303159 {
3160 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303161 hdd_station_ctx_t *pHddStaCtx;
3162
3163 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3164 if (VOS_STATUS_SUCCESS !=
3165 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3166 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3167 {
3168 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3169 "WLANTL_ClearInterfaceStats Failed", __func__);
3170 return -EINVAL;
3171 }
3172 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3173 (statsClearReqMask & WIFI_STATS_IFACE)) {
3174 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3175 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3176 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3177 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3178 }
3179
Sunil Duttc69bccb2014-05-26 21:30:20 +05303180 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3181 2 * sizeof(u32) +
3182 NLMSG_HDRLEN);
3183
3184 if (temp_skbuff != NULL)
3185 {
3186
3187 if (nla_put_u32(temp_skbuff,
3188 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3189 statsClearReqMask) ||
3190 nla_put_u32(temp_skbuff,
3191 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3192 stopReq))
3193 {
3194 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3195 kfree_skb(temp_skbuff);
3196 return -EINVAL;
3197 }
3198 /* If the ask is to stop the stats collection as part of clear
3199 * (stopReq = 1) , ensure that no further requests of get
3200 * go to the firmware by having isLinkLayerStatsSet set to 0.
3201 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303202 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303203 * case the firmware is just asked to clear the statistics.
3204 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303205 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303206 pAdapter->isLinkLayerStatsSet = 0;
3207 return cfg80211_vendor_cmd_reply(temp_skbuff);
3208 }
3209 return -ENOMEM;
3210 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303211
3212 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303213 return -EINVAL;
3214}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303215static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3216 struct wireless_dev *wdev,
3217 const void *data,
3218 int data_len)
3219{
3220 int ret = 0;
3221
3222 vos_ssr_protect(__func__);
3223 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3224 vos_ssr_unprotect(__func__);
3225
3226 return ret;
3227
3228
3229}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303230#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3231
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232#ifdef WLAN_FEATURE_EXTSCAN
3233static const struct nla_policy
3234wlan_hdd_extscan_config_policy
3235 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3236{
3237 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3238 { .type = NLA_U32 },
3239 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3240 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303241 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3242 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303243 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3244 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3245 { .type = NLA_U32 },
3246 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3247 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3248
3249 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3250 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3251 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3252 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3253 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303254 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3255 { .type = NLA_U32 },
3256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3257 { .type = NLA_U32 },
3258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3259 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303260 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3261 { .type = NLA_U32 },
3262 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3263 { .type = NLA_U32 },
3264 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3265 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303266 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3267 { .type = NLA_U8 },
3268 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303269 { .type = NLA_U8 },
3270 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3271 { .type = NLA_U8 },
3272 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3273 { .type = NLA_U8 },
3274
3275 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3276 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303277 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3278 .type = NLA_UNSPEC,
3279 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303280 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3281 { .type = NLA_S32 },
3282 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3283 { .type = NLA_S32 },
3284 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3285 { .type = NLA_U32 },
3286 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3287 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303288 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3289 { .type = NLA_U32 },
3290 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3291 { .type = NLA_BINARY,
3292 .len = IEEE80211_MAX_SSID_LEN + 1 },
3293 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303294 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303295 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3296 { .type = NLA_U32 },
3297 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3298 { .type = NLA_U8 },
3299 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3300 { .type = NLA_S32 },
3301 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3302 { .type = NLA_S32 },
3303 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3304 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303305};
3306
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303307/**
3308 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3309 * @ctx: hdd global context
3310 * @data: capabilities data
3311 *
3312 * Return: none
3313 */
3314static void
3315wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303316{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303317 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303318 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303319 tSirEXTScanCapabilitiesEvent *data =
3320 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303321
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303322 ENTER();
3323
3324 if (wlan_hdd_validate_context(pHddCtx))
3325 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326 return;
3327 }
3328
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303329 if (!pMsg)
3330 {
3331 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3332 return;
3333 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303334
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303335 vos_spin_lock_acquire(&hdd_context_lock);
3336
3337 context = &pHddCtx->ext_scan_context;
3338 /* validate response received from target*/
3339 if (context->request_id != data->requestId)
3340 {
3341 vos_spin_lock_release(&hdd_context_lock);
3342 hddLog(LOGE,
3343 FL("Target response id did not match: request_id %d resposne_id %d"),
3344 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303345 return;
3346 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303347 else
3348 {
3349 context->capability_response = *data;
3350 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303351 }
3352
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303353 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354
Dino Mycle6fb96c12014-06-10 11:52:40 +05303355 return;
3356}
3357
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303358/*
3359 * define short names for the global vendor params
3360 * used by wlan_hdd_send_ext_scan_capability()
3361 */
3362#define PARAM_REQUEST_ID \
3363 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3364#define PARAM_STATUS \
3365 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3366#define MAX_SCAN_CACHE_SIZE \
3367 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3368#define MAX_SCAN_BUCKETS \
3369 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3370#define MAX_AP_CACHE_PER_SCAN \
3371 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3372#define MAX_RSSI_SAMPLE_SIZE \
3373 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3374#define MAX_SCAN_RPT_THRHOLD \
3375 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3376#define MAX_HOTLIST_BSSIDS \
3377 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3378#define MAX_BSSID_HISTORY_ENTRIES \
3379 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3380#define MAX_HOTLIST_SSIDS \
3381 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303382#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3383 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303384
3385static int wlan_hdd_send_ext_scan_capability(void *ctx)
3386{
3387 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3388 struct sk_buff *skb = NULL;
3389 int ret;
3390 tSirEXTScanCapabilitiesEvent *data;
3391 tANI_U32 nl_buf_len;
3392
3393 ret = wlan_hdd_validate_context(pHddCtx);
3394 if (0 != ret)
3395 {
3396 return ret;
3397 }
3398
3399 data = &(pHddCtx->ext_scan_context.capability_response);
3400
3401 nl_buf_len = NLMSG_HDRLEN;
3402 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3403 (sizeof(data->status) + NLA_HDRLEN) +
3404 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3405 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3406 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3407 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3408 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3409 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3410 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3411 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3412
3413 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3414
3415 if (!skb)
3416 {
3417 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3418 return -ENOMEM;
3419 }
3420
3421 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3422 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3423 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3424 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3425 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3426 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3427 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3428 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3429
3430 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3431 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3432 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3433 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3434 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3435 data->maxApPerScan) ||
3436 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3437 data->maxRssiSampleSize) ||
3438 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3439 data->maxScanReportingThreshold) ||
3440 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3441 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3442 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303443 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3444 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303445 {
3446 hddLog(LOGE, FL("nla put fail"));
3447 goto nla_put_failure;
3448 }
3449
3450 cfg80211_vendor_cmd_reply(skb);
3451 return 0;
3452
3453nla_put_failure:
3454 kfree_skb(skb);
3455 return -EINVAL;;
3456}
3457
3458/*
3459 * done with short names for the global vendor params
3460 * used by wlan_hdd_send_ext_scan_capability()
3461 */
3462#undef PARAM_REQUEST_ID
3463#undef PARAM_STATUS
3464#undef MAX_SCAN_CACHE_SIZE
3465#undef MAX_SCAN_BUCKETS
3466#undef MAX_AP_CACHE_PER_SCAN
3467#undef MAX_RSSI_SAMPLE_SIZE
3468#undef MAX_SCAN_RPT_THRHOLD
3469#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303470#undef MAX_BSSID_HISTORY_ENTRIES
3471#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472
3473static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3474{
3475 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3476 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303478 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303480 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303481
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303482 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303483 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303485 if (!pMsg)
3486 {
3487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488 return;
3489 }
3490
Dino Mycle6fb96c12014-06-10 11:52:40 +05303491 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3492 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3493
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303494 context = &pHddCtx->ext_scan_context;
3495 spin_lock(&hdd_context_lock);
3496 if (context->request_id == pData->requestId) {
3497 context->response_status = pData->status ? -EINVAL : 0;
3498 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303500 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303501
3502 /*
3503 * Store the Request ID for comparing with the requestID obtained
3504 * in other requests.HDD shall return a failure is the extscan_stop
3505 * request is issued with a different requestId as that of the
3506 * extscan_start request. Also, This requestId shall be used while
3507 * indicating the full scan results to the upper layers.
3508 * The requestId is stored with the assumption that the firmware
3509 * shall return the ext scan start request's requestId in ext scan
3510 * start response.
3511 */
3512 if (pData->status == 0)
3513 pMac->sme.extScanStartReqId = pData->requestId;
3514
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303515 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303516 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303517}
3518
3519
3520static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3521{
3522 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3523 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303524 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303525
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303526 ENTER();
3527
3528 if (wlan_hdd_validate_context(pHddCtx)){
3529 return;
3530 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303531
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303532 if (!pMsg)
3533 {
3534 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303535 return;
3536 }
3537
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303538 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3539 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303541 context = &pHddCtx->ext_scan_context;
3542 spin_lock(&hdd_context_lock);
3543 if (context->request_id == pData->requestId) {
3544 context->response_status = pData->status ? -EINVAL : 0;
3545 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303546 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303547 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303549 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303550 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303551}
3552
Dino Mycle6fb96c12014-06-10 11:52:40 +05303553static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3554 void *pMsg)
3555{
3556 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 tpSirEXTScanSetBssidHotListRspParams pData =
3558 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303559 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303561 ENTER();
3562
3563 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564 return;
3565 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303566
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303567 if (!pMsg)
3568 {
3569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3570 return;
3571 }
3572
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303573 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3574 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303575
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303576 context = &pHddCtx->ext_scan_context;
3577 spin_lock(&hdd_context_lock);
3578 if (context->request_id == pData->requestId) {
3579 context->response_status = pData->status ? -EINVAL : 0;
3580 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303582 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303583
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303584 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303585 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303586}
3587
3588static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3589 void *pMsg)
3590{
3591 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592 tpSirEXTScanResetBssidHotlistRspParams pData =
3593 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303594 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303596 ENTER();
3597
3598 if (wlan_hdd_validate_context(pHddCtx)) {
3599 return;
3600 }
3601 if (!pMsg)
3602 {
3603 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604 return;
3605 }
3606
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303607 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3608 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303610 context = &pHddCtx->ext_scan_context;
3611 spin_lock(&hdd_context_lock);
3612 if (context->request_id == pData->requestId) {
3613 context->response_status = pData->status ? -EINVAL : 0;
3614 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303615 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303616 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303617
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303618 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303619 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303620}
3621
Dino Mycle6fb96c12014-06-10 11:52:40 +05303622static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3623 void *pMsg)
3624{
3625 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3626 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303627 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303628 tANI_S32 totalResults;
3629 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303630 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3631 struct hdd_ext_scan_context *context;
3632 bool ignore_cached_results = false;
3633 tExtscanCachedScanResult *result;
3634 struct nlattr *nla_results;
3635 tANI_U16 ieLength= 0;
3636 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303637
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303638 ENTER();
3639
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303640 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303641 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303642
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303643 if (!pMsg)
3644 {
3645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3646 return;
3647 }
3648
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303649 spin_lock(&hdd_context_lock);
3650 context = &pHddCtx->ext_scan_context;
3651 ignore_cached_results = context->ignore_cached_results;
3652 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303653
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303654 if (ignore_cached_results) {
3655 hddLog(LOGE,
3656 FL("Ignore the cached results received after timeout"));
3657 return;
3658 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303659
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303660 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3661 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303662
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303663 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303664
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303665 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3666 scan_id_index++) {
3667 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303668
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303669 totalResults = result->num_results;
3670 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3671 result->scan_id, result->flags, totalResults);
3672 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303674 do{
3675 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3676 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3677 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303679 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3680 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3681
3682 if (!skb) {
3683 hddLog(VOS_TRACE_LEVEL_ERROR,
3684 FL("cfg80211_vendor_event_alloc failed"));
3685 return;
3686 }
3687
3688 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3689
3690 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3691 pData->requestId) ||
3692 nla_put_u32(skb,
3693 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3694 resultsPerEvent)) {
3695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3696 goto fail;
3697 }
3698 if (nla_put_u8(skb,
3699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3700 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303701 {
3702 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3703 goto fail;
3704 }
3705
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303706 if (nla_put_u32(skb,
3707 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3708 result->scan_id)) {
3709 hddLog(LOGE, FL("put fail"));
3710 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303711 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303712
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303713 nla_results = nla_nest_start(skb,
3714 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3715 if (!nla_results)
3716 goto fail;
3717
3718 if (resultsPerEvent) {
3719 struct nlattr *aps;
3720 struct nlattr *nla_result;
3721
3722 nla_result = nla_nest_start(skb, scan_id_index);
3723 if(!nla_result)
3724 goto fail;
3725
3726 if (nla_put_u32(skb,
3727 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3728 result->scan_id) ||
3729 nla_put_u32(skb,
3730 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3731 result->flags) ||
3732 nla_put_u32(skb,
3733 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3734 totalResults)) {
3735 hddLog(LOGE, FL("put fail"));
3736 goto fail;
3737 }
3738
3739 aps = nla_nest_start(skb,
3740 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3741 if (!aps)
3742 {
3743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3744 goto fail;
3745 }
3746
3747 head_ptr = (tpSirWifiScanResult) &(result->ap);
3748
3749 for (j = 0; j < resultsPerEvent; j++, i++) {
3750 struct nlattr *ap;
3751 pSirWifiScanResult = head_ptr + i;
3752
3753 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303754 * Firmware returns timestamp from extscan_start till
3755 * BSSID was cached (in micro seconds). Add this with
3756 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303757 * to derive the time since boot when the
3758 * BSSID was cached.
3759 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303760 pSirWifiScanResult->ts +=
3761 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303762 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3763 "Ssid (%s)"
3764 "Bssid: %pM "
3765 "Channel (%u)"
3766 "Rssi (%d)"
3767 "RTT (%u)"
3768 "RTT_SD (%u)"
3769 "Beacon Period %u"
3770 "Capability 0x%x "
3771 "Ie length %d",
3772 i,
3773 pSirWifiScanResult->ts,
3774 pSirWifiScanResult->ssid,
3775 pSirWifiScanResult->bssid,
3776 pSirWifiScanResult->channel,
3777 pSirWifiScanResult->rssi,
3778 pSirWifiScanResult->rtt,
3779 pSirWifiScanResult->rtt_sd,
3780 pSirWifiScanResult->beaconPeriod,
3781 pSirWifiScanResult->capability,
3782 ieLength);
3783
3784 ap = nla_nest_start(skb, j + 1);
3785 if (!ap)
3786 {
3787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3788 goto fail;
3789 }
3790
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303791 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303792 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3793 pSirWifiScanResult->ts) )
3794 {
3795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3796 goto fail;
3797 }
3798 if (nla_put(skb,
3799 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3800 sizeof(pSirWifiScanResult->ssid),
3801 pSirWifiScanResult->ssid) )
3802 {
3803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3804 goto fail;
3805 }
3806 if (nla_put(skb,
3807 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3808 sizeof(pSirWifiScanResult->bssid),
3809 pSirWifiScanResult->bssid) )
3810 {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3812 goto fail;
3813 }
3814 if (nla_put_u32(skb,
3815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3816 pSirWifiScanResult->channel) )
3817 {
3818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3819 goto fail;
3820 }
3821 if (nla_put_s32(skb,
3822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3823 pSirWifiScanResult->rssi) )
3824 {
3825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3826 goto fail;
3827 }
3828 if (nla_put_u32(skb,
3829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3830 pSirWifiScanResult->rtt) )
3831 {
3832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3833 goto fail;
3834 }
3835 if (nla_put_u32(skb,
3836 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3837 pSirWifiScanResult->rtt_sd))
3838 {
3839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3840 goto fail;
3841 }
3842 if (nla_put_u32(skb,
3843 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3844 pSirWifiScanResult->beaconPeriod))
3845 {
3846 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3847 goto fail;
3848 }
3849 if (nla_put_u32(skb,
3850 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3851 pSirWifiScanResult->capability))
3852 {
3853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3854 goto fail;
3855 }
3856 if (nla_put_u32(skb,
3857 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3858 ieLength))
3859 {
3860 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3861 goto fail;
3862 }
3863
3864 if (ieLength)
3865 if (nla_put(skb,
3866 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3867 ieLength, ie)) {
3868 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3869 goto fail;
3870 }
3871
3872 nla_nest_end(skb, ap);
3873 }
3874 nla_nest_end(skb, aps);
3875 nla_nest_end(skb, nla_result);
3876 }
3877
3878 nla_nest_end(skb, nla_results);
3879
3880 cfg80211_vendor_cmd_reply(skb);
3881
3882 } while (totalResults > 0);
3883 }
3884
3885 if (!pData->moreData) {
3886 spin_lock(&hdd_context_lock);
3887 context->response_status = 0;
3888 complete(&context->response_event);
3889 spin_unlock(&hdd_context_lock);
3890 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303891
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303892 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303893 return;
3894fail:
3895 kfree_skb(skb);
3896 return;
3897}
3898
3899static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3900 void *pMsg)
3901{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303902 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303903 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3904 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303905 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303906
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303907 ENTER();
3908
3909 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303910 hddLog(LOGE,
3911 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303912 return;
3913 }
3914 if (!pMsg)
3915 {
3916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303917 return;
3918 }
3919
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303920 if (pData->bss_found)
3921 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3922 else
3923 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3924
Dino Mycle6fb96c12014-06-10 11:52:40 +05303925 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303926#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3927 NULL,
3928#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303929 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303930 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931
3932 if (!skb) {
3933 hddLog(VOS_TRACE_LEVEL_ERROR,
3934 FL("cfg80211_vendor_event_alloc failed"));
3935 return;
3936 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303937
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303938 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3939 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3940 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3941 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3942
3943 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303944 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3945 "Ssid (%s) "
3946 "Bssid (" MAC_ADDRESS_STR ") "
3947 "Channel (%u) "
3948 "Rssi (%d) "
3949 "RTT (%u) "
3950 "RTT_SD (%u) ",
3951 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303952 pData->bssHotlist[i].ts,
3953 pData->bssHotlist[i].ssid,
3954 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3955 pData->bssHotlist[i].channel,
3956 pData->bssHotlist[i].rssi,
3957 pData->bssHotlist[i].rtt,
3958 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959 }
3960
3961 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3962 pData->requestId) ||
3963 nla_put_u32(skb,
3964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303965 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303966 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3967 goto fail;
3968 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303969 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303970 struct nlattr *aps;
3971
3972 aps = nla_nest_start(skb,
3973 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3974 if (!aps)
3975 goto fail;
3976
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303977 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303978 struct nlattr *ap;
3979
3980 ap = nla_nest_start(skb, i + 1);
3981 if (!ap)
3982 goto fail;
3983
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303984 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303985 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303986 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303987 nla_put(skb,
3988 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303989 sizeof(pData->bssHotlist[i].ssid),
3990 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303991 nla_put(skb,
3992 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303993 sizeof(pData->bssHotlist[i].bssid),
3994 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303995 nla_put_u32(skb,
3996 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303997 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303998 nla_put_s32(skb,
3999 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304000 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304001 nla_put_u32(skb,
4002 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304003 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304004 nla_put_u32(skb,
4005 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304006 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304007 goto fail;
4008
4009 nla_nest_end(skb, ap);
4010 }
4011 nla_nest_end(skb, aps);
4012
4013 if (nla_put_u8(skb,
4014 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4015 pData->moreData))
4016 goto fail;
4017 }
4018
4019 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304020 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304021 return;
4022
4023fail:
4024 kfree_skb(skb);
4025 return;
4026
4027}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304028
4029static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4030 void *pMsg)
4031{
4032 struct sk_buff *skb;
4033 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4034 tpSirWifiFullScanResultEvent pData =
4035 (tpSirWifiFullScanResultEvent) (pMsg);
4036
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304037 ENTER();
4038
4039 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304040 hddLog(LOGE,
4041 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304042 return;
4043 }
4044 if (!pMsg)
4045 {
4046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304047 return;
4048 }
4049
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304050 /*
4051 * If the full scan result including IE data exceeds NL 4K size
4052 * limitation, drop that beacon/probe rsp frame.
4053 */
4054 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4055 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4056 return;
4057 }
4058
Dino Mycle6fb96c12014-06-10 11:52:40 +05304059 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304060#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4061 NULL,
4062#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304063 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4064 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4065 GFP_KERNEL);
4066
4067 if (!skb) {
4068 hddLog(VOS_TRACE_LEVEL_ERROR,
4069 FL("cfg80211_vendor_event_alloc failed"));
4070 return;
4071 }
4072
Dino Mycle6fb96c12014-06-10 11:52:40 +05304073 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4074 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4075 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4076 "Ssid (%s)"
4077 "Bssid (" MAC_ADDRESS_STR ")"
4078 "Channel (%u)"
4079 "Rssi (%d)"
4080 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304081 "RTT_SD (%u)"
4082 "Bcn Period %d"
4083 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304084 pData->ap.ts,
4085 pData->ap.ssid,
4086 MAC_ADDR_ARRAY(pData->ap.bssid),
4087 pData->ap.channel,
4088 pData->ap.rssi,
4089 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304090 pData->ap.rtt_sd,
4091 pData->ap.beaconPeriod,
4092 pData->ap.capability);
4093
Dino Mycle6fb96c12014-06-10 11:52:40 +05304094 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4095 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4096 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304097 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4099 pData->ap.ts) ||
4100 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4101 sizeof(pData->ap.ssid),
4102 pData->ap.ssid) ||
4103 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4104 WNI_CFG_BSSID_LEN,
4105 pData->ap.bssid) ||
4106 nla_put_u32(skb,
4107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4108 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304109 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304110 pData->ap.rssi) ||
4111 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4112 pData->ap.rtt) ||
4113 nla_put_u32(skb,
4114 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4115 pData->ap.rtt_sd) ||
4116 nla_put_u16(skb,
4117 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4118 pData->ap.beaconPeriod) ||
4119 nla_put_u16(skb,
4120 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4121 pData->ap.capability) ||
4122 nla_put_u32(skb,
4123 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304124 pData->ieLength) ||
4125 nla_put_u8(skb,
4126 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4127 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304128 {
4129 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4130 goto nla_put_failure;
4131 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304132
4133 if (pData->ieLength) {
4134 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4135 pData->ieLength,
4136 pData->ie))
4137 {
4138 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4139 goto nla_put_failure;
4140 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304141 }
4142
4143 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304144 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304145 return;
4146
4147nla_put_failure:
4148 kfree_skb(skb);
4149 return;
4150}
4151
4152static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4153 void *pMsg)
4154{
4155 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4156 struct sk_buff *skb = NULL;
4157 tpSirEXTScanResultsAvailableIndParams pData =
4158 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304160 ENTER();
4161
4162 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304163 hddLog(LOGE,
4164 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304165 return;
4166 }
4167 if (!pMsg)
4168 {
4169 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304170 return;
4171 }
4172
4173 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304174#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4175 NULL,
4176#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304177 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4178 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4179 GFP_KERNEL);
4180
4181 if (!skb) {
4182 hddLog(VOS_TRACE_LEVEL_ERROR,
4183 FL("cfg80211_vendor_event_alloc failed"));
4184 return;
4185 }
4186
Dino Mycle6fb96c12014-06-10 11:52:40 +05304187 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4188 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4189 pData->numResultsAvailable);
4190 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4191 pData->requestId) ||
4192 nla_put_u32(skb,
4193 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4194 pData->numResultsAvailable)) {
4195 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4196 goto nla_put_failure;
4197 }
4198
4199 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304200 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304201 return;
4202
4203nla_put_failure:
4204 kfree_skb(skb);
4205 return;
4206}
4207
4208static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4209{
4210 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4211 struct sk_buff *skb = NULL;
4212 tpSirEXTScanProgressIndParams pData =
4213 (tpSirEXTScanProgressIndParams) pMsg;
4214
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304215 ENTER();
4216
4217 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304218 hddLog(LOGE,
4219 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304220 return;
4221 }
4222 if (!pMsg)
4223 {
4224 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225 return;
4226 }
4227
4228 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304229#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4230 NULL,
4231#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304232 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4233 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4234 GFP_KERNEL);
4235
4236 if (!skb) {
4237 hddLog(VOS_TRACE_LEVEL_ERROR,
4238 FL("cfg80211_vendor_event_alloc failed"));
4239 return;
4240 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304241 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304242 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4243 pData->extScanEventType);
4244 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4245 pData->status);
4246
4247 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4248 pData->extScanEventType) ||
4249 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304250 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4251 pData->requestId) ||
4252 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304253 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4254 pData->status)) {
4255 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4256 goto nla_put_failure;
4257 }
4258
4259 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304260 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304261 return;
4262
4263nla_put_failure:
4264 kfree_skb(skb);
4265 return;
4266}
4267
4268void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4269 void *pMsg)
4270{
4271 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4272
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304273 ENTER();
4274
Dino Mycle6fb96c12014-06-10 11:52:40 +05304275 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304276 return;
4277 }
4278
4279 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4280
4281
4282 switch(evType) {
4283 case SIR_HAL_EXTSCAN_START_RSP:
4284 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4285 break;
4286
4287 case SIR_HAL_EXTSCAN_STOP_RSP:
4288 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4289 break;
4290 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4291 /* There is no need to send this response to upper layer
4292 Just log the message */
4293 hddLog(VOS_TRACE_LEVEL_INFO,
4294 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4295 break;
4296 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4297 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4298 break;
4299
4300 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4301 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4302 break;
4303
Dino Mycle6fb96c12014-06-10 11:52:40 +05304304 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304305 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304306 break;
4307 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4308 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4309 break;
4310 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4311 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4312 break;
4313 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4314 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4315 break;
4316 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4317 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4318 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304319 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4320 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4321 break;
4322 default:
4323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4324 break;
4325 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304326 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304327}
4328
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304329static bool wlan_hdd_is_extscan_supported(hdd_adapter_t *adapter,
4330 hdd_context_t *hdd_ctx)
4331{
4332 int status;
4333
4334 status = wlan_hdd_validate_context(hdd_ctx);
4335 if (status)
4336 return false;
4337
4338 if (!adapter) {
4339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid adapter"));
4340 return false;
4341 }
4342
4343 if (adapter->device_mode != WLAN_HDD_INFRA_STATION) {
4344 hddLog(VOS_TRACE_LEVEL_INFO,
4345 FL("ext scans only supported on STA ifaces"));
4346 return false;
4347 }
4348
4349 if (VOS_FTM_MODE == hdd_get_conparam()) {
4350 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4351 return false;
4352 }
4353
4354 /* check the EXTScan Capability */
4355 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4356 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4357 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED))) {
4358 hddLog(VOS_TRACE_LEVEL_ERROR,
4359 FL("EXTScan not enabled/supported by Firmware"));
4360 return false;
4361 }
4362 return true;
4363}
4364
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304365static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4366 struct wireless_dev *wdev,
4367 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304368{
Dino Myclee8843b32014-07-04 14:21:45 +05304369 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304370 struct net_device *dev = wdev->netdev;
4371 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4372 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4373 struct nlattr
4374 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4375 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304376 struct hdd_ext_scan_context *context;
4377 unsigned long rc;
4378 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304379
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304380 ENTER();
4381
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304382 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304383 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304384
Dino Mycle6fb96c12014-06-10 11:52:40 +05304385 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4386 data, dataLen,
4387 wlan_hdd_extscan_config_policy)) {
4388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4389 return -EINVAL;
4390 }
4391
4392 /* Parse and fetch request Id */
4393 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4394 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4395 return -EINVAL;
4396 }
4397
Dino Myclee8843b32014-07-04 14:21:45 +05304398 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304400 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304401
Dino Myclee8843b32014-07-04 14:21:45 +05304402 reqMsg.sessionId = pAdapter->sessionId;
4403 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304404
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304405 vos_spin_lock_acquire(&hdd_context_lock);
4406 context = &pHddCtx->ext_scan_context;
4407 context->request_id = reqMsg.requestId;
4408 INIT_COMPLETION(context->response_event);
4409 vos_spin_lock_release(&hdd_context_lock);
4410
Dino Myclee8843b32014-07-04 14:21:45 +05304411 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304412 if (!HAL_STATUS_SUCCESS(status)) {
4413 hddLog(VOS_TRACE_LEVEL_ERROR,
4414 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304415 return -EINVAL;
4416 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304417
4418 rc = wait_for_completion_timeout(&context->response_event,
4419 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4420 if (!rc) {
4421 hddLog(LOGE, FL("Target response timed out"));
4422 return -ETIMEDOUT;
4423 }
4424
4425 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4426 if (ret)
4427 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4428
4429 return ret;
4430
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304431 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304432 return 0;
4433}
4434
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304435static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4436 struct wireless_dev *wdev,
4437 const void *data, int dataLen)
4438{
4439 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304440
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304441 vos_ssr_protect(__func__);
4442 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4443 vos_ssr_unprotect(__func__);
4444
4445 return ret;
4446}
4447
4448static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4449 struct wireless_dev *wdev,
4450 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304451{
Dino Myclee8843b32014-07-04 14:21:45 +05304452 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304453 struct net_device *dev = wdev->netdev;
4454 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4455 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4456 struct nlattr
4457 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4458 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304459 struct hdd_ext_scan_context *context;
4460 unsigned long rc;
4461 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304462
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304463 ENTER();
4464
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304465 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304466 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304467
Dino Mycle6fb96c12014-06-10 11:52:40 +05304468 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4469 data, dataLen,
4470 wlan_hdd_extscan_config_policy)) {
4471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4472 return -EINVAL;
4473 }
4474 /* Parse and fetch request Id */
4475 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4477 return -EINVAL;
4478 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304479
Dino Myclee8843b32014-07-04 14:21:45 +05304480 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304481 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4482
Dino Myclee8843b32014-07-04 14:21:45 +05304483 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304484
Dino Myclee8843b32014-07-04 14:21:45 +05304485 reqMsg.sessionId = pAdapter->sessionId;
4486 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304487
4488 /* Parse and fetch flush parameter */
4489 if (!tb
4490 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4491 {
4492 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4493 goto failed;
4494 }
Dino Myclee8843b32014-07-04 14:21:45 +05304495 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304496 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4497
Dino Myclee8843b32014-07-04 14:21:45 +05304498 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304499
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304500 spin_lock(&hdd_context_lock);
4501 context = &pHddCtx->ext_scan_context;
4502 context->request_id = reqMsg.requestId;
4503 context->ignore_cached_results = false;
4504 INIT_COMPLETION(context->response_event);
4505 spin_unlock(&hdd_context_lock);
4506
Dino Myclee8843b32014-07-04 14:21:45 +05304507 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304508 if (!HAL_STATUS_SUCCESS(status)) {
4509 hddLog(VOS_TRACE_LEVEL_ERROR,
4510 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304511 return -EINVAL;
4512 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304513
4514 rc = wait_for_completion_timeout(&context->response_event,
4515 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4516 if (!rc) {
4517 hddLog(LOGE, FL("Target response timed out"));
4518 retval = -ETIMEDOUT;
4519 spin_lock(&hdd_context_lock);
4520 context->ignore_cached_results = true;
4521 spin_unlock(&hdd_context_lock);
4522 } else {
4523 spin_lock(&hdd_context_lock);
4524 retval = context->response_status;
4525 spin_unlock(&hdd_context_lock);
4526 }
4527
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304528 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304529 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304530
4531failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304532 return -EINVAL;
4533}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304534static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4535 struct wireless_dev *wdev,
4536 const void *data, int dataLen)
4537{
4538 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304539
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304540 vos_ssr_protect(__func__);
4541 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4542 vos_ssr_unprotect(__func__);
4543
4544 return ret;
4545}
4546
4547static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304548 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304549 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304550{
4551 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4552 struct net_device *dev = wdev->netdev;
4553 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4554 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4555 struct nlattr
4556 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4557 struct nlattr
4558 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4559 struct nlattr *apTh;
4560 eHalStatus status;
4561 tANI_U8 i = 0;
4562 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304563 struct hdd_ext_scan_context *context;
4564 tANI_U32 request_id;
4565 unsigned long rc;
4566 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304567
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304568 ENTER();
4569
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304570 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304571 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304572
Dino Mycle6fb96c12014-06-10 11:52:40 +05304573 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4574 data, dataLen,
4575 wlan_hdd_extscan_config_policy)) {
4576 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4577 return -EINVAL;
4578 }
4579
4580 /* Parse and fetch request Id */
4581 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4582 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4583 return -EINVAL;
4584 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304585 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4586 vos_mem_malloc(sizeof(*pReqMsg));
4587 if (!pReqMsg) {
4588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4589 return -ENOMEM;
4590 }
4591
Dino Myclee8843b32014-07-04 14:21:45 +05304592
Dino Mycle6fb96c12014-06-10 11:52:40 +05304593 pReqMsg->requestId = nla_get_u32(
4594 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4595 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4596
4597 /* Parse and fetch number of APs */
4598 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4599 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4600 goto fail;
4601 }
4602
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304603 /* Parse and fetch lost ap sample size */
4604 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4605 hddLog(LOGE, FL("attr lost ap sample size failed"));
4606 goto fail;
4607 }
4608
4609 pReqMsg->lostBssidSampleSize = nla_get_u32(
4610 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4611 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4612
Dino Mycle6fb96c12014-06-10 11:52:40 +05304613 pReqMsg->sessionId = pAdapter->sessionId;
4614 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4615
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304616 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304617 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304618 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4619 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4620 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4621 goto fail;
4622 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304623 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304624
4625 nla_for_each_nested(apTh,
4626 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304627 if (i == pReqMsg->numBssid) {
4628 hddLog(LOGW, FL("Ignoring excess AP"));
4629 break;
4630 }
4631
Dino Mycle6fb96c12014-06-10 11:52:40 +05304632 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4633 nla_data(apTh), nla_len(apTh),
4634 NULL)) {
4635 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4636 goto fail;
4637 }
4638
4639 /* Parse and fetch MAC address */
4640 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4641 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4642 goto fail;
4643 }
4644 memcpy(pReqMsg->ap[i].bssid, nla_data(
4645 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4646 sizeof(tSirMacAddr));
4647 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4648
4649 /* Parse and fetch low RSSI */
4650 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4652 goto fail;
4653 }
4654 pReqMsg->ap[i].low = nla_get_s32(
4655 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4656 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4657
4658 /* Parse and fetch high RSSI */
4659 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4661 goto fail;
4662 }
4663 pReqMsg->ap[i].high = nla_get_s32(
4664 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4665 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4666 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304667 i++;
4668 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304669
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304670 if (i < pReqMsg->numBssid) {
4671 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4672 i, pReqMsg->numBssid);
4673 pReqMsg->numBssid = i;
4674 }
4675
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304676 context = &pHddCtx->ext_scan_context;
4677 spin_lock(&hdd_context_lock);
4678 INIT_COMPLETION(context->response_event);
4679 context->request_id = request_id = pReqMsg->requestId;
4680 spin_unlock(&hdd_context_lock);
4681
Dino Mycle6fb96c12014-06-10 11:52:40 +05304682 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4683 if (!HAL_STATUS_SUCCESS(status)) {
4684 hddLog(VOS_TRACE_LEVEL_ERROR,
4685 FL("sme_SetBssHotlist failed(err=%d)"), status);
4686 vos_mem_free(pReqMsg);
4687 return -EINVAL;
4688 }
4689
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304690 /* request was sent -- wait for the response */
4691 rc = wait_for_completion_timeout(&context->response_event,
4692 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4693
4694 if (!rc) {
4695 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4696 retval = -ETIMEDOUT;
4697 } else {
4698 spin_lock(&hdd_context_lock);
4699 if (context->request_id == request_id)
4700 retval = context->response_status;
4701 else
4702 retval = -EINVAL;
4703 spin_unlock(&hdd_context_lock);
4704 }
4705
Dino Myclee8843b32014-07-04 14:21:45 +05304706 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304707 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304708 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304709
4710fail:
4711 vos_mem_free(pReqMsg);
4712 return -EINVAL;
4713}
4714
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304715static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4716 struct wireless_dev *wdev,
4717 const void *data, int dataLen)
4718{
4719 int ret = 0;
4720
4721 vos_ssr_protect(__func__);
4722 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4723 dataLen);
4724 vos_ssr_unprotect(__func__);
4725
4726 return ret;
4727}
4728
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304729static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304730 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304731 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304733 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4734 struct net_device *dev = wdev->netdev;
4735 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4736 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4737 uint8_t num_channels = 0;
4738 uint8_t num_chan_new = 0;
4739 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304740 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304741 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304742 tWifiBand wifiBand;
4743 eHalStatus status;
4744 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304745 tANI_U8 i,j,k;
4746 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304747
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304748 ENTER();
Ashish Kumar Dhanotiya747e9ce2019-09-16 12:47:03 +05304749 ret = wlan_hdd_validate_context(pHddCtx);
4750 if (ret)
4751 return false;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304752
Ashish Kumar Dhanotiya747e9ce2019-09-16 12:47:03 +05304753 if (!pAdapter) {
4754 hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Invalid adapter"));
4755 return false;
4756 }
4757
4758 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION) {
4759 hddLog(VOS_TRACE_LEVEL_DEBUG,
4760 FL("ext scans only supported on STA ifaces"));
4761 return false;
4762 }
4763
4764 if (VOS_FTM_MODE == hdd_get_conparam()) {
4765 hddLog(VOS_TRACE_LEVEL_DEBUG, FL("Command not allowed in FTM mode"));
4766 return false;
4767 }
Dino Myclee8843b32014-07-04 14:21:45 +05304768
Dino Mycle6fb96c12014-06-10 11:52:40 +05304769 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4770 data, dataLen,
4771 wlan_hdd_extscan_config_policy)) {
4772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4773 return -EINVAL;
4774 }
4775
4776 /* Parse and fetch request Id */
4777 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4779 return -EINVAL;
4780 }
4781 requestId = nla_get_u32(
4782 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4783 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4784
4785 /* Parse and fetch wifi band */
4786 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4787 {
4788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4789 return -EINVAL;
4790 }
4791 wifiBand = nla_get_u32(
4792 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4793 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4794
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304795 /* Parse and fetch max channels */
4796 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4797 {
4798 hddLog(LOGE, FL("attr max channels failed"));
4799 return -EINVAL;
4800 }
4801 maxChannels = nla_get_u32(
4802 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4803 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4804
Dino Mycle6fb96c12014-06-10 11:52:40 +05304805 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304806 wifiBand, chan_list,
4807 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304808 if (eHAL_STATUS_SUCCESS != status) {
4809 hddLog(VOS_TRACE_LEVEL_ERROR,
4810 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4811 return -EINVAL;
4812 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304813
Agrawal Ashish16abf782016-08-18 22:42:59 +05304814 num_channels = VOS_MIN(num_channels, maxChannels);
4815 num_chan_new = num_channels;
4816 /* remove the indoor only channels if iface is SAP */
4817 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4818 {
4819 num_chan_new = 0;
4820 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304821 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304822 if (wiphy->bands[j] == NULL)
4823 continue;
4824 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4825 if ((chan_list[i] ==
4826 wiphy->bands[j]->channels[k].center_freq) &&
4827 (!(wiphy->bands[j]->channels[k].flags &
4828 IEEE80211_CHAN_INDOOR_ONLY))) {
4829 chan_list[num_chan_new] = chan_list[i];
4830 num_chan_new++;
4831 }
4832 }
4833 }
4834 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304835
Agrawal Ashish16abf782016-08-18 22:42:59 +05304836 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4837 for (i = 0; i < num_chan_new; i++)
4838 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4839 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304840
4841 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304842 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304843 NLMSG_HDRLEN);
4844
4845 if (!replySkb) {
4846 hddLog(VOS_TRACE_LEVEL_ERROR,
4847 FL("valid channels: buffer alloc fail"));
4848 return -EINVAL;
4849 }
4850 if (nla_put_u32(replySkb,
4851 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304852 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304853 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304854 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304855
4856 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4857 kfree_skb(replySkb);
4858 return -EINVAL;
4859 }
4860
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304861 ret = cfg80211_vendor_cmd_reply(replySkb);
4862
4863 EXIT();
4864 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304865}
4866
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304867static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4868 struct wireless_dev *wdev,
4869 const void *data, int dataLen)
4870{
4871 int ret = 0;
4872
4873 vos_ssr_protect(__func__);
4874 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4875 dataLen);
4876 vos_ssr_unprotect(__func__);
4877
4878 return ret;
4879}
4880
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304881static int hdd_extscan_start_fill_bucket_channel_spec(
4882 hdd_context_t *pHddCtx,
4883 tpSirEXTScanStartReqParams pReqMsg,
4884 struct nlattr **tb)
4885{
4886 struct nlattr *bucket[
4887 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4888 struct nlattr *channel[
4889 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4890 struct nlattr *buckets;
4891 struct nlattr *channels;
4892 int rem1, rem2;
4893 eHalStatus status;
4894 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304895 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304896 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4897 tANI_U32 passive_max_chn_time, active_max_chn_time;
4898
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304899 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304900 bktIndex = 0;
4901
4902 nla_for_each_nested(buckets,
4903 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304904 if (bktIndex >= expected_buckets) {
4905 hddLog(LOGW, FL("ignoring excess buckets"));
4906 break;
4907 }
4908
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304909 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304910 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4911 nla_data(buckets), nla_len(buckets),
4912 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304913 hddLog(LOGE, FL("nla_parse failed"));
4914 return -EINVAL;
4915 }
4916
4917 /* Parse and fetch bucket spec */
4918 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4919 hddLog(LOGE, FL("attr bucket index failed"));
4920 return -EINVAL;
4921 }
4922 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4923 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4924 hddLog(LOG1, FL("Bucket spec Index %d"),
4925 pReqMsg->buckets[bktIndex].bucket);
4926
4927 /* Parse and fetch wifi band */
4928 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4929 hddLog(LOGE, FL("attr wifi band failed"));
4930 return -EINVAL;
4931 }
4932 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4933 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4934 hddLog(LOG1, FL("Wifi band %d"),
4935 pReqMsg->buckets[bktIndex].band);
4936
4937 /* Parse and fetch period */
4938 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4939 hddLog(LOGE, FL("attr period failed"));
4940 return -EINVAL;
4941 }
4942 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4943 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4944 hddLog(LOG1, FL("period %d"),
4945 pReqMsg->buckets[bktIndex].period);
4946
4947 /* Parse and fetch report events */
4948 if (!bucket[
4949 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4950 hddLog(LOGE, FL("attr report events failed"));
4951 return -EINVAL;
4952 }
4953 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4954 bucket[
4955 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4956 hddLog(LOG1, FL("report events %d"),
4957 pReqMsg->buckets[bktIndex].reportEvents);
4958
4959 /* Parse and fetch max period */
4960 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4961 hddLog(LOGE, FL("attr max period failed"));
4962 return -EINVAL;
4963 }
4964 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4965 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4966 hddLog(LOG1, FL("max period %u"),
4967 pReqMsg->buckets[bktIndex].max_period);
4968
4969 /* Parse and fetch exponent */
4970 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4971 hddLog(LOGE, FL("attr exponent failed"));
4972 return -EINVAL;
4973 }
4974 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4975 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4976 hddLog(LOG1, FL("exponent %u"),
4977 pReqMsg->buckets[bktIndex].exponent);
4978
4979 /* Parse and fetch step count */
4980 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4981 hddLog(LOGE, FL("attr step count failed"));
4982 return -EINVAL;
4983 }
4984 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4985 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4986 hddLog(LOG1, FL("Step count %u"),
4987 pReqMsg->buckets[bktIndex].step_count);
4988
4989 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4990 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4991
4992 /* Framework shall pass the channel list if the input WiFi band is
4993 * WIFI_BAND_UNSPECIFIED.
4994 * If the input WiFi band is specified (any value other than
4995 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4996 */
4997 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4998 numChannels = 0;
4999 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
5000 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
5001 pReqMsg->buckets[bktIndex].band,
5002 chanList, &numChannels);
5003 if (!HAL_STATUS_SUCCESS(status)) {
5004 hddLog(LOGE,
5005 FL("sme_GetValidChannelsByBand failed (err=%d)"),
5006 status);
5007 return -EINVAL;
5008 }
5009
5010 pReqMsg->buckets[bktIndex].numChannels =
5011 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
5012 hddLog(LOG1, FL("Num channels %d"),
5013 pReqMsg->buckets[bktIndex].numChannels);
5014
5015 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
5016 j++) {
5017 pReqMsg->buckets[bktIndex].channels[j].channel =
5018 chanList[j];
5019 pReqMsg->buckets[bktIndex].channels[j].
5020 chnlClass = 0;
5021 if (CSR_IS_CHANNEL_DFS(
5022 vos_freq_to_chan(chanList[j]))) {
5023 pReqMsg->buckets[bktIndex].channels[j].
5024 passive = 1;
5025 pReqMsg->buckets[bktIndex].channels[j].
5026 dwellTimeMs = passive_max_chn_time;
5027 } else {
5028 pReqMsg->buckets[bktIndex].channels[j].
5029 passive = 0;
5030 pReqMsg->buckets[bktIndex].channels[j].
5031 dwellTimeMs = active_max_chn_time;
5032 }
5033
5034 hddLog(LOG1,
5035 "Channel %u Passive %u Dwell time %u ms",
5036 pReqMsg->buckets[bktIndex].channels[j].channel,
5037 pReqMsg->buckets[bktIndex].channels[j].passive,
5038 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5039 }
5040
5041 bktIndex++;
5042 continue;
5043 }
5044
5045 /* Parse and fetch number of channels */
5046 if (!bucket[
5047 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5048 hddLog(LOGE, FL("attr num channels failed"));
5049 return -EINVAL;
5050 }
5051
5052 pReqMsg->buckets[bktIndex].numChannels =
5053 nla_get_u32(bucket[
5054 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5055 hddLog(LOG1, FL("num channels %d"),
5056 pReqMsg->buckets[bktIndex].numChannels);
5057
5058 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5059 hddLog(LOGE, FL("attr channel spec failed"));
5060 return -EINVAL;
5061 }
5062
5063 j = 0;
5064 nla_for_each_nested(channels,
5065 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5066 if (nla_parse(channel,
5067 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5068 nla_data(channels), nla_len(channels),
5069 wlan_hdd_extscan_config_policy)) {
5070 hddLog(LOGE, FL("nla_parse failed"));
5071 return -EINVAL;
5072 }
5073
5074 /* Parse and fetch channel */
5075 if (!channel[
5076 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5077 hddLog(LOGE, FL("attr channel failed"));
5078 return -EINVAL;
5079 }
5080 pReqMsg->buckets[bktIndex].channels[j].channel =
5081 nla_get_u32(channel[
5082 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5083 hddLog(LOG1, FL("channel %u"),
5084 pReqMsg->buckets[bktIndex].channels[j].channel);
5085
5086 /* Parse and fetch dwell time */
5087 if (!channel[
5088 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5089 hddLog(LOGE, FL("attr dwelltime failed"));
5090 return -EINVAL;
5091 }
5092 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5093 nla_get_u32(channel[
5094 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5095
5096 hddLog(LOG1, FL("Dwell time (%u ms)"),
5097 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5098
5099
5100 /* Parse and fetch channel spec passive */
5101 if (!channel[
5102 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5103 hddLog(LOGE,
5104 FL("attr channel spec passive failed"));
5105 return -EINVAL;
5106 }
5107 pReqMsg->buckets[bktIndex].channels[j].passive =
5108 nla_get_u8(channel[
5109 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5110 hddLog(LOG1, FL("Chnl spec passive %u"),
5111 pReqMsg->buckets[bktIndex].channels[j].passive);
5112
5113 j++;
5114 }
5115
Dundi Raviteja18d0c062018-11-13 19:56:45 +05305116 if (j != pReqMsg->buckets[bktIndex].numChannels) {
5117 hddLog(LOG1, FL("Input parameters didn't match"));
5118 return -EINVAL;
5119 }
5120
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305121 bktIndex++;
5122 }
5123
5124 return 0;
5125}
5126
5127
5128/*
5129 * define short names for the global vendor params
5130 * used by wlan_hdd_cfg80211_extscan_start()
5131 */
5132#define PARAM_MAX \
5133QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5134#define PARAM_REQUEST_ID \
5135QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5136#define PARAM_BASE_PERIOD \
5137QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5138#define PARAM_MAX_AP_PER_SCAN \
5139QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5140#define PARAM_RPT_THRHLD_PERCENT \
5141QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5142#define PARAM_RPT_THRHLD_NUM_SCANS \
5143QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5144#define PARAM_NUM_BUCKETS \
5145QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5146
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305147static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305148 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305149 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305150{
Dino Myclee8843b32014-07-04 14:21:45 +05305151 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305152 struct net_device *dev = wdev->netdev;
5153 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5154 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5155 struct nlattr *tb[PARAM_MAX + 1];
5156 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305157 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305158 tANI_U32 request_id;
5159 struct hdd_ext_scan_context *context;
5160 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305161
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305162 ENTER();
5163
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305164 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305165 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305166
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305167 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305168 data, dataLen,
5169 wlan_hdd_extscan_config_policy)) {
5170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5171 return -EINVAL;
5172 }
5173
5174 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305175 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305176 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5177 return -EINVAL;
5178 }
5179
Dino Myclee8843b32014-07-04 14:21:45 +05305180 pReqMsg = (tpSirEXTScanStartReqParams)
5181 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305182 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305183 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5184 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305185 }
5186
5187 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305188 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305189 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5190
5191 pReqMsg->sessionId = pAdapter->sessionId;
5192 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5193
5194 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305195 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5197 goto fail;
5198 }
5199 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305200 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305201 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5202 pReqMsg->basePeriod);
5203
5204 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305205 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5207 goto fail;
5208 }
5209 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305210 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305211 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5212 pReqMsg->maxAPperScan);
5213
5214 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305215 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5217 goto fail;
5218 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305219 pReqMsg->reportThresholdPercent = nla_get_u8(
5220 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305221 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305222 pReqMsg->reportThresholdPercent);
5223
5224 /* Parse and fetch report threshold num scans */
5225 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5226 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5227 goto fail;
5228 }
5229 pReqMsg->reportThresholdNumScans = nla_get_u8(
5230 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5231 hddLog(LOG1, FL("Report Threshold num scans %d"),
5232 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305233
5234 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305235 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5237 goto fail;
5238 }
5239 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305240 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305241 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5242 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5243 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5244 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5245 }
5246 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5247 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305248
Dino Mycle6fb96c12014-06-10 11:52:40 +05305249 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5250 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5251 goto fail;
5252 }
5253
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305254 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305255
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305256 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5257 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305258
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305259 context = &pHddCtx->ext_scan_context;
5260 spin_lock(&hdd_context_lock);
5261 INIT_COMPLETION(context->response_event);
5262 context->request_id = request_id = pReqMsg->requestId;
5263 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305264
Dino Mycle6fb96c12014-06-10 11:52:40 +05305265 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5266 if (!HAL_STATUS_SUCCESS(status)) {
5267 hddLog(VOS_TRACE_LEVEL_ERROR,
5268 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305269 goto fail;
5270 }
5271
Srinivas Dasari91727c12016-03-23 17:59:06 +05305272 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5273
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305274 /* request was sent -- wait for the response */
5275 rc = wait_for_completion_timeout(&context->response_event,
5276 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5277
5278 if (!rc) {
5279 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5280 retval = -ETIMEDOUT;
5281 } else {
5282 spin_lock(&hdd_context_lock);
5283 if (context->request_id == request_id)
5284 retval = context->response_status;
5285 else
5286 retval = -EINVAL;
5287 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305288 }
5289
Dino Myclee8843b32014-07-04 14:21:45 +05305290 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305291 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305292 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305293
5294fail:
5295 vos_mem_free(pReqMsg);
5296 return -EINVAL;
5297}
5298
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305299/*
5300 * done with short names for the global vendor params
5301 * used by wlan_hdd_cfg80211_extscan_start()
5302 */
5303#undef PARAM_MAX
5304#undef PARAM_REQUEST_ID
5305#undef PARAM_BASE_PERIOD
5306#undef PARAMS_MAX_AP_PER_SCAN
5307#undef PARAMS_RPT_THRHLD_PERCENT
5308#undef PARAMS_RPT_THRHLD_NUM_SCANS
5309#undef PARAMS_NUM_BUCKETS
5310
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305311static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5312 struct wireless_dev *wdev,
5313 const void *data, int dataLen)
5314{
5315 int ret = 0;
5316
5317 vos_ssr_protect(__func__);
5318 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5319 vos_ssr_unprotect(__func__);
5320
5321 return ret;
5322}
5323
5324static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305325 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305326 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305327{
Dino Myclee8843b32014-07-04 14:21:45 +05305328 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305329 struct net_device *dev = wdev->netdev;
5330 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5331 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5332 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5333 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305334 int retval;
5335 unsigned long rc;
5336 struct hdd_ext_scan_context *context;
5337 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305338
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305339 ENTER();
5340
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305341 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305342 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305343
Dino Mycle6fb96c12014-06-10 11:52:40 +05305344 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5345 data, dataLen,
5346 wlan_hdd_extscan_config_policy)) {
5347 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5348 return -EINVAL;
5349 }
5350
5351 /* Parse and fetch request Id */
5352 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5354 return -EINVAL;
5355 }
5356
Dino Myclee8843b32014-07-04 14:21:45 +05305357 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305358 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305359 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305360
Dino Myclee8843b32014-07-04 14:21:45 +05305361 reqMsg.sessionId = pAdapter->sessionId;
5362 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305363
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305364 context = &pHddCtx->ext_scan_context;
5365 spin_lock(&hdd_context_lock);
5366 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305367 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305368 spin_unlock(&hdd_context_lock);
5369
Dino Myclee8843b32014-07-04 14:21:45 +05305370 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305371 if (!HAL_STATUS_SUCCESS(status)) {
5372 hddLog(VOS_TRACE_LEVEL_ERROR,
5373 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305374 return -EINVAL;
5375 }
5376
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305377 /* request was sent -- wait for the response */
5378 rc = wait_for_completion_timeout(&context->response_event,
5379 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5380
5381 if (!rc) {
5382 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5383 retval = -ETIMEDOUT;
5384 } else {
5385 spin_lock(&hdd_context_lock);
5386 if (context->request_id == request_id)
5387 retval = context->response_status;
5388 else
5389 retval = -EINVAL;
5390 spin_unlock(&hdd_context_lock);
5391 }
5392
5393 return retval;
5394
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305395 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305396 return 0;
5397}
5398
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305399static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5400 struct wireless_dev *wdev,
5401 const void *data, int dataLen)
5402{
5403 int ret = 0;
5404
5405 vos_ssr_protect(__func__);
5406 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5407 vos_ssr_unprotect(__func__);
5408
5409 return ret;
5410}
5411
5412static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305413 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305414 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305415{
Dino Myclee8843b32014-07-04 14:21:45 +05305416 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305417 struct net_device *dev = wdev->netdev;
5418 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5419 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5420 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5421 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305422 struct hdd_ext_scan_context *context;
5423 tANI_U32 request_id;
5424 unsigned long rc;
5425 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305426
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305427 ENTER();
5428
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305429 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305430 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305431
Dino Mycle6fb96c12014-06-10 11:52:40 +05305432 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5433 data, dataLen,
5434 wlan_hdd_extscan_config_policy)) {
5435 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5436 return -EINVAL;
5437 }
5438
5439 /* Parse and fetch request Id */
5440 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5442 return -EINVAL;
5443 }
5444
Dino Myclee8843b32014-07-04 14:21:45 +05305445 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305446 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305447 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305448
Dino Myclee8843b32014-07-04 14:21:45 +05305449 reqMsg.sessionId = pAdapter->sessionId;
5450 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305451
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305452 context = &pHddCtx->ext_scan_context;
5453 spin_lock(&hdd_context_lock);
5454 INIT_COMPLETION(context->response_event);
5455 context->request_id = request_id = reqMsg.requestId;
5456 spin_unlock(&hdd_context_lock);
5457
Dino Myclee8843b32014-07-04 14:21:45 +05305458 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305459 if (!HAL_STATUS_SUCCESS(status)) {
5460 hddLog(VOS_TRACE_LEVEL_ERROR,
5461 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305462 return -EINVAL;
5463 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305464
5465 /* request was sent -- wait for the response */
5466 rc = wait_for_completion_timeout(&context->response_event,
5467 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5468 if (!rc) {
5469 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5470 retval = -ETIMEDOUT;
5471 } else {
5472 spin_lock(&hdd_context_lock);
5473 if (context->request_id == request_id)
5474 retval = context->response_status;
5475 else
5476 retval = -EINVAL;
5477 spin_unlock(&hdd_context_lock);
5478 }
5479
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305480 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305481 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305482}
5483
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305484static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5485 struct wireless_dev *wdev,
5486 const void *data, int dataLen)
5487{
5488 int ret = 0;
5489
5490 vos_ssr_protect(__func__);
5491 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5492 vos_ssr_unprotect(__func__);
5493
5494 return ret;
5495}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305496#endif /* WLAN_FEATURE_EXTSCAN */
5497
Atul Mittal115287b2014-07-08 13:26:33 +05305498/*EXT TDLS*/
5499static const struct nla_policy
5500wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5501{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305502 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5503 .type = NLA_UNSPEC,
5504 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305505 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5506 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5507 {.type = NLA_S32 },
5508 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5509 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5510
5511};
5512
5513static const struct nla_policy
5514wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5515{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305516 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5517 .type = NLA_UNSPEC,
5518 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305519
5520};
5521
5522static const struct nla_policy
5523wlan_hdd_tdls_config_state_change_policy[
5524 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5525{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305526 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5527 .type = NLA_UNSPEC,
5528 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305529 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5530 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305531 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5532 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5533 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305534
5535};
5536
5537static const struct nla_policy
5538wlan_hdd_tdls_config_get_status_policy[
5539 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5540{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305541 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5542 .type = NLA_UNSPEC,
5543 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305544 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5545 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305546 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5547 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5548 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305549
5550};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305551
5552static const struct nla_policy
5553wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5554{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305555 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5556 .type = NLA_UNSPEC,
5557 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305558};
5559
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305560static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305561 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305562 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305563 int data_len)
5564{
5565
5566 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Sourav Mohapatraaf2cc672018-10-30 17:43:29 +05305567 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305568 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5569
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305570 ENTER();
5571
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305572 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305573 return -EINVAL;
5574 }
Sourav Mohapatraaf2cc672018-10-30 17:43:29 +05305575
5576 if (!adapter) {
5577 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5578 return -EINVAL;
5579 }
5580
5581 if (adapter->device_mode != WLAN_HDD_INFRA_STATION) {
5582 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN allowed only in STA"));
5583 return -ENOTSUPP;
5584 }
5585
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305586 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305587 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305588 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305589 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305590 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305591 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305592 return -ENOTSUPP;
5593 }
5594
5595 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5596 data, data_len, wlan_hdd_mac_config)) {
5597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5598 return -EINVAL;
5599 }
5600
5601 /* Parse and fetch mac address */
5602 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5603 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5604 return -EINVAL;
5605 }
5606
5607 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5608 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5609 VOS_MAC_ADDR_LAST_3_BYTES);
5610
Siddharth Bhal76972212014-10-15 16:22:51 +05305611 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5612
5613 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305614 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5615 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305616 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5617 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5618 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5619 {
5620 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5621 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5622 VOS_MAC_ADDRESS_LEN);
5623 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305624 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305625
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305626 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5627 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305628
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305629 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305630 return 0;
5631}
5632
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305633static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5634 struct wireless_dev *wdev,
5635 const void *data,
5636 int data_len)
5637{
5638 int ret = 0;
5639
5640 vos_ssr_protect(__func__);
5641 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5642 vos_ssr_unprotect(__func__);
5643
5644 return ret;
5645}
5646
5647static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305648 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305649 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305650 int data_len)
5651{
5652 u8 peer[6] = {0};
5653 struct net_device *dev = wdev->netdev;
5654 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5655 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5656 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5657 eHalStatus ret;
5658 tANI_S32 state;
5659 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305660 tANI_S32 global_operating_class = 0;
5661 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305662 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305663 int retVal;
5664
5665 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305666
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305667 if (!pAdapter) {
5668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5669 return -EINVAL;
5670 }
5671
Atul Mittal115287b2014-07-08 13:26:33 +05305672 ret = wlan_hdd_validate_context(pHddCtx);
5673 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305675 return -EINVAL;
5676 }
5677 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305679 return -ENOTSUPP;
5680 }
5681 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5682 data, data_len,
5683 wlan_hdd_tdls_config_get_status_policy)) {
5684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5685 return -EINVAL;
5686 }
5687
5688 /* Parse and fetch mac address */
5689 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5690 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5691 return -EINVAL;
5692 }
5693
5694 memcpy(peer, nla_data(
5695 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5696 sizeof(peer));
5697 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5698
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305699 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305700
Atul Mittal115287b2014-07-08 13:26:33 +05305701 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305702 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305703 NLMSG_HDRLEN);
5704
5705 if (!skb) {
5706 hddLog(VOS_TRACE_LEVEL_ERROR,
5707 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5708 return -EINVAL;
5709 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305710 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 +05305711 reason,
5712 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305713 global_operating_class,
5714 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305715 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305716 if (nla_put_s32(skb,
5717 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5718 state) ||
5719 nla_put_s32(skb,
5720 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5721 reason) ||
5722 nla_put_s32(skb,
5723 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5724 global_operating_class) ||
5725 nla_put_s32(skb,
5726 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5727 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305728
5729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5730 goto nla_put_failure;
5731 }
5732
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305733 retVal = cfg80211_vendor_cmd_reply(skb);
5734 EXIT();
5735 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305736
5737nla_put_failure:
5738 kfree_skb(skb);
5739 return -EINVAL;
5740}
5741
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305742static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5743 struct wireless_dev *wdev,
5744 const void *data,
5745 int data_len)
5746{
5747 int ret = 0;
5748
5749 vos_ssr_protect(__func__);
5750 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5751 vos_ssr_unprotect(__func__);
5752
5753 return ret;
5754}
5755
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305756static int wlan_hdd_cfg80211_exttdls_callback(
5757#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5758 const tANI_U8* mac,
5759#else
5760 tANI_U8* mac,
5761#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305762 tANI_S32 state,
5763 tANI_S32 reason,
5764 void *ctx)
5765{
5766 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305767 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305768 tANI_S32 global_operating_class = 0;
5769 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305770 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305771
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305772 ENTER();
5773
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305774 if (!pAdapter) {
5775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5776 return -EINVAL;
5777 }
5778
5779 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305780 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305782 return -EINVAL;
5783 }
5784
5785 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305786 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305787 return -ENOTSUPP;
5788 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305789 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5791 NULL,
5792#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305793 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5794 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5795 GFP_KERNEL);
5796
5797 if (!skb) {
5798 hddLog(VOS_TRACE_LEVEL_ERROR,
5799 FL("cfg80211_vendor_event_alloc failed"));
5800 return -EINVAL;
5801 }
5802 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305803 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5804 reason,
5805 state,
5806 global_operating_class,
5807 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305808 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5809 MAC_ADDR_ARRAY(mac));
5810
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305811 if (nla_put(skb,
5812 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5813 VOS_MAC_ADDR_SIZE, mac) ||
5814 nla_put_s32(skb,
5815 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5816 state) ||
5817 nla_put_s32(skb,
5818 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5819 reason) ||
5820 nla_put_s32(skb,
5821 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5822 channel) ||
5823 nla_put_s32(skb,
5824 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5825 global_operating_class)
5826 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5828 goto nla_put_failure;
5829 }
5830
5831 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305832 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305833 return (0);
5834
5835nla_put_failure:
5836 kfree_skb(skb);
5837 return -EINVAL;
5838}
5839
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305840static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305841 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305842 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305843 int data_len)
5844{
5845 u8 peer[6] = {0};
5846 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5848 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5849 eHalStatus status;
5850 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305851 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305852 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305853
5854 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305855
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305856 if (!dev) {
5857 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5858 return -EINVAL;
5859 }
5860
5861 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5862 if (!pAdapter) {
5863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5864 return -EINVAL;
5865 }
5866
Atul Mittal115287b2014-07-08 13:26:33 +05305867 status = wlan_hdd_validate_context(pHddCtx);
5868 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305870 return -EINVAL;
5871 }
5872 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305873 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305874 return -ENOTSUPP;
5875 }
5876 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5877 data, data_len,
5878 wlan_hdd_tdls_config_enable_policy)) {
5879 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5880 return -EINVAL;
5881 }
5882
5883 /* Parse and fetch mac address */
5884 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5885 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5886 return -EINVAL;
5887 }
5888
5889 memcpy(peer, nla_data(
5890 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5891 sizeof(peer));
5892 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5893
5894 /* Parse and fetch channel */
5895 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5896 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5897 return -EINVAL;
5898 }
5899 pReqMsg.channel = nla_get_s32(
5900 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5901 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5902
5903 /* Parse and fetch global operating class */
5904 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5905 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5906 return -EINVAL;
5907 }
5908 pReqMsg.global_operating_class = nla_get_s32(
5909 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5910 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5911 pReqMsg.global_operating_class);
5912
5913 /* Parse and fetch latency ms */
5914 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5915 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5916 return -EINVAL;
5917 }
5918 pReqMsg.max_latency_ms = nla_get_s32(
5919 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5920 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5921 pReqMsg.max_latency_ms);
5922
5923 /* Parse and fetch required bandwidth kbps */
5924 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5925 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5926 return -EINVAL;
5927 }
5928
5929 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5930 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5931 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5932 pReqMsg.min_bandwidth_kbps);
5933
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305934 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305935 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305936 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305937 wlan_hdd_cfg80211_exttdls_callback);
5938
5939 EXIT();
5940 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305941}
5942
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305943static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5944 struct wireless_dev *wdev,
5945 const void *data,
5946 int data_len)
5947{
5948 int ret = 0;
5949
5950 vos_ssr_protect(__func__);
5951 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5952 vos_ssr_unprotect(__func__);
5953
5954 return ret;
5955}
5956
5957static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305958 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305959 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305960 int data_len)
5961{
5962 u8 peer[6] = {0};
5963 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305964 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5965 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5966 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305967 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305968 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305969
5970 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305971
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305972 if (!dev) {
5973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5974 return -EINVAL;
5975 }
5976
5977 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5978 if (!pAdapter) {
5979 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5980 return -EINVAL;
5981 }
5982
Atul Mittal115287b2014-07-08 13:26:33 +05305983 status = wlan_hdd_validate_context(pHddCtx);
5984 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305985 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305986 return -EINVAL;
5987 }
5988 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305990 return -ENOTSUPP;
5991 }
5992 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5993 data, data_len,
5994 wlan_hdd_tdls_config_disable_policy)) {
5995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5996 return -EINVAL;
5997 }
5998 /* Parse and fetch mac address */
5999 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
6000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
6001 return -EINVAL;
6002 }
6003
6004 memcpy(peer, nla_data(
6005 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
6006 sizeof(peer));
6007 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
6008
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306009 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
6010
6011 EXIT();
6012 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05306013}
6014
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306015static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6016 struct wireless_dev *wdev,
6017 const void *data,
6018 int data_len)
6019{
6020 int ret = 0;
6021
6022 vos_ssr_protect(__func__);
6023 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6024 vos_ssr_unprotect(__func__);
6025
6026 return ret;
6027}
6028
Dasari Srinivas7875a302014-09-26 17:50:57 +05306029static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306030__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306031 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306032 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306033{
6034 struct net_device *dev = wdev->netdev;
6035 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6036 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6037 struct sk_buff *skb = NULL;
6038 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306039 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306040
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306041 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306042
6043 ret = wlan_hdd_validate_context(pHddCtx);
6044 if (0 != ret)
6045 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306046 return ret;
6047 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306048 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6049 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6050 fset |= WIFI_FEATURE_INFRA;
6051 }
6052
6053 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6054 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6055 fset |= WIFI_FEATURE_INFRA_5G;
6056 }
6057
6058#ifdef WLAN_FEATURE_P2P
6059 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6060 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6061 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6062 fset |= WIFI_FEATURE_P2P;
6063 }
6064#endif
6065
6066 /* Soft-AP is supported currently by default */
6067 fset |= WIFI_FEATURE_SOFT_AP;
6068
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306069 /* HOTSPOT is a supplicant feature, enable it by default */
6070 fset |= WIFI_FEATURE_HOTSPOT;
6071
Dasari Srinivas7875a302014-09-26 17:50:57 +05306072#ifdef WLAN_FEATURE_EXTSCAN
6073 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306074 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6075 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6076 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306077 fset |= WIFI_FEATURE_EXTSCAN;
6078 }
6079#endif
6080
Dasari Srinivas7875a302014-09-26 17:50:57 +05306081 if (sme_IsFeatureSupportedByFW(NAN)) {
6082 hddLog(LOG1, FL("NAN is supported by firmware"));
6083 fset |= WIFI_FEATURE_NAN;
6084 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306085
6086 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306087 if (sme_IsFeatureSupportedByFW(RTT) &&
6088 pHddCtx->cfg_ini->enable_rtt_support) {
6089 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306090 fset |= WIFI_FEATURE_D2AP_RTT;
6091 }
6092
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306093 if (sme_IsFeatureSupportedByFW(RTT3)) {
6094 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6095 fset |= WIFI_FEATURE_RTT3;
6096 }
6097
Dasari Srinivas7875a302014-09-26 17:50:57 +05306098#ifdef FEATURE_WLAN_BATCH_SCAN
6099 if (fset & WIFI_FEATURE_EXTSCAN) {
6100 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6101 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6102 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6103 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6104 fset |= WIFI_FEATURE_BATCH_SCAN;
6105 }
6106#endif
6107
6108#ifdef FEATURE_WLAN_SCAN_PNO
6109 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6110 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6111 hddLog(LOG1, FL("PNO is supported by firmware"));
6112 fset |= WIFI_FEATURE_PNO;
6113 }
6114#endif
6115
6116 /* STA+STA is supported currently by default */
6117 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6118
6119#ifdef FEATURE_WLAN_TDLS
6120 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6121 sme_IsFeatureSupportedByFW(TDLS)) {
6122 hddLog(LOG1, FL("TDLS is supported by firmware"));
6123 fset |= WIFI_FEATURE_TDLS;
6124 }
6125
6126 /* TDLS_OFFCHANNEL is not supported currently by default */
6127#endif
6128
6129#ifdef WLAN_AP_STA_CONCURRENCY
6130 /* AP+STA concurrency is supported currently by default */
6131 fset |= WIFI_FEATURE_AP_STA;
6132#endif
6133
Mukul Sharma5add0532015-08-17 15:57:47 +05306134#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306135 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6136 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306137 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6138 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306139 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306140#endif
6141
Dasari Srinivas7875a302014-09-26 17:50:57 +05306142 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6143 NLMSG_HDRLEN);
6144
6145 if (!skb) {
6146 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6147 return -EINVAL;
6148 }
6149 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6150
6151 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6152 hddLog(LOGE, FL("nla put fail"));
6153 goto nla_put_failure;
6154 }
6155
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306156 ret = cfg80211_vendor_cmd_reply(skb);
6157 EXIT();
6158 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306159
6160nla_put_failure:
6161 kfree_skb(skb);
6162 return -EINVAL;
6163}
6164
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306165static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306166wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6167 struct wireless_dev *wdev,
6168 const void *data, int data_len)
6169{
6170 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306171 vos_ssr_protect(__func__);
6172 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6173 vos_ssr_unprotect(__func__);
6174
6175 return ret;
6176}
6177
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306178
6179static const struct
6180nla_policy
6181qca_wlan_vendor_wifi_logger_get_ring_data_policy
6182[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6183 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6184 = {.type = NLA_U32 },
6185};
6186
6187static int
6188 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6189 struct wireless_dev *wdev,
6190 const void *data,
6191 int data_len)
6192{
6193 int ret;
6194 VOS_STATUS status;
6195 uint32_t ring_id;
6196 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6197 struct nlattr *tb
6198 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6199
6200 ENTER();
6201
6202 ret = wlan_hdd_validate_context(hdd_ctx);
6203 if (0 != ret) {
6204 return ret;
6205 }
6206
6207 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6208 data, data_len,
6209 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6210 hddLog(LOGE, FL("Invalid attribute"));
6211 return -EINVAL;
6212 }
6213
6214 /* Parse and fetch ring id */
6215 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6216 hddLog(LOGE, FL("attr ATTR failed"));
6217 return -EINVAL;
6218 }
6219
6220 ring_id = nla_get_u32(
6221 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6222
6223 hddLog(LOG1, FL("Bug report triggered by framework"));
6224
6225 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6226 WLAN_LOG_INDICATOR_FRAMEWORK,
6227 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306228 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306229 );
6230 if (VOS_STATUS_SUCCESS != status) {
6231 hddLog(LOGE, FL("Failed to trigger bug report"));
6232
6233 return -EINVAL;
6234 }
6235
6236 return 0;
6237
6238
6239}
6240
6241
6242static int
6243 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6244 struct wireless_dev *wdev,
6245 const void *data,
6246 int data_len)
6247{
6248 int ret = 0;
6249
6250 vos_ssr_protect(__func__);
6251 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6252 wdev, data, data_len);
6253 vos_ssr_unprotect(__func__);
6254
6255 return ret;
6256
6257}
6258
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306259#define MAX_CONCURRENT_MATRIX \
6260 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6261#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6262 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6263static const struct nla_policy
6264wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6265 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6266};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306267
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306268static int
6269__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306270 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306271 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306272{
6273 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6274 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306275 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306276 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306277 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6278 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306279
6280 ENTER();
6281
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306282 ret = wlan_hdd_validate_context(pHddCtx);
6283 if (0 != ret)
6284 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306285 return ret;
6286 }
6287
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306288 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6289 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306290 hddLog(LOGE, FL("Invalid ATTR"));
6291 return -EINVAL;
6292 }
6293
6294 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306295 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306296 hddLog(LOGE, FL("Attr max feature set size failed"));
6297 return -EINVAL;
6298 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306299 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306300 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6301
6302 /* Fill feature combination matrix */
6303 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306304 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6305 WIFI_FEATURE_P2P;
6306
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306307 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6308 WIFI_FEATURE_SOFT_AP;
6309
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306310 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6311 WIFI_FEATURE_SOFT_AP;
6312
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306313 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6314 WIFI_FEATURE_SOFT_AP |
6315 WIFI_FEATURE_P2P;
6316
6317 /* Add more feature combinations here */
6318
6319 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6320 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6321 hddLog(LOG1, "Feature set matrix");
6322 for (i = 0; i < feature_sets; i++)
6323 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6324
6325 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6326 sizeof(u32) * feature_sets +
6327 NLMSG_HDRLEN);
6328
6329 if (reply_skb) {
6330 if (nla_put_u32(reply_skb,
6331 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6332 feature_sets) ||
6333 nla_put(reply_skb,
6334 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6335 sizeof(u32) * feature_sets, feature_set_matrix)) {
6336 hddLog(LOGE, FL("nla put fail"));
6337 kfree_skb(reply_skb);
6338 return -EINVAL;
6339 }
6340
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306341 ret = cfg80211_vendor_cmd_reply(reply_skb);
6342 EXIT();
6343 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306344 }
6345 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6346 return -ENOMEM;
6347
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306348}
6349
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306350#undef MAX_CONCURRENT_MATRIX
6351#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6352
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306353static int
6354wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6355 struct wireless_dev *wdev,
6356 const void *data, int data_len)
6357{
6358 int ret = 0;
6359
6360 vos_ssr_protect(__func__);
6361 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6362 data_len);
6363 vos_ssr_unprotect(__func__);
6364
6365 return ret;
6366}
6367
Sushant Kaushik8e644982015-09-23 12:18:54 +05306368static const struct
6369nla_policy
6370qca_wlan_vendor_wifi_logger_start_policy
6371[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6372 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6373 = {.type = NLA_U32 },
6374 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6375 = {.type = NLA_U32 },
6376 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6377 = {.type = NLA_U32 },
6378};
6379
6380/**
6381 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6382 * or disable the collection of packet statistics from the firmware
6383 * @wiphy: WIPHY structure pointer
6384 * @wdev: Wireless device structure pointer
6385 * @data: Pointer to the data received
6386 * @data_len: Length of the data received
6387 *
6388 * This function is used to enable or disable the collection of packet
6389 * statistics from the firmware
6390 *
6391 * Return: 0 on success and errno on failure
6392 */
6393static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6394 struct wireless_dev *wdev,
6395 const void *data,
6396 int data_len)
6397{
6398 eHalStatus status;
6399 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6400 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6401 tAniWifiStartLog start_log;
6402
6403 status = wlan_hdd_validate_context(hdd_ctx);
6404 if (0 != status) {
6405 return -EINVAL;
6406 }
6407
6408 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6409 data, data_len,
6410 qca_wlan_vendor_wifi_logger_start_policy)) {
6411 hddLog(LOGE, FL("Invalid attribute"));
6412 return -EINVAL;
6413 }
6414
6415 /* Parse and fetch ring id */
6416 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6417 hddLog(LOGE, FL("attr ATTR failed"));
6418 return -EINVAL;
6419 }
6420 start_log.ringId = nla_get_u32(
6421 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6422 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6423
6424 /* Parse and fetch verbose level */
6425 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6426 hddLog(LOGE, FL("attr verbose_level failed"));
6427 return -EINVAL;
6428 }
6429 start_log.verboseLevel = nla_get_u32(
6430 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6431 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6432
6433 /* Parse and fetch flag */
6434 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6435 hddLog(LOGE, FL("attr flag failed"));
6436 return -EINVAL;
6437 }
6438 start_log.flag = nla_get_u32(
6439 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6440 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6441
6442 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306443 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6444 !vos_isPktStatsEnabled()))
6445
Sushant Kaushik8e644982015-09-23 12:18:54 +05306446 {
6447 hddLog(LOGE, FL("per pkt stats not enabled"));
6448 return -EINVAL;
6449 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306450
Sushant Kaushik33200572015-08-05 16:46:20 +05306451 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306452 return 0;
6453}
6454
6455/**
6456 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6457 * or disable the collection of packet statistics from the firmware
6458 * @wiphy: WIPHY structure pointer
6459 * @wdev: Wireless device structure pointer
6460 * @data: Pointer to the data received
6461 * @data_len: Length of the data received
6462 *
6463 * This function is used to enable or disable the collection of packet
6464 * statistics from the firmware
6465 *
6466 * Return: 0 on success and errno on failure
6467 */
6468static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6469 struct wireless_dev *wdev,
6470 const void *data,
6471 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306472{
6473 int ret = 0;
6474
6475 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306476
6477 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6478 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306479 vos_ssr_unprotect(__func__);
6480
6481 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306482}
6483
6484
Agarwal Ashish738843c2014-09-25 12:27:56 +05306485static const struct nla_policy
6486wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6487 +1] =
6488{
6489 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6490};
6491
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306492static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306493 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306494 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306495 int data_len)
6496{
6497 struct net_device *dev = wdev->netdev;
6498 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6499 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6500 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6501 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6502 eHalStatus status;
6503 u32 dfsFlag = 0;
6504
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306505 ENTER();
6506
Agarwal Ashish738843c2014-09-25 12:27:56 +05306507 status = wlan_hdd_validate_context(pHddCtx);
6508 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306509 return -EINVAL;
6510 }
6511 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6512 data, data_len,
6513 wlan_hdd_set_no_dfs_flag_config_policy)) {
6514 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6515 return -EINVAL;
6516 }
6517
6518 /* Parse and fetch required bandwidth kbps */
6519 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6521 return -EINVAL;
6522 }
6523
6524 dfsFlag = nla_get_u32(
6525 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6526 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6527 dfsFlag);
6528
6529 pHddCtx->disable_dfs_flag = dfsFlag;
6530
6531 sme_disable_dfs_channel(hHal, dfsFlag);
6532 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306533
6534 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306535 return 0;
6536}
Atul Mittal115287b2014-07-08 13:26:33 +05306537
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306538static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6539 struct wireless_dev *wdev,
6540 const void *data,
6541 int data_len)
6542{
6543 int ret = 0;
6544
6545 vos_ssr_protect(__func__);
6546 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6547 vos_ssr_unprotect(__func__);
6548
6549 return ret;
6550
6551}
6552
Mukul Sharma2a271632014-10-13 14:59:01 +05306553const struct
6554nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6555{
6556 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306557 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6558 .type = NLA_UNSPEC,
6559 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306560};
6561
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306562static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306563 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306564{
6565
6566 u8 bssid[6] = {0};
6567 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6568 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6569 eHalStatus status = eHAL_STATUS_SUCCESS;
6570 v_U32_t isFwrRoamEnabled = FALSE;
6571 int ret;
6572
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306573 ENTER();
6574
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306575 ret = wlan_hdd_validate_context(pHddCtx);
6576 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306577 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306578 }
6579
6580 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6581 data, data_len,
6582 qca_wlan_vendor_attr);
6583 if (ret){
6584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6585 return -EINVAL;
6586 }
6587
6588 /* Parse and fetch Enable flag */
6589 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6591 return -EINVAL;
6592 }
6593
6594 isFwrRoamEnabled = nla_get_u32(
6595 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6596
6597 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6598
6599 /* Parse and fetch bssid */
6600 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6602 return -EINVAL;
6603 }
6604
6605 memcpy(bssid, nla_data(
6606 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6607 sizeof(bssid));
6608 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6609
6610 //Update roaming
6611 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306612 if (!HAL_STATUS_SUCCESS(status)) {
6613 hddLog(LOGE,
6614 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6615 return -EINVAL;
6616 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306617 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306618 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306619}
6620
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306621static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6622 struct wireless_dev *wdev, const void *data, int data_len)
6623{
6624 int ret = 0;
6625
6626 vos_ssr_protect(__func__);
6627 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6628 vos_ssr_unprotect(__func__);
6629
6630 return ret;
6631}
6632
Sushant Kaushik847890c2015-09-28 16:05:17 +05306633static const struct
6634nla_policy
6635qca_wlan_vendor_get_wifi_info_policy[
6636 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6637 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6638 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6639};
6640
6641
6642/**
6643 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6644 * @wiphy: pointer to wireless wiphy structure.
6645 * @wdev: pointer to wireless_dev structure.
6646 * @data: Pointer to the data to be passed via vendor interface
6647 * @data_len:Length of the data to be passed
6648 *
6649 * This is called when wlan driver needs to send wifi driver related info
6650 * (driver/fw version) to the user space application upon request.
6651 *
6652 * Return: Return the Success or Failure code.
6653 */
6654static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6655 struct wireless_dev *wdev,
6656 const void *data, int data_len)
6657{
6658 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6659 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6660 tSirVersionString version;
6661 uint32 version_len;
6662 uint8 attr;
6663 int status;
6664 struct sk_buff *reply_skb = NULL;
6665
6666 if (VOS_FTM_MODE == hdd_get_conparam()) {
6667 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6668 return -EINVAL;
6669 }
6670
6671 status = wlan_hdd_validate_context(hdd_ctx);
6672 if (0 != status) {
6673 hddLog(LOGE, FL("HDD context is not valid"));
6674 return -EINVAL;
6675 }
6676
6677 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6678 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6679 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6680 return -EINVAL;
6681 }
6682
6683 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6684 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6685 QWLAN_VERSIONSTR);
6686 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6687 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6688 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6689 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6690 hdd_ctx->fw_Version);
6691 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6692 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6693 } else {
6694 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6695 return -EINVAL;
6696 }
6697
6698 version_len = strlen(version);
6699 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6700 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6701 if (!reply_skb) {
6702 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6703 return -ENOMEM;
6704 }
6705
6706 if (nla_put(reply_skb, attr, version_len, version)) {
6707 hddLog(LOGE, FL("nla put fail"));
6708 kfree_skb(reply_skb);
6709 return -EINVAL;
6710 }
6711
6712 return cfg80211_vendor_cmd_reply(reply_skb);
6713}
6714
6715/**
6716 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6717 * @wiphy: pointer to wireless wiphy structure.
6718 * @wdev: pointer to wireless_dev structure.
6719 * @data: Pointer to the data to be passed via vendor interface
6720 * @data_len:Length of the data to be passed
6721 * @data_len: Length of the data received
6722 *
6723 * This function is used to enable or disable the collection of packet
6724 * statistics from the firmware
6725 *
6726 * Return: 0 on success and errno on failure
6727 */
6728
6729static int
6730wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6731 struct wireless_dev *wdev,
6732 const void *data, int data_len)
6733
6734
6735{
6736 int ret = 0;
6737
6738 vos_ssr_protect(__func__);
6739 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6740 wdev, data, data_len);
6741 vos_ssr_unprotect(__func__);
6742
6743 return ret;
6744}
6745
6746
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306747/*
6748 * define short names for the global vendor params
6749 * used by __wlan_hdd_cfg80211_monitor_rssi()
6750 */
6751#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6752#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6753#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6754#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6755#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6756
6757/**---------------------------------------------------------------------------
6758
6759 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6760 monitor start is completed successfully.
6761
6762 \return - None
6763
6764 --------------------------------------------------------------------------*/
6765void hdd_rssi_monitor_start_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 start successful"));
6779 }
6780 else
6781 {
6782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6783 }
6784
6785 return;
6786}
6787
6788/**---------------------------------------------------------------------------
6789
6790 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6791 stop is completed successfully.
6792
6793 \return - None
6794
6795 --------------------------------------------------------------------------*/
6796void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6797{
6798 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6799
6800 if (NULL == pHddCtx)
6801 {
6802 hddLog(VOS_TRACE_LEVEL_ERROR,
6803 "%s: HDD context is NULL",__func__);
6804 return;
6805 }
6806
6807 if (VOS_STATUS_SUCCESS == status)
6808 {
6809 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6810 }
6811 else
6812 {
6813 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6814 }
6815
6816 return;
6817}
6818
6819/**
6820 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6821 * @wiphy: Pointer to wireless phy
6822 * @wdev: Pointer to wireless device
6823 * @data: Pointer to data
6824 * @data_len: Data length
6825 *
6826 * Return: 0 on success, negative errno on failure
6827 */
6828
6829static int
6830__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6831 struct wireless_dev *wdev,
6832 const void *data,
6833 int data_len)
6834{
6835 struct net_device *dev = wdev->netdev;
6836 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6837 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6838 hdd_station_ctx_t *pHddStaCtx;
6839 struct nlattr *tb[PARAM_MAX + 1];
6840 tpSirRssiMonitorReq pReq;
6841 eHalStatus status;
6842 int ret;
6843 uint32_t control;
6844 static const struct nla_policy policy[PARAM_MAX + 1] = {
6845 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6846 [PARAM_CONTROL] = { .type = NLA_U32 },
6847 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6848 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6849 };
6850
6851 ENTER();
6852
6853 ret = wlan_hdd_validate_context(hdd_ctx);
6854 if (0 != ret) {
6855 return -EINVAL;
6856 }
6857
6858 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6859 hddLog(LOGE, FL("Not in Connected state!"));
6860 return -ENOTSUPP;
6861 }
6862
6863 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6864 hddLog(LOGE, FL("Invalid ATTR"));
6865 return -EINVAL;
6866 }
6867
6868 if (!tb[PARAM_REQUEST_ID]) {
6869 hddLog(LOGE, FL("attr request id failed"));
6870 return -EINVAL;
6871 }
6872
6873 if (!tb[PARAM_CONTROL]) {
6874 hddLog(LOGE, FL("attr control failed"));
6875 return -EINVAL;
6876 }
6877
6878 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6879
6880 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6881 if(NULL == pReq)
6882 {
6883 hddLog(LOGE,
6884 FL("vos_mem_alloc failed "));
6885 return eHAL_STATUS_FAILED_ALLOC;
6886 }
6887 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6888
6889 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6890 pReq->sessionId = pAdapter->sessionId;
6891 pReq->rssiMonitorCbContext = hdd_ctx;
6892 control = nla_get_u32(tb[PARAM_CONTROL]);
6893 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6894
6895 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6896 pReq->requestId, pReq->sessionId, control);
6897
6898 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6899 if (!tb[PARAM_MIN_RSSI]) {
6900 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306901 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306902 }
6903
6904 if (!tb[PARAM_MAX_RSSI]) {
6905 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306906 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306907 }
6908
6909 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6910 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6911 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6912
6913 if (!(pReq->minRssi < pReq->maxRssi)) {
6914 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6915 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306916 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306917 }
6918 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6919 pReq->minRssi, pReq->maxRssi);
6920 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6921
6922 }
6923 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6924 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6925 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6926 }
6927 else {
6928 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306929 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306930 }
6931
6932 if (!HAL_STATUS_SUCCESS(status)) {
6933 hddLog(LOGE,
6934 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306935 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306936 }
6937
6938 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306939fail:
6940 vos_mem_free(pReq);
6941 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306942}
6943
6944/*
6945 * done with short names for the global vendor params
6946 * used by __wlan_hdd_cfg80211_monitor_rssi()
6947 */
6948#undef PARAM_MAX
6949#undef PARAM_CONTROL
6950#undef PARAM_REQUEST_ID
6951#undef PARAM_MAX_RSSI
6952#undef PARAM_MIN_RSSI
6953
6954/**
6955 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6956 * @wiphy: wiphy structure pointer
6957 * @wdev: Wireless device structure pointer
6958 * @data: Pointer to the data received
6959 * @data_len: Length of @data
6960 *
6961 * Return: 0 on success; errno on failure
6962 */
6963static int
6964wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6965 const void *data, int data_len)
6966{
6967 int ret;
6968
6969 vos_ssr_protect(__func__);
6970 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6971 vos_ssr_unprotect(__func__);
6972
6973 return ret;
6974}
6975
6976/**
6977 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6978 * @hddctx: HDD context
6979 * @data: rssi breached event data
6980 *
6981 * This function reads the rssi breached event %data and fill in the skb with
6982 * NL attributes and send up the NL event.
6983 * This callback execute in atomic context and must not invoke any
6984 * blocking calls.
6985 *
6986 * Return: none
6987 */
6988void hdd_rssi_threshold_breached_cb(void *hddctx,
6989 struct rssi_breach_event *data)
6990{
6991 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6992 int status;
6993 struct sk_buff *skb;
6994
6995 ENTER();
6996 status = wlan_hdd_validate_context(pHddCtx);
6997
6998 if (0 != status) {
6999 return;
7000 }
7001
7002 if (!data) {
7003 hddLog(LOGE, FL("data is null"));
7004 return;
7005 }
7006
7007 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7008#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7009 NULL,
7010#endif
7011 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7012 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7013 GFP_KERNEL);
7014
7015 if (!skb) {
7016 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7017 return;
7018 }
7019
7020 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7021 data->request_id, data->curr_rssi);
7022 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7023 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7024
7025 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7026 data->request_id) ||
7027 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7028 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7029 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7030 data->curr_rssi)) {
7031 hddLog(LOGE, FL("nla put fail"));
7032 goto fail;
7033 }
7034
7035 cfg80211_vendor_event(skb, GFP_KERNEL);
7036 return;
7037
7038fail:
7039 kfree_skb(skb);
7040 return;
7041}
7042
7043
7044
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307045/**
7046 * __wlan_hdd_cfg80211_setband() - set band
7047 * @wiphy: Pointer to wireless phy
7048 * @wdev: Pointer to wireless device
7049 * @data: Pointer to data
7050 * @data_len: Data length
7051 *
7052 * Return: 0 on success, negative errno on failure
7053 */
7054static int
7055__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7056 struct wireless_dev *wdev,
7057 const void *data,
7058 int data_len)
7059{
7060 struct net_device *dev = wdev->netdev;
7061 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7062 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7063 int ret;
7064 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7065 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7066
7067 ENTER();
7068
7069 ret = wlan_hdd_validate_context(hdd_ctx);
7070 if (0 != ret) {
7071 hddLog(LOGE, FL("HDD context is not valid"));
7072 return ret;
7073 }
7074
7075 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7076 policy)) {
7077 hddLog(LOGE, FL("Invalid ATTR"));
7078 return -EINVAL;
7079 }
7080
7081 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7082 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7083 return -EINVAL;
7084 }
7085
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307086 hdd_ctx->isSetBandByNL = TRUE;
7087 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307088 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307089 hdd_ctx->isSetBandByNL = FALSE;
7090
7091 EXIT();
7092 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307093}
7094
7095/**
7096 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7097 * @wiphy: wiphy structure pointer
7098 * @wdev: Wireless device structure pointer
7099 * @data: Pointer to the data received
7100 * @data_len: Length of @data
7101 *
7102 * Return: 0 on success; errno on failure
7103 */
7104static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7105 struct wireless_dev *wdev,
7106 const void *data,
7107 int data_len)
7108{
7109 int ret = 0;
7110
7111 vos_ssr_protect(__func__);
7112 ret = __wlan_hdd_cfg80211_setband(wiphy,
7113 wdev, data, data_len);
7114 vos_ssr_unprotect(__func__);
7115
7116 return ret;
7117}
7118
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307119#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7120/**
7121 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7122 * @hdd_ctx: HDD context
7123 * @request_id: [input] request id
7124 * @pattern_id: [output] pattern id
7125 *
7126 * This function loops through request id to pattern id array
7127 * if the slot is available, store the request id and return pattern id
7128 * if entry exists, return the pattern id
7129 *
7130 * Return: 0 on success and errno on failure
7131 */
7132static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7133 uint32_t request_id,
7134 uint8_t *pattern_id)
7135{
7136 uint32_t i;
7137
7138 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7139 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7140 {
7141 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7142 {
7143 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7144 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7145 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7146 return 0;
7147 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7148 request_id) {
7149 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7150 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7151 return 0;
7152 }
7153 }
7154 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7155 return -EINVAL;
7156}
7157
7158/**
7159 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7160 * @hdd_ctx: HDD context
7161 * @request_id: [input] request id
7162 * @pattern_id: [output] pattern id
7163 *
7164 * This function loops through request id to pattern id array
7165 * reset request id to 0 (slot available again) and
7166 * return pattern id
7167 *
7168 * Return: 0 on success and errno on failure
7169 */
7170static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7171 uint32_t request_id,
7172 uint8_t *pattern_id)
7173{
7174 uint32_t i;
7175
7176 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7177 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7178 {
7179 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7180 {
7181 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7182 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7183 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7184 return 0;
7185 }
7186 }
7187 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7188 return -EINVAL;
7189}
7190
7191
7192/*
7193 * define short names for the global vendor params
7194 * used by __wlan_hdd_cfg80211_offloaded_packets()
7195 */
7196#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7197#define PARAM_REQUEST_ID \
7198 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7199#define PARAM_CONTROL \
7200 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7201#define PARAM_IP_PACKET \
7202 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7203#define PARAM_SRC_MAC_ADDR \
7204 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7205#define PARAM_DST_MAC_ADDR \
7206 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7207#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7208
7209/**
7210 * wlan_hdd_add_tx_ptrn() - add tx pattern
7211 * @adapter: adapter pointer
7212 * @hdd_ctx: hdd context
7213 * @tb: nl attributes
7214 *
7215 * This function reads the NL attributes and forms a AddTxPtrn message
7216 * posts it to SME.
7217 *
7218 */
7219static int
7220wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7221 struct nlattr **tb)
7222{
7223 struct sSirAddPeriodicTxPtrn *add_req;
7224 eHalStatus status;
7225 uint32_t request_id, ret, len;
7226 uint8_t pattern_id = 0;
7227 v_MACADDR_t dst_addr;
7228 uint16_t eth_type = htons(ETH_P_IP);
7229
7230 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7231 {
7232 hddLog(LOGE, FL("Not in Connected state!"));
7233 return -ENOTSUPP;
7234 }
7235
7236 add_req = vos_mem_malloc(sizeof(*add_req));
7237 if (!add_req)
7238 {
7239 hddLog(LOGE, FL("memory allocation failed"));
7240 return -ENOMEM;
7241 }
7242
7243 /* Parse and fetch request Id */
7244 if (!tb[PARAM_REQUEST_ID])
7245 {
7246 hddLog(LOGE, FL("attr request id failed"));
7247 goto fail;
7248 }
7249
7250 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7251 hddLog(LOG1, FL("Request Id: %u"), request_id);
7252 if (request_id == 0)
7253 {
7254 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307255 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307256 }
7257
7258 if (!tb[PARAM_PERIOD])
7259 {
7260 hddLog(LOGE, FL("attr period failed"));
7261 goto fail;
7262 }
7263 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7264 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7265 if (add_req->usPtrnIntervalMs == 0)
7266 {
7267 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7268 goto fail;
7269 }
7270
7271 if (!tb[PARAM_SRC_MAC_ADDR])
7272 {
7273 hddLog(LOGE, FL("attr source mac address failed"));
7274 goto fail;
7275 }
7276 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7277 VOS_MAC_ADDR_SIZE);
7278 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7279 MAC_ADDR_ARRAY(add_req->macAddress));
7280
7281 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7282 VOS_MAC_ADDR_SIZE))
7283 {
7284 hddLog(LOGE,
7285 FL("input src mac address and connected ap bssid are different"));
7286 goto fail;
7287 }
7288
7289 if (!tb[PARAM_DST_MAC_ADDR])
7290 {
7291 hddLog(LOGE, FL("attr dst mac address failed"));
7292 goto fail;
7293 }
7294 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7295 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7296 MAC_ADDR_ARRAY(dst_addr.bytes));
7297
7298 if (!tb[PARAM_IP_PACKET])
7299 {
7300 hddLog(LOGE, FL("attr ip packet failed"));
7301 goto fail;
7302 }
7303 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7304 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7305
7306 if (add_req->ucPtrnSize < 0 ||
7307 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7308 HDD_ETH_HEADER_LEN))
7309 {
7310 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7311 add_req->ucPtrnSize);
7312 goto fail;
7313 }
7314
7315 len = 0;
7316 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7317 len += VOS_MAC_ADDR_SIZE;
7318 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7319 VOS_MAC_ADDR_SIZE);
7320 len += VOS_MAC_ADDR_SIZE;
7321 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7322 len += 2;
7323
7324 /*
7325 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7326 * ------------------------------------------------------------
7327 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7328 * ------------------------------------------------------------
7329 */
7330 vos_mem_copy(&add_req->ucPattern[len],
7331 nla_data(tb[PARAM_IP_PACKET]),
7332 add_req->ucPtrnSize);
7333 add_req->ucPtrnSize += len;
7334
7335 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7336 add_req->ucPattern, add_req->ucPtrnSize);
7337
7338 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7339 if (ret)
7340 {
7341 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7342 goto fail;
7343 }
7344 add_req->ucPtrnId = pattern_id;
7345 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7346
7347 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7348 if (!HAL_STATUS_SUCCESS(status))
7349 {
7350 hddLog(LOGE,
7351 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7352 goto fail;
7353 }
7354
7355 EXIT();
7356 vos_mem_free(add_req);
7357 return 0;
7358
7359fail:
7360 vos_mem_free(add_req);
7361 return -EINVAL;
7362}
7363
7364/**
7365 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7366 * @adapter: adapter pointer
7367 * @hdd_ctx: hdd context
7368 * @tb: nl attributes
7369 *
7370 * This function reads the NL attributes and forms a DelTxPtrn message
7371 * posts it to SME.
7372 *
7373 */
7374static int
7375wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7376 struct nlattr **tb)
7377{
7378 struct sSirDelPeriodicTxPtrn *del_req;
7379 eHalStatus status;
7380 uint32_t request_id, ret;
7381 uint8_t pattern_id = 0;
7382
7383 /* Parse and fetch request Id */
7384 if (!tb[PARAM_REQUEST_ID])
7385 {
7386 hddLog(LOGE, FL("attr request id failed"));
7387 return -EINVAL;
7388 }
7389 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7390 if (request_id == 0)
7391 {
7392 hddLog(LOGE, FL("request_id cannot be zero"));
7393 return -EINVAL;
7394 }
7395
7396 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7397 if (ret)
7398 {
7399 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7400 return -EINVAL;
7401 }
7402
7403 del_req = vos_mem_malloc(sizeof(*del_req));
7404 if (!del_req)
7405 {
7406 hddLog(LOGE, FL("memory allocation failed"));
7407 return -ENOMEM;
7408 }
7409
7410 vos_mem_set(del_req, sizeof(*del_req), 0);
7411 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7412 VOS_MAC_ADDR_SIZE);
7413 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7414 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7415 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7416 request_id, pattern_id, del_req->ucPatternIdBitmap);
7417
7418 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7419 if (!HAL_STATUS_SUCCESS(status))
7420 {
7421 hddLog(LOGE,
7422 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7423 goto fail;
7424 }
7425
7426 EXIT();
7427 vos_mem_free(del_req);
7428 return 0;
7429
7430fail:
7431 vos_mem_free(del_req);
7432 return -EINVAL;
7433}
7434
7435
7436/**
7437 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7438 * @wiphy: Pointer to wireless phy
7439 * @wdev: Pointer to wireless device
7440 * @data: Pointer to data
7441 * @data_len: Data length
7442 *
7443 * Return: 0 on success, negative errno on failure
7444 */
7445static int
7446__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7447 struct wireless_dev *wdev,
7448 const void *data,
7449 int data_len)
7450{
7451 struct net_device *dev = wdev->netdev;
7452 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7453 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7454 struct nlattr *tb[PARAM_MAX + 1];
7455 uint8_t control;
7456 int ret;
7457 static const struct nla_policy policy[PARAM_MAX + 1] =
7458 {
7459 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7460 [PARAM_CONTROL] = { .type = NLA_U32 },
7461 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7462 .len = VOS_MAC_ADDR_SIZE },
7463 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7464 .len = VOS_MAC_ADDR_SIZE },
7465 [PARAM_PERIOD] = { .type = NLA_U32 },
7466 };
7467
7468 ENTER();
7469
7470 ret = wlan_hdd_validate_context(hdd_ctx);
7471 if (0 != ret)
7472 {
7473 hddLog(LOGE, FL("HDD context is not valid"));
7474 return ret;
7475 }
7476
7477 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7478 {
7479 hddLog(LOGE,
7480 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7481 return -ENOTSUPP;
7482 }
7483
7484 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7485 {
7486 hddLog(LOGE, FL("Invalid ATTR"));
7487 return -EINVAL;
7488 }
7489
7490 if (!tb[PARAM_CONTROL])
7491 {
7492 hddLog(LOGE, FL("attr control failed"));
7493 return -EINVAL;
7494 }
7495 control = nla_get_u32(tb[PARAM_CONTROL]);
7496 hddLog(LOG1, FL("Control: %d"), control);
7497
7498 if (control == WLAN_START_OFFLOADED_PACKETS)
7499 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7500 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7501 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7502 else
7503 {
7504 hddLog(LOGE, FL("Invalid control: %d"), control);
7505 return -EINVAL;
7506 }
7507}
7508
7509/*
7510 * done with short names for the global vendor params
7511 * used by __wlan_hdd_cfg80211_offloaded_packets()
7512 */
7513#undef PARAM_MAX
7514#undef PARAM_REQUEST_ID
7515#undef PARAM_CONTROL
7516#undef PARAM_IP_PACKET
7517#undef PARAM_SRC_MAC_ADDR
7518#undef PARAM_DST_MAC_ADDR
7519#undef PARAM_PERIOD
7520
7521/**
7522 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7523 * @wiphy: wiphy structure pointer
7524 * @wdev: Wireless device structure pointer
7525 * @data: Pointer to the data received
7526 * @data_len: Length of @data
7527 *
7528 * Return: 0 on success; errno on failure
7529 */
7530static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7531 struct wireless_dev *wdev,
7532 const void *data,
7533 int data_len)
7534{
7535 int ret = 0;
7536
7537 vos_ssr_protect(__func__);
7538 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7539 wdev, data, data_len);
7540 vos_ssr_unprotect(__func__);
7541
7542 return ret;
7543}
7544#endif
7545
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307546static const struct
7547nla_policy
7548qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307549 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7550 .type = NLA_BINARY,
7551 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307552};
7553
7554/**
7555 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7556 * get link properties like nss, rate flags and operating frequency for
7557 * the connection with the given peer.
7558 * @wiphy: WIPHY structure pointer
7559 * @wdev: Wireless device structure pointer
7560 * @data: Pointer to the data received
7561 * @data_len: Length of the data received
7562 *
7563 * This function return the above link properties on success.
7564 *
7565 * Return: 0 on success and errno on failure
7566 */
7567static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7568 struct wireless_dev *wdev,
7569 const void *data,
7570 int data_len)
7571{
7572 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7573 struct net_device *dev = wdev->netdev;
7574 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7575 hdd_station_ctx_t *hdd_sta_ctx;
7576 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7577 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7578 uint32_t sta_id;
7579 struct sk_buff *reply_skb;
7580 uint32_t rate_flags = 0;
7581 uint8_t nss;
7582 uint8_t final_rate_flags = 0;
7583 uint32_t freq;
7584 v_CONTEXT_t pVosContext = NULL;
7585 ptSapContext pSapCtx = NULL;
7586
7587 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7589 return -EINVAL;
7590 }
7591
7592 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7593 qca_wlan_vendor_attr_policy)) {
7594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7595 return -EINVAL;
7596 }
7597
7598 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7599 hddLog(VOS_TRACE_LEVEL_ERROR,
7600 FL("Attribute peerMac not provided for mode=%d"),
7601 adapter->device_mode);
7602 return -EINVAL;
7603 }
7604
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307605 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7606 hddLog(VOS_TRACE_LEVEL_ERROR,
7607 FL("Attribute peerMac is invalid=%d"),
7608 adapter->device_mode);
7609 return -EINVAL;
7610 }
7611
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307612 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7613 sizeof(peer_mac));
7614 hddLog(VOS_TRACE_LEVEL_INFO,
7615 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7616 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7617
7618 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7619 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7620 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7621 if ((hdd_sta_ctx->conn_info.connState !=
7622 eConnectionState_Associated) ||
7623 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7624 VOS_MAC_ADDRESS_LEN)) {
7625 hddLog(VOS_TRACE_LEVEL_ERROR,
7626 FL("Not Associated to mac "MAC_ADDRESS_STR),
7627 MAC_ADDR_ARRAY(peer_mac));
7628 return -EINVAL;
7629 }
7630
7631 nss = 1; //pronto supports only one spatial stream
7632 freq = vos_chan_to_freq(
7633 hdd_sta_ctx->conn_info.operationChannel);
7634 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7635
7636 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7637 adapter->device_mode == WLAN_HDD_SOFTAP) {
7638
7639 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7640 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7641 if(pSapCtx == NULL){
7642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7643 FL("psapCtx is NULL"));
7644 return -ENOENT;
7645 }
7646
7647
7648 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7649 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7650 !vos_is_macaddr_broadcast(
7651 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7652 vos_mem_compare(
7653 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7654 peer_mac, VOS_MAC_ADDRESS_LEN))
7655 break;
7656 }
7657
7658 if (WLAN_MAX_STA_COUNT == sta_id) {
7659 hddLog(VOS_TRACE_LEVEL_ERROR,
7660 FL("No active peer with mac="MAC_ADDRESS_STR),
7661 MAC_ADDR_ARRAY(peer_mac));
7662 return -EINVAL;
7663 }
7664
7665 nss = 1; //pronto supports only one spatial stream
7666 freq = vos_chan_to_freq(
7667 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7668 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7669 } else {
7670 hddLog(VOS_TRACE_LEVEL_ERROR,
7671 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7672 MAC_ADDR_ARRAY(peer_mac));
7673 return -EINVAL;
7674 }
7675
7676 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7677 if (rate_flags & eHAL_TX_RATE_VHT80) {
7678 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307679#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7680 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307681 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307682#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307683 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7684 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307685#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7686 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307687 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307688#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307689 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7690 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7691 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7692 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307693#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7694 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307695 if (rate_flags & eHAL_TX_RATE_HT40)
7696 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307697#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307698 }
7699
7700 if (rate_flags & eHAL_TX_RATE_SGI) {
7701 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7702 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7703 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7704 }
7705 }
7706
7707 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7708 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7709
7710 if (NULL == reply_skb) {
7711 hddLog(VOS_TRACE_LEVEL_ERROR,
7712 FL("getLinkProperties: skb alloc failed"));
7713 return -EINVAL;
7714 }
7715
7716 if (nla_put_u8(reply_skb,
7717 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7718 nss) ||
7719 nla_put_u8(reply_skb,
7720 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7721 final_rate_flags) ||
7722 nla_put_u32(reply_skb,
7723 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7724 freq)) {
7725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7726 kfree_skb(reply_skb);
7727 return -EINVAL;
7728 }
7729
7730 return cfg80211_vendor_cmd_reply(reply_skb);
7731}
7732
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307733#define BEACON_MISS_THRESH_2_4 \
7734 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7735#define BEACON_MISS_THRESH_5_0 \
7736 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307737#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7738#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7739#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7740#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307741#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7742 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307743#define PARAM_FORCE_RSN_IE \
7744 QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307745/*
7746 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7747 * @hdd_ctx: hdd context
7748 * @enable: Value received in the command, 1 for disable and 2 for enable
7749 *
7750 * Return: void
7751 */
7752static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7753{
7754 if (!hdd_ctx) {
7755 hddLog(LOGE, "hdd_ctx NULL");
7756 return;
7757 }
7758
7759 sme_set_qpower(hdd_ctx->hHal, enable);
7760}
7761
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307762/**
7763 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7764 * vendor command
7765 *
7766 * @wiphy: wiphy device pointer
7767 * @wdev: wireless device pointer
7768 * @data: Vendor command data buffer
7769 * @data_len: Buffer length
7770 *
7771 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7772 *
7773 * Return: EOK or other error codes.
7774 */
7775
7776static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7777 struct wireless_dev *wdev,
7778 const void *data,
7779 int data_len)
7780{
7781 struct net_device *dev = wdev->netdev;
7782 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7783 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7784 hdd_station_ctx_t *pHddStaCtx;
7785 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7786 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307787 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307788 eHalStatus status;
7789 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307790 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307791 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307792
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307793 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7794 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7795 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307796 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7797 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7798 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307799 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7800 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307801 [PARAM_FORCE_RSN_IE] = {.type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307802 };
7803
7804 ENTER();
7805
7806 if (VOS_FTM_MODE == hdd_get_conparam()) {
7807 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7808 return -EINVAL;
7809 }
7810
7811 ret_val = wlan_hdd_validate_context(pHddCtx);
7812 if (ret_val) {
7813 return ret_val;
7814 }
7815
7816 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7817
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307818 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7819 hddLog(LOGE, FL("Invalid ATTR"));
7820 return -EINVAL;
7821 }
7822
7823 /* check the Wifi Capability */
7824 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7825 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7826 {
7827 hddLog(VOS_TRACE_LEVEL_ERROR,
7828 FL("WIFICONFIG not supported by Firmware"));
7829 return -EINVAL;
7830 }
7831
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307832 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7833 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7834 modifyRoamParamsReq.value =
7835 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7836
7837 if (eHAL_STATUS_SUCCESS !=
7838 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7839 {
7840 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7841 ret_val = -EINVAL;
7842 }
7843 return ret_val;
7844 }
7845
7846 /* Moved this down in order to provide provision to set beacon
7847 * miss penalty count irrespective of connection state.
7848 */
7849 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7850 hddLog(LOGE, FL("Not in Connected state!"));
7851 return -ENOTSUPP;
7852 }
7853
7854 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307855
7856 if (!pReq) {
7857 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7858 "%s: Not able to allocate memory for tSetWifiConfigParams",
7859 __func__);
7860 return eHAL_STATUS_E_MALLOC_FAILED;
7861 }
7862
7863 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7864
7865 pReq->sessionId = pAdapter->sessionId;
7866 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7867
7868 if (tb[PARAM_MODULATED_DTIM]) {
7869 pReq->paramValue = nla_get_u32(
7870 tb[PARAM_MODULATED_DTIM]);
7871 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7872 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307873 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307874 hdd_set_pwrparams(pHddCtx);
7875 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7876 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7877
7878 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7879 iw_full_power_cbfn, pAdapter,
7880 eSME_FULL_PWR_NEEDED_BY_HDD);
7881 }
7882 else
7883 {
7884 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7885 }
7886 }
7887
7888 if (tb[PARAM_STATS_AVG_FACTOR]) {
7889 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7890 pReq->paramValue = nla_get_u16(
7891 tb[PARAM_STATS_AVG_FACTOR]);
7892 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7893 pReq->paramType, pReq->paramValue);
7894 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7895
7896 if (eHAL_STATUS_SUCCESS != status)
7897 {
7898 vos_mem_free(pReq);
7899 pReq = NULL;
7900 ret_val = -EPERM;
7901 return ret_val;
7902 }
7903 }
7904
7905
7906 if (tb[PARAM_GUARD_TIME]) {
7907 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7908 pReq->paramValue = nla_get_u32(
7909 tb[PARAM_GUARD_TIME]);
7910 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7911 pReq->paramType, pReq->paramValue);
7912 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7913
7914 if (eHAL_STATUS_SUCCESS != status)
7915 {
7916 vos_mem_free(pReq);
7917 pReq = NULL;
7918 ret_val = -EPERM;
7919 return ret_val;
7920 }
7921
7922 }
7923
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307924 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7925 hb_thresh_val = nla_get_u8(
7926 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7927
7928 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7929 hb_thresh_val);
7930 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7931 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7932 NULL, eANI_BOOLEAN_FALSE);
7933
7934 status = sme_update_hb_threshold(
7935 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7936 WNI_CFG_HEART_BEAT_THRESHOLD,
7937 hb_thresh_val, eCSR_BAND_24);
7938 if (eHAL_STATUS_SUCCESS != status) {
7939 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7940 vos_mem_free(pReq);
7941 pReq = NULL;
7942 return -EPERM;
7943 }
7944 }
7945
7946 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7947 hb_thresh_val = nla_get_u8(
7948 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7949
7950 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
7951 hb_thresh_val);
7952 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7953 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7954 NULL, eANI_BOOLEAN_FALSE);
7955
7956 status = sme_update_hb_threshold(
7957 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7958 WNI_CFG_HEART_BEAT_THRESHOLD,
7959 hb_thresh_val, eCSR_BAND_5G);
7960 if (eHAL_STATUS_SUCCESS != status) {
7961 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7962 vos_mem_free(pReq);
7963 pReq = NULL;
7964 return -EPERM;
7965 }
7966 }
7967
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307968 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
7969 qpower = nla_get_u8(
7970 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
7971
7972 if(qpower > 1) {
7973 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
7974 vos_mem_free(pReq);
7975 pReq = NULL;
7976 return -EINVAL;
7977 }
7978 /* FW is expacting qpower as 1 for Disable and 2 for enable */
7979 qpower++;
7980 hdd_set_qpower(pHddCtx, qpower);
7981 }
7982
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307983 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] &&
7984 pHddCtx->cfg_ini->force_rsne_override) {
7985 uint8_t force_rsne_override;
7986
7987 force_rsne_override =
7988 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
7989 if (force_rsne_override > 1) {
7990 hddLog(LOGE, "Invalid test_mode %d", force_rsne_override);
7991 ret_val = -EINVAL;
7992 }
7993 pHddCtx->force_rsne_override = force_rsne_override;
7994 hddLog(LOG1, "force_rsne_override - %d",
7995 pHddCtx->force_rsne_override);
7996 }
7997
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307998 EXIT();
7999 return ret_val;
8000}
8001
8002/**
8003 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8004 * vendor command
8005 *
8006 * @wiphy: wiphy device pointer
8007 * @wdev: wireless device pointer
8008 * @data: Vendor command data buffer
8009 * @data_len: Buffer length
8010 *
8011 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8012 *
8013 * Return: EOK or other error codes.
8014 */
8015static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8016 struct wireless_dev *wdev,
8017 const void *data,
8018 int data_len)
8019{
8020 int ret;
8021
8022 vos_ssr_protect(__func__);
8023 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8024 data, data_len);
8025 vos_ssr_unprotect(__func__);
8026
8027 return ret;
8028}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308029
8030/*
8031 * define short names for the global vendor params
8032 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8033 */
8034#define STATS_SET_INVALID \
8035 QCA_ATTR_NUD_STATS_SET_INVALID
8036#define STATS_SET_START \
8037 QCA_ATTR_NUD_STATS_SET_START
8038#define STATS_GW_IPV4 \
8039 QCA_ATTR_NUD_STATS_GW_IPV4
8040#define STATS_SET_MAX \
8041 QCA_ATTR_NUD_STATS_SET_MAX
8042
8043const struct nla_policy
8044qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8045{
8046 [STATS_SET_START] = {.type = NLA_FLAG },
8047 [STATS_GW_IPV4] = {.type = NLA_U32 },
8048};
8049
8050/**
8051 * hdd_set_nud_stats_cb() - hdd callback api to get status
8052 * @data: pointer to adapter
8053 * @rsp: status
8054 *
8055 * Return: None
8056 */
8057static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8058{
8059
8060 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8061
8062 if (NULL == adapter)
8063 return;
8064
8065 if (VOS_STATUS_SUCCESS == rsp) {
8066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8067 "%s success received STATS_SET_START", __func__);
8068 } else {
8069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8070 "%s STATS_SET_START Failed!!", __func__);
8071 }
8072 return;
8073}
8074
8075/**
8076 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8077 * @wiphy: pointer to wireless wiphy structure.
8078 * @wdev: pointer to wireless_dev structure.
8079 * @data: pointer to apfind configuration data.
8080 * @data_len: the length in byte of apfind data.
8081 *
8082 * This is called when wlan driver needs to send arp stats to
8083 * firmware.
8084 *
8085 * Return: An error code or 0 on success.
8086 */
8087static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8088 struct wireless_dev *wdev,
8089 const void *data, int data_len)
8090{
8091 struct nlattr *tb[STATS_SET_MAX + 1];
8092 struct net_device *dev = wdev->netdev;
8093 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8094 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308095 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308096 setArpStatsParams arp_stats_params;
8097 int err = 0;
8098
8099 ENTER();
8100
8101 err = wlan_hdd_validate_context(hdd_ctx);
8102 if (0 != err)
8103 return err;
8104
8105 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8107 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8108 return -EINVAL;
8109 }
8110
8111 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8112 qca_wlan_vendor_set_nud_stats);
8113 if (err)
8114 {
8115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8116 "%s STATS_SET_START ATTR", __func__);
8117 return err;
8118 }
8119
8120 if (tb[STATS_SET_START])
8121 {
8122 if (!tb[STATS_GW_IPV4]) {
8123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8124 "%s STATS_SET_START CMD", __func__);
8125 return -EINVAL;
8126 }
8127 arp_stats_params.flag = true;
8128 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8129 } else {
8130 arp_stats_params.flag = false;
8131 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308132 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8134 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308135 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8136 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308137
8138 arp_stats_params.pkt_type = 1; // ARP packet type
8139
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308140 if (arp_stats_params.flag) {
8141 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8142 WLANTL_SetARPFWDatapath(pVosContext, true);
8143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8144 "%s Set FW in data path for ARP with tgt IP :%d",
8145 __func__, hdd_ctx->track_arp_ip);
8146 }
8147 else {
8148 WLANTL_SetARPFWDatapath(pVosContext, false);
8149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8150 "%s Remove FW from data path", __func__);
8151 }
8152
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308153 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8154 arp_stats_params.data_ctx = adapter;
8155
8156 if (eHAL_STATUS_SUCCESS !=
8157 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8158 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8159 "%s STATS_SET_START CMD Failed!!", __func__);
8160 return -EINVAL;
8161 }
8162
8163 EXIT();
8164
8165 return err;
8166}
8167
8168/**
8169 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8170 * @wiphy: pointer to wireless wiphy structure.
8171 * @wdev: pointer to wireless_dev structure.
8172 * @data: pointer to apfind configuration data.
8173 * @data_len: the length in byte of apfind data.
8174 *
8175 * This is called when wlan driver needs to send arp stats to
8176 * firmware.
8177 *
8178 * Return: An error code or 0 on success.
8179 */
8180static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8181 struct wireless_dev *wdev,
8182 const void *data, int data_len)
8183{
8184 int ret;
8185
8186 vos_ssr_protect(__func__);
8187 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8188 vos_ssr_unprotect(__func__);
8189
8190 return ret;
8191}
8192#undef STATS_SET_INVALID
8193#undef STATS_SET_START
8194#undef STATS_GW_IPV4
8195#undef STATS_SET_MAX
8196
8197/*
8198 * define short names for the global vendor params
8199 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8200 */
8201#define STATS_GET_INVALID \
8202 QCA_ATTR_NUD_STATS_SET_INVALID
8203#define COUNT_FROM_NETDEV \
8204 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8205#define COUNT_TO_LOWER_MAC \
8206 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8207#define RX_COUNT_BY_LOWER_MAC \
8208 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8209#define COUNT_TX_SUCCESS \
8210 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8211#define RSP_RX_COUNT_BY_LOWER_MAC \
8212 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8213#define RSP_RX_COUNT_BY_UPPER_MAC \
8214 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8215#define RSP_COUNT_TO_NETDEV \
8216 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8217#define RSP_COUNT_OUT_OF_ORDER_DROP \
8218 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8219#define AP_LINK_ACTIVE \
8220 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8221#define AP_LINK_DAD \
8222 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8223#define STATS_GET_MAX \
8224 QCA_ATTR_NUD_STATS_GET_MAX
8225
8226const struct nla_policy
8227qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8228{
8229 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8230 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8231 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8232 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8233 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8234 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8235 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8236 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8237 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8238 [AP_LINK_DAD] = {.type = NLA_FLAG },
8239};
8240
8241static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8242{
8243
8244 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308245 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308246 struct hdd_nud_stats_context *context;
8247 int status;
8248
8249 ENTER();
8250
8251 if (NULL == adapter)
8252 return;
8253
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308254 if (!rsp) {
8255 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308256 return;
8257 }
8258
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308259 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8260 status = wlan_hdd_validate_context(hdd_ctx);
8261 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308262 return;
8263 }
8264
8265 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8266 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8267 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8268 adapter->dad |= rsp->dad;
8269
8270 spin_lock(&hdd_context_lock);
8271 context = &hdd_ctx->nud_stats_context;
8272 complete(&context->response_event);
8273 spin_unlock(&hdd_context_lock);
8274
8275 return;
8276}
8277static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8278 struct wireless_dev *wdev,
8279 const void *data, int data_len)
8280{
8281 int err = 0;
8282 unsigned long rc;
8283 struct hdd_nud_stats_context *context;
8284 struct net_device *dev = wdev->netdev;
8285 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8286 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8287 getArpStatsParams arp_stats_params;
8288 struct sk_buff *skb;
8289
8290 ENTER();
8291
8292 err = wlan_hdd_validate_context(hdd_ctx);
8293 if (0 != err)
8294 return err;
8295
8296 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8297 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8298 arp_stats_params.data_ctx = adapter;
8299
8300 spin_lock(&hdd_context_lock);
8301 context = &hdd_ctx->nud_stats_context;
8302 INIT_COMPLETION(context->response_event);
8303 spin_unlock(&hdd_context_lock);
8304
8305 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8307 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8308 return -EINVAL;
8309 }
8310
8311 if (eHAL_STATUS_SUCCESS !=
8312 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8314 "%s STATS_SET_START CMD Failed!!", __func__);
8315 return -EINVAL;
8316 }
8317
8318 rc = wait_for_completion_timeout(&context->response_event,
8319 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8320 if (!rc)
8321 {
8322 hddLog(LOGE,
8323 FL("Target response timed out request "));
8324 return -ETIMEDOUT;
8325 }
8326
8327 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8328 WLAN_NUD_STATS_LEN);
8329 if (!skb)
8330 {
8331 hddLog(VOS_TRACE_LEVEL_ERROR,
8332 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8333 __func__);
8334 return -ENOMEM;
8335 }
8336
8337 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8338 adapter->hdd_stats.hddArpStats.txCount) ||
8339 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8340 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8341 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8342 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8343 nla_put_u16(skb, COUNT_TX_SUCCESS,
8344 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8345 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8346 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8347 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8348 adapter->hdd_stats.hddArpStats.rxCount) ||
8349 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8350 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8351 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8352 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8353 hddLog(LOGE, FL("nla put fail"));
8354 kfree_skb(skb);
8355 return -EINVAL;
8356 }
8357 if (adapter->con_status)
8358 nla_put_flag(skb, AP_LINK_ACTIVE);
8359 if (adapter->dad)
8360 nla_put_flag(skb, AP_LINK_DAD);
8361
8362 cfg80211_vendor_cmd_reply(skb);
8363 return err;
8364}
8365
8366static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8367 struct wireless_dev *wdev,
8368 const void *data, int data_len)
8369{
8370 int ret;
8371
8372 vos_ssr_protect(__func__);
8373 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8374 vos_ssr_unprotect(__func__);
8375
8376 return ret;
8377}
8378
8379#undef QCA_ATTR_NUD_STATS_SET_INVALID
8380#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8381#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8382#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8383#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8384#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8385#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8386#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8387#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8388#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8389#undef QCA_ATTR_NUD_STATS_GET_MAX
8390
8391
8392
Kapil Guptaee33bf12016-12-20 18:27:37 +05308393#ifdef WLAN_FEATURE_APFIND
8394/**
8395 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8396 * @wiphy: pointer to wireless wiphy structure.
8397 * @wdev: pointer to wireless_dev structure.
8398 * @data: pointer to apfind configuration data.
8399 * @data_len: the length in byte of apfind data.
8400 *
8401 * This is called when wlan driver needs to send APFIND configurations to
8402 * firmware.
8403 *
8404 * Return: An error code or 0 on success.
8405 */
8406static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8407 struct wireless_dev *wdev,
8408 const void *data, int data_len)
8409{
8410 struct sme_ap_find_request_req apfind_req;
8411 VOS_STATUS status;
8412 int ret_val;
8413 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8414
8415 ENTER();
8416
8417 ret_val = wlan_hdd_validate_context(hdd_ctx);
8418 if (ret_val)
8419 return ret_val;
8420
8421 if (VOS_FTM_MODE == hdd_get_conparam()) {
8422 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8423 return -EPERM;
8424 }
8425
8426 apfind_req.request_data_len = data_len;
8427 apfind_req.request_data = data;
8428
8429 status = sme_apfind_set_cmd(&apfind_req);
8430 if (VOS_STATUS_SUCCESS != status) {
8431 ret_val = -EIO;
8432 }
8433 return ret_val;
8434}
8435
8436/**
8437 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8438 * @wiphy: pointer to wireless wiphy structure.
8439 * @wdev: pointer to wireless_dev structure.
8440 * @data: pointer to apfind configuration data.
8441 * @data_len: the length in byte of apfind data.
8442 *
8443 * This is called when wlan driver needs to send APFIND configurations to
8444 * firmware.
8445 *
8446 * Return: An error code or 0 on success.
8447 */
8448static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8449 struct wireless_dev *wdev,
8450 const void *data, int data_len)
8451{
8452 int ret;
8453
8454 vos_ssr_protect(__func__);
8455 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8456 vos_ssr_unprotect(__func__);
8457
8458 return ret;
8459}
8460#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308461
8462/**
8463 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8464 * @wiphy: pointer to wireless wiphy structure.
8465 * @wdev: pointer to wireless_dev structure.
8466 * @data: Pointer to the data to be passed via vendor interface
8467 * @data_len:Length of the data to be passed
8468 *
8469 * This is called by userspace to know the supported logger features
8470 *
8471 * Return: Return the Success or Failure code.
8472 */
8473static int
8474__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8475 struct wireless_dev *wdev,
8476 const void *data, int data_len)
8477{
8478 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8479 int status;
8480 uint32_t features;
8481 struct sk_buff *reply_skb = NULL;
8482
8483 if (VOS_FTM_MODE == hdd_get_conparam()) {
8484 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8485 return -EINVAL;
8486 }
8487
8488 status = wlan_hdd_validate_context(hdd_ctx);
8489 if (0 != status)
8490 return -EINVAL;
8491
8492 features = 0;
8493
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308494 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8495 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8496 if (!reply_skb) {
8497 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8498 return -ENOMEM;
8499 }
8500
8501 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8502 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8503 features)) {
8504 hddLog(LOGE, FL("nla put fail"));
8505 kfree_skb(reply_skb);
8506 return -EINVAL;
8507 }
8508
8509 return cfg80211_vendor_cmd_reply(reply_skb);
8510}
8511
8512/**
8513 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8514 * @wiphy: pointer to wireless wiphy structure.
8515 * @wdev: pointer to wireless_dev structure.
8516 * @data: Pointer to the data to be passed via vendor interface
8517 * @data_len:Length of the data to be passed
8518 *
8519 * This is called by userspace to know the supported logger features
8520 *
8521 * Return: Return the Success or Failure code.
8522 */
8523static int
8524wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8525 struct wireless_dev *wdev,
8526 const void *data, int data_len)
8527{
8528 int ret;
8529
8530 vos_ssr_protect(__func__);
8531 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8532 data, data_len);
8533 vos_ssr_unprotect(__func__);
8534
8535 return ret;
8536}
8537
Sunil Duttc69bccb2014-05-26 21:30:20 +05308538const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8539{
Mukul Sharma2a271632014-10-13 14:59:01 +05308540 {
8541 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8542 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8543 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8544 WIPHY_VENDOR_CMD_NEED_NETDEV |
8545 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308546 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308547 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308548
8549 {
8550 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8551 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8552 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8553 WIPHY_VENDOR_CMD_NEED_NETDEV |
8554 WIPHY_VENDOR_CMD_NEED_RUNNING,
8555 .doit = wlan_hdd_cfg80211_nan_request
8556 },
8557
Sunil Duttc69bccb2014-05-26 21:30:20 +05308558#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8559 {
8560 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8561 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8562 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8563 WIPHY_VENDOR_CMD_NEED_NETDEV |
8564 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308565 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308566 },
8567
8568 {
8569 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8570 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8571 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8572 WIPHY_VENDOR_CMD_NEED_NETDEV |
8573 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308574 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308575 },
8576
8577 {
8578 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8579 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8580 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8581 WIPHY_VENDOR_CMD_NEED_NETDEV |
8582 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308583 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308584 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308585#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308586#ifdef WLAN_FEATURE_EXTSCAN
8587 {
8588 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8589 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8590 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8591 WIPHY_VENDOR_CMD_NEED_NETDEV |
8592 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308593 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308594 },
8595 {
8596 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8597 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8598 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8599 WIPHY_VENDOR_CMD_NEED_NETDEV |
8600 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308601 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308602 },
8603 {
8604 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8605 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8606 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8607 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308608 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308609 },
8610 {
8611 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8612 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8613 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8614 WIPHY_VENDOR_CMD_NEED_NETDEV |
8615 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308616 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308617 },
8618 {
8619 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8620 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8621 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8622 WIPHY_VENDOR_CMD_NEED_NETDEV |
8623 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308624 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308625 },
8626 {
8627 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8628 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8629 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8630 WIPHY_VENDOR_CMD_NEED_NETDEV |
8631 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308632 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308633 },
8634 {
8635 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8636 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8637 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8638 WIPHY_VENDOR_CMD_NEED_NETDEV |
8639 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308640 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308641 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308642#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308643/*EXT TDLS*/
8644 {
8645 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8646 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8647 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8648 WIPHY_VENDOR_CMD_NEED_NETDEV |
8649 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308650 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308651 },
8652 {
8653 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8654 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8655 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8656 WIPHY_VENDOR_CMD_NEED_NETDEV |
8657 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308658 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308659 },
8660 {
8661 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8662 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8663 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Arun Kumar Khandavalli2cc36642020-02-26 12:03:56 +05308664 WIPHY_VENDOR_CMD_NEED_NETDEV |
8665 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308666 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308667 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308668 {
8669 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8670 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8671 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8672 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308673 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308674 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308675 {
8676 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8677 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8678 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Arun Kumar Khandavalli2cc36642020-02-26 12:03:56 +05308679 WIPHY_VENDOR_CMD_NEED_NETDEV |
8680 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308681 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308682 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308683 {
8684 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8685 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8686 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8687 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308688 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308689 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308690 {
8691 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8692 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8693 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8694 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308695 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308696 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308697 {
8698 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8699 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8700 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8701 WIPHY_VENDOR_CMD_NEED_NETDEV |
8702 WIPHY_VENDOR_CMD_NEED_RUNNING,
8703 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308704 },
8705 {
8706 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8707 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8708 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8709 WIPHY_VENDOR_CMD_NEED_NETDEV,
8710 .doit = wlan_hdd_cfg80211_wifi_logger_start
8711 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308712 {
8713 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8714 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8715 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8716 WIPHY_VENDOR_CMD_NEED_NETDEV|
8717 WIPHY_VENDOR_CMD_NEED_RUNNING,
8718 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308719 },
8720 {
8721 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8722 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8723 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8724 WIPHY_VENDOR_CMD_NEED_NETDEV |
8725 WIPHY_VENDOR_CMD_NEED_RUNNING,
8726 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308727 },
8728 {
8729 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8730 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8731 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8732 WIPHY_VENDOR_CMD_NEED_NETDEV |
8733 WIPHY_VENDOR_CMD_NEED_RUNNING,
8734 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308735 },
8736#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8737 {
8738 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8739 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8740 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8741 WIPHY_VENDOR_CMD_NEED_NETDEV |
8742 WIPHY_VENDOR_CMD_NEED_RUNNING,
8743 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308744 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308745#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308746 {
8747 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8748 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8749 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8750 WIPHY_VENDOR_CMD_NEED_NETDEV |
8751 WIPHY_VENDOR_CMD_NEED_RUNNING,
8752 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308753 },
8754 {
8755 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8756 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8757 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8758 WIPHY_VENDOR_CMD_NEED_NETDEV |
8759 WIPHY_VENDOR_CMD_NEED_RUNNING,
8760 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308761 },
8762#ifdef WLAN_FEATURE_APFIND
8763 {
8764 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8765 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8766 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8767 WIPHY_VENDOR_CMD_NEED_NETDEV,
8768 .doit = wlan_hdd_cfg80211_apfind_cmd
8769 },
8770#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308771 {
8772 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8773 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8774 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8775 WIPHY_VENDOR_CMD_NEED_NETDEV |
8776 WIPHY_VENDOR_CMD_NEED_RUNNING,
8777 .doit = wlan_hdd_cfg80211_set_nud_stats
8778 },
8779 {
8780 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8781 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8782 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8783 WIPHY_VENDOR_CMD_NEED_NETDEV |
8784 WIPHY_VENDOR_CMD_NEED_RUNNING,
8785 .doit = wlan_hdd_cfg80211_get_nud_stats
8786 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308787 {
8788 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8789 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8790 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8791 WIPHY_VENDOR_CMD_NEED_NETDEV |
8792 WIPHY_VENDOR_CMD_NEED_RUNNING,
8793 .doit = hdd_cfg80211_get_station_cmd
8794 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308795 {
8796 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8797 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8798 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Hanumanth Reddy Pothula07c95582018-05-23 12:41:22 +05308799 WIPHY_VENDOR_CMD_NEED_NETDEV,
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308800 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8801 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308802};
8803
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008804/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308805static const
8806struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008807{
8808#ifdef FEATURE_WLAN_CH_AVOID
8809 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308810 .vendor_id = QCA_NL80211_VENDOR_ID,
8811 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008812 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308813#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8814#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8815 {
8816 /* Index = 1*/
8817 .vendor_id = QCA_NL80211_VENDOR_ID,
8818 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8819 },
8820 {
8821 /* Index = 2*/
8822 .vendor_id = QCA_NL80211_VENDOR_ID,
8823 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8824 },
8825 {
8826 /* Index = 3*/
8827 .vendor_id = QCA_NL80211_VENDOR_ID,
8828 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8829 },
8830 {
8831 /* Index = 4*/
8832 .vendor_id = QCA_NL80211_VENDOR_ID,
8833 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8834 },
8835 {
8836 /* Index = 5*/
8837 .vendor_id = QCA_NL80211_VENDOR_ID,
8838 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8839 },
8840 {
8841 /* Index = 6*/
8842 .vendor_id = QCA_NL80211_VENDOR_ID,
8843 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8844 },
8845#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308846#ifdef WLAN_FEATURE_EXTSCAN
8847 {
8848 .vendor_id = QCA_NL80211_VENDOR_ID,
8849 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8850 },
8851 {
8852 .vendor_id = QCA_NL80211_VENDOR_ID,
8853 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8854 },
8855 {
8856 .vendor_id = QCA_NL80211_VENDOR_ID,
8857 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8858 },
8859 {
8860 .vendor_id = QCA_NL80211_VENDOR_ID,
8861 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8862 },
8863 {
8864 .vendor_id = QCA_NL80211_VENDOR_ID,
8865 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8866 },
8867 {
8868 .vendor_id = QCA_NL80211_VENDOR_ID,
8869 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8870 },
8871 {
8872 .vendor_id = QCA_NL80211_VENDOR_ID,
8873 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8874 },
8875 {
8876 .vendor_id = QCA_NL80211_VENDOR_ID,
8877 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8878 },
8879 {
8880 .vendor_id = QCA_NL80211_VENDOR_ID,
8881 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8882 },
8883 {
8884 .vendor_id = QCA_NL80211_VENDOR_ID,
8885 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8886 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308887#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308888/*EXT TDLS*/
8889 {
8890 .vendor_id = QCA_NL80211_VENDOR_ID,
8891 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8892 },
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308893 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308894 .vendor_id = QCA_NL80211_VENDOR_ID,
8895 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8896 },
8897
Sushant Kaushik084f6592015-09-10 13:11:56 +05308898 {
8899 .vendor_id = QCA_NL80211_VENDOR_ID,
8900 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308901 },
8902 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8903 .vendor_id = QCA_NL80211_VENDOR_ID,
8904 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8905 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308906 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8907 .vendor_id = QCA_NL80211_VENDOR_ID,
8908 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8909 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308910 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8911 .vendor_id = QCA_NL80211_VENDOR_ID,
8912 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8913 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308914 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8915 .vendor_id = QCA_NL80211_VENDOR_ID,
8916 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
8917 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05308918 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
8919 .vendor_id = QCA_NL80211_VENDOR_ID,
8920 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8921 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008922};
8923
Jeff Johnson295189b2012-06-20 16:38:30 -07008924/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308925 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308926 * This function is called by hdd_wlan_startup()
8927 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308928 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008929 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308930struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008931{
8932 struct wiphy *wiphy;
8933 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308934 /*
8935 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 */
8937 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8938
8939 if (!wiphy)
8940 {
8941 /* Print error and jump into err label and free the memory */
8942 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8943 return NULL;
8944 }
8945
Sunil Duttc69bccb2014-05-26 21:30:20 +05308946
Jeff Johnson295189b2012-06-20 16:38:30 -07008947 return wiphy;
8948}
8949
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308950#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8951 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8952/**
8953 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8954 * @wiphy: pointer to wiphy
8955 * @config: pointer to config
8956 *
8957 * Return: None
8958 */
8959static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8960 hdd_config_t *config)
8961{
8962 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8963 if (config->max_sched_scan_plan_interval)
8964 wiphy->max_sched_scan_plan_interval =
8965 config->max_sched_scan_plan_interval;
8966 if (config->max_sched_scan_plan_iterations)
8967 wiphy->max_sched_scan_plan_iterations =
8968 config->max_sched_scan_plan_iterations;
8969}
8970#else
8971static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8972 hdd_config_t *config)
8973{
8974}
8975#endif
8976
Jeff Johnson295189b2012-06-20 16:38:30 -07008977/*
8978 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308979 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 * private ioctl to change the band value
8981 */
8982int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8983{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308984 int i, j;
8985 eNVChannelEnabledType channelEnabledState;
8986
Jeff Johnsone7245742012-09-05 17:12:55 -07008987 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308988
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308989 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308991
8992 if (NULL == wiphy->bands[i])
8993 {
8994 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8995 __func__, i);
8996 continue;
8997 }
8998
8999 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9000 {
9001 struct ieee80211_supported_band *band = wiphy->bands[i];
9002
9003 channelEnabledState = vos_nv_getChannelEnabledState(
9004 band->channels[j].hw_value);
9005
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309006 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309007 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309008 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309009 continue;
9010 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309011 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309012 {
9013 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9014 continue;
9015 }
9016
9017 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9018 NV_CHANNEL_INVALID == channelEnabledState)
9019 {
9020 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9021 }
9022 else if (NV_CHANNEL_DFS == channelEnabledState)
9023 {
9024 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9025 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9026 }
9027 else
9028 {
9029 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9030 |IEEE80211_CHAN_RADAR);
9031 }
9032 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 }
9034 return 0;
9035}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309036
9037/**
9038 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9039 * @wiphy: Pointer to the wiphy.
9040 *
9041 * This Function adds Channel Switch support flag, if channel switch is
9042 * supported by kernel.
9043 * Return: void.
9044 */
9045#ifdef CHANNEL_SWITCH_SUPPORTED
9046static inline
9047void hdd_add_channel_switch_support(struct wiphy *wiphy)
9048{
9049 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9050 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9051}
9052#else
9053static inline
9054void hdd_add_channel_switch_support(struct wiphy *wiphy)
9055{
9056}
9057#endif
9058
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +05309059#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
9060 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
9061void wlan_hdd_cfg80211_scan_randomization_init(struct wiphy *wiphy)
9062{
9063 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
9064 hdd_config_t *config = hdd_ctx->cfg_ini;
9065
9066 if (config->enableMacSpoofing != MAC_ADDR_SPOOFING_FW_HOST_ENABLE)
9067 return;
9068
9069 wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
9070}
9071#endif
9072
Abhinav Kumar118efd02019-08-07 16:41:07 +05309073#if defined(WLAN_FEATURE_SAE) && \
9074 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
Abhinav Kumar97821072019-08-02 14:29:48 +05309075/**
9076 * wlan_hdd_cfg80211_set_wiphy_sae_feature() - Indicates support of SAE feature
9077 * @wiphy: Pointer to wiphy
9078 * @config: pointer to config
9079 *
9080 * This function is used to indicate the support of SAE
9081 *
9082 * Return: None
9083 */
9084static
9085void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy,
9086 hdd_config_t *config)
9087{
9088 if (config->is_sae_enabled)
9089 wiphy->features |= NL80211_FEATURE_SAE;
9090}
9091#else
9092static
9093void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy,
9094 hdd_config_t *config)
9095{
9096}
9097#endif
9098
Jeff Johnson295189b2012-06-20 16:38:30 -07009099/*
9100 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309101 * This function is called by hdd_wlan_startup()
9102 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009103 * This function is used to initialize and register wiphy structure.
9104 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309105int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009106 struct wiphy *wiphy,
9107 hdd_config_t *pCfg
9108 )
9109{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309110 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309111 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9112
Jeff Johnsone7245742012-09-05 17:12:55 -07009113 ENTER();
9114
Jeff Johnson295189b2012-06-20 16:38:30 -07009115 /* Now bind the underlying wlan device with wiphy */
9116 set_wiphy_dev(wiphy, dev);
9117
9118 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009119
Kiet Lam6c583332013-10-14 05:37:09 +05309120#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009121 /* the flag for the other case would be initialzed in
9122 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309123#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9124 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9125#else
Amar Singhal0a402232013-10-11 20:57:16 -07009126 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309127#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309128#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009129
Amar Singhalfddc28c2013-09-05 13:03:40 -07009130 /* This will disable updating of NL channels from passive to
9131 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309132#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9133 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9134#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009135 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309136#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009137
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309138#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9139 wiphy->wowlan = &wowlan_support_cfg80211_init;
9140#else
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +05309141 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
9142 WIPHY_WOWLAN_MAGIC_PKT;
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309143 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9144 wiphy->wowlan.pattern_min_len = 1;
9145 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9146#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009147
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009148#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009149 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9150 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9151 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009152 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309153#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309154 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309155#else
9156 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9157#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009158#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009159
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009160#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009161 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009162#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009163 || pCfg->isFastRoamIniFeatureEnabled
9164#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009165#ifdef FEATURE_WLAN_ESE
9166 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009167#endif
9168 )
9169 {
9170 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9171 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009172#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009173#ifdef FEATURE_WLAN_TDLS
9174 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9175 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9176#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309177#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309178 if (pCfg->configPNOScanSupport)
9179 {
9180 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9181 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9182 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9183 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9184 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309185#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009186
Abhishek Singh10d85972015-04-17 10:27:23 +05309187#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9188 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9189#endif
9190
Amar Singhalfddc28c2013-09-05 13:03:40 -07009191#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009192 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9193 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009194 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009195 driver need to determine what to do with both
9196 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009197
9198 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009199#else
9200 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009201#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009202
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309203 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9204
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309205 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009206
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309207 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9208
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309210 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9211 | BIT(NL80211_IFTYPE_ADHOC)
9212 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9213 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309214 | BIT(NL80211_IFTYPE_AP)
9215 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009216
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309217 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009218 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309219#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9220 if( pCfg->enableMCC )
9221 {
9222 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309223 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009224
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309225 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309226 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009227
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309228 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309229 wiphy->iface_combinations = wlan_hdd_iface_combination;
9230 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009231#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309232 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009233
Jeff Johnson295189b2012-06-20 16:38:30 -07009234 /* Before registering we need to update the ht capabilitied based
9235 * on ini values*/
9236 if( !pCfg->ShortGI20MhzEnable )
9237 {
9238 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9239 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009240 }
9241
9242 if( !pCfg->ShortGI40MhzEnable )
9243 {
9244 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9245 }
9246
9247 if( !pCfg->nChannelBondingMode5GHz )
9248 {
9249 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9250 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309251 /*
9252 * In case of static linked driver at the time of driver unload,
9253 * module exit doesn't happens. Module cleanup helps in cleaning
9254 * of static memory.
9255 * If driver load happens statically, at the time of driver unload,
9256 * wiphy flags don't get reset because of static memory.
9257 * It's better not to store channel in static memory.
9258 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309259 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9260 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309261 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309262 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309263 {
9264 hddLog(VOS_TRACE_LEVEL_ERROR,
9265 FL("Not enough memory to allocate channels"));
9266 return -ENOMEM;
9267 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309268 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309269 &hdd_channels_2_4_GHZ[0],
9270 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009271
Agrawal Ashish97dec502015-11-26 20:20:58 +05309272 if (true == hdd_is_5g_supported(pHddCtx))
9273 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309274 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9275 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309276 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309277 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309278 {
9279 hddLog(VOS_TRACE_LEVEL_ERROR,
9280 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309281 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9282 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309283 return -ENOMEM;
9284 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309285 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309286 &hdd_channels_5_GHZ[0],
9287 sizeof(hdd_channels_5_GHZ));
9288 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309289
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309290 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309291 {
9292
9293 if (NULL == wiphy->bands[i])
9294 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309295 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309296 __func__, i);
9297 continue;
9298 }
9299
9300 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9301 {
9302 struct ieee80211_supported_band *band = wiphy->bands[i];
9303
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309304 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309305 {
9306 // Enable social channels for P2P
9307 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9308 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9309 else
9310 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9311 continue;
9312 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309313 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309314 {
9315 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9316 continue;
9317 }
9318 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 }
9320 /*Initialise the supported cipher suite details*/
9321 wiphy->cipher_suites = hdd_cipher_suites;
9322 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9323
9324 /*signal strength in mBm (100*dBm) */
9325 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9326
9327#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309328 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009329#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009330
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309331 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309332 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9333 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009334 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9335 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9336
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309337 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
Abhinav Kumar97821072019-08-02 14:29:48 +05309338 wlan_hdd_cfg80211_set_wiphy_sae_feature(wiphy, pCfg);
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309339
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309340 EXIT();
9341 return 0;
9342}
9343
9344/* In this function we are registering wiphy. */
9345int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9346{
9347 ENTER();
9348 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 if (0 > wiphy_register(wiphy))
9350 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309351 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9353 return -EIO;
9354 }
9355
9356 EXIT();
9357 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309358}
Jeff Johnson295189b2012-06-20 16:38:30 -07009359
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309360/* In this function we are updating channel list when,
9361 regulatory domain is FCC and country code is US.
9362 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9363 As per FCC smart phone is not a indoor device.
9364 GO should not opeate on indoor channels */
9365void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9366{
9367 int j;
9368 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9369 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9370 //Default counrtycode from NV at the time of wiphy initialization.
9371 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9372 &defaultCountryCode[0]))
9373 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009374 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309375 }
9376 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9377 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309378 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309379 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309380 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309381 return;
9382 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309383 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309384 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309385 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309386 // Mark UNII -1 band channel as passive
9387 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9388 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9389 }
9390 }
9391}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309392/* This function registers for all frame which supplicant is interested in */
9393void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009394{
Jeff Johnson295189b2012-06-20 16:38:30 -07009395 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9396 /* Register for all P2P action, public action etc frames */
9397 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009398 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309399 /* Register frame indication call back */
9400 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009401 /* Right now we are registering these frame when driver is getting
9402 initialized. Once we will move to 2.6.37 kernel, in which we have
9403 frame register ops, we will move this code as a part of that */
9404 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309405 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009406 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9407
9408 /* GAS Initial Response */
9409 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9410 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309411
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 /* GAS Comeback Request */
9413 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9414 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9415
9416 /* GAS Comeback Response */
9417 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9418 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9419
9420 /* P2P Public Action */
9421 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309422 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 P2P_PUBLIC_ACTION_FRAME_SIZE );
9424
9425 /* P2P Action */
9426 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9427 (v_U8_t*)P2P_ACTION_FRAME,
9428 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009429
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309430 /* WNM BSS Transition Request frame */
9431 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9432 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9433 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009434
9435 /* WNM-Notification */
9436 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9437 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9438 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009439}
9440
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309441void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009442{
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9444 /* Register for all P2P action, public action etc frames */
9445 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9446
Jeff Johnsone7245742012-09-05 17:12:55 -07009447 ENTER();
9448
Jeff Johnson295189b2012-06-20 16:38:30 -07009449 /* Right now we are registering these frame when driver is getting
9450 initialized. Once we will move to 2.6.37 kernel, in which we have
9451 frame register ops, we will move this code as a part of that */
9452 /* GAS Initial Request */
9453
9454 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9455 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9456
9457 /* GAS Initial Response */
9458 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9459 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309460
Jeff Johnson295189b2012-06-20 16:38:30 -07009461 /* GAS Comeback Request */
9462 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9463 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9464
9465 /* GAS Comeback Response */
9466 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9467 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9468
9469 /* P2P Public Action */
9470 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309471 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 P2P_PUBLIC_ACTION_FRAME_SIZE );
9473
9474 /* P2P Action */
9475 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9476 (v_U8_t*)P2P_ACTION_FRAME,
9477 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009478 /* WNM-Notification */
9479 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9480 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9481 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009482}
9483
9484#ifdef FEATURE_WLAN_WAPI
9485void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309486 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009487{
9488 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9489 tCsrRoamSetKey setKey;
9490 v_BOOL_t isConnected = TRUE;
9491 int status = 0;
9492 v_U32_t roamId= 0xFF;
9493 tANI_U8 *pKeyPtr = NULL;
9494 int n = 0;
9495
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309496 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9497 __func__, hdd_device_modetoString(pAdapter->device_mode),
9498 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009499
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309500 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009501 setKey.keyId = key_index; // Store Key ID
9502 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9503 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9504 setKey.paeRole = 0 ; // the PAE role
9505 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9506 {
9507 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9508 }
9509 else
9510 {
9511 isConnected = hdd_connIsConnected(pHddStaCtx);
9512 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9513 }
9514 setKey.keyLength = key_Len;
9515 pKeyPtr = setKey.Key;
9516 memcpy( pKeyPtr, key, key_Len);
9517
Arif Hussain6d2a3322013-11-17 19:50:10 -08009518 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009519 __func__, key_Len);
9520 for (n = 0 ; n < key_Len; n++)
9521 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9522 __func__,n,setKey.Key[n]);
9523
9524 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9525 if ( isConnected )
9526 {
9527 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9528 pAdapter->sessionId, &setKey, &roamId );
9529 }
9530 if ( status != 0 )
9531 {
9532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9533 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9534 __LINE__, status );
9535 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9536 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309537 /* Need to clear any trace of key value in the memory.
9538 * Thus zero out the memory even though it is local
9539 * variable.
9540 */
9541 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009542}
9543#endif /* FEATURE_WLAN_WAPI*/
9544
9545#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309546int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 beacon_data_t **ppBeacon,
9548 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009549#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309550int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009551 beacon_data_t **ppBeacon,
9552 struct cfg80211_beacon_data *params,
9553 int dtim_period)
9554#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309555{
Jeff Johnson295189b2012-06-20 16:38:30 -07009556 int size;
9557 beacon_data_t *beacon = NULL;
9558 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309559 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9560 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009561
Jeff Johnsone7245742012-09-05 17:12:55 -07009562 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309564 {
9565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9566 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309568 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009569
9570 old = pAdapter->sessionCtx.ap.beacon;
9571
9572 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309573 {
9574 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9575 FL("session(%d) old and new heads points to NULL"),
9576 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009577 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309578 }
9579
9580 if (params->tail && !params->tail_len)
9581 {
9582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9583 FL("tail_len is zero but tail is not NULL"));
9584 return -EINVAL;
9585 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009586
Jeff Johnson295189b2012-06-20 16:38:30 -07009587#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9588 /* Kernel 3.0 is not updating dtim_period for set beacon */
9589 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309590 {
9591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9592 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309594 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009595#endif
9596
Kapil Gupta137ef892016-12-13 19:38:00 +05309597 if (params->head)
9598 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009599 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309600 head = params->head;
9601 } else
9602 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009603 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309604 head = old->head;
9605 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009606
Kapil Gupta137ef892016-12-13 19:38:00 +05309607 if (params->tail || !old)
9608 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009609 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309610 tail = params->tail;
9611 } else
9612 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309614 tail = old->tail;
9615 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009616
Kapil Gupta137ef892016-12-13 19:38:00 +05309617 if (params->proberesp_ies || !old)
9618 {
9619 proberesp_ies_len = params->proberesp_ies_len;
9620 proberesp_ies = params->proberesp_ies;
9621 } else
9622 {
9623 proberesp_ies_len = old->proberesp_ies_len;
9624 proberesp_ies = old->proberesp_ies;
9625 }
9626
9627 if (params->assocresp_ies || !old)
9628 {
9629 assocresp_ies_len = params->assocresp_ies_len;
9630 assocresp_ies = params->assocresp_ies;
9631 } else
9632 {
9633 assocresp_ies_len = old->assocresp_ies_len;
9634 assocresp_ies = old->assocresp_ies;
9635 }
9636
9637 size = sizeof(beacon_data_t) + head_len + tail_len +
9638 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009639
9640 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009641 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309642 {
9643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9644 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309646 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009647
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009648#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309649 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 beacon->dtim_period = params->dtim_period;
9651 else
9652 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009653#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309654 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009655 beacon->dtim_period = dtim_period;
9656 else
9657 beacon->dtim_period = old->dtim_period;
9658#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309659
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9661 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309662 beacon->proberesp_ies = beacon->tail + tail_len;
9663 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9664
Jeff Johnson295189b2012-06-20 16:38:30 -07009665 beacon->head_len = head_len;
9666 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309667 beacon->proberesp_ies_len = proberesp_ies_len;
9668 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009669
c_manjee527ecac2017-01-25 12:25:27 +05309670 if (head && head_len)
9671 memcpy(beacon->head, head, head_len);
9672 if (tail && tail_len)
9673 memcpy(beacon->tail, tail, tail_len);
9674 if (proberesp_ies && proberesp_ies_len)
9675 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9676 if (assocresp_ies && assocresp_ies_len)
9677 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009678
9679 *ppBeacon = beacon;
9680
9681 kfree(old);
9682
9683 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009684}
Jeff Johnson295189b2012-06-20 16:38:30 -07009685
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309686v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9687#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9688 const v_U8_t *pIes,
9689#else
9690 v_U8_t *pIes,
9691#endif
9692 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009693{
9694 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309695 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009696 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309697
Jeff Johnson295189b2012-06-20 16:38:30 -07009698 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309699 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 elem_id = ptr[0];
9701 elem_len = ptr[1];
9702 left -= 2;
9703 if(elem_len > left)
9704 {
9705 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009706 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009707 eid,elem_len,left);
9708 return NULL;
9709 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309710 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009711 {
9712 return ptr;
9713 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309714
Jeff Johnson295189b2012-06-20 16:38:30 -07009715 left -= elem_len;
9716 ptr += (elem_len + 2);
9717 }
9718 return NULL;
9719}
9720
Jeff Johnson295189b2012-06-20 16:38:30 -07009721/* Check if rate is 11g rate or not */
9722static int wlan_hdd_rate_is_11g(u8 rate)
9723{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009724 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009725 u8 i;
9726 for (i = 0; i < 8; i++)
9727 {
9728 if(rate == gRateArray[i])
9729 return TRUE;
9730 }
9731 return FALSE;
9732}
9733
9734/* Check for 11g rate and set proper 11g only mode */
9735static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9736 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9737{
9738 u8 i, num_rates = pIe[0];
9739
9740 pIe += 1;
9741 for ( i = 0; i < num_rates; i++)
9742 {
9743 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9744 {
9745 /* If rate set have 11g rate than change the mode to 11G */
9746 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9747 if (pIe[i] & BASIC_RATE_MASK)
9748 {
9749 /* If we have 11g rate as basic rate, it means mode
9750 is 11g only mode.
9751 */
9752 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9753 *pCheckRatesfor11g = FALSE;
9754 }
9755 }
9756 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9757 {
9758 *require_ht = TRUE;
9759 }
9760 }
9761 return;
9762}
9763
9764static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9765{
9766 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9767 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9768 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9769 u8 checkRatesfor11g = TRUE;
9770 u8 require_ht = FALSE;
9771 u8 *pIe=NULL;
9772
9773 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9774
9775 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9776 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9777 if (pIe != NULL)
9778 {
9779 pIe += 1;
9780 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9781 &pConfig->SapHw_mode);
9782 }
9783
9784 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9785 WLAN_EID_EXT_SUPP_RATES);
9786 if (pIe != NULL)
9787 {
9788
9789 pIe += 1;
9790 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9791 &pConfig->SapHw_mode);
9792 }
9793
9794 if( pConfig->channel > 14 )
9795 {
9796 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9797 }
9798
9799 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9800 WLAN_EID_HT_CAPABILITY);
9801
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309802 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009803 {
9804 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9805 if(require_ht)
9806 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9807 }
9808}
9809
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309810static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9811 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9812{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009813 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309814 v_U8_t *pIe = NULL;
9815 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9816
9817 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9818 pBeacon->tail, pBeacon->tail_len);
9819
9820 if (pIe)
9821 {
9822 ielen = pIe[1] + 2;
9823 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9824 {
9825 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9826 }
9827 else
9828 {
9829 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9830 return -EINVAL;
9831 }
9832 *total_ielen += ielen;
9833 }
9834 return 0;
9835}
9836
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009837static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9838 v_U8_t *genie, v_U8_t *total_ielen)
9839{
9840 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9841 int left = pBeacon->tail_len;
9842 v_U8_t *ptr = pBeacon->tail;
9843 v_U8_t elem_id, elem_len;
9844 v_U16_t ielen = 0;
9845
9846 if ( NULL == ptr || 0 == left )
9847 return;
9848
9849 while (left >= 2)
9850 {
9851 elem_id = ptr[0];
9852 elem_len = ptr[1];
9853 left -= 2;
9854 if (elem_len > left)
9855 {
9856 hddLog( VOS_TRACE_LEVEL_ERROR,
9857 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9858 elem_id, elem_len, left);
9859 return;
9860 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309861 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009862 {
9863 /* skipping the VSIE's which we don't want to include or
9864 * it will be included by existing code
9865 */
9866 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9867#ifdef WLAN_FEATURE_WFD
9868 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9869#endif
9870 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9871 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9872 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9873 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9874 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9875 {
9876 ielen = ptr[1] + 2;
9877 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9878 {
9879 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9880 *total_ielen += ielen;
9881 }
9882 else
9883 {
9884 hddLog( VOS_TRACE_LEVEL_ERROR,
9885 "IE Length is too big "
9886 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9887 elem_id, elem_len, *total_ielen);
9888 }
9889 }
9890 }
9891
9892 left -= elem_len;
9893 ptr += (elem_len + 2);
9894 }
9895 return;
9896}
9897
Kapil Gupta137ef892016-12-13 19:38:00 +05309898int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009899{
9900 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309901 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009902 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009903 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309904 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009905
9906 genie = vos_mem_malloc(MAX_GENIE_LEN);
9907
9908 if(genie == NULL) {
9909
9910 return -ENOMEM;
9911 }
9912
Kapil Gupta137ef892016-12-13 19:38:00 +05309913 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309914 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9915 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309917 hddLog(LOGE,
9918 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309919 ret = -EINVAL;
9920 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009921 }
9922
9923#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309924 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9925 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9926 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309927 hddLog(LOGE,
9928 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309929 ret = -EINVAL;
9930 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009931 }
9932#endif
9933
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309934 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9935 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009936 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309937 hddLog(LOGE,
9938 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309939 ret = -EINVAL;
9940 goto done;
9941 }
9942
9943 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9944 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009945 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009946 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009947
9948 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9949 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9950 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9951 {
9952 hddLog(LOGE,
9953 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009954 ret = -EINVAL;
9955 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009956 }
9957
9958 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9959 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9960 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9961 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9962 ==eHAL_STATUS_FAILURE)
9963 {
9964 hddLog(LOGE,
9965 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009966 ret = -EINVAL;
9967 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009968 }
9969
9970 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309971 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309973 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009974 u8 probe_rsp_ie_len[3] = {0};
9975 u8 counter = 0;
9976 /* Check Probe Resp Length if it is greater then 255 then Store
9977 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9978 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9979 Store More then 255 bytes into One Variable.
9980 */
9981 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9982 {
9983 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9984 {
9985 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9986 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9987 }
9988 else
9989 {
9990 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9991 rem_probe_resp_ie_len = 0;
9992 }
9993 }
9994
9995 rem_probe_resp_ie_len = 0;
9996
9997 if (probe_rsp_ie_len[0] > 0)
9998 {
9999 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10000 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +053010001 (tANI_U8*)&pBeacon->
10002 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 probe_rsp_ie_len[0], NULL,
10004 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10005 {
10006 hddLog(LOGE,
10007 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010008 ret = -EINVAL;
10009 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010010 }
10011 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10012 }
10013
10014 if (probe_rsp_ie_len[1] > 0)
10015 {
10016 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10017 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +053010018 (tANI_U8*)&pBeacon->
10019 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010020 probe_rsp_ie_len[1], NULL,
10021 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10022 {
10023 hddLog(LOGE,
10024 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010025 ret = -EINVAL;
10026 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 }
10028 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10029 }
10030
10031 if (probe_rsp_ie_len[2] > 0)
10032 {
10033 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10034 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010035 (tANI_U8*)&pBeacon->
10036 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 probe_rsp_ie_len[2], NULL,
10038 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10039 {
10040 hddLog(LOGE,
10041 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010042 ret = -EINVAL;
10043 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 }
10045 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10046 }
10047
10048 if (probe_rsp_ie_len[1] == 0 )
10049 {
10050 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10051 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10052 eANI_BOOLEAN_FALSE) )
10053 {
10054 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010055 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010056 }
10057 }
10058
10059 if (probe_rsp_ie_len[2] == 0 )
10060 {
10061 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10062 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10063 eANI_BOOLEAN_FALSE) )
10064 {
10065 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010066 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010067 }
10068 }
10069
10070 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10071 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10072 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10073 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10074 == eHAL_STATUS_FAILURE)
10075 {
10076 hddLog(LOGE,
10077 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010078 ret = -EINVAL;
10079 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010080 }
10081 }
10082 else
10083 {
10084 // Reset WNI_CFG_PROBE_RSP Flags
10085 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10086
10087 hddLog(VOS_TRACE_LEVEL_INFO,
10088 "%s: No Probe Response IE received in set beacon",
10089 __func__);
10090 }
10091
10092 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010093 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010094 {
10095 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010096 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10097 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10099 {
10100 hddLog(LOGE,
10101 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010102 ret = -EINVAL;
10103 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010104 }
10105
10106 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10107 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10108 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10109 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10110 == eHAL_STATUS_FAILURE)
10111 {
10112 hddLog(LOGE,
10113 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010114 ret = -EINVAL;
10115 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010116 }
10117 }
10118 else
10119 {
10120 hddLog(VOS_TRACE_LEVEL_INFO,
10121 "%s: No Assoc Response IE received in set beacon",
10122 __func__);
10123
10124 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10125 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10126 eANI_BOOLEAN_FALSE) )
10127 {
10128 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010129 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010130 }
10131 }
10132
Jeff Johnsone7245742012-09-05 17:12:55 -070010133done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010134 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010135 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010136}
Jeff Johnson295189b2012-06-20 16:38:30 -070010137
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010138/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010139 * FUNCTION: wlan_hdd_validate_operation_channel
10140 * called by wlan_hdd_cfg80211_start_bss() and
10141 * wlan_hdd_cfg80211_set_channel()
10142 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010143 * channel list.
10144 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010145VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010146{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010147
Jeff Johnson295189b2012-06-20 16:38:30 -070010148 v_U32_t num_ch = 0;
10149 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10150 u32 indx = 0;
10151 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010152 v_U8_t fValidChannel = FALSE, count = 0;
10153 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010154
Jeff Johnson295189b2012-06-20 16:38:30 -070010155 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10156
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010157 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010159 /* Validate the channel */
10160 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010161 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010162 if ( channel == rfChannels[count].channelNum )
10163 {
10164 fValidChannel = TRUE;
10165 break;
10166 }
10167 }
10168 if (fValidChannel != TRUE)
10169 {
10170 hddLog(VOS_TRACE_LEVEL_ERROR,
10171 "%s: Invalid Channel [%d]", __func__, channel);
10172 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010173 }
10174 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010175 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010177 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10178 valid_ch, &num_ch))
10179 {
10180 hddLog(VOS_TRACE_LEVEL_ERROR,
10181 "%s: failed to get valid channel list", __func__);
10182 return VOS_STATUS_E_FAILURE;
10183 }
10184 for (indx = 0; indx < num_ch; indx++)
10185 {
10186 if (channel == valid_ch[indx])
10187 {
10188 break;
10189 }
10190 }
10191
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010192 if (indx >= num_ch)
10193 {
10194 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10195 {
10196 eCsrBand band;
10197 unsigned int freq;
10198
10199 sme_GetFreqBand(hHal, &band);
10200
10201 if (eCSR_BAND_5G == band)
10202 {
10203#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10204 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10205 {
10206 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010207 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010208 }
10209 else
10210 {
10211 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010212 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010213 }
10214#else
10215 freq = ieee80211_channel_to_frequency(channel);
10216#endif
10217 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10218 return VOS_STATUS_SUCCESS;
10219 }
10220 }
10221
10222 hddLog(VOS_TRACE_LEVEL_ERROR,
10223 "%s: Invalid Channel [%d]", __func__, channel);
10224 return VOS_STATUS_E_FAILURE;
10225 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010226 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010227
Jeff Johnson295189b2012-06-20 16:38:30 -070010228 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010229
Jeff Johnson295189b2012-06-20 16:38:30 -070010230}
10231
Viral Modi3a32cc52013-02-08 11:14:52 -080010232/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010233 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010234 * This function is used to set the channel number
10235 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010236static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010237 struct ieee80211_channel *chan,
10238 enum nl80211_channel_type channel_type
10239 )
10240{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010241 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010242 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010243 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010244 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010245 hdd_context_t *pHddCtx;
10246 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010247
10248 ENTER();
10249
10250 if( NULL == dev )
10251 {
10252 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010253 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010254 return -ENODEV;
10255 }
10256 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010257
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010258 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10259 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10260 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010261 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010262 "%s: device_mode = %s (%d) freq = %d", __func__,
10263 hdd_device_modetoString(pAdapter->device_mode),
10264 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010265
10266 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10267 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010268 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010269 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010270 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010271 }
10272
10273 /*
10274 * Do freq to chan conversion
10275 * TODO: for 11a
10276 */
10277
10278 channel = ieee80211_frequency_to_channel(freq);
10279
10280 /* Check freq range */
10281 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10282 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10283 {
10284 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010285 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010286 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10287 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10288 return -EINVAL;
10289 }
10290
10291 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10292
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010293 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10294 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010295 {
10296 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10297 {
10298 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010299 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010300 return -EINVAL;
10301 }
10302 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10303 "%s: set channel to [%d] for device mode =%d",
10304 __func__, channel,pAdapter->device_mode);
10305 }
10306 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010307 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010308 )
10309 {
10310 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10311 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10312 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10313
10314 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10315 {
10316 /* Link is up then return cant set channel*/
10317 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010318 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010319 return -EINVAL;
10320 }
10321
10322 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10323 pHddStaCtx->conn_info.operationChannel = channel;
10324 pRoamProfile->ChannelInfo.ChannelList =
10325 &pHddStaCtx->conn_info.operationChannel;
10326 }
10327 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010328 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010329 )
10330 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010331 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10332 {
10333 if(VOS_STATUS_SUCCESS !=
10334 wlan_hdd_validate_operation_channel(pAdapter,channel))
10335 {
10336 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010337 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010338 return -EINVAL;
10339 }
10340 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10341 }
10342 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010343 {
10344 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10345
10346 /* If auto channel selection is configured as enable/ 1 then ignore
10347 channel set by supplicant
10348 */
10349 if ( cfg_param->apAutoChannelSelection )
10350 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010351 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10352 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010353 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010354 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10355 __func__, hdd_device_modetoString(pAdapter->device_mode),
10356 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010357 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010358 else
10359 {
10360 if(VOS_STATUS_SUCCESS !=
10361 wlan_hdd_validate_operation_channel(pAdapter,channel))
10362 {
10363 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010364 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010365 return -EINVAL;
10366 }
10367 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10368 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010369 }
10370 }
10371 else
10372 {
10373 hddLog(VOS_TRACE_LEVEL_FATAL,
10374 "%s: Invalid device mode failed to set valid channel", __func__);
10375 return -EINVAL;
10376 }
10377 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010378 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010379}
10380
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010381static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10382 struct net_device *dev,
10383 struct ieee80211_channel *chan,
10384 enum nl80211_channel_type channel_type
10385 )
10386{
10387 int ret;
10388
10389 vos_ssr_protect(__func__);
10390 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10391 vos_ssr_unprotect(__func__);
10392
10393 return ret;
10394}
10395
Anurag Chouhan83026002016-12-13 22:46:21 +053010396#ifdef DHCP_SERVER_OFFLOAD
10397void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10398 VOS_STATUS status)
10399{
10400 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10401
10402 ENTER();
10403
10404 if (NULL == adapter)
10405 {
10406 hddLog(VOS_TRACE_LEVEL_ERROR,
10407 "%s: adapter is NULL",__func__);
10408 return;
10409 }
10410
10411 adapter->dhcp_status.dhcp_offload_status = status;
10412 vos_event_set(&adapter->dhcp_status.vos_event);
10413 return;
10414}
10415
10416/**
10417 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10418 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010419 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010420 *
10421 * Return: None
10422 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010423VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10424 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010425{
10426 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10427 sir_dhcp_srv_offload_info dhcp_srv_info;
10428 tANI_U8 num_entries = 0;
10429 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10430 tANI_U8 num;
10431 tANI_U32 temp;
10432 VOS_STATUS ret;
10433
10434 ENTER();
10435
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010436 if (!re_init) {
10437 ret = wlan_hdd_validate_context(hdd_ctx);
10438 if (0 != ret)
10439 return VOS_STATUS_E_INVAL;
10440 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010441
10442 /* Prepare the request to send to SME */
10443 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10444 if (NULL == dhcp_srv_info) {
10445 hddLog(VOS_TRACE_LEVEL_ERROR,
10446 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10447 return VOS_STATUS_E_NOMEM;
10448 }
10449
10450 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10451
10452 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10453 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10454 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10455 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10456 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10457 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10458
10459 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10460 srv_ip,
10461 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010462 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010463 if (num_entries != IPADDR_NUM_ENTRIES) {
10464 hddLog(VOS_TRACE_LEVEL_ERROR,
10465 "%s: incorrect IP address (%s) assigned for DHCP server!",
10466 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10467 vos_mem_free(dhcp_srv_info);
10468 return VOS_STATUS_E_FAILURE;
10469 }
10470
10471 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10472 hddLog(VOS_TRACE_LEVEL_ERROR,
10473 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10474 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10475 vos_mem_free(dhcp_srv_info);
10476 return VOS_STATUS_E_FAILURE;
10477 }
10478
10479 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10480 hddLog(VOS_TRACE_LEVEL_ERROR,
10481 "%s: invalid IP address (%s)! The last field must be less than 100!",
10482 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10483 vos_mem_free(dhcp_srv_info);
10484 return VOS_STATUS_E_FAILURE;
10485 }
10486
10487 for (num = 0; num < num_entries; num++) {
10488 temp = srv_ip[num];
10489 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10490 }
10491
10492 if (eHAL_STATUS_SUCCESS !=
10493 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10494 hddLog(VOS_TRACE_LEVEL_ERROR,
10495 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10496 vos_mem_free(dhcp_srv_info);
10497 return VOS_STATUS_E_FAILURE;
10498 }
10499
10500 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10501 "%s: enable DHCP Server offload successfully!", __func__);
10502
10503 vos_mem_free(dhcp_srv_info);
10504 return 0;
10505}
10506#endif /* DHCP_SERVER_OFFLOAD */
10507
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010508/*
10509 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10510 * @wiphy_chan: wiphy channel number
10511 * @rfChannel: channel hw value
10512 * @disable: Disable/enable the flags
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010513 * @hdd_ctx: The HDD context handler
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010514 *
10515 * Modify wiphy flags and cds state if channel is indoor.
10516 *
10517 * Return: void
10518 */
10519void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010520 v_U32_t rfChannel, bool disable, hdd_context_t *hdd_ctx)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010521{
10522 v_U32_t channelLoop;
10523 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10524
10525 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10526
10527 if (rfChannels[channelLoop].channelNum == rfChannel) {
10528 channelEnum = (eRfChannels)channelLoop;
10529 break;
10530 }
10531 }
10532
10533 if (INVALID_RF_CHANNEL == channelEnum)
10534 return;
10535
10536 if (disable) {
10537 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10538 wiphy_chan->flags |=
10539 IEEE80211_CHAN_DISABLED;
10540 regChannels[channelEnum].enabled =
10541 NV_CHANNEL_DISABLE;
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010542 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DISABLE",
10543 channelEnum);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010544 }
10545 } else {
10546 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10547 wiphy_chan->flags &=
10548 ~IEEE80211_CHAN_DISABLED;
10549 /*
10550 * Indoor channels are marked as DFS
10551 * during regulatory processing
10552 */
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010553 if ((wiphy_chan->flags & (IEEE80211_CHAN_RADAR |
10554 IEEE80211_CHAN_PASSIVE_SCAN)) ||
10555 ((hdd_ctx->cfg_ini->indoor_channel_support == false)
10556 && (wiphy_chan->flags &
10557 IEEE80211_CHAN_INDOOR_ONLY))) {
10558 regChannels[channelEnum].enabled = NV_CHANNEL_DFS;
10559 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DFS",
10560 channelEnum);
10561 } else {
10562 regChannels[channelEnum].enabled =
10563 NV_CHANNEL_ENABLE;
10564 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as ENABLE",
10565 channelEnum);
10566 }
10567 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010568
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010569 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010570}
10571
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010572void hdd_update_indoor_channel(hdd_context_t *hdd_ctx, bool disable)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010573{
10574 int band_num;
10575 int chan_num;
10576 v_U32_t rfChannel;
10577 struct ieee80211_channel *wiphy_chan;
10578 struct wiphy *wiphy;
10579
10580 ENTER();
10581 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10582
10583 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010584 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010585
10586 if (wiphy->bands[band_num] == NULL)
10587 continue;
10588
10589 for (chan_num = 0;
10590 chan_num < wiphy->bands[band_num]->n_channels;
10591 chan_num++) {
10592
10593 wiphy_chan =
10594 &(wiphy->bands[band_num]->channels[chan_num]);
10595 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10596
10597 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010598 disable, hdd_ctx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010599 }
10600 }
10601 EXIT();
10602}
10603
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010604int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10605{
Dundi Raviteja49de66b2018-07-27 12:22:57 +053010606 eHalStatus status;
10607 int result = 0;
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010608 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10609 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10610 long ret;
10611 eConnectionState prev_conn_state;
10612 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10613
10614 ENTER();
10615
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010616 /* Indicate sme of disconnect so that in progress connection or preauth
10617 * can be aborted
10618 */
10619 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10620 pAdapter->sessionId);
10621 pHddCtx->isAmpAllowed = VOS_TRUE;
10622
10623 /* Need to apply spin lock before decreasing active sessions
10624 * as there can be chance for double decrement if context switch
10625 * Calls hdd_DisConnectHandler.
10626 */
10627
10628 prev_conn_state = pHddStaCtx->conn_info.connState;
10629
10630 spin_lock_bh(&pAdapter->lock_for_active_session);
10631 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10632 {
10633 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10634 }
10635 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10636 spin_unlock_bh(&pAdapter->lock_for_active_session);
10637 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10638
10639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10640 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10641
10642 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10643
10644 /*
10645 * stop tx queues before deleting STA/BSS context from the firmware.
10646 * tx has to be disabled because the firmware can get busy dropping
10647 * the tx frames after BSS/STA has been deleted and will not send
10648 * back a response resulting in WDI timeout
10649 */
10650 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10651 netif_tx_disable(pAdapter->dev);
10652 netif_carrier_off(pAdapter->dev);
10653
10654 wlan_hdd_check_and_stop_mon(pAdapter, true);
10655
10656 /*issue disconnect*/
10657 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10658 pAdapter->sessionId, reason);
10659 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10660 prev_conn_state != eConnectionState_Connecting)
10661 {
10662 hddLog(LOG1,
10663 FL("status = %d, already disconnected"), status);
10664 result = 0;
10665 /*
10666 * Wait here instead of returning directly. This will block the
10667 * next connect command and allow processing of the disconnect
10668 * in SME else we might hit some race conditions leading to SME
10669 * and HDD out of sync. As disconnect is already in progress,
10670 * wait here for 1 sec instead of 5 sec.
10671 */
10672 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10673 goto wait_for_disconnect;
10674 }
10675 /*
10676 * Wait here instead of returning directly, this will block the next
10677 * connect command and allow processing of the scan for ssid and
10678 * the previous connect command in CSR. Else we might hit some
10679 * race conditions leading to SME and HDD out of sync.
10680 */
10681 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10682 {
10683 hddLog(LOG1,
10684 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10685 }
10686 else if ( 0 != status )
10687 {
10688 hddLog(LOGE,
10689 FL("csrRoamDisconnect failure, returned %d"),
10690 (int)status);
10691 result = -EINVAL;
10692 goto disconnected;
10693 }
10694wait_for_disconnect:
10695 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10696 msecs_to_jiffies(wait_time));
10697 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10698 {
10699 hddLog(LOGE,
10700 "%s: Failed to disconnect, timed out", __func__);
10701 result = -ETIMEDOUT;
10702 }
10703disconnected:
10704 hddLog(LOG1,
10705 FL("Set HDD connState to eConnectionState_NotConnected"));
10706 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10707#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10708 /* Sending disconnect event to userspace for kernel version < 3.11
10709 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10710 */
10711 hddLog(LOG1, FL("Send disconnected event to userspace"));
10712
10713 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10714 WLAN_REASON_UNSPECIFIED);
10715#endif
10716
10717 EXIT();
10718 return result;
10719}
10720
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010721void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10722{
10723
10724 hdd_adapter_t *sta_adapter;
10725 tANI_U8 sta_chan;
10726
10727 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10728
10729 if (!sta_chan) {
10730 hddLog(LOG1, FL("STA not connected"));
10731 return;
10732 }
10733
10734 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10735
10736 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10737 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10738 sta_chan);
10739 return;
10740 }
10741
10742 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10743
10744 if (!sta_adapter) {
10745 hddLog(LOG1, FL("STA adapter doesn't exist"));
10746 return;
10747 }
10748
10749 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10750 /* Issue Disconnect request */
10751 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10752}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010753
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010754int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10755{
10756 struct hdd_cache_channels *cache_chann;
10757 struct wiphy *wiphy;
10758 int freq, status, rfChannel;
10759 int i, band_num, channel_num;
10760 struct ieee80211_channel *wiphy_channel;
10761
10762 ENTER();
10763
10764 if (!hdd_ctx) {
10765 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10766 return -EINVAL;
10767 }
10768
10769 wiphy = hdd_ctx->wiphy;
10770
10771 mutex_lock(&hdd_ctx->cache_channel_lock);
10772
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010773 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010774
10775 if (!cache_chann || !cache_chann->num_channels) {
10776 hddLog(VOS_TRACE_LEVEL_INFO,
10777 "%s channel list is NULL or num channels are zero",
10778 __func__);
10779 mutex_unlock(&hdd_ctx->cache_channel_lock);
10780 return -EINVAL;
10781 }
10782
10783 for (i = 0; i < cache_chann->num_channels; i++) {
10784 status = hdd_wlan_get_freq(
10785 cache_chann->channel_info[i].channel_num,
10786 &freq);
10787
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010788 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10789 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010790 if (!wiphy->bands[band_num])
10791 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010792 for (channel_num = 0; channel_num <
10793 wiphy->bands[band_num]->n_channels;
10794 channel_num++) {
10795 wiphy_channel = &(wiphy->bands[band_num]->
10796 channels[channel_num]);
10797 if (wiphy_channel->center_freq == freq) {
10798 rfChannel = wiphy_channel->hw_value;
10799 /*
10800 *Restore the orginal states
10801 *of the channels
10802 */
10803 vos_nv_set_channel_state(
10804 rfChannel,
10805 cache_chann->
10806 channel_info[i].reg_status);
10807 wiphy_channel->flags =
10808 cache_chann->
10809 channel_info[i].wiphy_status;
Ashish Kumar Dhanotiya1cf97dd2019-03-11 16:59:25 +053010810 hddLog(VOS_TRACE_LEVEL_DEBUG,
10811 "Restore channel %d reg_stat %d wiphy_stat 0x%x",
10812 cache_chann->
10813 channel_info[i].channel_num,
10814 cache_chann->
10815 channel_info[i].reg_status,
10816 wiphy_channel->flags);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010817 break;
10818 }
10819 }
10820 if (channel_num < wiphy->bands[band_num]->n_channels)
10821 break;
10822 }
10823 }
10824
10825 mutex_unlock(&hdd_ctx->cache_channel_lock);
10826
10827 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10828 if (status)
10829 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10830 EXIT();
10831
10832 return 0;
10833}
10834
Ashish Kumar Dhanotiya1cf97dd2019-03-11 16:59:25 +053010835int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010836{
10837 struct hdd_cache_channels *cache_chann;
10838 struct wiphy *wiphy;
10839 int freq, status, rfChannel;
10840 int i, band_num, band_ch_num;
10841 struct ieee80211_channel *wiphy_channel;
10842
10843 if (!hdd_ctx) {
10844 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10845 return -EINVAL;
10846 }
10847
10848 wiphy = hdd_ctx->wiphy;
10849
10850 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010851 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010852
10853 if (!cache_chann || !cache_chann->num_channels) {
10854 hddLog(VOS_TRACE_LEVEL_INFO,
10855 "%s channel list is NULL or num channels are zero",
10856 __func__);
10857 mutex_unlock(&hdd_ctx->cache_channel_lock);
10858 return -EINVAL;
10859 }
10860
10861 for (i = 0; i < cache_chann->num_channels; i++) {
10862 status = hdd_wlan_get_freq(
10863 cache_chann->channel_info[i].channel_num,
10864 &freq);
10865
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010866 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010867 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010868 if (!wiphy->bands[band_num])
10869 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010870 for (band_ch_num = 0; band_ch_num <
10871 wiphy->bands[band_num]->n_channels;
10872 band_ch_num++) {
10873 wiphy_channel = &(wiphy->bands[band_num]->
10874 channels[band_ch_num]);
10875 if (wiphy_channel->center_freq == freq) {
10876 rfChannel = wiphy_channel->hw_value;
10877 /*
10878 * Cache the current states of
10879 * the channels
10880 */
10881 cache_chann->
10882 channel_info[i].reg_status =
10883 vos_nv_getChannelEnabledState(
10884 rfChannel);
10885
10886 cache_chann->
10887 channel_info[i].wiphy_status =
10888 wiphy_channel->flags;
10889 hddLog(VOS_TRACE_LEVEL_INFO,
10890 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10891 cache_chann->
10892 channel_info[i].channel_num,
10893 cache_chann->
10894 channel_info[i].reg_status,
10895 wiphy_channel->flags);
10896
10897 vos_nv_set_channel_state(
10898 rfChannel,
10899 NV_CHANNEL_DISABLE);
10900 wiphy_channel->flags |=
10901 IEEE80211_CHAN_DISABLED;
10902 break;
10903 }
10904 }
10905 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10906 break;
10907 }
10908 }
10909
10910 mutex_unlock(&hdd_ctx->cache_channel_lock);
10911 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10912 return 0;
10913}
10914
Jeff Johnson295189b2012-06-20 16:38:30 -070010915#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10916static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10917 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010918#else
10919static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10920 struct cfg80211_beacon_data *params,
10921 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010922 enum nl80211_hidden_ssid hidden_ssid,
10923 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010924#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010925{
10926 tsap_Config_t *pConfig;
10927 beacon_data_t *pBeacon = NULL;
10928 struct ieee80211_mgmt *pMgmt_frame;
10929 v_U8_t *pIe=NULL;
10930 v_U16_t capab_info;
10931 eCsrAuthType RSNAuthType;
10932 eCsrEncryptionType RSNEncryptType;
10933 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010934 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010935 tpWLAN_SAPEventCB pSapEventCallback;
10936 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010937 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010938 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010939 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010940 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010941 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010942 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053010943 hdd_adapter_t *sta_adapter;
Peng Xu2446a892014-09-05 17:21:18 +053010944 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010945 v_BOOL_t MFPCapable = VOS_FALSE;
10946 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010947 v_BOOL_t sapEnable11AC =
10948 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010949 u_int16_t prev_rsn_length = 0;
10950
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 ENTER();
10952
Nitesh Shah9b066282017-06-06 18:05:52 +053010953 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053010954
10955 /*
10956 * For STA+SAP concurrency support from GUI, first STA connection gets
10957 * triggered and while it is in progress, SAP start also comes up.
10958 * Once STA association is successful, STA connect event is sent to
10959 * kernel which gets queued in kernel workqueue and supplicant won't
10960 * process M1 received from AP and send M2 until this NL80211_CONNECT
10961 * event is received. Workqueue is not scheduled as RTNL lock is already
10962 * taken by hostapd thread which has issued start_bss command to driver.
10963 * Driver cannot complete start_bss as the pending command at the head
10964 * of the SME command pending list is hw_mode_update for STA session
10965 * which cannot be processed as SME is in WAITforKey state for STA
10966 * interface. The start_bss command for SAP interface is queued behind
10967 * the hw_mode_update command and so it cannot be processed until
10968 * hw_mode_update command is processed. This is causing a deadlock so
10969 * disconnect the STA interface first if connection or key exchange is
10970 * in progress and then start SAP interface.
10971 */
10972 sta_adapter = hdd_get_sta_connection_in_progress(pHddCtx);
10973 if (sta_adapter) {
10974 hddLog(LOG1, FL("Disconnecting STA with session id: %d"),
10975 sta_adapter->sessionId);
10976 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10977 }
10978
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010979 iniConfig = pHddCtx->cfg_ini;
10980
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010981 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053010982 if (iniConfig->disable_indoor_channel &&
10983 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010984 hdd_update_indoor_channel(pHddCtx, true);
10985
10986 if (!VOS_IS_STATUS_SUCCESS(
10987 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10988 hdd_update_indoor_channel(pHddCtx, false);
10989 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
10990 FL("Can't start BSS: update channel list failed"));
Bala Venkatesh5c06a252018-07-12 16:08:04 +053010991 ret = eHAL_STATUS_FAILURE;
10992 goto tdls_enable;
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010993 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010994
10995 /* check if STA is on indoor channel */
10996 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
10997 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010998 }
10999
Jeff Johnson295189b2012-06-20 16:38:30 -070011000 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11001
11002 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11003
11004 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11005
11006 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11007
11008 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11009
11010 //channel is already set in the set_channel Call back
11011 //pConfig->channel = pCommitConfig->channel;
11012
11013 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011014 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011015 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11016
11017 pConfig->dtim_period = pBeacon->dtim_period;
11018
Arif Hussain6d2a3322013-11-17 19:50:10 -080011019 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011020 pConfig->dtim_period);
11021
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011022 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011023 {
11024 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011025 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011026 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11027 {
11028 tANI_BOOLEAN restartNeeded;
11029 pConfig->ieee80211d = 1;
11030 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11031 sme_setRegInfo(hHal, pConfig->countryCode);
11032 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11033 }
11034 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011035 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011036 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011037 pConfig->ieee80211d = 1;
11038 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11039 sme_setRegInfo(hHal, pConfig->countryCode);
11040 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011041 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011042 else
11043 {
11044 pConfig->ieee80211d = 0;
11045 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011046 /*
11047 * If auto channel is configured i.e. channel is 0,
11048 * so skip channel validation.
11049 */
11050 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11051 {
11052 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11053 {
11054 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011055 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011056 ret = -EINVAL;
11057 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011058 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011059 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011060 }
11061 else
11062 {
11063 if(1 != pHddCtx->is_dynamic_channel_range_set)
11064 {
11065 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11066 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11067 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11068 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011069 pHddCtx->is_dynamic_channel_range_set = 0;
11070 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011071 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011072 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011073 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011074 {
11075 pConfig->ieee80211d = 0;
11076 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011077
11078#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11079 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11080 pConfig->authType = eSAP_OPEN_SYSTEM;
11081 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11082 pConfig->authType = eSAP_SHARED_KEY;
11083 else
11084 pConfig->authType = eSAP_AUTO_SWITCH;
11085#else
11086 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11087 pConfig->authType = eSAP_OPEN_SYSTEM;
11088 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11089 pConfig->authType = eSAP_SHARED_KEY;
11090 else
11091 pConfig->authType = eSAP_AUTO_SWITCH;
11092#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011093
11094 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011095
11096 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011097 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011098#ifdef SAP_AUTH_OFFLOAD
11099 /* In case of sap offload, hostapd.conf is configuted with open mode and
11100 * security is configured from ini file. Due to open mode in hostapd.conf
11101 * privacy bit is set to false which will result in not sending,
11102 * data packets as encrypted.
11103 * If enable_sap_auth_offload is enabled in ini and
11104 * sap_auth_offload_sec_type is type of WPA2-PSK,
11105 * driver will set privacy bit to 1.
11106 */
11107 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11108 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11109 pConfig->privacy = VOS_TRUE;
11110#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011111
11112 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11113
11114 /*Set wps station to configured*/
11115 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11116
11117 if(pIe)
11118 {
11119 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11120 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011121 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011122 ret = -EINVAL;
11123 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011124 }
11125 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11126 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011127 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011128 /* Check 15 bit of WPS IE as it contain information for wps state
11129 * WPS state
11130 */
11131 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11132 {
11133 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11134 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11135 {
11136 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11137 }
11138 }
11139 }
11140 else
11141 {
11142 pConfig->wps_state = SAP_WPS_DISABLED;
11143 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011144 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011145
c_hpothufe599e92014-06-16 11:38:55 +053011146 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11147 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11148 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11149 eCSR_ENCRYPT_TYPE_NONE;
11150
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011152 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011153 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 WLAN_EID_RSN);
11155 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011156 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011157 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011158 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11159 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11160 pConfig->RSNWPAReqIELength);
11161 else
11162 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11163 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011164 /* The actual processing may eventually be more extensive than
11165 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011166 * by the app.
11167 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011168 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011169 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11170 &RSNEncryptType,
11171 &mcRSNEncryptType,
11172 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011173 &MFPCapable,
11174 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011175 pConfig->RSNWPAReqIE[1]+2,
11176 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011177
11178 if( VOS_STATUS_SUCCESS == status )
11179 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011180 /* Now copy over all the security attributes you have
11181 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 * */
11183 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11184 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11185 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11186 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011187 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011188 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011189 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11190 }
11191 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011192
Jeff Johnson295189b2012-06-20 16:38:30 -070011193 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11194 pBeacon->tail, pBeacon->tail_len);
11195
11196 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11197 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011198 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011199 {
11200 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011201 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011202 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011203 if (pConfig->RSNWPAReqIELength <=
11204 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11205 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11206 pIe[1] + 2);
11207 else
11208 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11209 pConfig->RSNWPAReqIELength);
11210
Jeff Johnson295189b2012-06-20 16:38:30 -070011211 }
11212 else
11213 {
11214 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011215 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11216 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11217 pConfig->RSNWPAReqIELength);
11218 else
11219 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11220 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011221 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011222 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11223 &RSNEncryptType,
11224 &mcRSNEncryptType,
11225 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011226 &MFPCapable,
11227 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011228 pConfig->RSNWPAReqIE[1]+2,
11229 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011230
11231 if( VOS_STATUS_SUCCESS == status )
11232 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011233 /* Now copy over all the security attributes you have
11234 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 * */
11236 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11237 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11238 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11239 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011240 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011241 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011242 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11243 }
11244 }
11245 }
11246
Kapil Gupta137ef892016-12-13 19:38:00 +053011247 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011248 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011249 ret = -EINVAL;
11250 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011251 }
11252
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11254
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011255#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011256 if (params->ssid != NULL)
11257 {
11258 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11259 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11260 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11261 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11262 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011263#else
11264 if (ssid != NULL)
11265 {
11266 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11267 pConfig->SSIDinfo.ssid.length = ssid_len;
11268 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11269 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11270 }
11271#endif
11272
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011273 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011274 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011275
Jeff Johnson295189b2012-06-20 16:38:30 -070011276 /* default value */
11277 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11278 pConfig->num_accept_mac = 0;
11279 pConfig->num_deny_mac = 0;
11280
11281 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11282 pBeacon->tail, pBeacon->tail_len);
11283
11284 /* pIe for black list is following form:
11285 type : 1 byte
11286 length : 1 byte
11287 OUI : 4 bytes
11288 acl type : 1 byte
11289 no of mac addr in black list: 1 byte
11290 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011291 */
11292 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 {
11294 pConfig->SapMacaddr_acl = pIe[6];
11295 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011296 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011298 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11299 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011300 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11301 for (i = 0; i < pConfig->num_deny_mac; i++)
11302 {
11303 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11304 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011305 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011306 }
11307 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11308 pBeacon->tail, pBeacon->tail_len);
11309
11310 /* pIe for white list is following form:
11311 type : 1 byte
11312 length : 1 byte
11313 OUI : 4 bytes
11314 acl type : 1 byte
11315 no of mac addr in white list: 1 byte
11316 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011317 */
11318 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011319 {
11320 pConfig->SapMacaddr_acl = pIe[6];
11321 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011322 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011323 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011324 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11325 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011326 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11327 for (i = 0; i < pConfig->num_accept_mac; i++)
11328 {
11329 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11330 acl_entry++;
11331 }
11332 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011333
Jeff Johnson295189b2012-06-20 16:38:30 -070011334 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11335
Jeff Johnsone7245742012-09-05 17:12:55 -070011336#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011337 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011338 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11339 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011340 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11341 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011342 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11343 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011344 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11345 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011346 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011347 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011348 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011349 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011350
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011351 /* If ACS disable and selected channel <= 14
11352 * OR
11353 * ACS enabled and ACS operating band is choosen as 2.4
11354 * AND
11355 * VHT in 2.4G Disabled
11356 * THEN
11357 * Fallback to 11N mode
11358 */
11359 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11360 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011361 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011362 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011363 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011364 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11365 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011366 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11367 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011368 }
11369#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011370
Jeff Johnson295189b2012-06-20 16:38:30 -070011371 // ht_capab is not what the name conveys,this is used for protection bitmap
11372 pConfig->ht_capab =
11373 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11374
Kapil Gupta137ef892016-12-13 19:38:00 +053011375 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011376 {
11377 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011378 ret = -EINVAL;
11379 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011380 }
11381
11382 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011383 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011384 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11385 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011386 pConfig->obssProtEnabled =
11387 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011388
Chet Lanctot8cecea22014-02-11 19:09:36 -080011389#ifdef WLAN_FEATURE_11W
11390 pConfig->mfpCapable = MFPCapable;
11391 pConfig->mfpRequired = MFPRequired;
11392 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11393 pConfig->mfpCapable, pConfig->mfpRequired);
11394#endif
11395
Arif Hussain6d2a3322013-11-17 19:50:10 -080011396 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011397 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011398 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11399 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11400 (int)pConfig->channel);
11401 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11402 pConfig->SapHw_mode, pConfig->privacy,
11403 pConfig->authType);
11404 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11405 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11406 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11407 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011408
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011409 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 {
11411 //Bss already started. just return.
11412 //TODO Probably it should update some beacon params.
11413 hddLog( LOGE, "Bss Already started...Ignore the request");
11414 EXIT();
11415 return 0;
11416 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011417
Agarwal Ashish51325b52014-06-16 16:50:49 +053011418 if (vos_max_concurrent_connections_reached()) {
11419 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011420 ret = -EINVAL;
11421 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011422 }
11423
Jeff Johnson295189b2012-06-20 16:38:30 -070011424 pConfig->persona = pHostapdAdapter->device_mode;
11425
Peng Xu2446a892014-09-05 17:21:18 +053011426 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11427 if ( NULL != psmeConfig)
11428 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011429 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011430 sme_GetConfigParam(hHal, psmeConfig);
11431 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011432#ifdef WLAN_FEATURE_AP_HT40_24G
11433 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11434 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11435 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11436 {
11437 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11438 sme_UpdateConfig (hHal, psmeConfig);
11439 }
11440#endif
Peng Xu2446a892014-09-05 17:21:18 +053011441 vos_mem_free(psmeConfig);
11442 }
Peng Xuafc34e32014-09-25 13:23:55 +053011443 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011444
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011445 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 pSapEventCallback = hdd_hostapd_SAPEventCB;
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011447
11448 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11450 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11451 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011452 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011453 ret = -EINVAL;
11454 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011455 }
11456
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011457 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11459
11460 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011461
Jeff Johnson295189b2012-06-20 16:38:30 -070011462 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011463 {
11464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011465 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011466 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 VOS_ASSERT(0);
11468 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011469
Jeff Johnson295189b2012-06-20 16:38:30 -070011470 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011471 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11472 VOS_STATUS_SUCCESS)
11473 {
11474 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11475 VOS_ASSERT(0);
11476 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011477 /* Initialize WMM configuation */
11478 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011479 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011480
Anurag Chouhan83026002016-12-13 22:46:21 +053011481#ifdef DHCP_SERVER_OFFLOAD
11482 /* set dhcp server offload */
11483 if (iniConfig->enable_dhcp_srv_offload &&
11484 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011485 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011486 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011487 if (!VOS_IS_STATUS_SUCCESS(status))
11488 {
11489 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11490 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011491 vos_event_reset(&pHostapdState->vosEvent);
11492 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11493 status = vos_wait_single_event(&pHostapdState->vosEvent,
11494 10000);
11495 if (!VOS_IS_STATUS_SUCCESS(status)) {
11496 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011497 ret = -EINVAL;
11498 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011499 }
11500 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011501 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011502 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11503 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11504 {
11505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11506 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11507 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011508 vos_event_reset(&pHostapdState->vosEvent);
11509 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11510 status = vos_wait_single_event(&pHostapdState->vosEvent,
11511 10000);
11512 if (!VOS_IS_STATUS_SUCCESS(status)) {
11513 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011514 ret = -EINVAL;
11515 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011516 }
11517 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011518 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011519#ifdef MDNS_OFFLOAD
11520 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011521 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011522 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11523 if (VOS_IS_STATUS_SUCCESS(status))
11524 {
11525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11526 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011527 vos_event_reset(&pHostapdState->vosEvent);
11528 if (VOS_STATUS_SUCCESS ==
11529 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11530 status = vos_wait_single_event(&pHostapdState->vosEvent,
11531 10000);
11532 if (!VOS_IS_STATUS_SUCCESS(status)) {
11533 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011534 ret = -EINVAL;
11535 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011536 }
11537 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011538 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011539 status = vos_wait_single_event(&pHostapdAdapter->
11540 mdns_status.vos_event, 2000);
11541 if (!VOS_IS_STATUS_SUCCESS(status) ||
11542 pHostapdAdapter->mdns_status.mdns_enable_status ||
11543 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11544 pHostapdAdapter->mdns_status.mdns_resp_status)
11545 {
11546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11547 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11548 pHostapdAdapter->mdns_status.mdns_enable_status,
11549 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11550 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011551 vos_event_reset(&pHostapdState->vosEvent);
11552 if (VOS_STATUS_SUCCESS ==
11553 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11554 status = vos_wait_single_event(&pHostapdState->vosEvent,
11555 10000);
11556 if (!VOS_IS_STATUS_SUCCESS(status)) {
11557 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011558 ret = -EINVAL;
11559 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011560 }
11561 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011562 }
11563 }
11564#endif /* MDNS_OFFLOAD */
11565 } else {
11566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11567 ("DHCP Disabled ini %d, FW %d"),
11568 iniConfig->enable_dhcp_srv_offload,
11569 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011570 }
11571#endif /* DHCP_SERVER_OFFLOAD */
11572
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011573#ifdef WLAN_FEATURE_P2P_DEBUG
11574 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11575 {
11576 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11577 {
11578 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11579 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011580 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011581 }
11582 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11583 {
11584 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11585 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011586 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011587 }
11588 }
11589#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011590 /* Check and restart SAP if it is on Unsafe channel */
11591 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011592
Jeff Johnson295189b2012-06-20 16:38:30 -070011593 pHostapdState->bCommit = TRUE;
11594 EXIT();
11595
11596 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011597error:
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011598 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011599 if (iniConfig->disable_indoor_channel &&
11600 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011601 hdd_update_indoor_channel(pHddCtx, false);
11602 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11603 }
11604
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011605 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011606
11607tdls_enable:
11608 if (ret != eHAL_STATUS_SUCCESS)
11609 wlan_hdd_tdls_reenable(pHddCtx);
11610
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011611 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011612}
11613
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011614#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011615static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011616 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011617 struct beacon_parameters *params)
11618{
11619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011620 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011621 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011622
11623 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011624
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011625 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11626 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11627 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011628 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11629 hdd_device_modetoString(pAdapter->device_mode),
11630 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011631
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011632 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11633 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011634 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011635 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011636 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011637 }
11638
Agarwal Ashish51325b52014-06-16 16:50:49 +053011639 if (vos_max_concurrent_connections_reached()) {
11640 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11641 return -EINVAL;
11642 }
11643
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011644 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011645 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011646 )
11647 {
11648 beacon_data_t *old,*new;
11649
11650 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011651
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011653 {
11654 hddLog(VOS_TRACE_LEVEL_WARN,
11655 FL("already beacon info added to session(%d)"),
11656 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011657 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011658 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011659
11660 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11661
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011662 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011663 {
11664 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011665 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011666 return -EINVAL;
11667 }
11668
11669 pAdapter->sessionCtx.ap.beacon = new;
11670
11671 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11672 }
11673
11674 EXIT();
11675 return status;
11676}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011677
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011678static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11679 struct net_device *dev,
11680 struct beacon_parameters *params)
11681{
11682 int ret;
11683
11684 vos_ssr_protect(__func__);
11685 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11686 vos_ssr_unprotect(__func__);
11687
11688 return ret;
11689}
11690
11691static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011692 struct net_device *dev,
11693 struct beacon_parameters *params)
11694{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011695 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011696 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11697 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011698 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011699
11700 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011701
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011702 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11703 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11704 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11705 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11706 __func__, hdd_device_modetoString(pAdapter->device_mode),
11707 pAdapter->device_mode);
11708
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011709 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11710 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011711 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011712 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011713 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011714 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011715
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011716 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011718 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 {
11720 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011721
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011723
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011725 {
11726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11727 FL("session(%d) old and new heads points to NULL"),
11728 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011729 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011730 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011731
11732 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11733
11734 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011735 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011736 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 return -EINVAL;
11738 }
11739
11740 pAdapter->sessionCtx.ap.beacon = new;
11741
11742 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11743 }
11744
11745 EXIT();
11746 return status;
11747}
11748
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011749static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11750 struct net_device *dev,
11751 struct beacon_parameters *params)
11752{
11753 int ret;
11754
11755 vos_ssr_protect(__func__);
11756 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11757 vos_ssr_unprotect(__func__);
11758
11759 return ret;
11760}
11761
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011762#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11763
11764#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011765static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011767#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011768static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011769 struct net_device *dev)
11770#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011771{
11772 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011773 hdd_adapter_t *staAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011774 hdd_context_t *pHddCtx = NULL;
11775 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011776 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011777 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011778
11779 ENTER();
11780
11781 if (NULL == pAdapter)
11782 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011783 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011784 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011785 return -ENODEV;
11786 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011787
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011788 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11789 TRACE_CODE_HDD_CFG80211_STOP_AP,
11790 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011791 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11792 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011793 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011794 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011795 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011796 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011797
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011798 pScanInfo = &pHddCtx->scan_info;
11799
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11801 __func__, hdd_device_modetoString(pAdapter->device_mode),
11802 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011803
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011804 /*
11805 * if a sta connection is in progress in another adapter, disconnect
11806 * the sta and complete the sap operation. sta will reconnect
11807 * after sap stop is done.
11808 */
11809 staAdapter = hdd_get_sta_connection_in_progress(pHddCtx);
11810 if (staAdapter) {
11811 hddLog(LOG1, FL("disconnecting sta with session id: %d"),
11812 staAdapter->sessionId);
11813 wlan_hdd_disconnect(staAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
11814 }
11815
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011816 ret = wlan_hdd_scan_abort(pAdapter);
11817
Girish Gowli4bf7a632014-06-12 13:42:11 +053011818 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011819 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11821 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011822
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011823 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011824 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11826 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011827
Jeff Johnsone7245742012-09-05 17:12:55 -070011828 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011829 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011830 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011831 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011832 }
11833
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011834 /* Delete all associated STAs before stopping AP/P2P GO */
11835 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011836 hdd_hostapd_stop(dev);
11837
Jeff Johnson295189b2012-06-20 16:38:30 -070011838 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011839 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011840 )
11841 {
11842 beacon_data_t *old;
11843
11844 old = pAdapter->sessionCtx.ap.beacon;
11845
11846 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011847 {
11848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11849 FL("session(%d) beacon data points to NULL"),
11850 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011851 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011852 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011853
Jeff Johnson295189b2012-06-20 16:38:30 -070011854 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011855
11856 mutex_lock(&pHddCtx->sap_lock);
11857 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11858 {
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011859 hdd_hostapd_state_t *pHostapdState =
11860 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11861
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011862 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11863 hdd_wait_for_ecsa_complete(pHddCtx);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011864 vos_event_reset(&pHostapdState->vosEvent);
11865
Jeff Johnson4416a782013-03-25 14:17:50 -070011866 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011867 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011868 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11869
11870 if (!VOS_IS_STATUS_SUCCESS(status))
11871 {
11872 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011873 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011875 }
11876 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011877 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011878 /* BSS stopped, clear the active sessions for this device mode */
11879 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011880 }
11881 mutex_unlock(&pHddCtx->sap_lock);
11882
11883 if(status != VOS_STATUS_SUCCESS)
11884 {
11885 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011886 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011887 return -EINVAL;
11888 }
11889
Jeff Johnson4416a782013-03-25 14:17:50 -070011890 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011891 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11892 ==eHAL_STATUS_FAILURE)
11893 {
11894 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011895 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 }
11897
Jeff Johnson4416a782013-03-25 14:17:50 -070011898 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011899 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11900 eANI_BOOLEAN_FALSE) )
11901 {
11902 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011903 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011904 }
11905
11906 // Reset WNI_CFG_PROBE_RSP Flags
11907 wlan_hdd_reset_prob_rspies(pAdapter);
11908
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011909 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11910
Jeff Johnson295189b2012-06-20 16:38:30 -070011911 pAdapter->sessionCtx.ap.beacon = NULL;
11912 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011913#ifdef WLAN_FEATURE_P2P_DEBUG
11914 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11915 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11916 {
11917 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11918 "GO got removed");
11919 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11920 }
11921#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011922 }
11923 EXIT();
11924 return status;
11925}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011926
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011927#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11928static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11929 struct net_device *dev)
11930{
11931 int ret;
11932
11933 vos_ssr_protect(__func__);
11934 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11935 vos_ssr_unprotect(__func__);
11936
11937 return ret;
11938}
11939#else
11940static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11941 struct net_device *dev)
11942{
11943 int ret;
11944
11945 vos_ssr_protect(__func__);
11946 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11947 vos_ssr_unprotect(__func__);
11948
11949 return ret;
11950}
11951#endif
11952
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011953#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11954
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011955static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011956 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011957 struct cfg80211_ap_settings *params)
11958{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011959 hdd_adapter_t *pAdapter;
11960 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011961 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011962
11963 ENTER();
11964
Girish Gowlib143d7a2015-02-18 19:39:55 +053011965 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011966 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011968 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011969 return -ENODEV;
11970 }
11971
11972 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11973 if (NULL == pAdapter)
11974 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011975 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011976 "%s: HDD adapter is Null", __func__);
11977 return -ENODEV;
11978 }
11979
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011980 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11981 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11982 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011983 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11984 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011986 "%s: HDD adapter magic is invalid", __func__);
11987 return -ENODEV;
11988 }
11989
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011990 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11991
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011992 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011993 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011994 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011995 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011996 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011997 }
11998
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011999 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12000 __func__, hdd_device_modetoString(pAdapter->device_mode),
12001 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012002
12003 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012004 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012005 )
12006 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012007 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012008
12009 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012010
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012011 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012012 {
12013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12014 FL("already beacon info added to session(%d)"),
12015 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012016 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012017 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012018
Girish Gowlib143d7a2015-02-18 19:39:55 +053012019#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12020 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12021 &new,
12022 &params->beacon);
12023#else
12024 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12025 &new,
12026 &params->beacon,
12027 params->dtim_period);
12028#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012029
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012030 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012031 {
12032 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012033 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012034 return -EINVAL;
12035 }
12036 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012037#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012038 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12039#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12040 params->channel, params->channel_type);
12041#else
12042 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12043#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012044#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012045 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012046 params->ssid_len, params->hidden_ssid,
12047 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012048 }
12049
12050 EXIT();
12051 return status;
12052}
12053
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012054static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12055 struct net_device *dev,
12056 struct cfg80211_ap_settings *params)
12057{
12058 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012059
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012060 vos_ssr_protect(__func__);
12061 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12062 vos_ssr_unprotect(__func__);
12063
12064 return ret;
12065}
12066
12067static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012068 struct net_device *dev,
12069 struct cfg80211_beacon_data *params)
12070{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012071 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012072 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012073 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012074
12075 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012076
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012077 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12078 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12079 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012080 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012081 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012082
12083 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12084 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012085 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012086 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012087 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012088 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012089
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012090 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012091 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012092 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012093 {
12094 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012095
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012096 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012097
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012098 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012099 {
12100 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12101 FL("session(%d) beacon data points to NULL"),
12102 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012103 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012104 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012105
12106 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12107
12108 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012109 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012110 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012111 return -EINVAL;
12112 }
12113
12114 pAdapter->sessionCtx.ap.beacon = new;
12115
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012116 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12117 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012118 }
12119
12120 EXIT();
12121 return status;
12122}
12123
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012124static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12125 struct net_device *dev,
12126 struct cfg80211_beacon_data *params)
12127{
12128 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012129
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012130 vos_ssr_protect(__func__);
12131 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12132 vos_ssr_unprotect(__func__);
12133
12134 return ret;
12135}
12136
12137#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012138
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012139static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012140 struct net_device *dev,
12141 struct bss_parameters *params)
12142{
12143 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012144 hdd_context_t *pHddCtx;
12145 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012146
12147 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012148
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012149 if (NULL == pAdapter)
12150 {
12151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12152 "%s: HDD adapter is Null", __func__);
12153 return -ENODEV;
12154 }
12155 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012156 ret = wlan_hdd_validate_context(pHddCtx);
12157 if (0 != ret)
12158 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012159 return ret;
12160 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012161 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12162 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12163 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012164 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12165 __func__, hdd_device_modetoString(pAdapter->device_mode),
12166 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012167
12168 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012169 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012170 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012171 {
12172 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12173 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012174 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 {
12176 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012177 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012178 }
12179
12180 EXIT();
12181 return 0;
12182}
12183
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012184static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12185 struct net_device *dev,
12186 struct bss_parameters *params)
12187{
12188 int ret;
12189
12190 vos_ssr_protect(__func__);
12191 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12192 vos_ssr_unprotect(__func__);
12193
12194 return ret;
12195}
Kiet Lam10841362013-11-01 11:36:50 +053012196/* FUNCTION: wlan_hdd_change_country_code_cd
12197* to wait for contry code completion
12198*/
12199void* wlan_hdd_change_country_code_cb(void *pAdapter)
12200{
12201 hdd_adapter_t *call_back_pAdapter = pAdapter;
12202 complete(&call_back_pAdapter->change_country_code);
12203 return NULL;
12204}
12205
Jeff Johnson295189b2012-06-20 16:38:30 -070012206/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012207 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012208 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12209 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012210int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 struct net_device *ndev,
12212 enum nl80211_iftype type,
12213 u32 *flags,
12214 struct vif_params *params
12215 )
12216{
12217 struct wireless_dev *wdev;
12218 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012219 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012220 tCsrRoamProfile *pRoamProfile = NULL;
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012221 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012222 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012223 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 eMib_dot11DesiredBssType connectedBssType;
12225 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012226 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012227
12228 ENTER();
12229
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012230 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012231 {
12232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12233 "%s: Adapter context is null", __func__);
12234 return VOS_STATUS_E_FAILURE;
12235 }
12236
12237 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12238 if (!pHddCtx)
12239 {
12240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12241 "%s: HDD context is null", __func__);
12242 return VOS_STATUS_E_FAILURE;
12243 }
12244
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012245 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12246 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12247 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012248 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012249 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012250 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012251 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012252 }
12253
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012254 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12255 __func__, hdd_device_modetoString(pAdapter->device_mode),
12256 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012257
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012258 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12259 hddLog(VOS_TRACE_LEVEL_FATAL,
12260 "%s: STA + MON is in progress, cannot change interface",
12261 __func__);
12262 }
12263
Agarwal Ashish51325b52014-06-16 16:50:49 +053012264 if (vos_max_concurrent_connections_reached()) {
12265 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12266 return -EINVAL;
12267 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012268 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012269 wdev = ndev->ieee80211_ptr;
12270
12271#ifdef WLAN_BTAMP_FEATURE
12272 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12273 (NL80211_IFTYPE_ADHOC == type)||
12274 (NL80211_IFTYPE_AP == type)||
12275 (NL80211_IFTYPE_P2P_GO == type))
12276 {
12277 pHddCtx->isAmpAllowed = VOS_FALSE;
12278 // stop AMP traffic
12279 status = WLANBAP_StopAmp();
12280 if(VOS_STATUS_SUCCESS != status )
12281 {
12282 pHddCtx->isAmpAllowed = VOS_TRUE;
12283 hddLog(VOS_TRACE_LEVEL_FATAL,
12284 "%s: Failed to stop AMP", __func__);
12285 return -EINVAL;
12286 }
12287 }
12288#endif //WLAN_BTAMP_FEATURE
12289 /* Reset the current device mode bit mask*/
12290 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12291
Bala Venkatesh5c06a252018-07-12 16:08:04 +053012292 if (((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12293 (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)) ||
12294 type == NL80211_IFTYPE_AP)
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012295 {
12296 /* Notify Mode change in case of concurrency.
12297 * Below function invokes TDLS teardown Functionality Since TDLS is
12298 * not Supported in case of concurrency i.e Once P2P session
12299 * is detected disable offchannel and teardown TDLS links
12300 */
12301 hddLog(LOG1,
12302 FL("Device mode = %d Interface type = %d"),
12303 pAdapter->device_mode, type);
12304 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12305 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012306
Jeff Johnson295189b2012-06-20 16:38:30 -070012307 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012308 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012309 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012310 )
12311 {
12312 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012313 if (!pWextState)
12314 {
12315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12316 "%s: pWextState is null", __func__);
12317 return VOS_STATUS_E_FAILURE;
12318 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012319 pRoamProfile = &pWextState->roamProfile;
12320 LastBSSType = pRoamProfile->BSSType;
12321
12322 switch (type)
12323 {
12324 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012325 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012326 hddLog(VOS_TRACE_LEVEL_INFO,
12327 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12328 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012329#ifdef WLAN_FEATURE_11AC
12330 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12331 {
12332 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12333 }
12334#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012335 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012336 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012337 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012338 //Check for sub-string p2p to confirm its a p2p interface
12339 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012340 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012341#ifdef FEATURE_WLAN_TDLS
12342 mutex_lock(&pHddCtx->tdls_lock);
12343 wlan_hdd_tdls_exit(pAdapter, TRUE);
12344 mutex_unlock(&pHddCtx->tdls_lock);
12345#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012346 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12347 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12348 }
12349 else
12350 {
12351 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012352 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012353 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012354 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012355
Jeff Johnson295189b2012-06-20 16:38:30 -070012356 case NL80211_IFTYPE_ADHOC:
12357 hddLog(VOS_TRACE_LEVEL_INFO,
12358 "%s: setting interface Type to ADHOC", __func__);
12359 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12360 pRoamProfile->phyMode =
12361 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012362 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012363 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012364 hdd_set_ibss_ops( pAdapter );
12365 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012366
12367 status = hdd_sta_id_hash_attach(pAdapter);
12368 if (VOS_STATUS_SUCCESS != status) {
12369 hddLog(VOS_TRACE_LEVEL_ERROR,
12370 FL("Failed to initialize hash for IBSS"));
12371 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 break;
12373
12374 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012375 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012376 {
12377 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12378 "%s: setting interface Type to %s", __func__,
12379 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12380
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012381 //Cancel any remain on channel for GO mode
12382 if (NL80211_IFTYPE_P2P_GO == type)
12383 {
12384 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12385 }
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012386 if (NL80211_IFTYPE_AP == type)
12387 {
12388 /*
12389 * As Loading WLAN Driver one interface being created
12390 * for p2p device address. This will take one HW STA and
12391 * the max number of clients that can connect to softAP
12392 * will be reduced by one. so while changing the interface
12393 * type to NL80211_IFTYPE_AP (SoftAP) remove p2p0 interface
12394 * as it is not required in SoftAP mode.
12395 */
12396
12397 // Get P2P Adapter
12398 pP2pAdapter = hdd_get_adapter(pHddCtx,
12399 WLAN_HDD_P2P_DEVICE);
12400 if (pP2pAdapter)
12401 {
Min Liuf3481952018-12-10 16:01:14 +080012402 wlan_hdd_release_intf_addr(pHddCtx,
12403 pP2pAdapter->macAddressCurrent.bytes);
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012404 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12405 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
12406 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12407 }
12408 }
12409
Swaroop Goltia2e32212014-04-09 23:37:33 +053012410 //Disable IMPS & BMPS for SAP/GO
12411 if(VOS_STATUS_E_FAILURE ==
12412 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12413 {
12414 //Fail to Exit BMPS
12415 VOS_ASSERT(0);
12416 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012417
12418 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12419
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012420#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012421
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012422 /* A Mutex Lock is introduced while changing the mode to
12423 * protect the concurrent access for the Adapters by TDLS
12424 * module.
12425 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012426 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012427#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012428 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012429 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012430 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012431 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12432 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012433#ifdef FEATURE_WLAN_TDLS
12434 mutex_unlock(&pHddCtx->tdls_lock);
12435#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012436 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12437 (pConfig->apRandomBssidEnabled))
12438 {
12439 /* To meet Android requirements create a randomized
12440 MAC address of the form 02:1A:11:Fx:xx:xx */
12441 get_random_bytes(&ndev->dev_addr[3], 3);
12442 ndev->dev_addr[0] = 0x02;
12443 ndev->dev_addr[1] = 0x1A;
12444 ndev->dev_addr[2] = 0x11;
12445 ndev->dev_addr[3] |= 0xF0;
12446 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12447 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012448 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12449 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012450 }
12451
Jeff Johnson295189b2012-06-20 16:38:30 -070012452 hdd_set_ap_ops( pAdapter->dev );
12453
Kiet Lam10841362013-11-01 11:36:50 +053012454 /* This is for only SAP mode where users can
12455 * control country through ini.
12456 * P2P GO follows station country code
12457 * acquired during the STA scanning. */
12458 if((NL80211_IFTYPE_AP == type) &&
12459 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12460 {
12461 int status = 0;
12462 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12463 "%s: setting country code from INI ", __func__);
12464 init_completion(&pAdapter->change_country_code);
12465 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12466 (void *)(tSmeChangeCountryCallback)
12467 wlan_hdd_change_country_code_cb,
12468 pConfig->apCntryCode, pAdapter,
12469 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012470 eSIR_FALSE,
12471 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012472 if (eHAL_STATUS_SUCCESS == status)
12473 {
12474 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012475 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012476 &pAdapter->change_country_code,
12477 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012478 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012479 {
12480 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012481 FL("SME Timed out while setting country code %ld"),
12482 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012483
12484 if (pHddCtx->isLogpInProgress)
12485 {
12486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12487 "%s: LOGP in Progress. Ignore!!!", __func__);
12488 return -EAGAIN;
12489 }
Kiet Lam10841362013-11-01 11:36:50 +053012490 }
12491 }
12492 else
12493 {
12494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012495 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012496 return -EINVAL;
12497 }
12498 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012499 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012500 if(status != VOS_STATUS_SUCCESS)
12501 {
12502 hddLog(VOS_TRACE_LEVEL_FATAL,
12503 "%s: Error initializing the ap mode", __func__);
12504 return -EINVAL;
12505 }
12506 hdd_set_conparam(1);
12507
Nirav Shah7e3c8132015-06-22 23:51:42 +053012508 status = hdd_sta_id_hash_attach(pAdapter);
12509 if (VOS_STATUS_SUCCESS != status)
12510 {
12511 hddLog(VOS_TRACE_LEVEL_ERROR,
12512 FL("Failed to initialize hash for AP"));
12513 return -EINVAL;
12514 }
12515
Jeff Johnson295189b2012-06-20 16:38:30 -070012516 /*interface type changed update in wiphy structure*/
12517 if(wdev)
12518 {
12519 wdev->iftype = type;
12520 pHddCtx->change_iface = type;
12521 }
12522 else
12523 {
12524 hddLog(VOS_TRACE_LEVEL_ERROR,
12525 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12526 return -EINVAL;
12527 }
12528 goto done;
12529 }
12530
12531 default:
12532 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12533 __func__);
12534 return -EOPNOTSUPP;
12535 }
12536 }
12537 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012538 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 )
12540 {
12541 switch(type)
12542 {
12543 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012545 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012546
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012547 if (pAdapter->device_mode == WLAN_HDD_SOFTAP
12548 && !hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE)) {
12549 /*
12550 * The p2p interface was deleted while SoftAP mode was init,
12551 * create that interface now that the SoftAP is going down.
12552 */
12553 pP2pAdapter = hdd_open_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE,
12554 "p2p%d", wlan_hdd_get_intf_addr(pHddCtx),
12555 VOS_TRUE);
12556 }
12557
Deepthi Gowri500fc472014-08-11 19:53:10 +053012558 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012559
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012560#ifdef FEATURE_WLAN_TDLS
12561
12562 /* A Mutex Lock is introduced while changing the mode to
12563 * protect the concurrent access for the Adapters by TDLS
12564 * module.
12565 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012566 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012567#endif
c_hpothu002231a2015-02-05 14:58:51 +053012568 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012569 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012570 //Check for sub-string p2p to confirm its a p2p interface
12571 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012572 {
12573 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12574 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12575 }
12576 else
12577 {
12578 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012579 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012580 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012581
12582 /* set con_mode to STA only when no SAP concurrency mode */
12583 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12584 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012585 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012586 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12587 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012588#ifdef FEATURE_WLAN_TDLS
12589 mutex_unlock(&pHddCtx->tdls_lock);
12590#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012591 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 if( VOS_STATUS_SUCCESS != status )
12593 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012594 /* In case of JB, for P2P-GO, only change interface will be called,
12595 * This is the right place to enable back bmps_imps()
12596 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012597 if (pHddCtx->hdd_wlan_suspended)
12598 {
12599 hdd_set_pwrparams(pHddCtx);
12600 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012601 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012602 goto done;
12603 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012605 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012606 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12607 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012608 goto done;
12609 default:
12610 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12611 __func__);
12612 return -EOPNOTSUPP;
12613
12614 }
12615
12616 }
12617 else
12618 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012619 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12620 __func__, hdd_device_modetoString(pAdapter->device_mode),
12621 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012622 return -EOPNOTSUPP;
12623 }
12624
12625
12626 if(pRoamProfile)
12627 {
12628 if ( LastBSSType != pRoamProfile->BSSType )
12629 {
12630 /*interface type changed update in wiphy structure*/
12631 wdev->iftype = type;
12632
12633 /*the BSS mode changed, We need to issue disconnect
12634 if connected or in IBSS disconnect state*/
12635 if ( hdd_connGetConnectedBssType(
12636 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12637 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12638 {
12639 /*need to issue a disconnect to CSR.*/
12640 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12641 if( eHAL_STATUS_SUCCESS ==
12642 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12643 pAdapter->sessionId,
12644 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12645 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012646 ret = wait_for_completion_interruptible_timeout(
12647 &pAdapter->disconnect_comp_var,
12648 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12649 if (ret <= 0)
12650 {
12651 hddLog(VOS_TRACE_LEVEL_ERROR,
12652 FL("wait on disconnect_comp_var failed %ld"), ret);
12653 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012654 }
12655 }
12656 }
12657 }
12658
12659done:
12660 /*set bitmask based on updated value*/
12661 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012662
12663 /* Only STA mode support TM now
12664 * all other mode, TM feature should be disabled */
12665 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12666 (~VOS_STA & pHddCtx->concurrency_mode) )
12667 {
12668 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12669 }
12670
Jeff Johnson295189b2012-06-20 16:38:30 -070012671#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012672 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012673 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 {
12675 //we are ok to do AMP
12676 pHddCtx->isAmpAllowed = VOS_TRUE;
12677 }
12678#endif //WLAN_BTAMP_FEATURE
12679 EXIT();
12680 return 0;
12681}
12682
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012683/*
12684 * FUNCTION: wlan_hdd_cfg80211_change_iface
12685 * wrapper function to protect the actual implementation from SSR.
12686 */
12687int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12688 struct net_device *ndev,
12689 enum nl80211_iftype type,
12690 u32 *flags,
12691 struct vif_params *params
12692 )
12693{
12694 int ret;
12695
12696 vos_ssr_protect(__func__);
12697 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12698 vos_ssr_unprotect(__func__);
12699
12700 return ret;
12701}
12702
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012703#ifdef FEATURE_WLAN_TDLS
12704static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012705 struct net_device *dev,
12706#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12707 const u8 *mac,
12708#else
12709 u8 *mac,
12710#endif
12711 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012712{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012713 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012714 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012715 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012716 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012717 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012718 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012719
12720 ENTER();
12721
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012722 if (!dev) {
12723 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12724 return -EINVAL;
12725 }
12726
12727 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12728 if (!pAdapter) {
12729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12730 return -EINVAL;
12731 }
12732
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012733 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012734 {
12735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12736 "Invalid arguments");
12737 return -EINVAL;
12738 }
Hoonki Lee27511902013-03-14 18:19:06 -070012739
12740 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12741 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12742 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012744 "%s: TDLS mode is disabled OR not enabled in FW."
12745 MAC_ADDRESS_STR " Request declined.",
12746 __func__, MAC_ADDR_ARRAY(mac));
12747 return -ENOTSUPP;
12748 }
12749
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012750 if (pHddCtx->isLogpInProgress)
12751 {
12752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12753 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012754 wlan_hdd_tdls_set_link_status(pAdapter,
12755 mac,
12756 eTDLS_LINK_IDLE,
12757 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012758 return -EBUSY;
12759 }
12760
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012761 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012762 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012763
12764 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012765 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012766 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12767 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012768 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012769 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012770 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012771
12772 /* in add station, we accept existing valid staId if there is */
12773 if ((0 == update) &&
12774 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12775 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012776 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012778 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012779 " link_status %d. staId %d. add station ignored.",
12780 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012781 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012782 return 0;
12783 }
12784 /* in change station, we accept only when staId is valid */
12785 if ((1 == update) &&
12786 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12787 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12788 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012789 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012791 "%s: " MAC_ADDRESS_STR
12792 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012793 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12794 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12795 mutex_unlock(&pHddCtx->tdls_lock);
12796 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012797 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012798 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012799
12800 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012801 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012802 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012803 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12804 "%s: " MAC_ADDRESS_STR
12805 " TDLS setup is ongoing. Request declined.",
12806 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012807 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012808 }
12809
12810 /* first to check if we reached to maximum supported TDLS peer.
12811 TODO: for now, return -EPERM looks working fine,
12812 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012813 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12814 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012815 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12817 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012818 " TDLS Max peer already connected. Request declined."
12819 " Num of peers (%d), Max allowed (%d).",
12820 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12821 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012822 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012823 }
12824 else
12825 {
12826 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012827 mutex_lock(&pHddCtx->tdls_lock);
12828 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012829 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012830 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012831 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12833 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12834 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012835 return -EPERM;
12836 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012837 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012838 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012839 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012840 wlan_hdd_tdls_set_link_status(pAdapter,
12841 mac,
12842 eTDLS_LINK_CONNECTING,
12843 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012844
Jeff Johnsond75fe012013-04-06 10:53:06 -070012845 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012846 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012847 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012849 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012850 if(StaParams->htcap_present)
12851 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012853 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012855 "ht_capa->extended_capabilities: %0x",
12856 StaParams->HTCap.extendedHtCapInfo);
12857 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012859 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012861 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012862 if(StaParams->vhtcap_present)
12863 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012865 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12866 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12867 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12868 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012869 {
12870 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012871 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012872 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012874 "[%d]: %x ", i, StaParams->supported_rates[i]);
12875 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012876 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012877 else if ((1 == update) && (NULL == StaParams))
12878 {
12879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12880 "%s : update is true, but staParams is NULL. Error!", __func__);
12881 return -EPERM;
12882 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012883
12884 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12885
12886 if (!update)
12887 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012888 /*Before adding sta make sure that device exited from BMPS*/
12889 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12890 {
12891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12892 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12893 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12894 if (status != VOS_STATUS_SUCCESS) {
12895 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12896 }
12897 }
12898
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012899 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012900 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012901 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012902 hddLog(VOS_TRACE_LEVEL_ERROR,
12903 FL("Failed to add TDLS peer STA. Enable Bmps"));
12904 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012905 return -EPERM;
12906 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012907 }
12908 else
12909 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012910 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012911 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012912 if (ret != eHAL_STATUS_SUCCESS) {
12913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12914 return -EPERM;
12915 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012916 }
12917
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012918 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012919 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12920
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012921 mutex_lock(&pHddCtx->tdls_lock);
12922 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12923
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012924 if ((pTdlsPeer != NULL) &&
12925 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012926 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012927 hddLog(VOS_TRACE_LEVEL_ERROR,
12928 FL("peer link status %u"), pTdlsPeer->link_status);
12929 mutex_unlock(&pHddCtx->tdls_lock);
12930 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012931 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012932 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012933
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012934 if (ret <= 0)
12935 {
12936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12937 "%s: timeout waiting for tdls add station indication %ld",
12938 __func__, ret);
12939 goto error;
12940 }
12941
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012942 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12943 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012945 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012946 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012947 }
12948
12949 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012950
12951error:
Atul Mittal115287b2014-07-08 13:26:33 +053012952 wlan_hdd_tdls_set_link_status(pAdapter,
12953 mac,
12954 eTDLS_LINK_IDLE,
12955 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012956 return -EPERM;
12957
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012958}
12959#endif
12960
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012961VOS_STATUS wlan_hdd_send_sta_authorized_event(
12962 hdd_adapter_t *adapter,
12963 hdd_context_t *hdd_ctx,
12964 const v_MACADDR_t *mac_addr)
12965{
12966 struct sk_buff *vendor_event;
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012967 VOS_STATUS status;
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053012968 struct nl80211_sta_flag_update sta_flags;
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012969
12970 ENTER();
12971
12972 if (!hdd_ctx) {
12973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
12974 return -EINVAL;
12975 }
12976
12977 vendor_event =
12978 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053012979 hdd_ctx->wiphy,
12980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12981 &adapter->wdev,
12982#endif
12983 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012984 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
12985 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
12986 GFP_KERNEL);
12987 if (!vendor_event) {
12988 hddLog(VOS_TRACE_LEVEL_ERROR,
12989 FL("cfg80211_vendor_event_alloc failed"));
12990 return -EINVAL;
12991 }
12992
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053012993 sta_flags.mask |= BIT(NL80211_STA_FLAG_AUTHORIZED);
12994 sta_flags.set = true;
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012995
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053012996 status = nla_put(vendor_event,
12997 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
12998 sizeof(struct nl80211_sta_flag_update),
12999 &sta_flags);
13000
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013001 if (status) {
13002 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
13003 kfree_skb(vendor_event);
13004 return VOS_STATUS_E_FAILURE;
13005 }
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053013006
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013007 status = nla_put(vendor_event,
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053013008 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR,
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013009 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
13010 if (status) {
13011 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
13012 kfree_skb(vendor_event);
13013 return VOS_STATUS_E_FAILURE;
13014 }
13015
13016 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13017
13018 EXIT();
13019 return 0;
13020}
13021
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013022static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013023 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13025 const u8 *mac,
13026#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013027 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013028#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013029 struct station_parameters *params)
13030{
13031 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013032 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013033 hdd_context_t *pHddCtx;
13034 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013035 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013036 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013037#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013038 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013039 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013040 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013041 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013042#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013043
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013044 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013045
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013046 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013047 if ((NULL == pAdapter))
13048 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013050 "invalid adapter ");
13051 return -EINVAL;
13052 }
13053
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013054 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13055 TRACE_CODE_HDD_CHANGE_STATION,
13056 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013057 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013058
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013059 ret = wlan_hdd_validate_context(pHddCtx);
13060 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013061 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013062 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013063 }
13064
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013065 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13066
13067 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013068 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13070 "invalid HDD station context");
13071 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013072 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013073 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13074
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013075 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13076 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013077 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013078 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013079 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013080 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013081 WLANTL_STA_AUTHENTICATED);
13082
Gopichand Nakkala29149562013-05-10 21:43:41 +053013083 if (status != VOS_STATUS_SUCCESS)
13084 {
13085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13086 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13087 return -EINVAL;
13088 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013089 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13090 &STAMacAddress);
13091 if (status != VOS_STATUS_SUCCESS)
13092 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013093 }
13094 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013095 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13096 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013097#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013098 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13099 StaParams.capability = params->capability;
13100 StaParams.uapsd_queues = params->uapsd_queues;
13101 StaParams.max_sp = params->max_sp;
13102
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013103 /* Convert (first channel , number of channels) tuple to
13104 * the total list of channels. This goes with the assumption
13105 * that if the first channel is < 14, then the next channels
13106 * are an incremental of 1 else an incremental of 4 till the number
13107 * of channels.
13108 */
13109 if (0 != params->supported_channels_len) {
13110 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013111 for ( i = 0 ; i < params->supported_channels_len
13112 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013113 {
13114 int wifi_chan_index;
13115 StaParams.supported_channels[j] = params->supported_channels[i];
13116 wifi_chan_index =
13117 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13118 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013119 for(k=1; k <= no_of_channels
13120 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013121 {
13122 StaParams.supported_channels[j+1] =
13123 StaParams.supported_channels[j] + wifi_chan_index;
13124 j+=1;
13125 }
13126 }
13127 StaParams.supported_channels_len = j;
13128 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013129 if (params->supported_oper_classes_len >
13130 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13132 "received oper classes:%d, resetting it to max supported %d",
13133 params->supported_oper_classes_len,
13134 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13135 params->supported_oper_classes_len =
13136 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13137 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013138 vos_mem_copy(StaParams.supported_oper_classes,
13139 params->supported_oper_classes,
13140 params->supported_oper_classes_len);
13141 StaParams.supported_oper_classes_len =
13142 params->supported_oper_classes_len;
13143
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013144 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13146 "received extn capabilities:%d, resetting it to max supported",
13147 params->ext_capab_len);
13148 params->ext_capab_len = sizeof(StaParams.extn_capability);
13149 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013150 if (0 != params->ext_capab_len)
13151 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013152 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013153
13154 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013155 {
13156 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013157 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013158 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013159
13160 StaParams.supported_rates_len = params->supported_rates_len;
13161
13162 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13163 * The supported_rates array , for all the structures propogating till Add Sta
13164 * to the firmware has to be modified , if the supplicant (ieee80211) is
13165 * modified to send more rates.
13166 */
13167
13168 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13169 */
13170 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13171 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13172
13173 if (0 != StaParams.supported_rates_len) {
13174 int i = 0;
13175 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13176 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013178 "Supported Rates with Length %d", StaParams.supported_rates_len);
13179 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013181 "[%d]: %0x", i, StaParams.supported_rates[i]);
13182 }
13183
13184 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013185 {
13186 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013187 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013188 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013189
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013190 if (0 != params->ext_capab_len ) {
13191 /*Define A Macro : TODO Sunil*/
13192 if ((1<<4) & StaParams.extn_capability[3]) {
13193 isBufSta = 1;
13194 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013195 /* TDLS Channel Switching Support */
13196 if ((1<<6) & StaParams.extn_capability[3]) {
13197 isOffChannelSupported = 1;
13198 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013199 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013200
13201 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013202 (params->ht_capa || params->vht_capa ||
13203 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013204 /* TDLS Peer is WME/QoS capable */
13205 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013206
13207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13208 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13209 __func__, isQosWmmSta, StaParams.htcap_present);
13210
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013211 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13212 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013213 isOffChannelSupported,
13214 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013215
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013216 if (VOS_STATUS_SUCCESS != status) {
13217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13218 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13219 return -EINVAL;
13220 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013221 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13222
13223 if (VOS_STATUS_SUCCESS != status) {
13224 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13225 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13226 return -EINVAL;
13227 }
13228 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013229#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013230 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013231 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013232 return status;
13233}
13234
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013235#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13236static int wlan_hdd_change_station(struct wiphy *wiphy,
13237 struct net_device *dev,
13238 const u8 *mac,
13239 struct station_parameters *params)
13240#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013241static int wlan_hdd_change_station(struct wiphy *wiphy,
13242 struct net_device *dev,
13243 u8 *mac,
13244 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013245#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013246{
13247 int ret;
13248
13249 vos_ssr_protect(__func__);
13250 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
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_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013258 * This function is used to initialize the key information
13259 */
13260#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013261static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013262 struct net_device *ndev,
13263 u8 key_index, bool pairwise,
13264 const u8 *mac_addr,
13265 struct key_params *params
13266 )
13267#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013268static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013269 struct net_device *ndev,
13270 u8 key_index, const u8 *mac_addr,
13271 struct key_params *params
13272 )
13273#endif
13274{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013275 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013276 tCsrRoamSetKey setKey;
13277 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013278 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013279 v_U32_t roamId= 0xFF;
13280 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013281 hdd_hostapd_state_t *pHostapdState;
13282 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013283 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013284 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013285 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013286 v_MACADDR_t *peerMacAddr;
13287 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013288 uint8_t staid = HDD_MAX_STA_COUNT;
13289 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013290
13291 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013292
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013293 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13294 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13295 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013296 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13297 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013298 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013299 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013300 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013301 }
13302
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013303 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13304 __func__, hdd_device_modetoString(pAdapter->device_mode),
13305 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013306
13307 if (CSR_MAX_NUM_KEY <= key_index)
13308 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013310 key_index);
13311
13312 return -EINVAL;
13313 }
13314
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013315 if (CSR_MAX_KEY_LEN < params->key_len)
13316 {
13317 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13318 params->key_len);
13319
13320 return -EINVAL;
13321 }
13322
Jingxiang Gec438aea2017-10-26 16:44:00 +080013323 if (CSR_MAX_RSC_LEN < params->seq_len)
13324 {
13325 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13326 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013327
13328 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013329 }
13330
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013331 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013332 "%s: called with key index = %d & key length %d & seq length %d",
13333 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013334
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013335 peerMacAddr = (v_MACADDR_t *)mac_addr;
13336
Jeff Johnson295189b2012-06-20 16:38:30 -070013337 /*extract key idx, key len and key*/
13338 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13339 setKey.keyId = key_index;
13340 setKey.keyLength = params->key_len;
13341 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013342 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013343
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013344 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013345 {
13346 case WLAN_CIPHER_SUITE_WEP40:
13347 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13348 break;
13349
13350 case WLAN_CIPHER_SUITE_WEP104:
13351 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13352 break;
13353
13354 case WLAN_CIPHER_SUITE_TKIP:
13355 {
13356 u8 *pKey = &setKey.Key[0];
13357 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13358
13359 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13360
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013361 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013362
13363 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013364 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013365 |--------------|----------|----------|
13366 <---16bytes---><--8bytes--><--8bytes-->
13367
13368 */
13369 /*Sme expects the 32 bytes key to be in the below order
13370
13371 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013372 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013373 |--------------|----------|----------|
13374 <---16bytes---><--8bytes--><--8bytes-->
13375 */
13376 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013377 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013378
13379 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013380 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013381
13382 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013383 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013384
13385
13386 break;
13387 }
13388
13389 case WLAN_CIPHER_SUITE_CCMP:
13390 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13391 break;
13392
13393#ifdef FEATURE_WLAN_WAPI
13394 case WLAN_CIPHER_SUITE_SMS4:
13395 {
13396 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13397 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13398 params->key, params->key_len);
13399 return 0;
13400 }
13401#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013402
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013403#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013404 case WLAN_CIPHER_SUITE_KRK:
13405 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13406 break;
13407#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013408
13409#ifdef WLAN_FEATURE_11W
13410 case WLAN_CIPHER_SUITE_AES_CMAC:
13411 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013412 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013413#endif
13414
Jeff Johnson295189b2012-06-20 16:38:30 -070013415 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013416 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013417 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013418 status = -EOPNOTSUPP;
13419 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013420 }
13421
13422 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13423 __func__, setKey.encType);
13424
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013425 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013426#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13427 (!pairwise)
13428#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013429 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013430#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013431 )
13432 {
13433 /* set group key*/
13434 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13435 "%s- %d: setting Broadcast key",
13436 __func__, __LINE__);
13437 setKey.keyDirection = eSIR_RX_ONLY;
13438 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13439 }
13440 else
13441 {
13442 /* set pairwise key*/
13443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13444 "%s- %d: setting pairwise key",
13445 __func__, __LINE__);
13446 setKey.keyDirection = eSIR_TX_RX;
13447 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013448 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013449 }
13450 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13451 {
13452 setKey.keyDirection = eSIR_TX_RX;
13453 /*Set the group key*/
13454 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13455 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013456
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013457 if ( 0 != status )
13458 {
13459 hddLog(VOS_TRACE_LEVEL_ERROR,
13460 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013461 status = -EINVAL;
13462 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013463 }
13464 /*Save the keys here and call sme_RoamSetKey for setting
13465 the PTK after peer joins the IBSS network*/
13466 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13467 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013468 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013469 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013470 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13471 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13472 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013473 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013474 if( pHostapdState->bssState == BSS_START )
13475 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013476 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13477 vos_status = wlan_hdd_check_ula_done(pAdapter);
13478
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013479 if (peerMacAddr && (pairwise_set_key == true))
13480 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013481
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013482 if ( vos_status != VOS_STATUS_SUCCESS )
13483 {
13484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13485 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13486 __LINE__, vos_status );
13487
13488 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13489
13490 status = -EINVAL;
13491 goto end;
13492 }
13493
Jeff Johnson295189b2012-06-20 16:38:30 -070013494 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13495
13496 if ( status != eHAL_STATUS_SUCCESS )
13497 {
13498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13499 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13500 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013501 status = -EINVAL;
13502 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013503 }
13504 }
13505
13506 /* Saving WEP keys */
13507 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13508 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13509 {
13510 //Save the wep key in ap context. Issue setkey after the BSS is started.
13511 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13512 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13513 }
13514 else
13515 {
13516 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013517 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013518 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13519 }
13520 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013521 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13522 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013523 {
13524 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13525 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13526
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013527#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13528 if (!pairwise)
13529#else
13530 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13531#endif
13532 {
13533 /* set group key*/
13534 if (pHddStaCtx->roam_info.deferKeyComplete)
13535 {
13536 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13537 "%s- %d: Perform Set key Complete",
13538 __func__, __LINE__);
13539 hdd_PerformRoamSetKeyComplete(pAdapter);
13540 }
13541 }
13542
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013543 if (pairwise_set_key == true)
13544 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013545
Jeff Johnson295189b2012-06-20 16:38:30 -070013546 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13547
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013548 pWextState->roamProfile.Keys.defaultIndex = key_index;
13549
13550
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013551 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013552 params->key, params->key_len);
13553
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013554
Jeff Johnson295189b2012-06-20 16:38:30 -070013555 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13556
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013557 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013558 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013559 __func__, setKey.peerMac[0], setKey.peerMac[1],
13560 setKey.peerMac[2], setKey.peerMac[3],
13561 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 setKey.keyDirection);
13563
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013564 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013565
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013566 if ( vos_status != VOS_STATUS_SUCCESS )
13567 {
13568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013569 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13570 __LINE__, vos_status );
13571
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013572 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013573
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013574 status = -EINVAL;
13575 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013576
13577 }
13578
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013579#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013580 /* The supplicant may attempt to set the PTK once pre-authentication
13581 is done. Save the key in the UMAC and include it in the ADD BSS
13582 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013583 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013584 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013585 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013586 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13587 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013588 status = 0;
13589 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013590 }
13591 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13592 {
13593 hddLog(VOS_TRACE_LEVEL_ERROR,
13594 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013595 status = -EINVAL;
13596 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013597 }
13598#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013599
13600 /* issue set key request to SME*/
13601 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13602 pAdapter->sessionId, &setKey, &roamId );
13603
13604 if ( 0 != status )
13605 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013606 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013607 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13608 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013609 status = -EINVAL;
13610 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013611 }
13612
13613
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013614 /* in case of IBSS as there was no information available about WEP keys during
13615 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013616 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013617 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13618 !( ( IW_AUTH_KEY_MGMT_802_1X
13619 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13621 )
13622 &&
13623 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13624 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13625 )
13626 )
13627 {
13628 setKey.keyDirection = eSIR_RX_ONLY;
13629 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13630
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013631 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013632 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013633 __func__, setKey.peerMac[0], setKey.peerMac[1],
13634 setKey.peerMac[2], setKey.peerMac[3],
13635 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013636 setKey.keyDirection);
13637
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013638 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013639 pAdapter->sessionId, &setKey, &roamId );
13640
13641 if ( 0 != status )
13642 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013643 hddLog(VOS_TRACE_LEVEL_ERROR,
13644 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013645 __func__, status);
13646 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013647 status = -EINVAL;
13648 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013649 }
13650 }
13651 }
13652
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013653 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013654 for (i = 0; i < params->seq_len; i++) {
13655 rsc_counter |= (params->seq[i] << i*8);
13656 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013657 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13658 }
13659
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013660end:
13661 /* Need to clear any trace of key value in the memory.
13662 * Thus zero out the memory even though it is local
13663 * variable.
13664 */
13665 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013666 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013667 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013668}
13669
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013670#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13671static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13672 struct net_device *ndev,
13673 u8 key_index, bool pairwise,
13674 const u8 *mac_addr,
13675 struct key_params *params
13676 )
13677#else
13678static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13679 struct net_device *ndev,
13680 u8 key_index, const u8 *mac_addr,
13681 struct key_params *params
13682 )
13683#endif
13684{
13685 int ret;
13686 vos_ssr_protect(__func__);
13687#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13688 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13689 mac_addr, params);
13690#else
13691 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13692 params);
13693#endif
13694 vos_ssr_unprotect(__func__);
13695
13696 return ret;
13697}
13698
Jeff Johnson295189b2012-06-20 16:38:30 -070013699/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013700 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013701 * This function is used to get the key information
13702 */
13703#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013704static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013705 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013706 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013707 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013708 const u8 *mac_addr, void *cookie,
13709 void (*callback)(void *cookie, struct key_params*)
13710 )
13711#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013712static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013713 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013714 struct net_device *ndev,
13715 u8 key_index, const u8 *mac_addr, void *cookie,
13716 void (*callback)(void *cookie, struct key_params*)
13717 )
13718#endif
13719{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013720 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013721 hdd_wext_state_t *pWextState = NULL;
13722 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013723 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013724 hdd_context_t *pHddCtx;
13725 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013726
13727 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013728
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013729 if (NULL == pAdapter)
13730 {
13731 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13732 "%s: HDD adapter is Null", __func__);
13733 return -ENODEV;
13734 }
13735
13736 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13737 ret = wlan_hdd_validate_context(pHddCtx);
13738 if (0 != ret)
13739 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013740 return ret;
13741 }
13742
13743 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13744 pRoamProfile = &(pWextState->roamProfile);
13745
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013746 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13747 __func__, hdd_device_modetoString(pAdapter->device_mode),
13748 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013749
Jeff Johnson295189b2012-06-20 16:38:30 -070013750 memset(&params, 0, sizeof(params));
13751
13752 if (CSR_MAX_NUM_KEY <= key_index)
13753 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013755 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013756 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013757
13758 switch(pRoamProfile->EncryptionType.encryptionType[0])
13759 {
13760 case eCSR_ENCRYPT_TYPE_NONE:
13761 params.cipher = IW_AUTH_CIPHER_NONE;
13762 break;
13763
13764 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13765 case eCSR_ENCRYPT_TYPE_WEP40:
13766 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13767 break;
13768
13769 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13770 case eCSR_ENCRYPT_TYPE_WEP104:
13771 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13772 break;
13773
13774 case eCSR_ENCRYPT_TYPE_TKIP:
13775 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13776 break;
13777
13778 case eCSR_ENCRYPT_TYPE_AES:
13779 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13780 break;
13781
13782 default:
13783 params.cipher = IW_AUTH_CIPHER_NONE;
13784 break;
13785 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013786
c_hpothuaaf19692014-05-17 17:01:48 +053013787 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13788 TRACE_CODE_HDD_CFG80211_GET_KEY,
13789 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013790
Jeff Johnson295189b2012-06-20 16:38:30 -070013791 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13792 params.seq_len = 0;
13793 params.seq = NULL;
13794 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13795 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013796 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013797 return 0;
13798}
13799
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013800#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13801static int wlan_hdd_cfg80211_get_key(
13802 struct wiphy *wiphy,
13803 struct net_device *ndev,
13804 u8 key_index, bool pairwise,
13805 const u8 *mac_addr, void *cookie,
13806 void (*callback)(void *cookie, struct key_params*)
13807 )
13808#else
13809static int wlan_hdd_cfg80211_get_key(
13810 struct wiphy *wiphy,
13811 struct net_device *ndev,
13812 u8 key_index, const u8 *mac_addr, void *cookie,
13813 void (*callback)(void *cookie, struct key_params*)
13814 )
13815#endif
13816{
13817 int ret;
13818
13819 vos_ssr_protect(__func__);
13820#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13821 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13822 mac_addr, cookie, callback);
13823#else
13824 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13825 callback);
13826#endif
13827 vos_ssr_unprotect(__func__);
13828
13829 return ret;
13830}
13831
Jeff Johnson295189b2012-06-20 16:38:30 -070013832/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013833 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013834 * This function is used to delete the key information
13835 */
13836#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013837static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013838 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013839 u8 key_index,
13840 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013841 const u8 *mac_addr
13842 )
13843#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013844static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013845 struct net_device *ndev,
13846 u8 key_index,
13847 const u8 *mac_addr
13848 )
13849#endif
13850{
13851 int status = 0;
13852
13853 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013854 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013855 //it is observed that this is invalidating peer
13856 //key index whenever re-key is done. This is affecting data link.
13857 //It should be ok to ignore del_key.
13858#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013859 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13860 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013861 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13862 tCsrRoamSetKey setKey;
13863 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013864
Jeff Johnson295189b2012-06-20 16:38:30 -070013865 ENTER();
13866
13867 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13868 __func__,pAdapter->device_mode);
13869
13870 if (CSR_MAX_NUM_KEY <= key_index)
13871 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013873 key_index);
13874
13875 return -EINVAL;
13876 }
13877
13878 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13879 setKey.keyId = key_index;
13880
13881 if (mac_addr)
13882 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13883 else
13884 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13885
13886 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13887
13888 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013889 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013890 )
13891 {
13892
13893 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013894 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13895 if( pHostapdState->bssState == BSS_START)
13896 {
13897 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013898
Jeff Johnson295189b2012-06-20 16:38:30 -070013899 if ( status != eHAL_STATUS_SUCCESS )
13900 {
13901 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13902 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13903 __LINE__, status );
13904 }
13905 }
13906 }
13907 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013908 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013909 )
13910 {
13911 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13912
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013913 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13914
13915 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013916 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013917 __func__, setKey.peerMac[0], setKey.peerMac[1],
13918 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013919 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013920 if(pAdapter->sessionCtx.station.conn_info.connState ==
13921 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013922 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013923 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013924 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013925
Jeff Johnson295189b2012-06-20 16:38:30 -070013926 if ( 0 != status )
13927 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013928 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013929 "%s: sme_RoamSetKey failure, returned %d",
13930 __func__, status);
13931 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13932 return -EINVAL;
13933 }
13934 }
13935 }
13936#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013937 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 return status;
13939}
13940
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013941#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13942static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13943 struct net_device *ndev,
13944 u8 key_index,
13945 bool pairwise,
13946 const u8 *mac_addr
13947 )
13948#else
13949static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13950 struct net_device *ndev,
13951 u8 key_index,
13952 const u8 *mac_addr
13953 )
13954#endif
13955{
13956 int ret;
13957
13958 vos_ssr_protect(__func__);
13959#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13960 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13961 mac_addr);
13962#else
13963 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13964#endif
13965 vos_ssr_unprotect(__func__);
13966
13967 return ret;
13968}
13969
Jeff Johnson295189b2012-06-20 16:38:30 -070013970/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013971 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013972 * This function is used to set the default tx key index
13973 */
13974#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013975static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013976 struct net_device *ndev,
13977 u8 key_index,
13978 bool unicast, bool multicast)
13979#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013980static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013981 struct net_device *ndev,
13982 u8 key_index)
13983#endif
13984{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013985 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013986 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013987 hdd_wext_state_t *pWextState;
13988 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013989 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013990
13991 ENTER();
13992
Gopichand Nakkala29149562013-05-10 21:43:41 +053013993 if ((NULL == pAdapter))
13994 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013996 "invalid adapter");
13997 return -EINVAL;
13998 }
13999
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014000 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14001 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
14002 pAdapter->sessionId, key_index));
14003
Gopichand Nakkala29149562013-05-10 21:43:41 +053014004 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14005 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14006
14007 if ((NULL == pWextState) || (NULL == pHddStaCtx))
14008 {
14009 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14010 "invalid Wext state or HDD context");
14011 return -EINVAL;
14012 }
14013
Arif Hussain6d2a3322013-11-17 19:50:10 -080014014 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014015 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014016
Jeff Johnson295189b2012-06-20 16:38:30 -070014017 if (CSR_MAX_NUM_KEY <= key_index)
14018 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014019 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014020 key_index);
14021
14022 return -EINVAL;
14023 }
14024
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014025 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14026 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014027 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014028 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014029 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014030 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014031
Jeff Johnson295189b2012-06-20 16:38:30 -070014032 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014033 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014034 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014035 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014036 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014037 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014038#ifdef FEATURE_WLAN_WAPI
14039 (eCSR_ENCRYPT_TYPE_WPI !=
14040 pHddStaCtx->conn_info.ucEncryptionType) &&
14041#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014042 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014043 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014044 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014045 {
14046 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014047 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014048
Jeff Johnson295189b2012-06-20 16:38:30 -070014049 tCsrRoamSetKey setKey;
14050 v_U32_t roamId= 0xFF;
14051 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014052
14053 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014054 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014055
Jeff Johnson295189b2012-06-20 16:38:30 -070014056 Keys->defaultIndex = (u8)key_index;
14057 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14058 setKey.keyId = key_index;
14059 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014060
14061 vos_mem_copy(&setKey.Key[0],
14062 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014063 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014064
Gopichand Nakkala29149562013-05-10 21:43:41 +053014065 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014066
14067 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014068 &pHddStaCtx->conn_info.bssId[0],
14069 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014070
Gopichand Nakkala29149562013-05-10 21:43:41 +053014071 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14072 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14073 eCSR_ENCRYPT_TYPE_WEP104)
14074 {
14075 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14076 even though ap is configured for WEP-40 encryption. In this canse the key length
14077 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14078 type(104) and switching encryption type to 40*/
14079 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14080 eCSR_ENCRYPT_TYPE_WEP40;
14081 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14082 eCSR_ENCRYPT_TYPE_WEP40;
14083 }
14084
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014085 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014086 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014087
Jeff Johnson295189b2012-06-20 16:38:30 -070014088 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014089 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014090 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014091
Jeff Johnson295189b2012-06-20 16:38:30 -070014092 if ( 0 != status )
14093 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014094 hddLog(VOS_TRACE_LEVEL_ERROR,
14095 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014096 status);
14097 return -EINVAL;
14098 }
14099 }
14100 }
14101
14102 /* In SoftAp mode setting key direction for default mode */
14103 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14104 {
14105 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14106 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14107 (eCSR_ENCRYPT_TYPE_AES !=
14108 pWextState->roamProfile.EncryptionType.encryptionType[0])
14109 )
14110 {
14111 /* Saving key direction for default key index to TX default */
14112 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14113 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14114 }
14115 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014116 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014117 return status;
14118}
14119
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014120#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14121static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14122 struct net_device *ndev,
14123 u8 key_index,
14124 bool unicast, bool multicast)
14125#else
14126static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14127 struct net_device *ndev,
14128 u8 key_index)
14129#endif
14130{
14131 int ret;
14132 vos_ssr_protect(__func__);
14133#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14134 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14135 multicast);
14136#else
14137 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14138#endif
14139 vos_ssr_unprotect(__func__);
14140
14141 return ret;
14142}
14143
Jeff Johnson295189b2012-06-20 16:38:30 -070014144/*
14145 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14146 * This function is used to inform the BSS details to nl80211 interface.
14147 */
14148static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14149 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14150{
14151 struct net_device *dev = pAdapter->dev;
14152 struct wireless_dev *wdev = dev->ieee80211_ptr;
14153 struct wiphy *wiphy = wdev->wiphy;
14154 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14155 int chan_no;
14156 int ie_length;
14157 const char *ie;
14158 unsigned int freq;
14159 struct ieee80211_channel *chan;
14160 int rssi = 0;
14161 struct cfg80211_bss *bss = NULL;
14162
Jeff Johnson295189b2012-06-20 16:38:30 -070014163 if( NULL == pBssDesc )
14164 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014165 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014166 return bss;
14167 }
14168
14169 chan_no = pBssDesc->channelId;
14170 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14171 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14172
14173 if( NULL == ie )
14174 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014175 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014176 return bss;
14177 }
14178
14179#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14180 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14181 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014182 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014183 }
14184 else
14185 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014186 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014187 }
14188#else
14189 freq = ieee80211_channel_to_frequency(chan_no);
14190#endif
14191
14192 chan = __ieee80211_get_channel(wiphy, freq);
14193
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014194 if (!chan) {
14195 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14196 return NULL;
14197 }
14198
Abhishek Singhaee43942014-06-16 18:55:47 +053014199 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014200
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014201 return cfg80211_inform_bss(wiphy, chan,
14202#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14203 CFG80211_BSS_FTYPE_UNKNOWN,
14204#endif
14205 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014206 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014207 pBssDesc->capabilityInfo,
14208 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014209 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014210}
14211
Abhishek Singhe6137b82019-03-22 20:06:09 +053014212void wlan_hdd_cfg80211_unlink_bss(hdd_adapter_t *pAdapter, tSirMacAddr bssid)
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014213{
14214 struct net_device *dev = pAdapter->dev;
14215 struct wireless_dev *wdev = dev->ieee80211_ptr;
14216 struct wiphy *wiphy = wdev->wiphy;
14217 struct cfg80211_bss *bss = NULL;
14218
Abhishek Singh5a597e62016-12-05 15:16:30 +053014219 bss = hdd_get_bss_entry(wiphy,
14220 NULL, bssid,
14221 NULL, 0);
Abhishek Singhe6137b82019-03-22 20:06:09 +053014222 if (!bss) {
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014223 hddLog(LOGE, FL("BSS not present"));
14224 } else {
14225 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14226 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14227 cfg80211_unlink_bss(wiphy, bss);
Abhishek Singhe6137b82019-03-22 20:06:09 +053014228 /* cfg80211_get_bss get bss with ref count so release it */
14229 cfg80211_put_bss(wiphy, bss);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014230 }
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014231}
Jeff Johnson295189b2012-06-20 16:38:30 -070014232
14233
14234/*
14235 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14236 * This function is used to inform the BSS details to nl80211 interface.
14237 */
14238struct cfg80211_bss*
14239wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14240 tSirBssDescription *bss_desc
14241 )
14242{
14243 /*
14244 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14245 already exists in bss data base of cfg80211 for that particular BSS ID.
14246 Using cfg80211_inform_bss_frame to update the bss entry instead of
14247 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14248 now there is no possibility to get the mgmt(probe response) frame from PE,
14249 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14250 cfg80211_inform_bss_frame.
14251 */
14252 struct net_device *dev = pAdapter->dev;
14253 struct wireless_dev *wdev = dev->ieee80211_ptr;
14254 struct wiphy *wiphy = wdev->wiphy;
14255 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014256#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14257 qcom_ie_age *qie_age = NULL;
14258 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14259#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014260 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014261#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014262 const char *ie =
14263 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14264 unsigned int freq;
14265 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014266 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014267 struct cfg80211_bss *bss_status = NULL;
Hanumanth Reddy Pothulae04e06c2018-05-31 14:41:36 +053014268 size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
14269 u.probe_resp.variable);
Jeff Johnson295189b2012-06-20 16:38:30 -070014270 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014271 hdd_context_t *pHddCtx;
14272 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014273#ifdef WLAN_OPEN_SOURCE
14274 struct timespec ts;
14275#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014276
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014277
Wilson Yangf80a0542013-10-07 13:02:37 -070014278 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14279 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014280 if (0 != status)
14281 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014282 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014283 }
14284
Hanumanth Reddy Pothula33548e22018-05-31 13:28:51 +053014285 mgmt = kzalloc(frame_len, GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014286 if (!mgmt)
14287 {
14288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14289 "%s: memory allocation failed ", __func__);
14290 return NULL;
14291 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014292
Jeff Johnson295189b2012-06-20 16:38:30 -070014293 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014294
14295#ifdef WLAN_OPEN_SOURCE
14296 /* Android does not want the timestamp from the frame.
14297 Instead it wants a monotonic increasing value */
14298 get_monotonic_boottime(&ts);
14299 mgmt->u.probe_resp.timestamp =
14300 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14301#else
14302 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014303 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14304 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014305
14306#endif
14307
Jeff Johnson295189b2012-06-20 16:38:30 -070014308 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14309 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014310
14311#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14312 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14313 /* Assuming this is the last IE, copy at the end */
14314 ie_length -=sizeof(qcom_ie_age);
14315 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14316 qie_age->element_id = QCOM_VENDOR_IE_ID;
14317 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14318 qie_age->oui_1 = QCOM_OUI1;
14319 qie_age->oui_2 = QCOM_OUI2;
14320 qie_age->oui_3 = QCOM_OUI3;
14321 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014322 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14323 * bss related timestamp is in units of ms. Due to this when scan results
14324 * are sent to lowi the scan age is high.To address this, send age in units
14325 * of 1/10 ms.
14326 */
14327 qie_age->age = (vos_timer_get_system_time() -
14328 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014329#endif
14330
Jeff Johnson295189b2012-06-20 16:38:30 -070014331 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014332 if (bss_desc->fProbeRsp)
14333 {
14334 mgmt->frame_control |=
14335 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14336 }
14337 else
14338 {
14339 mgmt->frame_control |=
14340 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14341 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014342
14343#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014344 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014345 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014346 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014347 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014348 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014349 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014350 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014351
14352 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014353 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014354 }
14355 else
14356 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014357 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14358 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014359 kfree(mgmt);
14360 return NULL;
14361 }
14362#else
14363 freq = ieee80211_channel_to_frequency(chan_no);
14364#endif
14365 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014366 /*when the band is changed on the fly using the GUI, three things are done
14367 * 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)
14368 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14369 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14370 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14371 * and discards the channels correponding to previous band and calls back with zero bss results.
14372 * 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
14373 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14374 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14375 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14376 * So drop the bss and continue to next bss.
14377 */
14378 if(chan == NULL)
14379 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014380 hddLog(VOS_TRACE_LEVEL_ERROR,
14381 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14382 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014383 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014384 return NULL;
14385 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014386 /*To keep the rssi icon of the connected AP in the scan window
14387 *and the rssi icon of the wireless networks in sync
14388 * */
14389 if (( eConnectionState_Associated ==
14390 pAdapter->sessionCtx.station.conn_info.connState ) &&
14391 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14392 pAdapter->sessionCtx.station.conn_info.bssId,
14393 WNI_CFG_BSSID_LEN)) &&
14394 (pHddCtx->hdd_wlan_suspended == FALSE))
14395 {
14396 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14397 rssi = (pAdapter->rssi * 100);
14398 }
14399 else
14400 {
14401 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14402 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014403
Nirav Shah20ac06f2013-12-12 18:14:06 +053014404 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014405 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14406 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014407
Jeff Johnson295189b2012-06-20 16:38:30 -070014408 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14409 frame_len, rssi, GFP_KERNEL);
14410 kfree(mgmt);
14411 return bss_status;
14412}
14413
14414/*
14415 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14416 * This function is used to update the BSS data base of CFG8011
14417 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014418struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014419 tCsrRoamInfo *pRoamInfo
14420 )
14421{
14422 tCsrRoamConnectedProfile roamProfile;
14423 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14424 struct cfg80211_bss *bss = NULL;
14425
14426 ENTER();
14427
14428 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14429 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14430
14431 if (NULL != roamProfile.pBssDesc)
14432 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014433 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14434 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014435
14436 if (NULL == bss)
14437 {
14438 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14439 __func__);
14440 }
14441
14442 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14443 }
14444 else
14445 {
14446 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14447 __func__);
14448 }
14449 return bss;
14450}
14451
14452/*
14453 * FUNCTION: wlan_hdd_cfg80211_update_bss
14454 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014455static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14456 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014457 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014458{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014459 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014460 tCsrScanResultInfo *pScanResult;
14461 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014462 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014463 tScanResultHandle pResult;
14464 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014465 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014466 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014467 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014468
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014469 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14470 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14471 NO_SESSION, pAdapter->sessionId));
14472
Wilson Yangf80a0542013-10-07 13:02:37 -070014473 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014474 ret = wlan_hdd_validate_context(pHddCtx);
14475 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014476 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014477 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014478 }
14479
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014480 if (pAdapter->request != NULL)
14481 {
14482 if ((pAdapter->request->n_ssids == 1)
14483 && (pAdapter->request->ssids != NULL)
14484 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14485 is_p2p_scan = true;
14486 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014487 /*
14488 * start getting scan results and populate cgf80211 BSS database
14489 */
14490 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14491
14492 /* no scan results */
14493 if (NULL == pResult)
14494 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014495 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14496 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014497 wlan_hdd_get_frame_logs(pAdapter,
14498 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014499 return status;
14500 }
14501
14502 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14503
14504 while (pScanResult)
14505 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014506 /*
14507 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14508 * entry already exists in bss data base of cfg80211 for that
14509 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14510 * bss entry instead of cfg80211_inform_bss, But this call expects
14511 * mgmt packet as input. As of now there is no possibility to get
14512 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014513 * ieee80211_mgmt(probe response) and passing to c
14514 * fg80211_inform_bss_frame.
14515 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014516 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14517 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14518 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014519 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14520 continue; //Skip the non p2p bss entries
14521 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014522 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14523 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014524
Jeff Johnson295189b2012-06-20 16:38:30 -070014525
14526 if (NULL == bss_status)
14527 {
14528 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014529 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014530 }
14531 else
14532 {
Yue Maf49ba872013-08-19 12:04:25 -070014533 cfg80211_put_bss(
14534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14535 wiphy,
14536#endif
14537 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014538 }
14539
14540 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14541 }
14542
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014543 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014544 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014545 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014546}
14547
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014548void
14549hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14550{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014551 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014552 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014553} /****** end hddPrintMacAddr() ******/
14554
14555void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014556hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014557{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014558 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014559 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014560 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14561 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14562 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014563} /****** end hddPrintPmkId() ******/
14564
14565//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14566//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14567
14568//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14569//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14570
14571#define dump_bssid(bssid) \
14572 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014573 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14574 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014575 }
14576
14577#define dump_pmkid(pMac, pmkid) \
14578 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014579 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14580 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014581 }
14582
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014583#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014584/*
14585 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14586 * This function is used to notify the supplicant of a new PMKSA candidate.
14587 */
14588int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014589 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014590 int index, bool preauth )
14591{
Jeff Johnsone7245742012-09-05 17:12:55 -070014592#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014593 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014594 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014595
14596 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014597 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014598
14599 if( NULL == pRoamInfo )
14600 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014601 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014602 return -EINVAL;
14603 }
14604
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014605 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14606 {
14607 dump_bssid(pRoamInfo->bssid);
14608 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014609 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014610 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014611#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014612 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014613}
14614#endif //FEATURE_WLAN_LFR
14615
Yue Maef608272013-04-08 23:09:17 -070014616#ifdef FEATURE_WLAN_LFR_METRICS
14617/*
14618 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14619 * 802.11r/LFR metrics reporting function to report preauth initiation
14620 *
14621 */
14622#define MAX_LFR_METRICS_EVENT_LENGTH 100
14623VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14624 tCsrRoamInfo *pRoamInfo)
14625{
14626 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14627 union iwreq_data wrqu;
14628
14629 ENTER();
14630
14631 if (NULL == pAdapter)
14632 {
14633 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14634 return VOS_STATUS_E_FAILURE;
14635 }
14636
14637 /* create the event */
14638 memset(&wrqu, 0, sizeof(wrqu));
14639 memset(metrics_notification, 0, sizeof(metrics_notification));
14640
14641 wrqu.data.pointer = metrics_notification;
14642 wrqu.data.length = scnprintf(metrics_notification,
14643 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14644 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14645
14646 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14647
14648 EXIT();
14649
14650 return VOS_STATUS_SUCCESS;
14651}
14652
14653/*
14654 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14655 * 802.11r/LFR metrics reporting function to report preauth completion
14656 * or failure
14657 */
14658VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14659 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14660{
14661 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14662 union iwreq_data wrqu;
14663
14664 ENTER();
14665
14666 if (NULL == pAdapter)
14667 {
14668 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14669 return VOS_STATUS_E_FAILURE;
14670 }
14671
14672 /* create the event */
14673 memset(&wrqu, 0, sizeof(wrqu));
14674 memset(metrics_notification, 0, sizeof(metrics_notification));
14675
14676 scnprintf(metrics_notification, sizeof(metrics_notification),
14677 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14678 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14679
14680 if (1 == preauth_status)
14681 strncat(metrics_notification, " TRUE", 5);
14682 else
14683 strncat(metrics_notification, " FALSE", 6);
14684
14685 wrqu.data.pointer = metrics_notification;
14686 wrqu.data.length = strlen(metrics_notification);
14687
14688 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14689
14690 EXIT();
14691
14692 return VOS_STATUS_SUCCESS;
14693}
14694
14695/*
14696 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14697 * 802.11r/LFR metrics reporting function to report handover initiation
14698 *
14699 */
14700VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14701 tCsrRoamInfo *pRoamInfo)
14702{
14703 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14704 union iwreq_data wrqu;
14705
14706 ENTER();
14707
14708 if (NULL == pAdapter)
14709 {
14710 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14711 return VOS_STATUS_E_FAILURE;
14712 }
14713
14714 /* create the event */
14715 memset(&wrqu, 0, sizeof(wrqu));
14716 memset(metrics_notification, 0, sizeof(metrics_notification));
14717
14718 wrqu.data.pointer = metrics_notification;
14719 wrqu.data.length = scnprintf(metrics_notification,
14720 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14721 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14722
14723 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14724
14725 EXIT();
14726
14727 return VOS_STATUS_SUCCESS;
14728}
14729#endif
14730
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014731
14732/**
14733 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14734 * @scan_req: scan request to be checked
14735 *
14736 * Return: true or false
14737 */
14738#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14739static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14740 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014741 *scan_req, hdd_context_t
14742 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014743{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014744 if (!scan_req || !scan_req->wiphy ||
14745 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014746 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14747 return false;
14748 }
14749 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14750 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14751 return false;
14752 }
14753 return true;
14754}
14755#else
14756static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14757 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014758 *scan_req, hdd_context_t
14759 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014760{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014761 if (!scan_req || !scan_req->wiphy ||
14762 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014763 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14764 return false;
14765 }
14766 return true;
14767}
14768#endif
14769
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014770#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14771/**
14772 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14773 * @adapter: Pointer to the adapter
14774 * @req : Scan request
14775 * @aborted : true scan aborted false scan success
14776 *
14777 * This function notifies scan done to cfg80211
14778 *
14779 * Return: none
14780 */
14781static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14782 struct cfg80211_scan_request *req,
14783 bool aborted)
14784{
14785 struct cfg80211_scan_info info = {
14786 .aborted = aborted
14787 };
14788
14789 if (adapter->dev->flags & IFF_UP)
14790 cfg80211_scan_done(req, &info);
14791 else
14792 hddLog(LOGW,
14793 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14794}
14795#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14796/**
14797 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14798 * @adapter: Pointer to the adapter
14799 * @req : Scan request
14800 * @aborted : true scan aborted false scan success
14801 *
14802 * This function notifies scan done to cfg80211
14803 *
14804 * Return: none
14805 */
14806static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14807 struct cfg80211_scan_request *req,
14808 bool aborted)
14809{
14810 if (adapter->dev->flags & IFF_UP)
14811 cfg80211_scan_done(req, aborted);
14812 else
14813 hddLog(LOGW,
14814 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14815}
14816#else
14817/**
14818 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14819 * @adapter: Pointer to the adapter
14820 * @req : Scan request
14821 * @aborted : true scan aborted false scan success
14822 *
14823 * This function notifies scan done to cfg80211
14824 *
14825 * Return: none
14826 */
14827static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14828 struct cfg80211_scan_request *req,
14829 bool aborted)
14830{
14831 cfg80211_scan_done(req, aborted);
14832}
14833#endif
14834
Mukul Sharmab392b642017-08-17 17:45:29 +053014835#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014836/*
14837 * FUNCTION: hdd_cfg80211_scan_done_callback
14838 * scanning callback function, called after finishing scan
14839 *
14840 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014841static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014842 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14843{
14844 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014845 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014846 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014847 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014848 struct cfg80211_scan_request *req = NULL;
14849 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014850 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014851 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014852 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014853
14854 ENTER();
14855
c_manjee1b4ab9a2016-10-26 11:36:55 +053014856 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14857 !pAdapter->dev) {
14858 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14859 return 0;
14860 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014861 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014862 if (NULL == pHddCtx) {
14863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014864 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014865 }
14866
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014867#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014868 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014869 {
14870 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014871 }
14872#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014873 pScanInfo = &pHddCtx->scan_info;
14874
Jeff Johnson295189b2012-06-20 16:38:30 -070014875 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014876 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014877 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014878 __func__, halHandle, pContext, (int) scanId, (int) status);
14879
Kiet Lamac06e2c2013-10-23 16:25:07 +053014880 pScanInfo->mScanPendingCounter = 0;
14881
Jeff Johnson295189b2012-06-20 16:38:30 -070014882 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014883 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014884 &pScanInfo->scan_req_completion_event,
14885 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014886 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014887 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014888 hddLog(VOS_TRACE_LEVEL_ERROR,
14889 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014890 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014891 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014892 }
14893
Yue Maef608272013-04-08 23:09:17 -070014894 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014895 {
14896 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014897 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014898 }
14899
14900 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014901 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014902 {
14903 hddLog(VOS_TRACE_LEVEL_INFO,
14904 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014905 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014906 (int) scanId);
14907 }
14908
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014910 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014911#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014912 {
14913 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14914 pAdapter);
14915 if (0 > ret)
14916 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014917 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014918
Jeff Johnson295189b2012-06-20 16:38:30 -070014919 /* If any client wait scan result through WEXT
14920 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014921 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014922 {
14923 /* The other scan request waiting for current scan finish
14924 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014925 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014926 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014927 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014928 }
14929 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014930 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014931 {
14932 struct net_device *dev = pAdapter->dev;
14933 union iwreq_data wrqu;
14934 int we_event;
14935 char *msg;
14936
14937 memset(&wrqu, '\0', sizeof(wrqu));
14938 we_event = SIOCGIWSCAN;
14939 msg = NULL;
14940 wireless_send_event(dev, we_event, &wrqu, msg);
14941 }
14942 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014943 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014944
14945 /* Get the Scan Req */
14946 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014947 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014948
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014949 /* Scan is no longer pending */
14950 pScanInfo->mScanPending = VOS_FALSE;
14951
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014952 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014953 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014956 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014957#endif
14958
14959 if (pAdapter->dev) {
14960 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14961 pAdapter->dev->name);
14962 }
mukul sharmae7041822015-12-03 15:09:21 +053014963 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014964 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014965 }
14966
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014967 /* last_scan_timestamp is used to decide if new scan
14968 * is needed or not on station interface. If last station
14969 * scan time and new station scan time is less then
14970 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014971 * Also only last_scan_timestamp is updated here last_scan_channellist
14972 * is updated on receiving scan request itself to make sure kernel
14973 * allocated scan request(scan_req) object is not dereferenced here,
14974 * because interface down, where kernel frees scan_req, may happen any
14975 * time while driver is processing scan_done_callback. So it's better
14976 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014977 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014978 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
14979 if (status == eCSR_SCAN_SUCCESS)
14980 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14981 else {
14982 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
14983 sizeof(pHddCtx->scan_info.last_scan_channelList));
14984 pHddCtx->scan_info.last_scan_numChannels = 0;
14985 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014986 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014987 }
14988
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014989 /*
14990 * cfg80211_scan_done informing NL80211 about completion
14991 * of scanning
14992 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014993 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14994 {
14995 aborted = true;
14996 }
mukul sharmae7041822015-12-03 15:09:21 +053014997
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014998#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014999 if (NET_DEV_IS_IFF_UP(pAdapter) &&
15000 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015001#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015002 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053015003
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080015004 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070015005
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015006allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015007 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
15008 ) && (pHddCtx->spoofMacAddr.isEnabled
15009 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015010 /* Generate new random mac addr for next scan */
15011 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015012
15013 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15014 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015015 }
15016
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015017 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015018 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015019
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015020 /* Acquire wakelock to handle the case where APP's tries to suspend
15021 * immediatly after the driver gets connect request(i.e after scan)
15022 * from supplicant, this result in app's is suspending and not able
15023 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015024 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015025
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015026#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015027 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015028#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015029#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015030 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015031#endif
15032
Jeff Johnson295189b2012-06-20 16:38:30 -070015033 EXIT();
15034 return 0;
15035}
15036
15037/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015038 * FUNCTION: hdd_isConnectionInProgress
15039 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015040 *
15041 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015042v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15043 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015044{
15045 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15046 hdd_station_ctx_t *pHddStaCtx = NULL;
15047 hdd_adapter_t *pAdapter = NULL;
15048 VOS_STATUS status = 0;
15049 v_U8_t staId = 0;
15050 v_U8_t *staMac = NULL;
15051
15052 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15053
15054 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15055 {
15056 pAdapter = pAdapterNode->pAdapter;
15057
15058 if( pAdapter )
15059 {
15060 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015061 "%s: Adapter with device mode %s (%d) exists",
15062 __func__, hdd_device_modetoString(pAdapter->device_mode),
15063 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015064 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015065 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15066 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15067 (eConnectionState_Connecting ==
15068 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15069 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015070 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015071 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015072 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015073 if (session_id && reason)
15074 {
15075 *session_id = pAdapter->sessionId;
15076 *reason = eHDD_CONNECTION_IN_PROGRESS;
15077 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015078 return VOS_TRUE;
15079 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015080 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015081 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015082 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015083 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015084 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015085 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015086 if (session_id && reason)
15087 {
15088 *session_id = pAdapter->sessionId;
15089 *reason = eHDD_REASSOC_IN_PROGRESS;
15090 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015091 return VOS_TRUE;
15092 }
15093 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015094 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15095 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015096 {
15097 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15098 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Vignesh Viswanathan0ac8e562018-06-14 17:24:10 +053015099 sme_is_sta_key_exchange_in_progress(pHddCtx->hHal,
15100 pAdapter->sessionId))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015101 {
15102 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015103 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015104 "%s: client " MAC_ADDRESS_STR
15105 " is in the middle of WPS/EAPOL exchange.", __func__,
15106 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015107 if (session_id && reason)
15108 {
15109 *session_id = pAdapter->sessionId;
15110 *reason = eHDD_EAPOL_IN_PROGRESS;
15111 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015112 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015113 }
15114 }
15115 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15116 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15117 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015118 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15119 ptSapContext pSapCtx = NULL;
15120 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15121 if(pSapCtx == NULL){
15122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15123 FL("psapCtx is NULL"));
15124 return VOS_FALSE;
15125 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015126 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15127 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015128 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15129 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015130 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015131 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015132
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015133 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015134 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15135 "middle of WPS/EAPOL exchange.", __func__,
15136 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015137 if (session_id && reason)
15138 {
15139 *session_id = pAdapter->sessionId;
15140 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15141 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015142 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015143 }
15144 }
15145 }
15146 }
15147 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15148 pAdapterNode = pNext;
15149 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015150 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015151}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015152
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015153/**
15154 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15155 * to the Scan request
15156 * @scanRequest: Pointer to the csr scan request
15157 * @request: Pointer to the scan request from supplicant
15158 *
15159 * Return: None
15160 */
15161#ifdef CFG80211_SCAN_BSSID
15162static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15163 struct cfg80211_scan_request *request)
15164{
15165 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15166}
15167#else
15168static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15169 struct cfg80211_scan_request *request)
15170{
15171}
15172#endif
15173
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015174#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
15175 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
15176/**
15177 * hdd_is_wiphy_scan_random_support() - Check NL80211 scan randomization support
15178 * @wiphy: Pointer to wiphy structure
15179 *
15180 * This function is used to check whether @wiphy supports
15181 * NL80211 scan randomization feature.
15182 *
15183 * Return: If randomization is supported then return true else false.
15184 */
15185static bool
15186hdd_is_wiphy_scan_random_support(struct wiphy *wiphy)
15187{
15188 if (wiphy->features & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)
15189 return true;
15190
15191 return false;
15192}
15193
15194/**
15195 * hdd_is_nl_scan_random() - Check for randomization flag in cfg80211 scan
15196 * @nl_scan: cfg80211 scan request
15197 *
15198 * This function is used to check whether scan randomization flag is set for
15199 * current cfg80211 scan request identified by @nl_scan.
15200 *
15201 * Return: If randomization flag is set then return true else false.
15202 */
15203static bool
15204hdd_is_nl_scan_random(struct cfg80211_scan_request *nl_scan)
15205{
15206 if (nl_scan->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
15207 return true;
15208
15209 return false;
15210}
15211#else
15212static bool
15213hdd_is_wiphy_scan_random_support(struct wiphy *wiphy)
15214{
15215 return false;
15216}
15217
15218static bool
15219hdd_is_nl_scan_random(struct cfg80211_scan_request *nl_scan)
15220{
15221 return false;
15222}
15223#endif
15224
15225/**
15226 * hdd_generate_scan_random_mac() - Generate Random mac addr for cfg80211 scan
15227 * @mac_addr: Input mac-addr from which random-mac address is to be generated
15228 * @mac_mask: Bits of mac_addr which should not be randomized
15229 * @random_mac: Output pointer to hold generated random mac address
15230 *
15231 * This function is used generate random mac address using @mac_addr and
15232 * @mac_mask with following logic:
15233 * Bit value 0 in the mask means that we should randomize that bit.
15234 * Bit value 1 in the mask means that we should take specific bit value
15235 * from mac address provided.
15236 *
15237 * Return: None
15238 */
15239static void
15240hdd_generate_scan_random_mac(uint8_t *mac_addr, uint8_t *mac_mask,
15241 uint8_t *random_mac)
15242{
15243 uint32_t i;
15244 uint8_t random_byte;
15245
15246 for (i = 0; i < VOS_MAC_ADDRESS_LEN; i++) {
15247 random_byte = 0;
15248 get_random_bytes(&random_byte, 1);
15249 random_mac[i] = (mac_addr[i] & mac_mask[i]) |
15250 (random_byte & (~(mac_mask[i])));
15251 }
15252
15253 /*
15254 * Make sure locally administered bit is set if that
15255 * particular bit in the mask is 0
15256 */
15257 if (!(mac_mask[0] & 0x2))
15258 random_mac[0] |= 0x2;
15259
15260 /*
15261 * Make sure multicast/group address bit is NOT set if that
15262 * particular bit in the mask is 0
15263 */
15264 if (!(mac_mask[0] & 0x1))
15265 random_mac[0] &= ~0x1;
15266}
15267
15268/**
15269 * hdd_spoof_scan() - Spoof cfg80211 scan
15270 * @wiphy: Pointer to wiphy
15271 * @adapter: Pointer to adapter for which scan is requested
15272 * @nl_scan: Cfg80211 scan request
15273 * @is_p2p_scan: Check for p2p scan
15274 * @csr_scan: Pointer to internal (csr) scan request
15275 *
15276 * This function is used for following purposes:
15277 * (a) If cfg80211 supports scan randomization then this function invokes helper
15278 * functions to generate random-mac address.
15279 * (b) If the cfg80211 doesn't support scan randomization then randomize scans
15280 * using spoof mac received with VENDOR_SUBCMD_MAC_OUI.
15281 * (c) Configure the random-mac in transport layer.
15282 *
15283 * Return: For success return 0 else return negative value.
15284 */
15285static int
15286hdd_spoof_scan(struct wiphy *wiphy, hdd_adapter_t *adapter,
15287 struct cfg80211_scan_request *nl_scan,
15288 bool is_p2p_scan, tCsrScanRequest *csr_scan)
15289{
15290 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
15291 hdd_config_t *config = hdd_ctx->cfg_ini;
15292 uint8_t random_mac[VOS_MAC_ADDRESS_LEN];
15293 VOS_STATUS vos_status;
15294 eHalStatus hal_status;
15295
15296 csr_scan->nl_scan = true;
15297 csr_scan->scan_randomize = false;
15298
15299 if (config->enableMacSpoofing != MAC_ADDR_SPOOFING_FW_HOST_ENABLE ||
15300 !sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN))
15301 return 0;
15302
15303 vos_flush_delayed_work(&hdd_ctx->spoof_mac_addr_work);
15304
15305 if (hdd_is_wiphy_scan_random_support(wiphy)) {
15306 if (!hdd_is_nl_scan_random(nl_scan) || is_p2p_scan)
15307 return 0;
15308
15309 hdd_generate_scan_random_mac(nl_scan->mac_addr,
15310 nl_scan->mac_addr_mask,
15311 random_mac);
15312
15313 hddLog(VOS_TRACE_LEVEL_INFO,
15314 FL("cfg80211 scan random attributes:"));
15315 hddLog(VOS_TRACE_LEVEL_INFO, "mac-addr: "MAC_ADDRESS_STR
15316 " mac-mask: "MAC_ADDRESS_STR
15317 " random-mac: "MAC_ADDRESS_STR,
15318 MAC_ADDR_ARRAY(nl_scan->mac_addr),
15319 MAC_ADDR_ARRAY(nl_scan->mac_addr_mask),
15320 MAC_ADDR_ARRAY(random_mac));
15321
15322 hal_status = sme_SpoofMacAddrReq(hdd_ctx->hHal,
15323 (v_MACADDR_t *)random_mac,
15324 false);
15325 if (hal_status != eHAL_STATUS_SUCCESS) {
15326 hddLog(LOGE,
15327 FL("Send of Spoof request failed"));
15328 hddLog(LOGE,
15329 FL("Disable spoofing and use self-mac"));
15330 return 0;
15331 }
15332
15333 vos_status = WLANTL_updateSpoofMacAddr(hdd_ctx->pvosContext,
15334 (v_MACADDR_t*)random_mac,
15335 &adapter->macAddressCurrent);
15336 if(vos_status != VOS_STATUS_SUCCESS) {
15337 hddLog(VOS_TRACE_LEVEL_ERROR,
15338 FL("Failed to update spoof mac in TL"));
15339 return -EINVAL;
15340 }
15341
15342 csr_scan->scan_randomize = true;
15343
15344 return 0;
15345 }
15346
15347 /*
15348 * If wiphy does not support cfg80211 scan randomization then scan
15349 * will be randomized using the vendor MAC OUI.
15350 */
15351 if (!hdd_ctx->spoofMacAddr.isEnabled)
15352 return 0;
15353
15354 hddLog(VOS_TRACE_LEVEL_INFO,
15355 FL("MAC Spoofing enabled for current scan and spoof addr is:"
15356 MAC_ADDRESS_STR),
15357 MAC_ADDR_ARRAY(hdd_ctx->spoofMacAddr.randomMacAddr.bytes));
15358
15359 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15360 * to fill TxBds for probe request during current scan
15361 */
15362 vos_status = WLANTL_updateSpoofMacAddr(hdd_ctx->pvosContext,
15363 &hdd_ctx->spoofMacAddr.randomMacAddr, &adapter->macAddressCurrent);
15364 if(vos_status != VOS_STATUS_SUCCESS) {
15365 hddLog(VOS_TRACE_LEVEL_ERROR,
15366 FL("Failed to update spoof mac in TL"));
15367 return -EINVAL;
15368 }
15369
15370 csr_scan->scan_randomize = true;
15371
15372 return 0;
15373}
15374
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015375/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015376 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015377 * this scan respond to scan trigger and update cfg80211 scan database
15378 * later, scan dump command can be used to recieve scan results
15379 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015380int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015381#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15382 struct net_device *dev,
15383#endif
15384 struct cfg80211_scan_request *request)
15385{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015386 hdd_adapter_t *pAdapter = NULL;
15387 hdd_context_t *pHddCtx = NULL;
15388 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015389 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015390 tCsrScanRequest scanRequest;
15391 tANI_U8 *channelList = NULL, i;
15392 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015393 int status;
15394 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015395 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015396 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015397 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015398 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015399 v_U8_t curr_session_id;
15400 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015401
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015402#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15403 struct net_device *dev = NULL;
15404 if (NULL == request)
15405 {
15406 hddLog(VOS_TRACE_LEVEL_ERROR,
15407 "%s: scan req param null", __func__);
15408 return -EINVAL;
15409 }
15410 dev = request->wdev->netdev;
15411#endif
15412
15413 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15414 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15415 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15416
Jeff Johnson295189b2012-06-20 16:38:30 -070015417 ENTER();
15418
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015419 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15420 __func__, hdd_device_modetoString(pAdapter->device_mode),
15421 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015422
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015423 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015424 if (0 != status)
15425 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015426 return status;
15427 }
15428
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015429 if (NULL == pwextBuf)
15430 {
15431 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15432 __func__);
15433 return -EIO;
15434 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015435 cfg_param = pHddCtx->cfg_ini;
15436 pScanInfo = &pHddCtx->scan_info;
15437
Jeff Johnson295189b2012-06-20 16:38:30 -070015438#ifdef WLAN_BTAMP_FEATURE
15439 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015440 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015441 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015442 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015443 "%s: No scanning when AMP is on", __func__);
15444 return -EOPNOTSUPP;
15445 }
15446#endif
15447 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015448 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015449 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015450 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015451 "%s: Not scanning on device_mode = %s (%d)",
15452 __func__, hdd_device_modetoString(pAdapter->device_mode),
15453 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015454 return -EOPNOTSUPP;
15455 }
15456
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015457 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15458 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15459 return -EOPNOTSUPP;
15460 }
15461
Jeff Johnson295189b2012-06-20 16:38:30 -070015462 if (TRUE == pScanInfo->mScanPending)
15463 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015464 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15465 {
15466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15467 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015468 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015469 }
15470
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015471 // Don't allow scan if PNO scan is going on.
15472 if (pHddCtx->isPnoEnable)
15473 {
15474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15475 FL("pno scan in progress"));
15476 return -EBUSY;
15477 }
15478
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015479 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015480 //Channel and action frame is pending
15481 //Otherwise Cancel Remain On Channel and allow Scan
15482 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015483 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015484 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015485 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015486 return -EBUSY;
15487 }
15488
Jeff Johnson295189b2012-06-20 16:38:30 -070015489 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15490 {
15491 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015492 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015493 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015494 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015495 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15496 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015497 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015498 "%s: MAX TM Level Scan not allowed", __func__);
15499 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015500 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015501 }
15502 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15503
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015504 /* Check if scan is allowed at this point of time.
15505 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015506 if (TRUE == pHddCtx->btCoexModeSet)
15507 {
15508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15509 FL("BTCoex Mode operation in progress"));
15510 return -EBUSY;
15511 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015512 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015513 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015514
15515 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15516 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15517 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015518 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15519 pHddCtx->last_scan_reject_reason != curr_reason ||
15520 !pHddCtx->last_scan_reject_timestamp)
15521 {
15522 pHddCtx->last_scan_reject_session_id = curr_session_id;
15523 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015524 pHddCtx->last_scan_reject_timestamp =
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015525 jiffies + msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
Abhishek Singhe4b12562017-06-20 16:53:39 +053015526 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015527 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015528 else
15529 {
15530 pHddCtx->scan_reject_cnt++;
15531
Abhishek Singhe4b12562017-06-20 16:53:39 +053015532 if ((pHddCtx->scan_reject_cnt >=
15533 SCAN_REJECT_THRESHOLD) &&
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015534 vos_system_time_after(jiffies,
Abhishek Singh3e500772017-07-17 10:13:43 +053015535 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015536 {
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015537 hddLog(LOGE, FL("Session %d reason %d reject cnt %d reject timestamp %lu jiffies %lu"),
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015538 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015539 pHddCtx->last_scan_reject_timestamp, jiffies);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015540 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015541 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015542 if (pHddCtx->cfg_ini->enableFatalEvent)
15543 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15544 WLAN_LOG_INDICATOR_HOST_DRIVER,
15545 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15546 FALSE, FALSE);
15547 else
15548 {
15549 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015550 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015551 }
15552 }
15553 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015554 return -EBUSY;
15555 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015556 pHddCtx->last_scan_reject_timestamp = 0;
15557 pHddCtx->last_scan_reject_session_id = 0xFF;
15558 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015559 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015560
Jeff Johnson295189b2012-06-20 16:38:30 -070015561 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15562
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015563 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15564 * Becasue of this, driver is assuming that this is not wildcard scan and so
15565 * is not aging out the scan results.
15566 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015567 if ((request->ssids) && (request->n_ssids == 1) &&
15568 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015569 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015570 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015571
15572 if ((request->ssids) && (0 < request->n_ssids))
15573 {
15574 tCsrSSIDInfo *SsidInfo;
15575 int j;
15576 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15577 /* Allocate num_ssid tCsrSSIDInfo structure */
15578 SsidInfo = scanRequest.SSIDs.SSIDList =
15579 ( tCsrSSIDInfo *)vos_mem_malloc(
15580 request->n_ssids*sizeof(tCsrSSIDInfo));
15581
15582 if(NULL == scanRequest.SSIDs.SSIDList)
15583 {
15584 hddLog(VOS_TRACE_LEVEL_ERROR,
15585 "%s: memory alloc failed SSIDInfo buffer", __func__);
15586 return -ENOMEM;
15587 }
15588
15589 /* copy all the ssid's and their length */
15590 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15591 {
15592 /* get the ssid length */
15593 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15594 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15595 SsidInfo->SSID.length);
15596 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15597 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15598 j, SsidInfo->SSID.ssId);
15599 }
15600 /* set the scan type to active */
15601 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15602 }
15603 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015604 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015605 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15606 TRACE_CODE_HDD_CFG80211_SCAN,
15607 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015608 /* set the scan type to active */
15609 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015610 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015611 else
15612 {
15613 /*Set the scan type to default type, in this case it is ACTIVE*/
15614 scanRequest.scanType = pScanInfo->scan_mode;
15615 }
15616 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15617 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015618
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015619 csr_scan_request_assign_bssid(&scanRequest, request);
15620
Jeff Johnson295189b2012-06-20 16:38:30 -070015621 /* set BSSType to default type */
15622 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15623
15624 /*TODO: scan the requested channels only*/
15625
15626 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015627 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015628 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015629 hddLog(VOS_TRACE_LEVEL_WARN,
15630 "No of Scan Channels exceeded limit: %d", request->n_channels);
15631 request->n_channels = MAX_CHANNEL;
15632 }
15633
15634 hddLog(VOS_TRACE_LEVEL_INFO,
15635 "No of Scan Channels: %d", request->n_channels);
15636
15637
15638 if( request->n_channels )
15639 {
15640 char chList [(request->n_channels*5)+1];
15641 int len;
15642 channelList = vos_mem_malloc( request->n_channels );
15643 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015644 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015645 hddLog(VOS_TRACE_LEVEL_ERROR,
15646 "%s: memory alloc failed channelList", __func__);
15647 status = -ENOMEM;
15648 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015649 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015650
15651 for( i = 0, len = 0; i < request->n_channels ; i++ )
15652 {
15653 channelList[i] = request->channels[i]->hw_value;
15654 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15655 }
15656
Nirav Shah20ac06f2013-12-12 18:14:06 +053015657 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015658 "Channel-List: %s ", chList);
15659 }
c_hpothu53512302014-04-15 18:49:53 +053015660
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015661 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15662 scanRequest.ChannelInfo.ChannelList = channelList;
15663
15664 /* set requestType to full scan */
15665 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15666
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015667 /* if there is back to back scan happening in driver with in
15668 * nDeferScanTimeInterval interval driver should defer new scan request
15669 * and should provide last cached scan results instead of new channel list.
15670 * This rule is not applicable if scan is p2p scan.
15671 * This condition will work only in case when last request no of channels
15672 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015673 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015674 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015675 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015676
Sushant Kaushik86592172015-04-27 16:35:03 +053015677 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15678 /* if wps ie is NULL , then only defer scan */
15679 if ( pWpsIe == NULL &&
15680 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015681 {
15682 if ( pScanInfo->last_scan_timestamp !=0 &&
15683 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15684 {
15685 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15686 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15687 vos_mem_compare(pScanInfo->last_scan_channelList,
15688 channelList, pScanInfo->last_scan_numChannels))
15689 {
15690 hddLog(VOS_TRACE_LEVEL_WARN,
15691 " New and old station scan time differ is less then %u",
15692 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15693
15694 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015695 pAdapter);
15696
Agarwal Ashish57e84372014-12-05 18:26:53 +053015697 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015698 "Return old cached scan as all channels and no of channels are same");
15699
Agarwal Ashish57e84372014-12-05 18:26:53 +053015700 if (0 > ret)
15701 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015702
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015703 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015704
15705 status = eHAL_STATUS_SUCCESS;
15706 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015707 }
15708 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015709 }
15710
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015711 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15712 * search (Flush on both full scan and social scan but not on single
15713 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15714 */
15715
15716 /* Supplicant does single channel scan after 8-way handshake
15717 * and in that case driver shoudnt flush scan results. If
15718 * driver flushes the scan results here and unfortunately if
15719 * the AP doesnt respond to our probe req then association
15720 * fails which is not desired
15721 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015722 if ((request->n_ssids == 1)
15723 && (request->ssids != NULL)
15724 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15725 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015726
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015727 if( is_p2p_scan ||
15728 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015729 {
15730 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15731 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15732 pAdapter->sessionId );
15733 }
15734
15735 if( request->ie_len )
15736 {
15737 /* save this for future association (join requires this) */
15738 /*TODO: Array needs to be converted to dynamic allocation,
15739 * as multiple ie.s can be sent in cfg80211_scan_request structure
15740 * CR 597966
15741 */
15742 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15743 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15744 pScanInfo->scanAddIE.length = request->ie_len;
15745
15746 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15747 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15748 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015749 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015750 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015751 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015752 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15753 memcpy( pwextBuf->roamProfile.addIEScan,
15754 request->ie, request->ie_len);
15755 }
15756 else
15757 {
15758 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15759 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015760 }
15761
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015762 }
15763 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15764 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15765
15766 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15767 request->ie_len);
15768 if (pP2pIe != NULL)
15769 {
15770#ifdef WLAN_FEATURE_P2P_DEBUG
15771 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15772 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15773 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015774 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015775 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15776 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15777 "Go nego completed to Connection is started");
15778 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15779 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015780 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015781 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15782 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015783 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015784 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15785 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15786 "Disconnected state to Connection is started");
15787 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15788 "for 4way Handshake");
15789 }
15790#endif
15791
15792 /* no_cck will be set during p2p find to disable 11b rates */
15793 if(TRUE == request->no_cck)
15794 {
15795 hddLog(VOS_TRACE_LEVEL_INFO,
15796 "%s: This is a P2P Search", __func__);
15797 scanRequest.p2pSearch = 1;
15798
15799 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015800 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015801 /* set requestType to P2P Discovery */
15802 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15803 }
15804
15805 /*
15806 Skip Dfs Channel in case of P2P Search
15807 if it is set in ini file
15808 */
15809 if(cfg_param->skipDfsChnlInP2pSearch)
15810 {
15811 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015812 }
15813 else
15814 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015815 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015816 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015817
Agarwal Ashish4f616132013-12-30 23:32:50 +053015818 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015819 }
15820 }
15821
15822 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15823
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015824#ifdef FEATURE_WLAN_TDLS
15825 /* if tdls disagree scan right now, return immediately.
15826 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15827 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15828 */
15829 status = wlan_hdd_tdls_scan_callback (pAdapter,
15830 wiphy,
15831#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15832 dev,
15833#endif
15834 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015835 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015836 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015837 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015838 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15839 "scan rejected %d", __func__, status);
15840 else
15841 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15842 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015843 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015844 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015845 }
15846#endif
15847
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015848 /* acquire the wakelock to avoid the apps suspend during the scan. To
15849 * address the following issues.
15850 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15851 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15852 * for long time, this result in apps running at full power for long time.
15853 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15854 * be stuck in full power because of resume BMPS
15855 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015856 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015857
Nirav Shah20ac06f2013-12-12 18:14:06 +053015858 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15859 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015860 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15861 scanRequest.requestType, scanRequest.scanType,
15862 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015863 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15864
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015865 ret = hdd_spoof_scan(wiphy, pAdapter, request, is_p2p_scan, &scanRequest);
15866 if(ret) {
15867 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
15868 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015869#ifdef FEATURE_WLAN_TDLS
15870 wlan_hdd_tdls_scan_done_callback(pAdapter);
15871#endif
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015872 goto free_mem;
Siddharth Bhal76972212014-10-15 16:22:51 +053015873 }
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015874
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015875 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015876 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015877 pAdapter->sessionId, &scanRequest, &scanId,
15878 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015879
Jeff Johnson295189b2012-06-20 16:38:30 -070015880 if (eHAL_STATUS_SUCCESS != status)
15881 {
15882 hddLog(VOS_TRACE_LEVEL_ERROR,
15883 "%s: sme_ScanRequest returned error %d", __func__, status);
15884 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015885 if(eHAL_STATUS_RESOURCES == status)
15886 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015887 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15888 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015889 status = -EBUSY;
15890 } else {
15891 status = -EIO;
15892 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015893 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015894
15895#ifdef FEATURE_WLAN_TDLS
15896 wlan_hdd_tdls_scan_done_callback(pAdapter);
15897#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015898 goto free_mem;
15899 }
15900
15901 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015902 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015903 pAdapter->request = request;
15904 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015905 pScanInfo->no_cck = request->no_cck;
15906 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15907 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15908 pHddCtx->scan_info.last_scan_channelList[i] =
15909 request->channels[i]->hw_value;
15910 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015911
15912 complete(&pScanInfo->scan_req_completion_event);
15913
15914free_mem:
15915 if( scanRequest.SSIDs.SSIDList )
15916 {
15917 vos_mem_free(scanRequest.SSIDs.SSIDList);
15918 }
15919
15920 if( channelList )
15921 vos_mem_free( channelList );
15922
15923 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015924 return status;
15925}
15926
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015927int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15928#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15929 struct net_device *dev,
15930#endif
15931 struct cfg80211_scan_request *request)
15932{
15933 int ret;
15934
15935 vos_ssr_protect(__func__);
15936 ret = __wlan_hdd_cfg80211_scan(wiphy,
15937#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15938 dev,
15939#endif
15940 request);
15941 vos_ssr_unprotect(__func__);
15942
15943 return ret;
15944}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015945
15946void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15947{
15948 v_U8_t iniDot11Mode =
15949 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15950 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15951
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015952 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15953 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015954 switch ( iniDot11Mode )
15955 {
15956 case eHDD_DOT11_MODE_AUTO:
15957 case eHDD_DOT11_MODE_11ac:
15958 case eHDD_DOT11_MODE_11ac_ONLY:
15959#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015960 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15961 sme_IsFeatureSupportedByFW(DOT11AC) )
15962 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15963 else
15964 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015965#else
15966 hddDot11Mode = eHDD_DOT11_MODE_11n;
15967#endif
15968 break;
15969 case eHDD_DOT11_MODE_11n:
15970 case eHDD_DOT11_MODE_11n_ONLY:
15971 hddDot11Mode = eHDD_DOT11_MODE_11n;
15972 break;
15973 default:
15974 hddDot11Mode = iniDot11Mode;
15975 break;
15976 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015977#ifdef WLAN_FEATURE_AP_HT40_24G
15978 if (operationChannel > SIR_11B_CHANNEL_END)
15979#endif
15980 {
15981 /* This call decides required channel bonding mode */
15982 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015983 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015984 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015985 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015986}
15987
Jeff Johnson295189b2012-06-20 16:38:30 -070015988/*
15989 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015990 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015991 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015992int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015993 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15994 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015995{
15996 int status = 0;
15997 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015998 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015999 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016000 v_U32_t roamId;
16001 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070016002 eCsrAuthType RSNAuthType;
16003
16004 ENTER();
16005
16006 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080016007 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016008 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080016009
16010 status = wlan_hdd_validate_context(pHddCtx);
16011 if (status)
16012 {
Yue Mae36e3552014-03-05 17:06:20 -080016013 return status;
16014 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016015
Jeff Johnson295189b2012-06-20 16:38:30 -070016016 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
16017 {
16018 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
16019 return -EINVAL;
16020 }
16021
Nitesh Shah9b066282017-06-06 18:05:52 +053016022
Jeff Johnson295189b2012-06-20 16:38:30 -070016023 pRoamProfile = &pWextState->roamProfile;
16024
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016025 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070016026 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016027 hdd_station_ctx_t *pHddStaCtx;
16028 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053016029 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016030
Siddharth Bhalda0d1622015-04-24 15:47:49 +053016031 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
16032
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016033 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070016034 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
16035 {
16036 /*QoS not enabled in cfg file*/
16037 pRoamProfile->uapsd_mask = 0;
16038 }
16039 else
16040 {
16041 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016042 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070016043 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
16044 }
16045
16046 pRoamProfile->SSIDs.numOfSSIDs = 1;
16047 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
16048 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016049 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070016050 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
16051 ssid, ssid_len);
16052
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016053 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
16054 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
16055
Jeff Johnson295189b2012-06-20 16:38:30 -070016056 if (bssid)
16057 {
16058 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016059 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070016060 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016061 /* Save BSSID in seperate variable as well, as RoamProfile
16062 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070016063 case of join failure we should send valid BSSID to supplicant
16064 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016065 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070016066 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016067
Jeff Johnson295189b2012-06-20 16:38:30 -070016068 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016069 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070016070 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016071 /* Store bssid_hint to use in the scan filter. */
16072 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
16073 WNI_CFG_BSSID_LEN);
16074 /*
16075 * Save BSSID in seperate variable as well, as RoamProfile
16076 * BSSID is getting zeroed out in the association process. And in
16077 * case of join failure we should send valid BSSID to supplicant
16078 */
16079 vos_mem_copy(pWextState->req_bssId, bssid_hint,
16080 WNI_CFG_BSSID_LEN);
16081 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
16082 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070016083 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016084
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016085
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016086 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
16087 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016088 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
16089 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016090 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016091 /*set gen ie*/
16092 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
16093 /*set auth*/
16094 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
16095 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016096#ifdef FEATURE_WLAN_WAPI
16097 if (pAdapter->wapi_info.nWapiMode)
16098 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016099 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016100 switch (pAdapter->wapi_info.wapiAuthMode)
16101 {
16102 case WAPI_AUTH_MODE_PSK:
16103 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016104 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 pAdapter->wapi_info.wapiAuthMode);
16106 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
16107 break;
16108 }
16109 case WAPI_AUTH_MODE_CERT:
16110 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016111 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016112 pAdapter->wapi_info.wapiAuthMode);
16113 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
16114 break;
16115 }
16116 } // End of switch
16117 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
16118 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
16119 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016120 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016121 pRoamProfile->AuthType.numEntries = 1;
16122 pRoamProfile->EncryptionType.numEntries = 1;
16123 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
16124 pRoamProfile->mcEncryptionType.numEntries = 1;
16125 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
16126 }
16127 }
16128#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016129#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016130 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016131 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
16132 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
16133 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016134 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
16135 sizeof (tSirGtkOffloadParams));
16136 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016137 }
16138#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016139 pRoamProfile->csrPersona = pAdapter->device_mode;
16140
Jeff Johnson32d95a32012-09-10 13:15:23 -070016141 if( operatingChannel )
16142 {
16143 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
16144 pRoamProfile->ChannelInfo.numOfChannels = 1;
16145 }
Chet Lanctot186b5732013-03-18 10:26:30 -070016146 else
16147 {
16148 pRoamProfile->ChannelInfo.ChannelList = NULL;
16149 pRoamProfile->ChannelInfo.numOfChannels = 0;
16150 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016151 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
16152 {
16153 hdd_select_cbmode(pAdapter,operatingChannel);
16154 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016155
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016156 /*
16157 * Change conn_state to connecting before sme_RoamConnect(),
16158 * because sme_RoamConnect() has a direct path to call
16159 * hdd_smeRoamCallback(), which will change the conn_state
16160 * If direct path, conn_state will be accordingly changed
16161 * to NotConnected or Associated by either
16162 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
16163 * in sme_RoamCallback()
16164 * if sme_RomConnect is to be queued,
16165 * Connecting state will remain until it is completed.
16166 * If connection state is not changed,
16167 * connection state will remain in eConnectionState_NotConnected state.
16168 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
16169 * if conn state is eConnectionState_NotConnected.
16170 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
16171 * informed of connect result indication which is an issue.
16172 */
16173
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016174 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16175 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053016176 {
16177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016178 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016179 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
16180 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016181 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
16182 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053016183 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016184
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016185 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070016186 pAdapter->sessionId, pRoamProfile, &roamId);
16187
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016188 if ((eHAL_STATUS_SUCCESS != status) &&
16189 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16190 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016191
16192 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016193 hddLog(VOS_TRACE_LEVEL_ERROR,
16194 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
16195 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016196 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016197 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016198 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016199 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016200
16201 pRoamProfile->ChannelInfo.ChannelList = NULL;
16202 pRoamProfile->ChannelInfo.numOfChannels = 0;
16203
Jeff Johnson295189b2012-06-20 16:38:30 -070016204 }
16205 else
16206 {
16207 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16208 return -EINVAL;
16209 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016210 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016211 return status;
16212}
16213
16214/*
16215 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16216 * This function is used to set the authentication type (OPEN/SHARED).
16217 *
16218 */
16219static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16220 enum nl80211_auth_type auth_type)
16221{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016222 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016223 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16224
16225 ENTER();
16226
16227 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016228 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016229 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016230 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016231 hddLog(VOS_TRACE_LEVEL_INFO,
16232 "%s: set authentication type to AUTOSWITCH", __func__);
16233 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16234 break;
16235
16236 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016237#ifdef WLAN_FEATURE_VOWIFI_11R
16238 case NL80211_AUTHTYPE_FT:
16239#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016240 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016241 "%s: set authentication type to OPEN", __func__);
16242 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16243 break;
16244
16245 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016246 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016247 "%s: set authentication type to SHARED", __func__);
16248 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16249 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016250#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016251 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016252 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016253 "%s: set authentication type to CCKM WPA", __func__);
16254 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16255 break;
16256#endif
Abhinav Kumar4d44f632019-08-02 13:55:54 +053016257 case NL80211_AUTHTYPE_SAE:
16258 hddLog(LOG1, "set authentication type to SAE");
16259 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SAE;
16260 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016261
16262 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016263 hddLog(VOS_TRACE_LEVEL_ERROR,
16264 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016265 auth_type);
16266 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16267 return -EINVAL;
16268 }
16269
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016270 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016271 pHddStaCtx->conn_info.authType;
16272 return 0;
16273}
16274
16275/*
16276 * FUNCTION: wlan_hdd_set_akm_suite
16277 * This function is used to set the key mgmt type(PSK/8021x).
16278 *
16279 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016280static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016281 u32 key_mgmt
16282 )
16283{
16284 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16285 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016286 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016287#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016288#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016289#endif
16290#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016291#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016292#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016293 /*set key mgmt type*/
16294 switch(key_mgmt)
16295 {
16296 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016297 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016298#ifdef WLAN_FEATURE_VOWIFI_11R
16299 case WLAN_AKM_SUITE_FT_PSK:
16300#endif
16301 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016302 __func__);
16303 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16304 break;
16305
16306 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016307 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016308#ifdef WLAN_FEATURE_VOWIFI_11R
16309 case WLAN_AKM_SUITE_FT_8021X:
16310#endif
16311 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016312 __func__);
16313 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16314 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016315#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016316#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16317#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16318 case WLAN_AKM_SUITE_CCKM:
16319 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16320 __func__);
16321 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16322 break;
16323#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016324#ifndef WLAN_AKM_SUITE_OSEN
16325#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16326 case WLAN_AKM_SUITE_OSEN:
16327 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16328 __func__);
16329 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16330 break;
16331#endif
Abhinav Kumar4d44f632019-08-02 13:55:54 +053016332 case WLAN_AKM_SUITE_SAE:
16333 hddLog(LOG1, "setting key mgmt type to SAE");
16334 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16335 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016336
Abhinav Kumar487e49e2019-07-22 14:46:18 +053016337 case WLAN_AKM_SUITE_OWE_1:
16338 hddLog(LOG1, "setting key mgmt type to OWE");
16339 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16340 break;
16341
Jeff Johnson295189b2012-06-20 16:38:30 -070016342 default:
Abhinav Kumar487e49e2019-07-22 14:46:18 +053016343 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016344 __func__, key_mgmt);
16345 return -EINVAL;
16346
16347 }
16348 return 0;
16349}
16350
16351/*
16352 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016353 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016354 * (NONE/WEP40/WEP104/TKIP/CCMP).
16355 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016356static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16357 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016358 bool ucast
16359 )
16360{
16361 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016362 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016363 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16364
16365 ENTER();
16366
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016367 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016368 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016369 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016370 __func__, cipher);
16371 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16372 }
16373 else
16374 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016375
Jeff Johnson295189b2012-06-20 16:38:30 -070016376 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016377 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016378 {
16379 case IW_AUTH_CIPHER_NONE:
16380 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16381 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016382
Jeff Johnson295189b2012-06-20 16:38:30 -070016383 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016384 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016385 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016386
Jeff Johnson295189b2012-06-20 16:38:30 -070016387 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016388 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016389 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016390
Jeff Johnson295189b2012-06-20 16:38:30 -070016391 case WLAN_CIPHER_SUITE_TKIP:
16392 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16393 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016394
Jeff Johnson295189b2012-06-20 16:38:30 -070016395 case WLAN_CIPHER_SUITE_CCMP:
16396 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16397 break;
16398#ifdef FEATURE_WLAN_WAPI
16399 case WLAN_CIPHER_SUITE_SMS4:
16400 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16401 break;
16402#endif
16403
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016404#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016405 case WLAN_CIPHER_SUITE_KRK:
16406 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16407 break;
16408#endif
16409 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016410 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016411 __func__, cipher);
16412 return -EOPNOTSUPP;
16413 }
16414 }
16415
16416 if (ucast)
16417 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016418 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016419 __func__, encryptionType);
16420 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16421 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016422 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016423 encryptionType;
16424 }
16425 else
16426 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016427 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016428 __func__, encryptionType);
16429 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16430 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16431 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16432 }
16433
16434 return 0;
16435}
16436
16437
16438/*
16439 * FUNCTION: wlan_hdd_cfg80211_set_ie
16440 * This function is used to parse WPA/RSN IE's.
16441 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016442int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016443#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16444 const u8 *ie,
16445#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016446 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016447#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016448 size_t ie_len
16449 )
16450{
16451 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016452#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16453 const u8 *genie = ie;
16454#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016455 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016456#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016457 v_U16_t remLen = ie_len;
16458#ifdef FEATURE_WLAN_WAPI
16459 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16460 u16 *tmp;
16461 v_U16_t akmsuiteCount;
16462 int *akmlist;
16463#endif
16464 ENTER();
16465
16466 /* clear previous assocAddIE */
16467 pWextState->assocAddIE.length = 0;
16468 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016469 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016470
16471 while (remLen >= 2)
16472 {
16473 v_U16_t eLen = 0;
16474 v_U8_t elementId;
16475 elementId = *genie++;
16476 eLen = *genie++;
16477 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016478
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016479 /* Sanity check on eLen */
16480 if (eLen > remLen) {
16481 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16482 __func__, eLen, elementId);
16483 VOS_ASSERT(0);
16484 return -EINVAL;
16485 }
16486
Arif Hussain6d2a3322013-11-17 19:50:10 -080016487 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016488 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016489
16490 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016491 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016492 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016493 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 -070016494 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016495 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016496 "%s: Invalid WPA IE", __func__);
16497 return -EINVAL;
16498 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016499 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016500 {
16501 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016502 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016503 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016504
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016505 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016506 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016507 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16508 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016509 VOS_ASSERT(0);
16510 return -ENOMEM;
16511 }
16512 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16513 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16514 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016515
Jeff Johnson295189b2012-06-20 16:38:30 -070016516 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16517 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16518 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16519 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016520 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16521 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016522 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16523 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16524 __func__, eLen);
16525 VOS_ASSERT(0);
16526 return -EINVAL;
16527 }
16528
Jeff Johnson295189b2012-06-20 16:38:30 -070016529 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16530 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16531 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16532 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16533 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16534 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016535 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016536 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016537 {
16538 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016539 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016540 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016541
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016542 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016543 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016544 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16545 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016546 VOS_ASSERT(0);
16547 return -ENOMEM;
16548 }
16549 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16550 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16551 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016552
Jeff Johnson295189b2012-06-20 16:38:30 -070016553 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16554 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16555 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016556#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016557 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16558 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016559 /*Consider WFD IE, only for P2P Client */
16560 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16561 {
16562 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016563 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016564 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016565
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016566 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016567 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016568 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16569 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016570 VOS_ASSERT(0);
16571 return -ENOMEM;
16572 }
16573 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16574 // WPS IE + P2P IE + WFD IE
16575 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16576 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016577
Jeff Johnson295189b2012-06-20 16:38:30 -070016578 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16579 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16580 }
16581#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016582 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016583 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016584 HS20_OUI_TYPE_SIZE)) )
16585 {
16586 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016587 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016588 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016589
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016590 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016591 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016592 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16593 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016594 VOS_ASSERT(0);
16595 return -ENOMEM;
16596 }
16597 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16598 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016599
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016600 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16601 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16602 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016603 /* Appending OSEN Information Element in Assiciation Request */
16604 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16605 OSEN_OUI_TYPE_SIZE)) )
16606 {
16607 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16608 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16609 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016610
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016611 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016612 {
16613 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16614 "Need bigger buffer space");
16615 VOS_ASSERT(0);
16616 return -ENOMEM;
16617 }
16618 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16619 pWextState->assocAddIE.length += eLen + 2;
16620
16621 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16622 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16623 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16624 }
16625
Abhishek Singh4322e622015-06-10 15:42:54 +053016626 /* Update only for WPA IE */
16627 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16628 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016629
16630 /* populating as ADDIE in beacon frames */
16631 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016632 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016633 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16634 {
16635 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16636 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16637 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16638 {
16639 hddLog(LOGE,
16640 "Coldn't pass "
16641 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16642 }
16643 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16644 else
16645 hddLog(LOGE,
16646 "Could not pass on "
16647 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16648
16649 /* IBSS mode doesn't contain params->proberesp_ies still
16650 beaconIE's need to be populated in probe response frames */
16651 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16652 {
16653 u16 rem_probe_resp_ie_len = eLen + 2;
16654 u8 probe_rsp_ie_len[3] = {0};
16655 u8 counter = 0;
16656
16657 /* Check Probe Resp Length if it is greater then 255 then
16658 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16659 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16660 not able Store More then 255 bytes into One Variable */
16661
16662 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16663 {
16664 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16665 {
16666 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16667 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16668 }
16669 else
16670 {
16671 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16672 rem_probe_resp_ie_len = 0;
16673 }
16674 }
16675
16676 rem_probe_resp_ie_len = 0;
16677
16678 if (probe_rsp_ie_len[0] > 0)
16679 {
16680 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16681 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16682 (tANI_U8*)(genie - 2),
16683 probe_rsp_ie_len[0], NULL,
16684 eANI_BOOLEAN_FALSE)
16685 == eHAL_STATUS_FAILURE)
16686 {
16687 hddLog(LOGE,
16688 "Could not pass"
16689 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16690 }
16691 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16692 }
16693
16694 if (probe_rsp_ie_len[1] > 0)
16695 {
16696 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16697 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16698 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16699 probe_rsp_ie_len[1], NULL,
16700 eANI_BOOLEAN_FALSE)
16701 == eHAL_STATUS_FAILURE)
16702 {
16703 hddLog(LOGE,
16704 "Could not pass"
16705 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16706 }
16707 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16708 }
16709
16710 if (probe_rsp_ie_len[2] > 0)
16711 {
16712 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16713 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16714 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16715 probe_rsp_ie_len[2], NULL,
16716 eANI_BOOLEAN_FALSE)
16717 == eHAL_STATUS_FAILURE)
16718 {
16719 hddLog(LOGE,
16720 "Could not pass"
16721 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16722 }
16723 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16724 }
16725
16726 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16727 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16728 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16729 {
16730 hddLog(LOGE,
16731 "Could not pass"
16732 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16733 }
16734 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016735 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016736 break;
16737 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016738 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16739 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16740 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16741 VOS_ASSERT(0);
16742 return -EINVAL;
16743 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016744 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16745 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16746 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16747 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16748 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16749 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016750
Abhishek Singhb16f3562016-01-20 11:08:32 +053016751 /* Appending extended capabilities with Interworking or
16752 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016753 *
16754 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016755 * interworkingService or bsstransition bit is set to 1.
16756 * Driver is only interested in interworkingService and
16757 * bsstransition capability from supplicant.
16758 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016759 * required from supplicat, it needs to be handled while
16760 * sending Assoc Req in LIM.
16761 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016762 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016763 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016764 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016765 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016766 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016767
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016768 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016769 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016770 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16771 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016772 VOS_ASSERT(0);
16773 return -ENOMEM;
16774 }
16775 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16776 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016777
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016778 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16779 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16780 break;
16781 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016782#ifdef FEATURE_WLAN_WAPI
16783 case WLAN_EID_WAPI:
16784 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016785 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016786 pAdapter->wapi_info.nWapiMode);
16787 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016788 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016789 akmsuiteCount = WPA_GET_LE16(tmp);
16790 tmp = tmp + 1;
16791 akmlist = (int *)(tmp);
16792 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16793 {
16794 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16795 }
16796 else
16797 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016798 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016799 VOS_ASSERT(0);
16800 return -EINVAL;
16801 }
16802
16803 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16804 {
16805 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016806 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016807 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016808 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016809 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016810 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016811 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016812 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016813 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16814 }
16815 break;
16816#endif
Abhinav Kumar487e49e2019-07-22 14:46:18 +053016817 case SIR_MAC_REQUEST_EID_MAX:
16818 if (genie[0] == SIR_DH_PARAMETER_ELEMENT_EXT_EID)
16819 {
16820 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16821 if (SIR_MAC_MAX_ADD_IE_LENGTH <
16822 (pWextState->assocAddIE.length + eLen))
16823 {
16824 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16825 "Need bigger buffer space");
16826 VOS_ASSERT(0);
16827 return -ENOMEM;
16828 }
16829 hddLog(VOS_TRACE_LEVEL_INFO, "Set DH EXT IE(len %d)",
16830 eLen + 2);
16831 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen,
16832 genie - 2, eLen + 2);
16833 pWextState->assocAddIE.length += eLen + 2;
16834 pWextState->roamProfile.pAddIEAssoc =
16835 pWextState->assocAddIE.addIEdata;
16836 pWextState->roamProfile.nAddIEAssocLength =
16837 pWextState->assocAddIE.length;
16838 }else {
16839 hddLog(VOS_TRACE_LEVEL_FATAL, "UNKNOWN EID: %X", genie[0]);
16840 }
16841 break;
16842
Jeff Johnson295189b2012-06-20 16:38:30 -070016843 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016844 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016845 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016846 /* when Unknown IE is received we should break and continue
16847 * to the next IE in the buffer instead we were returning
16848 * so changing this to break */
16849 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016850 }
16851 genie += eLen;
16852 remLen -= eLen;
16853 }
16854 EXIT();
16855 return 0;
16856}
16857
16858/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016859 * FUNCTION: hdd_isWPAIEPresent
16860 * Parse the received IE to find the WPA IE
16861 *
16862 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016863static bool hdd_isWPAIEPresent(
16864#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16865 const u8 *ie,
16866#else
16867 u8 *ie,
16868#endif
16869 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016870{
16871 v_U8_t eLen = 0;
16872 v_U16_t remLen = ie_len;
16873 v_U8_t elementId = 0;
16874
16875 while (remLen >= 2)
16876 {
16877 elementId = *ie++;
16878 eLen = *ie++;
16879 remLen -= 2;
16880 if (eLen > remLen)
16881 {
16882 hddLog(VOS_TRACE_LEVEL_ERROR,
16883 "%s: IE length is wrong %d", __func__, eLen);
16884 return FALSE;
16885 }
16886 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16887 {
16888 /* OUI - 0x00 0X50 0XF2
16889 WPA Information Element - 0x01
16890 WPA version - 0x01*/
16891 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16892 return TRUE;
16893 }
16894 ie += eLen;
16895 remLen -= eLen;
16896 }
16897 return FALSE;
16898}
16899
16900/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016901 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016902 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016903 * parameters during connect operation.
16904 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016905int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016906 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016907 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016908{
16909 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016910 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016911 ENTER();
16912
16913 /*set wpa version*/
16914 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16915
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016916 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016917 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016918 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016919 {
16920 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16921 }
16922 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16923 {
16924 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16925 }
16926 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016927
16928 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016929 pWextState->wpaVersion);
16930
16931 /*set authentication type*/
16932 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16933
16934 if (0 > status)
16935 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016936 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016937 "%s: failed to set authentication type ", __func__);
16938 return status;
16939 }
16940
16941 /*set key mgmt type*/
16942 if (req->crypto.n_akm_suites)
16943 {
16944 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16945 if (0 > status)
16946 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016947 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016948 __func__);
16949 return status;
16950 }
16951 }
16952
16953 /*set pairwise cipher type*/
16954 if (req->crypto.n_ciphers_pairwise)
16955 {
16956 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16957 req->crypto.ciphers_pairwise[0], true);
16958 if (0 > status)
16959 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016960 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016961 "%s: failed to set unicast cipher type", __func__);
16962 return status;
16963 }
16964 }
16965 else
16966 {
16967 /*Reset previous cipher suite to none*/
16968 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16969 if (0 > status)
16970 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016971 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016972 "%s: failed to set unicast cipher type", __func__);
16973 return status;
16974 }
16975 }
16976
16977 /*set group cipher type*/
16978 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16979 false);
16980
16981 if (0 > status)
16982 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016983 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016984 __func__);
16985 return status;
16986 }
16987
Chet Lanctot186b5732013-03-18 10:26:30 -070016988#ifdef WLAN_FEATURE_11W
16989 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16990#endif
16991
Jeff Johnson295189b2012-06-20 16:38:30 -070016992 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16993 if (req->ie_len)
16994 {
16995 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16996 if ( 0 > status)
16997 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016998 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016999 __func__);
17000 return status;
17001 }
17002 }
17003
17004 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017005 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070017006 {
17007 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
17008 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
17009 )
17010 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017011 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070017012 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
17013 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017014 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017015 __func__);
17016 return -EOPNOTSUPP;
17017 }
17018 else
17019 {
17020 u8 key_len = req->key_len;
17021 u8 key_idx = req->key_idx;
17022
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017023 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070017024 && (CSR_MAX_NUM_KEY > key_idx)
17025 )
17026 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017027 hddLog(VOS_TRACE_LEVEL_INFO,
17028 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017029 __func__, key_idx, key_len);
17030 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017031 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070017032 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017033 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070017034 (u8)key_len;
17035 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
17036 }
17037 }
17038 }
17039 }
17040
17041 return status;
17042}
17043
17044/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017045 * FUNCTION: wlan_hdd_try_disconnect
17046 * This function is used to disconnect from previous
17047 * connection
17048 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053017049int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017050{
17051 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017052 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017053 hdd_station_ctx_t *pHddStaCtx;
17054 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053017055 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017056
Abhishek Singh19a7dd92015-12-30 16:31:51 +053017057 ret = wlan_hdd_validate_context(pHddCtx);
17058 if (0 != ret)
17059 {
17060 return ret;
17061 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017062 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17063
17064 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
17065
17066 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
17067 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053017068 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017069 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
17070 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053017071 /* Indicate disconnect to SME so that in-progress connection or preauth
17072 * can be aborted
17073 */
17074 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
17075 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053017076 spin_lock_bh(&pAdapter->lock_for_active_session);
17077 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
17078 {
17079 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
17080 }
17081 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053017082 hdd_connSetConnectionState(pHddStaCtx,
17083 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017084 /* Issue disconnect to CSR */
17085 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017086 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017087 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017088 eCSR_DISCONNECT_REASON_UNSPECIFIED);
17089 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
17090 hddLog(LOG1,
17091 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
17092 } else if ( 0 != status ) {
17093 hddLog(LOGE,
17094 FL("csrRoamDisconnect failure, returned %d"),
17095 (int)status );
17096 result = -EINVAL;
17097 goto disconnected;
17098 }
17099 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017100 &pAdapter->disconnect_comp_var,
17101 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017102 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
17103 hddLog(LOGE,
17104 "%s: Failed to disconnect, timed out", __func__);
17105 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017106 }
17107 }
17108 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
17109 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017110 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017111 &pAdapter->disconnect_comp_var,
17112 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017113 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017114 {
17115 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017116 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017117 }
17118 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017119disconnected:
17120 hddLog(LOG1,
17121 FL("Set HDD connState to eConnectionState_NotConnected"));
17122 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
17123 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017124}
17125
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017126/**
17127 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
17128 * @adapter: Pointer to the HDD adapter
17129 * @req: Pointer to the structure cfg_connect_params receieved from user space
17130 *
Abhinav Kumar42c34902018-09-27 19:00:35 +053017131 * This function will start reassociation if prev_bssid is set and bssid/
17132 * bssid_hint, channel/channel_hint parameters are present in connect request.
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017133 *
17134 * Return: success if reassociation is happening
17135 * Error code if reassociation is not permitted or not happening
17136 */
17137#ifdef CFG80211_CONNECT_PREV_BSSID
17138static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
17139 struct cfg80211_connect_params *req)
17140{
17141 int status = -EPERM;
Abhinav Kumar42c34902018-09-27 19:00:35 +053017142 const uint8_t *bssid = NULL;
17143 uint16_t channel = 0;
17144
17145 if (req->bssid)
17146 bssid = req->bssid;
17147 else if (req->bssid_hint)
17148 bssid = req->bssid_hint;
17149
17150 if (req->channel)
17151 channel = req->channel->hw_value;
17152 else if (req->channel_hint)
17153 channel = req->channel_hint->hw_value;
17154
17155 if (bssid && channel && req->prev_bssid) {
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017156 hddLog(VOS_TRACE_LEVEL_INFO,
17157 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
Abhinav Kumar42c34902018-09-27 19:00:35 +053017158 channel, MAC_ADDR_ARRAY(bssid));
17159 status = hdd_reassoc(adapter, bssid, channel,
17160 CONNECT_CMD_USERSPACE);
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017161 }
17162 return status;
17163}
17164#else
17165static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
17166 struct cfg80211_connect_params *req)
17167{
17168 return -EPERM;
17169}
17170#endif
17171
Abhishek Singhe3beee22017-07-31 15:35:40 +053017172/**
17173 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
17174 * connect in HT20 mode
17175 * @hdd_ctx: hdd context
17176 * @adapter: Pointer to the HDD adapter
17177 * @req: Pointer to the structure cfg_connect_params receieved from user space
17178 *
17179 * This function will check if supplicant has indicated to to connect in HT20
17180 * mode. this is currently applicable only for 2.4Ghz mode only.
17181 * if feature is enabled and supplicant indicate HT20 set
17182 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
17183 *
17184 * Return: void
17185 */
17186#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
17187static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17188 hdd_adapter_t *adapter,
17189 struct cfg80211_connect_params *req)
17190{
17191 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17192 tCsrRoamProfile *roam_profile;
17193
17194 roam_profile = &wext_state->roamProfile;
17195 roam_profile->force_24ghz_in_ht20 = false;
17196 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
17197 !(req->ht_capa.cap_info &
17198 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
17199 roam_profile->force_24ghz_in_ht20 = true;
17200
17201 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
17202 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
17203}
17204#else
17205static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17206 hdd_adapter_t *adapter,
17207 struct cfg80211_connect_params *req)
17208{
17209 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17210 tCsrRoamProfile *roam_profile;
17211
17212 roam_profile = &wext_state->roamProfile;
17213 roam_profile->force_24ghz_in_ht20 = false;
17214}
17215#endif
17216
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017217/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053017218 * FUNCTION: __wlan_hdd_cfg80211_connect
17219 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070017220 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017221static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017222 struct net_device *ndev,
17223 struct cfg80211_connect_params *req
17224 )
17225{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017226 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017227 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053017228#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
17229 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017230 const u8 *bssid_hint = req->bssid_hint;
17231#else
17232 const u8 *bssid_hint = NULL;
17233#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017234 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017235 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053017236 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017237
17238 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017239
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017240 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17241 TRACE_CODE_HDD_CFG80211_CONNECT,
17242 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017243 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017244 "%s: device_mode = %s (%d)", __func__,
17245 hdd_device_modetoString(pAdapter->device_mode),
17246 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017247
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017248 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017249 if (!pHddCtx)
17250 {
17251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17252 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017253 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017254 }
17255
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017256 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017257 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017258 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017259 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017260 }
17261
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017262 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17263 return -EINVAL;
17264
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017265 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17266 if (0 == status)
17267 return status;
17268
Agarwal Ashish51325b52014-06-16 16:50:49 +053017269
Jeff Johnson295189b2012-06-20 16:38:30 -070017270#ifdef WLAN_BTAMP_FEATURE
17271 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017272 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017273 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017274 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017275 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017276 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017277 }
17278#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017279
17280 //If Device Mode is Station Concurrent Sessions Exit BMps
17281 //P2P Mode will be taken care in Open/close adapter
17282 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017283 (vos_concurrent_open_sessions_running())) {
17284 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17285 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017286 }
17287
17288 /*Try disconnecting if already in connected state*/
17289 status = wlan_hdd_try_disconnect(pAdapter);
17290 if ( 0 > status)
17291 {
17292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17293 " connection"));
17294 return -EALREADY;
17295 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017296 /* Check for max concurrent connections after doing disconnect if any*/
17297 if (vos_max_concurrent_connections_reached()) {
17298 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17299 return -ECONNREFUSED;
17300 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017301
Jeff Johnson295189b2012-06-20 16:38:30 -070017302 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017303 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017304
17305 if ( 0 > status)
17306 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017307 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017308 __func__);
17309 return status;
17310 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017311
17312 if (pHddCtx->spoofMacAddr.isEnabled)
17313 {
17314 hddLog(VOS_TRACE_LEVEL_INFO,
17315 "%s: MAC Spoofing enabled ", __func__);
17316 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17317 * to fill TxBds for probe request during SSID scan which may happen
17318 * as part of connect command
17319 */
17320 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17321 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17322 if (status != VOS_STATUS_SUCCESS)
17323 return -ECONNREFUSED;
17324 }
17325
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017326 if (req->channel)
17327 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017328 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017329 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017330
17331 /* Abort if any scan is going on */
17332 status = wlan_hdd_scan_abort(pAdapter);
17333 if (0 != status)
17334 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17335
Abhishek Singhe3beee22017-07-31 15:35:40 +053017336 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17337
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017338 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17339 req->ssid_len, req->bssid,
17340 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017341
Sushant Kaushikd7083982015-03-18 14:33:24 +053017342 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017343 {
17344 //ReEnable BMPS if disabled
17345 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17346 (NULL != pHddCtx))
17347 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017348 if (pHddCtx->hdd_wlan_suspended)
17349 {
17350 hdd_set_pwrparams(pHddCtx);
17351 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017352 //ReEnable Bmps and Imps back
17353 hdd_enable_bmps_imps(pHddCtx);
17354 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017356 return status;
17357 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017358 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017359 EXIT();
17360 return status;
17361}
17362
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017363static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17364 struct net_device *ndev,
17365 struct cfg80211_connect_params *req)
17366{
17367 int ret;
17368 vos_ssr_protect(__func__);
17369 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17370 vos_ssr_unprotect(__func__);
17371
17372 return ret;
17373}
Jeff Johnson295189b2012-06-20 16:38:30 -070017374
17375/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017376 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017377 * This function is used to issue a disconnect request to SME
17378 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017379static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017380 struct net_device *dev,
17381 u16 reason
17382 )
17383{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017384 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017385 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017386 tCsrRoamProfile *pRoamProfile;
17387 hdd_station_ctx_t *pHddStaCtx;
17388 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017389#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017390 tANI_U8 staIdx;
17391#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017392
Jeff Johnson295189b2012-06-20 16:38:30 -070017393 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017394
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017395 if (!pAdapter) {
17396 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17397 return -EINVAL;
17398 }
17399
17400 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17401 if (!pHddStaCtx) {
17402 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17403 return -EINVAL;
17404 }
17405
17406 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17407 status = wlan_hdd_validate_context(pHddCtx);
17408 if (0 != status)
17409 {
17410 return status;
17411 }
17412
17413 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17414
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017415 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17416 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17417 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017418 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17419 __func__, hdd_device_modetoString(pAdapter->device_mode),
17420 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017421
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017422 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17423 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017424
Jeff Johnson295189b2012-06-20 16:38:30 -070017425 if (NULL != pRoamProfile)
17426 {
17427 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017428 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17429 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017430 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017431 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017432 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017433 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017434 switch(reason)
17435 {
17436 case WLAN_REASON_MIC_FAILURE:
17437 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17438 break;
17439
17440 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17441 case WLAN_REASON_DISASSOC_AP_BUSY:
17442 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17443 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17444 break;
17445
17446 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17447 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017448 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017449 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17450 break;
17451
Jeff Johnson295189b2012-06-20 16:38:30 -070017452 default:
17453 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17454 break;
17455 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017456 pScanInfo = &pHddCtx->scan_info;
17457 if (pScanInfo->mScanPending)
17458 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017459 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017460 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017461 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017462 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017463 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017464 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017465#ifdef FEATURE_WLAN_TDLS
17466 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017467 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017468 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017469 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17470 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017471 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017472 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017473 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017475 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017476 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017477 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017478 status = sme_DeleteTdlsPeerSta(
17479 WLAN_HDD_GET_HAL_CTX(pAdapter),
17480 pAdapter->sessionId,
17481 mac);
17482 if (status != eHAL_STATUS_SUCCESS) {
17483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17484 return -EPERM;
17485 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017486 }
17487 }
17488#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017489
17490 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17491 reasonCode,
17492 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017493 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17494 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017495 {
17496 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017497 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017498 __func__, (int)status );
17499 return -EINVAL;
17500 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017501 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017502 else
17503 {
17504 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17505 "called while in %d state", __func__,
17506 pHddStaCtx->conn_info.connState);
17507 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017508 }
17509 else
17510 {
17511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17512 }
17513
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017514 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017515 return status;
17516}
17517
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017518static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17519 struct net_device *dev,
17520 u16 reason
17521 )
17522{
17523 int ret;
17524 vos_ssr_protect(__func__);
17525 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17526 vos_ssr_unprotect(__func__);
17527
17528 return ret;
17529}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017530
Jeff Johnson295189b2012-06-20 16:38:30 -070017531/*
17532 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017533 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017534 * settings in IBSS mode.
17535 */
17536static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017537 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017538 struct cfg80211_ibss_params *params
17539 )
17540{
17541 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017542 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017543 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017544 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17545 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017546
Jeff Johnson295189b2012-06-20 16:38:30 -070017547 ENTER();
17548
17549 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017550 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017551
17552 if (params->ie_len && ( NULL != params->ie) )
17553 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017554 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17555 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017556 {
17557 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17558 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17559 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017560 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017561 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017562 tDot11fIEWPA dot11WPAIE;
17563 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017564 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017565
Wilson Yang00256342013-10-10 23:13:38 -070017566 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017567 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17568 params->ie_len, DOT11F_EID_WPA);
17569 if ( NULL != ie )
17570 {
17571 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Hanumanth Reddy Pothulad6d2d2c2018-06-27 12:28:12 +053017572
17573 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
17574 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
17575 hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
17576 return -EINVAL;
17577 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017578 // Unpack the WPA IE
17579 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017580 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017581 &ie[2+4],
17582 ie[1] - 4,
17583 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017584 if (DOT11F_FAILED(ret))
17585 {
17586 hddLog(LOGE,
17587 FL("unpack failed status:(0x%08x)"),
17588 ret);
17589 return -EINVAL;
17590 }
17591
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017592 /*Extract the multicast cipher, the encType for unicast
17593 cipher for wpa-none is none*/
17594 encryptionType =
17595 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17596 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017597 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017598
Jeff Johnson295189b2012-06-20 16:38:30 -070017599 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17600
17601 if (0 > status)
17602 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017604 __func__);
17605 return status;
17606 }
17607 }
17608
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017609 pWextState->roamProfile.AuthType.authType[0] =
17610 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017611 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017612 if (params->privacy)
17613 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017614 /* Security enabled IBSS, At this time there is no information available
17615 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017616 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017617 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017618 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017619 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017620 *enable privacy bit in beacons */
17621
17622 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17623 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017624 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17625 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017626 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17627 pWextState->roamProfile.EncryptionType.numEntries = 1;
17628 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017629 return status;
17630}
17631
17632/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017633 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017634 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017635 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017636static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017637 struct net_device *dev,
17638 struct cfg80211_ibss_params *params
17639 )
17640{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017641 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017642 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17643 tCsrRoamProfile *pRoamProfile;
17644 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017645 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17646 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017647 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017648
17649 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017650
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017651 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17652 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17653 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017654 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017655 "%s: device_mode = %s (%d)", __func__,
17656 hdd_device_modetoString(pAdapter->device_mode),
17657 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017658
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017659 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017660 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017661 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017662 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017663 }
17664
17665 if (NULL == pWextState)
17666 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017667 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017668 __func__);
17669 return -EIO;
17670 }
17671
Agarwal Ashish51325b52014-06-16 16:50:49 +053017672 if (vos_max_concurrent_connections_reached()) {
17673 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17674 return -ECONNREFUSED;
17675 }
17676
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017677 /*Try disconnecting if already in connected state*/
17678 status = wlan_hdd_try_disconnect(pAdapter);
17679 if ( 0 > status)
17680 {
17681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17682 " IBSS connection"));
17683 return -EALREADY;
17684 }
17685
Jeff Johnson295189b2012-06-20 16:38:30 -070017686 pRoamProfile = &pWextState->roamProfile;
17687
17688 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17689 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017690 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017691 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017692 return -EINVAL;
17693 }
17694
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017695 /* BSSID is provided by upper layers hence no need to AUTO generate */
17696 if (NULL != params->bssid) {
17697 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17698 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17699 hddLog (VOS_TRACE_LEVEL_ERROR,
17700 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17701 return -EIO;
17702 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017703 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017704 }
krunal sonie9002db2013-11-25 14:24:17 -080017705 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17706 {
17707 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17708 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17709 {
17710 hddLog (VOS_TRACE_LEVEL_ERROR,
17711 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17712 return -EIO;
17713 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017714
17715 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017716 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017717 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017718 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017719
Jeff Johnson295189b2012-06-20 16:38:30 -070017720 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017721 if (NULL !=
17722#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17723 params->chandef.chan)
17724#else
17725 params->channel)
17726#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017727 {
17728 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017729 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17730 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17731 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17732 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017733
17734 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017735 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017736 ieee80211_frequency_to_channel(
17737#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17738 params->chandef.chan->center_freq);
17739#else
17740 params->channel->center_freq);
17741#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017742
17743 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17744 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017745 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17747 __func__);
17748 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017749 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017750
17751 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017752 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017753 if (channelNum == validChan[indx])
17754 {
17755 break;
17756 }
17757 }
17758 if (indx >= numChans)
17759 {
17760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017761 __func__, channelNum);
17762 return -EINVAL;
17763 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017764 /* Set the Operational Channel */
17765 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17766 channelNum);
17767 pRoamProfile->ChannelInfo.numOfChannels = 1;
17768 pHddStaCtx->conn_info.operationChannel = channelNum;
17769 pRoamProfile->ChannelInfo.ChannelList =
17770 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017771 }
17772
17773 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017774 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017775 if (status < 0)
17776 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017778 __func__);
17779 return status;
17780 }
17781
17782 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017783 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017784 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017785 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017786
17787 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017788 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017789
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017790 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017791 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017792}
17793
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017794static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17795 struct net_device *dev,
17796 struct cfg80211_ibss_params *params
17797 )
17798{
17799 int ret = 0;
17800
17801 vos_ssr_protect(__func__);
17802 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17803 vos_ssr_unprotect(__func__);
17804
17805 return ret;
17806}
17807
Jeff Johnson295189b2012-06-20 16:38:30 -070017808/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017809 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017810 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017811 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017812static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017813 struct net_device *dev
17814 )
17815{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017816 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017817 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17818 tCsrRoamProfile *pRoamProfile;
17819 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017820 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017821 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017822#ifdef WLAN_FEATURE_RMC
17823 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17824#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017825
17826 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017827
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017828 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17829 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17830 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017831 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017832 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017833 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017834 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017835 }
17836
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017837 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17838 hdd_device_modetoString(pAdapter->device_mode),
17839 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017840 if (NULL == pWextState)
17841 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017842 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017843 __func__);
17844 return -EIO;
17845 }
17846
17847 pRoamProfile = &pWextState->roamProfile;
17848
17849 /* Issue disconnect only if interface type is set to IBSS */
17850 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17851 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017852 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017853 __func__);
17854 return -EINVAL;
17855 }
17856
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017857#ifdef WLAN_FEATURE_RMC
17858 /* Clearing add IE of beacon */
17859 if (ccmCfgSetStr(pHddCtx->hHal,
17860 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17861 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17862 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17863 {
17864 hddLog (VOS_TRACE_LEVEL_ERROR,
17865 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17866 return -EINVAL;
17867 }
17868 if (ccmCfgSetInt(pHddCtx->hHal,
17869 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17870 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17871 {
17872 hddLog (VOS_TRACE_LEVEL_ERROR,
17873 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17874 __func__);
17875 return -EINVAL;
17876 }
17877
17878 // Reset WNI_CFG_PROBE_RSP Flags
17879 wlan_hdd_reset_prob_rspies(pAdapter);
17880
17881 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17882 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17883 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17884 {
17885 hddLog (VOS_TRACE_LEVEL_ERROR,
17886 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17887 __func__);
17888 return -EINVAL;
17889 }
17890#endif
17891
Jeff Johnson295189b2012-06-20 16:38:30 -070017892 /* Issue Disconnect request */
17893 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017894 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17895 pAdapter->sessionId,
17896 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17897 if (!HAL_STATUS_SUCCESS(hal_status)) {
17898 hddLog(LOGE,
17899 FL("sme_RoamDisconnect failed hal_status(%d)"),
17900 hal_status);
17901 return -EAGAIN;
17902 }
17903 status = wait_for_completion_timeout(
17904 &pAdapter->disconnect_comp_var,
17905 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17906 if (!status) {
17907 hddLog(LOGE,
17908 FL("wait on disconnect_comp_var failed"));
17909 return -ETIMEDOUT;
17910 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017911
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017912 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017913 return 0;
17914}
17915
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017916static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17917 struct net_device *dev
17918 )
17919{
17920 int ret = 0;
17921
17922 vos_ssr_protect(__func__);
17923 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17924 vos_ssr_unprotect(__func__);
17925
17926 return ret;
17927}
17928
Jeff Johnson295189b2012-06-20 16:38:30 -070017929/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017930 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017931 * This function is used to set the phy parameters
17932 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17933 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017934static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017935 u32 changed)
17936{
17937 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17938 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017939 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017940
17941 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017942
17943 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017944 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17945 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017946
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017947 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017948 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017949 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017950 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017951 }
17952
Jeff Johnson295189b2012-06-20 16:38:30 -070017953 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17954 {
17955 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17956 WNI_CFG_RTS_THRESHOLD_STAMAX :
17957 wiphy->rts_threshold;
17958
17959 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017960 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017961 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017962 hddLog(VOS_TRACE_LEVEL_ERROR,
17963 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017964 __func__, rts_threshold);
17965 return -EINVAL;
17966 }
17967
17968 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17969 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017970 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017971 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017972 hddLog(VOS_TRACE_LEVEL_ERROR,
17973 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017974 __func__, rts_threshold);
17975 return -EIO;
17976 }
17977
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017978 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017979 rts_threshold);
17980 }
17981
17982 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17983 {
17984 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17985 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17986 wiphy->frag_threshold;
17987
17988 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017989 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017990 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017991 hddLog(VOS_TRACE_LEVEL_ERROR,
17992 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017993 frag_threshold);
17994 return -EINVAL;
17995 }
17996
17997 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17998 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017999 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018000 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018001 hddLog(VOS_TRACE_LEVEL_ERROR,
18002 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018003 __func__, frag_threshold);
18004 return -EIO;
18005 }
18006
18007 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
18008 frag_threshold);
18009 }
18010
18011 if ((changed & WIPHY_PARAM_RETRY_SHORT)
18012 || (changed & WIPHY_PARAM_RETRY_LONG))
18013 {
18014 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
18015 wiphy->retry_short :
18016 wiphy->retry_long;
18017
18018 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
18019 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
18020 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018021 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018022 __func__, retry_value);
18023 return -EINVAL;
18024 }
18025
18026 if (changed & WIPHY_PARAM_RETRY_SHORT)
18027 {
18028 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
18029 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018030 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018031 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018032 hddLog(VOS_TRACE_LEVEL_ERROR,
18033 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018034 __func__, retry_value);
18035 return -EIO;
18036 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018037 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018038 __func__, retry_value);
18039 }
18040 else if (changed & WIPHY_PARAM_RETRY_SHORT)
18041 {
18042 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
18043 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018044 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018045 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018046 hddLog(VOS_TRACE_LEVEL_ERROR,
18047 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018048 __func__, retry_value);
18049 return -EIO;
18050 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018051 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018052 __func__, retry_value);
18053 }
18054 }
18055
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018056 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018057 return 0;
18058}
18059
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018060static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
18061 u32 changed)
18062{
18063 int ret;
18064
18065 vos_ssr_protect(__func__);
18066 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
18067 vos_ssr_unprotect(__func__);
18068
18069 return ret;
18070}
18071
Jeff Johnson295189b2012-06-20 16:38:30 -070018072/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018073 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070018074 * This function is used to set the txpower
18075 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018076static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070018077#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18078 struct wireless_dev *wdev,
18079#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018080#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018081 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070018082#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018083 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070018084#endif
18085 int dbm)
18086{
18087 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018088 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070018089 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
18090 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018091 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018092
18093 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018094
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018095 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18096 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
18097 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018098 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018099 if (0 != status)
18100 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018101 return status;
18102 }
18103
18104 hHal = pHddCtx->hHal;
18105
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018106 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
18107 dbm, ccmCfgSetCallback,
18108 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018109 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018110 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018111 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
18112 return -EIO;
18113 }
18114
18115 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
18116 dbm);
18117
18118 switch(type)
18119 {
18120 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
18121 /* Fall through */
18122 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
18123 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
18124 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018125 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
18126 __func__);
18127 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070018128 }
18129 break;
18130 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070018132 __func__);
18133 return -EOPNOTSUPP;
18134 break;
18135 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018136 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
18137 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070018138 return -EIO;
18139 }
18140
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018141 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018142 return 0;
18143}
18144
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018145static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
18146#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18147 struct wireless_dev *wdev,
18148#endif
18149#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
18150 enum tx_power_setting type,
18151#else
18152 enum nl80211_tx_power_setting type,
18153#endif
18154 int dbm)
18155{
18156 int ret;
18157 vos_ssr_protect(__func__);
18158 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
18159#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18160 wdev,
18161#endif
18162#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
18163 type,
18164#else
18165 type,
18166#endif
18167 dbm);
18168 vos_ssr_unprotect(__func__);
18169
18170 return ret;
18171}
18172
Jeff Johnson295189b2012-06-20 16:38:30 -070018173/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018174 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070018175 * This function is used to read the txpower
18176 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018177static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070018178#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18179 struct wireless_dev *wdev,
18180#endif
18181 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070018182{
18183
18184 hdd_adapter_t *pAdapter;
18185 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018186 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018187
Jeff Johnsone7245742012-09-05 17:12:55 -070018188 ENTER();
18189
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018190 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018191 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018192 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018193 *dbm = 0;
18194 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018195 }
18196
Jeff Johnson295189b2012-06-20 16:38:30 -070018197 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
18198 if (NULL == pAdapter)
18199 {
18200 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
18201 return -ENOENT;
18202 }
18203
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018204 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18205 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
18206 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070018207 wlan_hdd_get_classAstats(pAdapter);
18208 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
18209
Jeff Johnsone7245742012-09-05 17:12:55 -070018210 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018211 return 0;
18212}
18213
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018214static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
18215#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18216 struct wireless_dev *wdev,
18217#endif
18218 int *dbm)
18219{
18220 int ret;
18221
18222 vos_ssr_protect(__func__);
18223 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
18224#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18225 wdev,
18226#endif
18227 dbm);
18228 vos_ssr_unprotect(__func__);
18229
18230 return ret;
18231}
18232
Dustin Brown8c1d4092017-07-28 18:08:01 +053018233/*
18234 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
18235 * @stats: summary stats to use as a source
18236 * @info: kernel station_info struct to use as a destination
18237 *
18238 * Return: None
18239 */
18240static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
18241 struct station_info *info)
18242{
18243 int i;
18244
18245 info->rx_packets = stats->rx_frm_cnt;
18246 info->tx_packets = 0;
18247 info->tx_retries = 0;
18248 info->tx_failed = 0;
18249
18250 for (i = 0; i < 4; ++i) {
18251 info->tx_packets += stats->tx_frm_cnt[i];
18252 info->tx_retries += stats->multiple_retry_cnt[i];
18253 info->tx_failed += stats->fail_cnt[i];
18254 }
18255
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018256#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18257 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018258 info->filled |= STATION_INFO_TX_PACKETS |
18259 STATION_INFO_TX_RETRIES |
18260 STATION_INFO_TX_FAILED |
18261 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018262#else
18263 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18264 BIT(NL80211_STA_INFO_TX_RETRIES) |
18265 BIT(NL80211_STA_INFO_TX_FAILED) |
18266 BIT(NL80211_STA_INFO_RX_PACKETS);
18267#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018268}
18269
18270/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018271 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18272 * @adapter: sap adapter pointer
18273 * @staid: station id of the client
18274 * @rssi: rssi value to fill
18275 *
18276 * Return: None
18277 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018278void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018279wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18280{
18281 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18282
18283 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18284}
18285
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018286#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18287 !defined(WITH_BACKPORTS)
18288static inline void wlan_hdd_fill_station_info_signal(struct station_info
18289 *sinfo)
18290{
18291 sinfo->filled |= STATION_INFO_SIGNAL;
18292}
18293#else
18294static inline void wlan_hdd_fill_station_info_signal(struct station_info
18295 *sinfo)
18296{
18297 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18298}
18299#endif
18300
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018301/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018302 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18303 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018304 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018305 * @info: kernel station_info struct to populate
18306 *
18307 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18308 * support "station dump" and "station get" for SAP vdevs, even though they
18309 * aren't technically stations.
18310 *
18311 * Return: errno
18312 */
18313static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018314wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18315#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18316 const u8* mac,
18317#else
18318 u8* mac,
18319#endif
18320 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018321{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018322 v_MACADDR_t *peerMacAddr;
18323 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018324 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018325 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018326
18327 status = wlan_hdd_get_station_stats(adapter);
18328 if (!VOS_IS_STATUS_SUCCESS(status)) {
18329 hddLog(VOS_TRACE_LEVEL_ERROR,
18330 "Failed to get SAP stats; status:%d", status);
18331 return 0;
18332 }
18333
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018334 peerMacAddr = (v_MACADDR_t *)mac;
18335 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18336 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18337 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18338
18339 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18340 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018341 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018342 }
18343
Dustin Brown8c1d4092017-07-28 18:08:01 +053018344 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18345
18346 return 0;
18347}
18348
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018349static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018350#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18351 const u8* mac,
18352#else
18353 u8* mac,
18354#endif
18355 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018356{
18357 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18358 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
c_hpothu44ff4e02014-05-08 00:13:57 +053018359 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018360
18361 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18362 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018363
18364 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18365 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18366 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18367 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18368 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18369 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18370 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018371 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018372 tANI_U16 myRate;
18373 tANI_U16 currentRate = 0;
18374 tANI_U8 maxSpeedMCS = 0;
18375 tANI_U8 maxMCSIdx = 0;
18376 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018377 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018378 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018379 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018380
Leo Chang6f8870f2013-03-26 18:11:36 -070018381#ifdef WLAN_FEATURE_11AC
18382 tANI_U32 vht_mcs_map;
18383 eDataRate11ACMaxMcs vhtMaxMcs;
18384#endif /* WLAN_FEATURE_11AC */
18385
Jeff Johnsone7245742012-09-05 17:12:55 -070018386 ENTER();
18387
Dustin Brown8c1d4092017-07-28 18:08:01 +053018388 status = wlan_hdd_validate_context(pHddCtx);
18389 if (0 != status)
18390 {
18391 return status;
18392 }
18393
18394 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018395 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018396
Abhinav Kumarf70293b2019-09-19 12:33:43 +053018397 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -070018398 {
Abhinav Kumarf70293b2019-09-19 12:33:43 +053018399 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018400 /*To keep GUI happy*/
18401 return 0;
18402 }
18403
Mukul Sharma811205f2014-07-09 21:07:30 +053018404 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18405 {
18406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18407 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018408 /* return a cached value */
18409 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018410 return 0;
18411 }
18412
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018413 wlan_hdd_get_station_stats(pAdapter);
18414 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018415
Kiet Lam3b17fc82013-09-27 05:24:08 +053018416 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018417 wlan_hdd_get_snr(pAdapter, &snr);
18418 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018419 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018420 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018421 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018422 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018423
c_hpothu09f19542014-05-30 21:53:31 +053018424 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018425 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18426 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018427 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018428 {
18429 rate_flags = pAdapter->maxRateFlags;
18430 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018431
Jeff Johnson295189b2012-06-20 16:38:30 -070018432 //convert to the UI units of 100kbps
18433 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18434
18435#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018436 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 -070018437 sinfo->signal,
18438 pCfg->reportMaxLinkSpeed,
18439 myRate,
18440 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018441 (int) pCfg->linkSpeedRssiMid,
18442 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018443 (int) rate_flags,
18444 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018445#endif //LINKSPEED_DEBUG_ENABLED
18446
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018447#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18448 /* assume basic BW. anything else will override this later */
18449 sinfo->txrate.bw = RATE_INFO_BW_20;
18450#endif
18451
Jeff Johnson295189b2012-06-20 16:38:30 -070018452 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18453 {
18454 // we do not want to necessarily report the current speed
18455 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18456 {
18457 // report the max possible speed
18458 rssidx = 0;
18459 }
18460 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18461 {
18462 // report the max possible speed with RSSI scaling
18463 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18464 {
18465 // report the max possible speed
18466 rssidx = 0;
18467 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018468 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018469 {
18470 // report middle speed
18471 rssidx = 1;
18472 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018473 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18474 {
18475 // report middle speed
18476 rssidx = 2;
18477 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018478 else
18479 {
18480 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018481 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018482 }
18483 }
18484 else
18485 {
18486 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18487 hddLog(VOS_TRACE_LEVEL_ERROR,
18488 "%s: Invalid value for reportMaxLinkSpeed: %u",
18489 __func__, pCfg->reportMaxLinkSpeed);
18490 rssidx = 0;
18491 }
18492
18493 maxRate = 0;
18494
18495 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018496 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18497 OperationalRates, &ORLeng))
18498 {
18499 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18500 /*To keep GUI happy*/
18501 return 0;
18502 }
18503
Jeff Johnson295189b2012-06-20 16:38:30 -070018504 for (i = 0; i < ORLeng; i++)
18505 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018506 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018507 {
18508 /* Validate Rate Set */
18509 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18510 {
18511 currentRate = supported_data_rate[j].supported_rate[rssidx];
18512 break;
18513 }
18514 }
18515 /* Update MAX rate */
18516 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18517 }
18518
18519 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018520 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18521 ExtendedRates, &ERLeng))
18522 {
18523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18524 /*To keep GUI happy*/
18525 return 0;
18526 }
18527
Jeff Johnson295189b2012-06-20 16:38:30 -070018528 for (i = 0; i < ERLeng; i++)
18529 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018530 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018531 {
18532 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18533 {
18534 currentRate = supported_data_rate[j].supported_rate[rssidx];
18535 break;
18536 }
18537 }
18538 /* Update MAX rate */
18539 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18540 }
c_hpothu79aab322014-07-14 21:11:01 +053018541
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018542 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018543 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018544 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018545 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018546 {
c_hpothu79aab322014-07-14 21:11:01 +053018547 if (rate_flags & eHAL_TX_RATE_VHT80)
18548 mode = 2;
18549 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18550 mode = 1;
18551 else
18552 mode = 0;
18553
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018554 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18555 MCSRates, &MCSLeng))
18556 {
18557 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18558 /*To keep GUI happy*/
18559 return 0;
18560 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018561 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018562#ifdef WLAN_FEATURE_11AC
18563 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018564 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018565 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018566 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018567 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018568 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018569 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018570 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018571 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018572 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018573 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018574 maxMCSIdx = 7;
18575 }
18576 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18577 {
18578 maxMCSIdx = 8;
18579 }
18580 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18581 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018582 //VHT20 is supporting 0~8
18583 if (rate_flags & eHAL_TX_RATE_VHT20)
18584 maxMCSIdx = 8;
18585 else
18586 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018587 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018588
c_hpothu79aab322014-07-14 21:11:01 +053018589 if (0 != rssidx)/*check for scaled */
18590 {
18591 //get middle rate MCS index if rssi=1/2
18592 for (i=0; i <= maxMCSIdx; i++)
18593 {
18594 if (sinfo->signal <= rssiMcsTbl[mode][i])
18595 {
18596 maxMCSIdx = i;
18597 break;
18598 }
18599 }
18600 }
18601
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018602 if (rate_flags & eHAL_TX_RATE_VHT80)
18603 {
18604 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18605 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18606 }
18607 else if (rate_flags & eHAL_TX_RATE_VHT40)
18608 {
18609 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18610 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18611 }
18612 else if (rate_flags & eHAL_TX_RATE_VHT20)
18613 {
18614 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18615 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18616 }
18617
Leo Chang6f8870f2013-03-26 18:11:36 -070018618 maxSpeedMCS = 1;
18619 if (currentRate > maxRate)
18620 {
18621 maxRate = currentRate;
18622 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018623
Leo Chang6f8870f2013-03-26 18:11:36 -070018624 }
18625 else
18626#endif /* WLAN_FEATURE_11AC */
18627 {
18628 if (rate_flags & eHAL_TX_RATE_HT40)
18629 {
18630 rateFlag |= 1;
18631 }
18632 if (rate_flags & eHAL_TX_RATE_SGI)
18633 {
18634 rateFlag |= 2;
18635 }
18636
Girish Gowli01abcee2014-07-31 20:18:55 +053018637 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018638 if (rssidx == 1 || rssidx == 2)
18639 {
18640 //get middle rate MCS index if rssi=1/2
18641 for (i=0; i <= 7; i++)
18642 {
18643 if (sinfo->signal <= rssiMcsTbl[mode][i])
18644 {
18645 temp = i+1;
18646 break;
18647 }
18648 }
18649 }
c_hpothu79aab322014-07-14 21:11:01 +053018650
18651 for (i = 0; i < MCSLeng; i++)
18652 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018653 for (j = 0; j < temp; j++)
18654 {
18655 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18656 {
18657 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018658 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018659 break;
18660 }
18661 }
18662 if ((j < temp) && (currentRate > maxRate))
18663 {
18664 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018665 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018666 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018667 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018668 }
18669 }
18670
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018671 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18672 {
18673 maxRate = myRate;
18674 maxSpeedMCS = 1;
18675 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18676 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018677 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018678 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018679 {
18680 maxRate = myRate;
18681 if (rate_flags & eHAL_TX_RATE_LEGACY)
18682 {
18683 maxSpeedMCS = 0;
18684 }
18685 else
18686 {
18687 maxSpeedMCS = 1;
18688 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18689 }
18690 }
18691
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018692 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018693 {
18694 sinfo->txrate.legacy = maxRate;
18695#ifdef LINKSPEED_DEBUG_ENABLED
18696 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18697#endif //LINKSPEED_DEBUG_ENABLED
18698 }
18699 else
18700 {
18701 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018702#ifdef WLAN_FEATURE_11AC
18703 sinfo->txrate.nss = 1;
18704 if (rate_flags & eHAL_TX_RATE_VHT80)
18705 {
18706 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018707#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18708 defined(WITH_BACKPORTS)
18709 sinfo->txrate.bw = RATE_INFO_BW_80;
18710#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018711 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018712#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018713 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018714 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018715 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018716 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018717#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18718 defined(WITH_BACKPORTS)
18719 sinfo->txrate.bw = RATE_INFO_BW_40;
18720#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018721 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018722#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018723 }
18724 else if (rate_flags & eHAL_TX_RATE_VHT20)
18725 {
18726 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18727 }
18728#endif /* WLAN_FEATURE_11AC */
18729 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18730 {
18731 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18732 if (rate_flags & eHAL_TX_RATE_HT40)
18733 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018734#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18735 defined(WITH_BACKPORTS)
18736 sinfo->txrate.bw = RATE_INFO_BW_40;
18737#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018738 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018739#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018740 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018741 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018742 if (rate_flags & eHAL_TX_RATE_SGI)
18743 {
18744 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18745 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018746
Jeff Johnson295189b2012-06-20 16:38:30 -070018747#ifdef LINKSPEED_DEBUG_ENABLED
18748 pr_info("Reporting MCS rate %d flags %x\n",
18749 sinfo->txrate.mcs,
18750 sinfo->txrate.flags );
18751#endif //LINKSPEED_DEBUG_ENABLED
18752 }
18753 }
18754 else
18755 {
18756 // report current rate instead of max rate
18757
18758 if (rate_flags & eHAL_TX_RATE_LEGACY)
18759 {
18760 //provide to the UI in units of 100kbps
18761 sinfo->txrate.legacy = myRate;
18762#ifdef LINKSPEED_DEBUG_ENABLED
18763 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18764#endif //LINKSPEED_DEBUG_ENABLED
18765 }
18766 else
18767 {
18768 //must be MCS
18769 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018770#ifdef WLAN_FEATURE_11AC
18771 sinfo->txrate.nss = 1;
18772 if (rate_flags & eHAL_TX_RATE_VHT80)
18773 {
18774 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18775 }
18776 else
18777#endif /* WLAN_FEATURE_11AC */
18778 {
18779 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18780 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018781 if (rate_flags & eHAL_TX_RATE_SGI)
18782 {
18783 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18784 }
18785 if (rate_flags & eHAL_TX_RATE_HT40)
18786 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018787#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18788 defined(WITH_BACKPORTS)
18789 sinfo->txrate.bw = RATE_INFO_BW_40;
18790#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018791 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018792#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018793 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018794#ifdef WLAN_FEATURE_11AC
18795 else if (rate_flags & eHAL_TX_RATE_VHT80)
18796 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018797#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18798 defined(WITH_BACKPORTS)
18799 sinfo->txrate.bw = RATE_INFO_BW_80;
18800#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018801 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018802#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018803 }
18804#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018805#ifdef LINKSPEED_DEBUG_ENABLED
18806 pr_info("Reporting actual MCS rate %d flags %x\n",
18807 sinfo->txrate.mcs,
18808 sinfo->txrate.flags );
18809#endif //LINKSPEED_DEBUG_ENABLED
18810 }
18811 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018812
18813#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18814 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018815 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018816#else
18817 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18818#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018819
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018820 sinfo->tx_packets =
18821 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18822 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18823 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18824 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18825
18826 sinfo->tx_retries =
18827 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18828 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18829 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18830 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18831
18832 sinfo->tx_failed =
18833 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18834 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18835 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18836 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18837
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018838#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18839 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018840 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018841 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018842 STATION_INFO_TX_PACKETS |
18843 STATION_INFO_TX_RETRIES |
18844 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018845#else
18846 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18847 BIT(NL80211_STA_INFO_TX_PACKETS) |
18848 BIT(NL80211_STA_INFO_TX_RETRIES) |
18849 BIT(NL80211_STA_INFO_TX_FAILED);
18850#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018851
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018852 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018853
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018854 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18855 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018856 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18857 &sinfo->txrate, sizeof(sinfo->txrate));
18858
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018859 if (rate_flags & eHAL_TX_RATE_LEGACY)
18860 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18861 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18862 sinfo->rx_packets);
18863 else
18864 hddLog(LOG1,
18865 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18866 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18867 sinfo->tx_packets, sinfo->rx_packets);
18868
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018869 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18870 TRACE_CODE_HDD_CFG80211_GET_STA,
18871 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018872 EXIT();
18873 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018874}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018875#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18876static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18877 const u8* mac, struct station_info *sinfo)
18878#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018879static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18880 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018881#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018882{
18883 int ret;
18884
18885 vos_ssr_protect(__func__);
18886 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18887 vos_ssr_unprotect(__func__);
18888
18889 return ret;
18890}
18891
18892static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018893 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018894{
18895 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018896 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018897 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018898 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018899
Jeff Johnsone7245742012-09-05 17:12:55 -070018900 ENTER();
18901
Jeff Johnson295189b2012-06-20 16:38:30 -070018902 if (NULL == pAdapter)
18903 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018905 return -ENODEV;
18906 }
18907
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018908 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18909 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18910 pAdapter->sessionId, timeout));
18911
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018912 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018913 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018914 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018915 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018916 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018917 }
18918
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018919 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18920 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18921 (pHddCtx->cfg_ini->fhostArpOffload) &&
18922 (eConnectionState_Associated ==
18923 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18924 {
Amar Singhald53568e2013-09-26 11:03:45 -070018925
18926 hddLog(VOS_TRACE_LEVEL_INFO,
18927 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018928 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018929 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18930 {
18931 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018932 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018933 __func__, vos_status);
18934 }
18935 }
18936
Jeff Johnson295189b2012-06-20 16:38:30 -070018937 /**The get power cmd from the supplicant gets updated by the nl only
18938 *on successful execution of the function call
18939 *we are oppositely mapped w.r.t mode in the driver
18940 **/
18941 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18942
18943 if (VOS_STATUS_E_FAILURE == vos_status)
18944 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18946 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018947 return -EINVAL;
18948 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018949 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018950 return 0;
18951}
18952
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018953static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18954 struct net_device *dev, bool mode, int timeout)
18955{
18956 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018957
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018958 vos_ssr_protect(__func__);
18959 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18960 vos_ssr_unprotect(__func__);
18961
18962 return ret;
18963}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018964
Jeff Johnson295189b2012-06-20 16:38:30 -070018965#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018966static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18967 struct net_device *netdev,
18968 u8 key_index)
18969{
18970 ENTER();
18971 return 0;
18972}
18973
Jeff Johnson295189b2012-06-20 16:38:30 -070018974static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018975 struct net_device *netdev,
18976 u8 key_index)
18977{
18978 int ret;
18979 vos_ssr_protect(__func__);
18980 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18981 vos_ssr_unprotect(__func__);
18982 return ret;
18983}
18984#endif //LINUX_VERSION_CODE
18985
18986#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18987static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18988 struct net_device *dev,
18989 struct ieee80211_txq_params *params)
18990{
18991 ENTER();
18992 return 0;
18993}
18994#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18995static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18996 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018997{
Jeff Johnsone7245742012-09-05 17:12:55 -070018998 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018999 return 0;
19000}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019001#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070019002
19003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
19004static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019005 struct net_device *dev,
19006 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070019007{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019008 int ret;
19009
19010 vos_ssr_protect(__func__);
19011 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
19012 vos_ssr_unprotect(__func__);
19013 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070019014}
19015#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19016static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
19017 struct ieee80211_txq_params *params)
19018{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019019 int ret;
19020
19021 vos_ssr_protect(__func__);
19022 ret = __wlan_hdd_set_txq_params(wiphy, params);
19023 vos_ssr_unprotect(__func__);
19024 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070019025}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019026#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019027
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019028static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019029 struct net_device *dev,
19030 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070019031{
19032 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019033 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019034 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019035 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019036 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019037 v_CONTEXT_t pVosContext = NULL;
19038 ptSapContext pSapCtx = NULL;
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019039 hdd_hostapd_state_t *hostap_state;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019040
Jeff Johnsone7245742012-09-05 17:12:55 -070019041 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019042
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019043 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070019044 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019045 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070019046 return -EINVAL;
19047 }
19048
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019049 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19050 TRACE_CODE_HDD_CFG80211_DEL_STA,
19051 pAdapter->sessionId, pAdapter->device_mode));
19052
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019053 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19054 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019055 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019056 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019057 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019058 }
19059
Jeff Johnson295189b2012-06-20 16:38:30 -070019060 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070019061 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070019062 )
19063 {
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019064 hostap_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019065 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
19066 pSapCtx = VOS_GET_SAP_CB(pVosContext);
19067 if(pSapCtx == NULL){
19068 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19069 FL("psapCtx is NULL"));
19070 return -ENOENT;
19071 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053019072 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
19073 {
19074 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
19075 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
19076 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
19077 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019078 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070019079 {
19080 v_U16_t i;
19081 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
19082 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019083 if ((pSapCtx->aStaInfo[i].isUsed) &&
19084 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070019085 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019086 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019087 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019088 ETHER_ADDR_LEN);
19089
Jeff Johnson295189b2012-06-20 16:38:30 -070019090 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080019091 "%s: Delete STA with MAC::"
19092 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019093 __func__,
19094 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019095 vos_event_reset(&hostap_state->sta_discon_event);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019096 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070019097 if (VOS_IS_STATUS_SUCCESS(vos_status))
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019098 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019099 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019100 vos_status =
19101 vos_wait_single_event(
19102 &hostap_state->sta_discon_event,
19103 WLAN_WAIT_TIME_DISCONNECT);
19104 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19105 hddLog(LOGE,"!!%s: ERROR: Deauth wait expired!!",
19106 __func__);
19107 }
Jeff Johnson295189b2012-06-20 16:38:30 -070019108 }
19109 }
19110 }
19111 else
19112 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019113
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019114 vos_status = hdd_softap_GetStaId(pAdapter,
19115 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019116 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19117 {
19118 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080019119 "%s: Skip this DEL STA as this is not used::"
19120 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019121 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019122 return -ENOENT;
19123 }
19124
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019125 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019126 {
19127 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080019128 "%s: Skip this DEL STA as deauth is in progress::"
19129 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019130 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019131 return -ENOENT;
19132 }
19133
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019134 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019135
Jeff Johnson295189b2012-06-20 16:38:30 -070019136 hddLog(VOS_TRACE_LEVEL_INFO,
19137 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080019138 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070019139 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019140 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019141
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019142 vos_event_reset(&hostap_state->sta_discon_event);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019143 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019144 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19145 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019146 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019147 hddLog(VOS_TRACE_LEVEL_INFO,
19148 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080019149 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019150 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019151 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019152 return -ENOENT;
19153 }
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019154 vos_status =
19155 vos_wait_single_event(&hostap_state->sta_discon_event,
19156 WLAN_WAIT_TIME_DISCONNECT);
19157 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19158 hddLog(LOGE,"!!%s: ERROR: Deauth wait expired!!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070019159 }
19160 }
19161
19162 EXIT();
19163
19164 return 0;
19165}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019166
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019167#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053019168int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019169 struct net_device *dev,
19170 struct station_del_parameters *param)
19171#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019172#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053019173int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019174 struct net_device *dev, const u8 *mac)
19175#else
Kapil Gupta137ef892016-12-13 19:38:00 +053019176int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019177 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019178#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019179#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019180{
19181 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019182 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070019183
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019184 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019185
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019186#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019187 if (NULL == param) {
19188 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019189 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019190 return -EINVAL;
19191 }
19192
19193 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
19194 param->subtype, &delStaParams);
19195
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019196#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053019197 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019198 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019199#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019200 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
19201
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019202 vos_ssr_unprotect(__func__);
19203
19204 return ret;
19205}
19206
19207static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019208 struct net_device *dev,
19209#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19210 const u8 *mac,
19211#else
19212 u8 *mac,
19213#endif
19214 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019215{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019216 hdd_adapter_t *pAdapter;
19217 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019218 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019219#ifdef FEATURE_WLAN_TDLS
19220 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019221
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019222 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019223
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019224 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19225 if (NULL == pAdapter)
19226 {
19227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19228 "%s: Adapter is NULL",__func__);
19229 return -EINVAL;
19230 }
19231 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19232 status = wlan_hdd_validate_context(pHddCtx);
19233 if (0 != status)
19234 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019235 return status;
19236 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019237
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019238 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19239 TRACE_CODE_HDD_CFG80211_ADD_STA,
19240 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019241 mask = params->sta_flags_mask;
19242
19243 set = params->sta_flags_set;
19244
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019246 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
19247 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019248
19249 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19250 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080019251 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019252 }
19253 }
19254#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019255 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019256 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070019257}
19258
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019259#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19260static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19261 struct net_device *dev, const u8 *mac,
19262 struct station_parameters *params)
19263#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019264static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19265 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019266#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019267{
19268 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019269
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019270 vos_ssr_protect(__func__);
19271 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19272 vos_ssr_unprotect(__func__);
19273
19274 return ret;
19275}
Abhinav Kumar8c122592019-08-07 15:43:20 +053019276
19277#if defined(WLAN_FEATURE_SAE) && \
19278 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
19279/*
19280 * wlan_hdd_is_pmksa_valid: API to validate pmksa
19281 * @pmksa: pointer to cfg80211_pmksa structure
19282 *
19283 * Return: True if valid else false
19284 */
19285static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
19286{
19287 if (pmksa->bssid){
19288 return true;
19289 }
19290 else
19291 {
19292 hddLog(LOGE, FL(" Either of bssid (%p) is NULL"), pmksa->bssid);
19293 return false;
19294 }
19295}
19296
19297/*
19298 * hdd_update_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
19299 * @pmk_cache: pmksa from supplicant
19300 * @pmk_cache: pmk needs to be updated
19301 *
19302 * Return: None
19303 */
19304static void hdd_update_pmksa_info(tPmkidCacheInfo *pmk_cache,
19305 struct cfg80211_pmksa *pmksa, bool is_delete)
19306{
19307 if (pmksa->bssid) {
19308 hddLog(VOS_TRACE_LEVEL_DEBUG,"set PMKSA for " MAC_ADDRESS_STR,
19309 MAC_ADDR_ARRAY(pmksa->bssid));
19310 vos_mem_copy(pmk_cache->BSSID,
19311 pmksa->bssid, VOS_MAC_ADDR_SIZE);
19312 }
19313
19314 if (is_delete)
19315 return;
19316
19317 vos_mem_copy(pmk_cache->PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
19318 if (pmksa->pmk_len && (pmksa->pmk_len <= CSR_RSN_MAX_PMK_LEN)) {
19319 vos_mem_copy(pmk_cache->pmk, pmksa->pmk, pmksa->pmk_len);
19320 pmk_cache->pmk_len = pmksa->pmk_len;
19321 } else
19322 hddLog(VOS_TRACE_LEVEL_INFO, "pmk len is %zu", pmksa->pmk_len);
19323}
19324#else
19325/*
19326 * wlan_hdd_is_pmksa_valid: API to validate pmksa
19327 * @pmksa: pointer to cfg80211_pmksa structure
19328 *
19329 * Return: True if valid else false
19330 */
19331static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
19332{
19333 if (!pmksa->bssid) {
19334 hddLog(LOGE,FL("both bssid is NULL %p"), pmksa->bssid);
19335 return false;
19336 }
19337 return true;
19338}
19339
19340/*
19341 * hdd_update_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
19342 * @pmk_cache: pmksa from supplicant
19343 * @pmk_cache: pmk needs to be updated
19344 *
19345 * Return: None
19346 */
19347static void hdd_update_pmksa_info(tPmkidCacheInfo *pmk_cache,
19348 struct cfg80211_pmksa *pmksa, bool is_delete)
19349{
19350 hddLog(VOS_TRACE_LEVEL_INFO,"set PMKSA for " MAC_ADDRESS_STR,
19351 MAC_ADDR_ARRAY(pmksa->bssid));
19352 vos_mem_copy(pmk_cache->BSSID,
19353 pmksa->bssid, VOS_MAC_ADDR_SIZE);
19354
19355 if (is_delete)
19356 return;
19357
19358 vos_mem_copy(pmk_cache->PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
19359}
19360#endif
19361
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019362#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019363
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019364static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019365 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019366{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019367 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19368 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019369 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019370 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019371 hdd_context_t *pHddCtx;
Abhinav Kumar8c122592019-08-07 15:43:20 +053019372 tPmkidCacheInfo pmk_cache;
Jeff Johnsone7245742012-09-05 17:12:55 -070019373
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019374 ENTER();
19375
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019376 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019377 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019378 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019379 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019380 return -EINVAL;
19381 }
19382
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019383 if (!pmksa) {
19384 hddLog(LOGE, FL("pmksa is NULL"));
19385 return -EINVAL;
19386 }
19387
Abhinav Kumar8c122592019-08-07 15:43:20 +053019388 if (!pmksa->pmkid) {
19389 hddLog(LOGE, FL("pmksa->pmkid(%p) is NULL"), pmksa->pmkid);
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019390 return -EINVAL;
19391 }
19392
Abhinav Kumar8c122592019-08-07 15:43:20 +053019393 if (!wlan_hdd_is_pmksa_valid(pmksa))
19394 return -EINVAL;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019395
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019396 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19397 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019398 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019399 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019400 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019401 }
19402
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019403 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019404 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19405
Abhinav Kumar8c122592019-08-07 15:43:20 +053019406 vos_mem_zero(&pmk_cache, sizeof(pmk_cache));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019407
Abhinav Kumar8c122592019-08-07 15:43:20 +053019408 hdd_update_pmksa_info(&pmk_cache, pmksa, false);
19409
19410
19411 /* Add to the PMKSA ID Cache in CSR
19412 * PMKSA cache will be having following
19413 * 1. pmkid id
19414 * 2. pmk 15733
19415 * 3. bssid or cache identifier
19416 */
19417 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
19418 &pmk_cache, 1, FALSE);
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019419
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019420 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19421 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19422 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019423
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019424 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019425 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019426}
19427
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019428static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19429 struct cfg80211_pmksa *pmksa)
19430{
19431 int ret;
19432
19433 vos_ssr_protect(__func__);
19434 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19435 vos_ssr_unprotect(__func__);
19436
19437 return ret;
19438}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019439
Wilson Yang6507c4e2013-10-01 20:11:19 -070019440
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019441static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019442 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019443{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019444 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19445 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019446 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019447 int status = 0;
Abhinav Kumar8c122592019-08-07 15:43:20 +053019448 tPmkidCacheInfo pmk_cache;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019449
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019450 ENTER();
19451
Wilson Yang6507c4e2013-10-01 20:11:19 -070019452 /* Validate pAdapter */
19453 if (NULL == pAdapter)
19454 {
19455 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19456 return -EINVAL;
19457 }
19458
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019459 if (!pmksa) {
19460 hddLog(LOGE, FL("pmksa is NULL"));
19461 return -EINVAL;
19462 }
19463
Abhinav Kumar8c122592019-08-07 15:43:20 +053019464 if (!wlan_hdd_is_pmksa_valid(pmksa))
19465 return -EINVAL;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019466
Kiet Lam98c46a12014-10-31 15:34:57 -070019467
Wilson Yang6507c4e2013-10-01 20:11:19 -070019468 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19469 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019470 if (0 != status)
19471 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019472 return status;
19473 }
19474
19475 /*Retrieve halHandle*/
19476 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19477
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019478 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19479 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19480 pAdapter->sessionId, 0));
Abhinav Kumar8c122592019-08-07 15:43:20 +053019481
19482 vos_mem_zero(&pmk_cache, sizeof(pmk_cache));
19483
19484 hdd_update_pmksa_info(&pmk_cache, pmksa, true);
19485
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019486 /* Delete the PMKID CSR cache */
19487 if (eHAL_STATUS_SUCCESS !=
19488 sme_RoamDelPMKIDfromCache(halHandle,
Abhinav Kumar8c122592019-08-07 15:43:20 +053019489 pAdapter->sessionId, &pmk_cache, FALSE)) {
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019490 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19491 MAC_ADDR_ARRAY(pmksa->bssid));
19492 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019493 }
19494
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019495 EXIT();
19496 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019497}
19498
Wilson Yang6507c4e2013-10-01 20:11:19 -070019499
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019500static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19501 struct cfg80211_pmksa *pmksa)
19502{
19503 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019504
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019505 vos_ssr_protect(__func__);
19506 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19507 vos_ssr_unprotect(__func__);
19508
19509 return ret;
19510
19511}
19512
19513static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019514{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019515 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19516 tHalHandle halHandle;
19517 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019518 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019519
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019520 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019521
19522 /* Validate pAdapter */
19523 if (NULL == pAdapter)
19524 {
19525 hddLog(VOS_TRACE_LEVEL_ERROR,
19526 "%s: Invalid Adapter" ,__func__);
19527 return -EINVAL;
19528 }
19529
19530 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19531 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019532 if (0 != status)
19533 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019534 return status;
19535 }
19536
19537 /*Retrieve halHandle*/
19538 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19539
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019540 /* Flush the PMKID cache in CSR */
19541 if (eHAL_STATUS_SUCCESS !=
19542 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19543 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19544 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019545 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019546 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019547 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019548}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019549
19550static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19551{
19552 int ret;
19553
19554 vos_ssr_protect(__func__);
19555 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19556 vos_ssr_unprotect(__func__);
19557
19558 return ret;
19559}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019560#endif
19561
Abhinav Kumar118efd02019-08-07 16:41:07 +053019562#if defined(WLAN_FEATURE_SAE) && \
19563 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
19564/**
19565 * __wlan_hdd_cfg80211_external_auth() - Handle external auth
19566 * @wiphy: Pointer to wireless phy
19567 * @dev: net device
19568 * @params: Pointer to external auth params
19569 *
19570 * Return: 0 on success, negative errno on failure
19571 */
19572static int
19573__wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev,
19574 struct cfg80211_external_auth_params *params)
19575{
19576 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19577 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19578 int ret;
19579
19580 if (hdd_get_conparam() == VOS_FTM_MODE) {
19581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Command not allowed in FTM mode"));
19582 return -EPERM;
19583 }
19584
19585 ret = wlan_hdd_validate_context(hdd_ctx);
19586 if (ret)
19587 return ret;
19588
19589 hddLog(VOS_TRACE_LEVEL_DEBUG, FL("external_auth status: %d"),
19590 params->status);
19591
19592 sme_handle_sae_msg(hdd_ctx->hHal, adapter->sessionId, params->status);
19593
19594 return ret;
19595}
19596
19597/**
19598 * wlan_hdd_cfg80211_external_auth() - Handle external auth
19599 * @wiphy: Pointer to wireless phy
19600 * @dev: net device
19601 * @params: Pointer to external auth params
19602 *
19603 * Return: 0 on success, negative errno on failure
19604 */
19605static int
19606wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
19607 struct net_device *dev,
19608 struct cfg80211_external_auth_params *params)
19609{
19610 int ret;
19611
19612 vos_ssr_protect(__func__);
19613 ret = __wlan_hdd_cfg80211_external_auth(wiphy, dev, params);
19614 vos_ssr_unprotect(__func__);
19615
19616 return ret;
19617}
19618#endif
19619
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019620#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019621static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19622 struct net_device *dev,
19623 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019624{
19625 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19626 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019627 hdd_context_t *pHddCtx;
19628 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019629
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019630 ENTER();
19631
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019632 if (NULL == pAdapter)
19633 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019634 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019635 return -ENODEV;
19636 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019637 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19638 ret = wlan_hdd_validate_context(pHddCtx);
19639 if (0 != ret)
19640 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019641 return ret;
19642 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019643 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019644 if (NULL == pHddStaCtx)
19645 {
19646 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19647 return -EINVAL;
19648 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019649
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019650 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19651 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19652 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019653 // Added for debug on reception of Re-assoc Req.
19654 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19655 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019656 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019657 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019658 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019659 }
19660
19661#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Abhinav Kumar36177e12018-10-30 11:55:48 +053019662 hddLog(LOG1, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019663 ftie->ie_len);
19664#endif
19665
19666 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019667 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19668 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019669 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019670
19671 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019672 return 0;
19673}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019674
19675static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19676 struct net_device *dev,
19677 struct cfg80211_update_ft_ies_params *ftie)
19678{
19679 int ret;
19680
19681 vos_ssr_protect(__func__);
19682 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19683 vos_ssr_unprotect(__func__);
19684
19685 return ret;
19686}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019687#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019688
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019689#ifdef FEATURE_WLAN_SCAN_PNO
19690
19691void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19692 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19693{
19694 int ret;
19695 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19696 hdd_context_t *pHddCtx;
19697
Nirav Shah80830bf2013-12-31 16:35:12 +053019698 ENTER();
19699
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019700 if (NULL == pAdapter)
19701 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019703 "%s: HDD adapter is Null", __func__);
19704 return ;
19705 }
19706
19707 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19708 if (NULL == pHddCtx)
19709 {
19710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19711 "%s: HDD context is Null!!!", __func__);
19712 return ;
19713 }
19714
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019715 spin_lock(&pHddCtx->schedScan_lock);
19716 if (TRUE == pHddCtx->isWiphySuspended)
19717 {
19718 pHddCtx->isSchedScanUpdatePending = TRUE;
19719 spin_unlock(&pHddCtx->schedScan_lock);
19720 hddLog(VOS_TRACE_LEVEL_INFO,
19721 "%s: Update cfg80211 scan database after it resume", __func__);
19722 return ;
19723 }
19724 spin_unlock(&pHddCtx->schedScan_lock);
19725
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019726 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19727
19728 if (0 > ret)
19729 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019730 else
19731 {
19732 /* Acquire wakelock to handle the case where APP's tries to suspend
19733 * immediatly after the driver gets connect request(i.e after pno)
19734 * from supplicant, this result in app's is suspending and not able
19735 * to process the connect request to AP */
19736 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19737 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019738 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19740 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019741}
19742
19743/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019744 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019745 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019746 */
19747static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19748{
19749 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19750 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019751 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019752 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19753 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019754
19755 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19756 {
19757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19758 "%s: PNO is allowed only in STA interface", __func__);
19759 return eHAL_STATUS_FAILURE;
19760 }
19761
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019762 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19763
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019764 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019765 * active sessions. PNO is allowed only in case when sap session
19766 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019767 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019768 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19769 {
19770 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019771 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019772
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019773 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19774 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19775 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19776 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019777 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19778 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019779 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019780 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019781 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019782 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019783 }
19784 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19785 pAdapterNode = pNext;
19786 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019787 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019788}
19789
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019790void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19791{
19792 hdd_adapter_t *pAdapter = callbackContext;
19793 hdd_context_t *pHddCtx;
19794
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019795 ENTER();
19796
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019797 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19798 {
19799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19800 FL("Invalid adapter or adapter has invalid magic"));
19801 return;
19802 }
19803
19804 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19805 if (0 != wlan_hdd_validate_context(pHddCtx))
19806 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019807 return;
19808 }
19809
c_hpothub53c45d2014-08-18 16:53:14 +053019810 if (VOS_STATUS_SUCCESS != status)
19811 {
19812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019813 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019814 pHddCtx->isPnoEnable = FALSE;
19815 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019816
19817 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19818 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019819 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019820}
19821
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019822#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19823 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19824/**
19825 * hdd_config_sched_scan_plan() - configures the sched scan plans
19826 * from the framework.
19827 * @pno_req: pointer to PNO scan request
19828 * @request: pointer to scan request from framework
19829 *
19830 * Return: None
19831 */
19832static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19833 struct cfg80211_sched_scan_request *request,
19834 hdd_context_t *hdd_ctx)
19835{
19836 v_U32_t i = 0;
19837
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019838 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019839 for (i = 0; i < request->n_scan_plans; i++)
19840 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019841 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19842 request->scan_plans[i].iterations;
19843 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19844 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019845 }
19846}
19847#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019848static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019849 struct cfg80211_sched_scan_request *request,
19850 hdd_context_t *hdd_ctx)
19851{
19852 v_U32_t i, temp_int;
19853 /* Driver gets only one time interval which is hardcoded in
19854 * supplicant for 10000ms. Taking power consumption into account 6
19855 * timers will be used, Timervalue is increased exponentially
19856 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19857 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19858 * If it is set to 0 only one timer will be used and PNO scan cycle
19859 * will be repeated after each interval specified by supplicant
19860 * till PNO is disabled.
19861 */
19862 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019863 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019864 HDD_PNO_SCAN_TIMERS_SET_ONE;
19865 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019866 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019867 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19868
19869 temp_int = (request->interval)/1000;
19870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19871 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19872 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019873 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019874 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019875 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019876 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019877 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019878 temp_int *= 2;
19879 }
19880 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019881 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019882}
19883#endif
19884
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019885/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019886 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19887 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019888 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019889static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019890 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19891{
19892 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019893 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019894 hdd_context_t *pHddCtx;
19895 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019896 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019897 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19898 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019899 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19900 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019901 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019902 hdd_config_t *pConfig = NULL;
19903 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019904
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019905 ENTER();
19906
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019907 if (NULL == pAdapter)
19908 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019909 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019910 "%s: HDD adapter is Null", __func__);
19911 return -ENODEV;
19912 }
19913
19914 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019915 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019916
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019917 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019918 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019919 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019920 }
19921
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019922 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019923 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19924 if (NULL == hHal)
19925 {
19926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19927 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019928 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019929 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019930 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19931 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19932 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019933 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019934 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019935 {
19936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19937 "%s: aborting the existing scan is unsuccessfull", __func__);
19938 return -EBUSY;
19939 }
19940
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019941 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019942 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019944 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019945 return -EBUSY;
19946 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019947
c_hpothu37f21312014-04-09 21:49:54 +053019948 if (TRUE == pHddCtx->isPnoEnable)
19949 {
19950 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19951 FL("already PNO is enabled"));
19952 return -EBUSY;
19953 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019954
19955 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19956 {
19957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19958 "%s: abort ROC failed ", __func__);
19959 return -EBUSY;
19960 }
19961
c_hpothu37f21312014-04-09 21:49:54 +053019962 pHddCtx->isPnoEnable = TRUE;
19963
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019964 pnoRequest.enable = 1; /*Enable PNO */
19965 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019966
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019967 if (( !pnoRequest.ucNetworksCount ) ||
19968 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019969 {
19970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019971 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019972 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019973 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019974 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019975 goto error;
19976 }
19977
19978 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19979 {
19980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019981 "%s: Incorrect number of channels %d",
19982 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019983 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019984 goto error;
19985 }
19986
19987 /* Framework provides one set of channels(all)
19988 * common for all saved profile */
19989 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19990 channels_allowed, &num_channels_allowed))
19991 {
19992 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19993 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019994 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019995 goto error;
19996 }
19997 /* Checking each channel against allowed channel list */
19998 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019999 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020000 {
Nirav Shah80830bf2013-12-31 16:35:12 +053020001 char chList [(request->n_channels*5)+1];
20002 int len;
20003 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020004 {
Nirav Shah80830bf2013-12-31 16:35:12 +053020005 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020006 {
Nirav Shah80830bf2013-12-31 16:35:12 +053020007 if (request->channels[i]->hw_value == channels_allowed[indx])
20008 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053020009 if ((!pConfig->enableDFSPnoChnlScan) &&
20010 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
20011 {
20012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20013 "%s : Dropping DFS channel : %d",
20014 __func__,channels_allowed[indx]);
20015 num_ignore_dfs_ch++;
20016 break;
20017 }
20018
Nirav Shah80830bf2013-12-31 16:35:12 +053020019 valid_ch[num_ch++] = request->channels[i]->hw_value;
20020 len += snprintf(chList+len, 5, "%d ",
20021 request->channels[i]->hw_value);
20022 break ;
20023 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020024 }
20025 }
Nirav Shah80830bf2013-12-31 16:35:12 +053020026 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020027
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053020028 /*If all channels are DFS and dropped, then ignore the PNO request*/
20029 if (num_ignore_dfs_ch == request->n_channels)
20030 {
20031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20032 "%s : All requested channels are DFS channels", __func__);
20033 ret = -EINVAL;
20034 goto error;
20035 }
20036 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020037
20038 pnoRequest.aNetworks =
20039 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
20040 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020041 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020042 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
20043 FL("failed to allocate memory aNetworks %u"),
20044 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
20045 goto error;
20046 }
20047 vos_mem_zero(pnoRequest.aNetworks,
20048 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
20049
20050 /* Filling per profile params */
20051 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
20052 {
20053 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020054 request->match_sets[i].ssid.ssid_len;
20055
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020056 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
20057 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020058 {
20059 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053020060 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020061 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020062 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020063 goto error;
20064 }
20065
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020066 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020067 request->match_sets[i].ssid.ssid,
20068 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053020069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20070 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020071 i, pnoRequest.aNetworks[i].ssId.ssId);
20072 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
20073 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
20074 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020075
20076 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020077 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
20078 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020079
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020080 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020081 }
20082
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020083 for (i = 0; i < request->n_ssids; i++)
20084 {
20085 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020086 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020087 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020088 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020089 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020090 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020091 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020092 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020093 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020094 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020095 break;
20096 }
20097 j++;
20098 }
20099 }
20100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20101 "Number of hidden networks being Configured = %d",
20102 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053020103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080020104 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020105
20106 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
20107 if (pnoRequest.p24GProbeTemplate == NULL)
20108 {
20109 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
20110 FL("failed to allocate memory p24GProbeTemplate %u"),
20111 SIR_PNO_MAX_PB_REQ_SIZE);
20112 goto error;
20113 }
20114
20115 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
20116 if (pnoRequest.p5GProbeTemplate == NULL)
20117 {
20118 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
20119 FL("failed to allocate memory p5GProbeTemplate %u"),
20120 SIR_PNO_MAX_PB_REQ_SIZE);
20121 goto error;
20122 }
20123
20124 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
20125 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
20126
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053020127 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
20128 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053020129 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020130 pnoRequest.us24GProbeTemplateLen = request->ie_len;
20131 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
20132 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053020133
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020134 pnoRequest.us5GProbeTemplateLen = request->ie_len;
20135 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
20136 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053020137 }
20138
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053020139 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053020140
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020141 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020142
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020143 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020144 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
20145 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020146 pAdapter->pno_req_status = 0;
20147
Nirav Shah80830bf2013-12-31 16:35:12 +053020148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20149 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020150 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
20151 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053020152
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020153 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020154 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020155 hdd_cfg80211_sched_scan_done_callback, pAdapter);
20156 if (eHAL_STATUS_SUCCESS != status)
20157 {
20158 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053020159 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020160 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020161 goto error;
20162 }
20163
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020164 ret = wait_for_completion_timeout(
20165 &pAdapter->pno_comp_var,
20166 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
20167 if (0 >= ret)
20168 {
20169 // Did not receive the response for PNO enable in time.
20170 // Assuming the PNO enable was success.
20171 // Returning error from here, because we timeout, results
20172 // in side effect of Wifi (Wifi Setting) not to work.
20173 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20174 FL("Timed out waiting for PNO to be Enabled"));
20175 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020176 }
20177
20178 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053020179 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020180
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020181error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20183 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053020184 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020185 if (pnoRequest.aNetworks)
20186 vos_mem_free(pnoRequest.aNetworks);
20187 if (pnoRequest.p24GProbeTemplate)
20188 vos_mem_free(pnoRequest.p24GProbeTemplate);
20189 if (pnoRequest.p5GProbeTemplate)
20190 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020191
20192 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020193 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020194}
20195
20196/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020197 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
20198 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020199 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020200static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
20201 struct net_device *dev, struct cfg80211_sched_scan_request *request)
20202{
20203 int ret;
20204
20205 vos_ssr_protect(__func__);
20206 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
20207 vos_ssr_unprotect(__func__);
20208
20209 return ret;
20210}
20211
20212/*
20213 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
20214 * Function to disable PNO
20215 */
20216static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020217 struct net_device *dev)
20218{
20219 eHalStatus status = eHAL_STATUS_FAILURE;
20220 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20221 hdd_context_t *pHddCtx;
20222 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020223 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020224 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020225
20226 ENTER();
20227
20228 if (NULL == pAdapter)
20229 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020230 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020231 "%s: HDD adapter is Null", __func__);
20232 return -ENODEV;
20233 }
20234
20235 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020236
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020237 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020238 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020240 "%s: HDD context is Null", __func__);
20241 return -ENODEV;
20242 }
20243
20244 /* The return 0 is intentional when isLogpInProgress and
20245 * isLoadUnloadInProgress. We did observe a crash due to a return of
20246 * failure in sched_scan_stop , especially for a case where the unload
20247 * of the happens at the same time. The function __cfg80211_stop_sched_scan
20248 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
20249 * success. If it returns a failure , then its next invocation due to the
20250 * clean up of the second interface will have the dev pointer corresponding
20251 * to the first one leading to a crash.
20252 */
20253 if (pHddCtx->isLogpInProgress)
20254 {
20255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20256 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053020257 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020258 return ret;
20259 }
20260
Mihir Shete18156292014-03-11 15:38:30 +053020261 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020262 {
20263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20264 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20265 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020266 }
20267
20268 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20269 if (NULL == hHal)
20270 {
20271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20272 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020273 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020274 }
20275
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020276 pnoRequest.enable = 0; /* Disable PNO */
20277 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020278
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020279 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20280 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
20281 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053020282
20283 INIT_COMPLETION(pAdapter->pno_comp_var);
20284 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
20285 pnoRequest.callbackContext = pAdapter;
20286 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020287 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020288 pAdapter->sessionId,
20289 NULL, pAdapter);
20290 if (eHAL_STATUS_SUCCESS != status)
20291 {
20292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20293 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020294 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020295 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020296 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053020297 ret = wait_for_completion_timeout(
20298 &pAdapter->pno_comp_var,
20299 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
20300 if (0 >= ret)
20301 {
20302 // Did not receive the response for PNO disable in time.
20303 // Assuming the PNO disable was success.
20304 // Returning error from here, because we timeout, results
20305 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053020306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053020307 FL("Timed out waiting for PNO to be disabled"));
20308 ret = 0;
20309 }
20310
20311 ret = pAdapter->pno_req_status;
20312 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020313
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020314error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020315 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020316 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020317
20318 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020319 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020320}
20321
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020322/*
20323 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
20324 * NL interface to disable PNO
20325 */
20326static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
20327 struct net_device *dev)
20328{
20329 int ret;
20330
20331 vos_ssr_protect(__func__);
20332 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
20333 vos_ssr_unprotect(__func__);
20334
20335 return ret;
20336}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020337#endif /*FEATURE_WLAN_SCAN_PNO*/
20338
20339
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020340#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020341#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020342static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20343 struct net_device *dev,
20344 u8 *peer, u8 action_code,
20345 u8 dialog_token,
20346 u16 status_code, u32 peer_capability,
20347 const u8 *buf, size_t len)
20348#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020349#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20350 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020351static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20352 struct net_device *dev,
20353 const u8 *peer, u8 action_code,
20354 u8 dialog_token, u16 status_code,
20355 u32 peer_capability, bool initiator,
20356 const u8 *buf, size_t len)
20357#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20358static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20359 struct net_device *dev,
20360 const u8 *peer, u8 action_code,
20361 u8 dialog_token, u16 status_code,
20362 u32 peer_capability, const u8 *buf,
20363 size_t len)
20364#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20365static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20366 struct net_device *dev,
20367 u8 *peer, u8 action_code,
20368 u8 dialog_token,
20369 u16 status_code, u32 peer_capability,
20370 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020371#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020372static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20373 struct net_device *dev,
20374 u8 *peer, u8 action_code,
20375 u8 dialog_token,
20376 u16 status_code, const u8 *buf,
20377 size_t len)
20378#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020379#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020380{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020381 hdd_adapter_t *pAdapter;
20382 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020383 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070020384 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080020385 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070020386 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020387 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020388 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020389#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020390 u32 peer_capability = 0;
20391#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020392 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020393 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020394 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020395
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020396 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20397 if (NULL == pAdapter)
20398 {
20399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20400 "%s: Adapter is NULL",__func__);
20401 return -EINVAL;
20402 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020403 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20404 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
20405 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020406
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020407 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020408 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020409 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020410 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020411 "Invalid arguments");
20412 return -EINVAL;
20413 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020414
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020415 if (pHddCtx->isLogpInProgress)
20416 {
20417 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20418 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053020419 wlan_hdd_tdls_set_link_status(pAdapter,
20420 peer,
20421 eTDLS_LINK_IDLE,
20422 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020423 return -EBUSY;
20424 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020425
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020426 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20427 {
20428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20429 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20430 return -EAGAIN;
20431 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020432
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020433 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20434 if (!pHddTdlsCtx) {
20435 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20436 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020437 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020438 }
20439
Hoonki Lee27511902013-03-14 18:19:06 -070020440 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020441 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020443 "%s: TDLS mode is disabled OR not enabled in FW."
20444 MAC_ADDRESS_STR " action %d declined.",
20445 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020446 return -ENOTSUPP;
20447 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020448
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020449 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20450
20451 if( NULL == pHddStaCtx )
20452 {
20453 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20454 "%s: HDD station context NULL ",__func__);
20455 return -EINVAL;
20456 }
20457
20458 /* STA should be connected and authenticated
20459 * before sending any TDLS frames
20460 */
20461 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20462 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20463 {
20464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20465 "STA is not connected or unauthenticated. "
20466 "connState %u, uIsAuthenticated %u",
20467 pHddStaCtx->conn_info.connState,
20468 pHddStaCtx->conn_info.uIsAuthenticated);
20469 return -EAGAIN;
20470 }
20471
Hoonki Lee27511902013-03-14 18:19:06 -070020472 /* other than teardown frame, other mgmt frames are not sent if disabled */
20473 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20474 {
20475 /* if tdls_mode is disabled to respond to peer's request */
20476 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20477 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020478 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020479 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020480 " TDLS mode is disabled. action %d declined.",
20481 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020482
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020483 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020484 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020485
20486 if (vos_max_concurrent_connections_reached())
20487 {
20488 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20489 return -EINVAL;
20490 }
Hoonki Lee27511902013-03-14 18:19:06 -070020491 }
20492
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020493 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20494 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020495 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020496 {
20497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020498 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020499 " TDLS setup is ongoing. action %d declined.",
20500 __func__, MAC_ADDR_ARRAY(peer), action_code);
20501 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020502 }
20503 }
20504
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020505 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20506 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020507 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020508 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20509 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020510 {
20511 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20512 we return error code at 'add_station()'. Hence we have this
20513 check again in addtion to add_station().
20514 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020515 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020516 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20518 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020519 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20520 __func__, MAC_ADDR_ARRAY(peer), action_code,
20521 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020522 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020523 }
20524 else
20525 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020526 /* maximum reached. tweak to send error code to peer and return
20527 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020528 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20530 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020531 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20532 __func__, MAC_ADDR_ARRAY(peer), status_code,
20533 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020534 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020535 /* fall through to send setup resp with failure status
20536 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020537 }
20538 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020539 else
20540 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020541 mutex_lock(&pHddCtx->tdls_lock);
20542 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020543 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020544 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020545 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020546 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020547 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20548 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020549 return -EPERM;
20550 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020551 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020552 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020553 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020554
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020556 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020557 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20558 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020559
Hoonki Leea34dd892013-02-05 22:56:02 -080020560 /*Except teardown responder will not be used so just make 0*/
20561 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020562 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020563 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020564
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020565 mutex_lock(&pHddCtx->tdls_lock);
20566 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020567
20568 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20569 responder = pTdlsPeer->is_responder;
20570 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020571 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020573 "%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 -070020574 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20575 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020576 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020577 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020578 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020579 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020580 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020581
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020582 /* Discard TDLS setup if peer is removed by user app */
20583 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20584 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20585 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20586 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20587
20588 mutex_lock(&pHddCtx->tdls_lock);
20589 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20590 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20591 mutex_unlock(&pHddCtx->tdls_lock);
20592 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20593 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20594 MAC_ADDR_ARRAY(peer), action_code);
20595 return -EINVAL;
20596 }
20597 mutex_unlock(&pHddCtx->tdls_lock);
20598 }
20599
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020600 /* For explicit trigger of DIS_REQ come out of BMPS for
20601 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020602 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020603 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020604 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20605 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020606 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020607 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020609 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20610 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020611 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20612 if (status != VOS_STATUS_SUCCESS) {
20613 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020614 } else {
20615 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020616 }
Hoonki Lee14621352013-04-16 17:51:19 -070020617 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020618 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020619 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20621 }
20622 }
Hoonki Lee14621352013-04-16 17:51:19 -070020623 }
20624
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020625 /* make sure doesn't call send_mgmt() while it is pending */
20626 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20627 {
20628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020629 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020630 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020631 ret = -EBUSY;
20632 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020633 }
20634
20635 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020636 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20637
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020638 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20639 pAdapter->sessionId, peer, action_code, dialog_token,
20640 status_code, peer_capability, (tANI_U8 *)buf, len,
20641 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020642
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020643 if (VOS_STATUS_SUCCESS != status)
20644 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20646 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020647 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020648 ret = -EINVAL;
20649 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020650 }
20651
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20653 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20654 WAIT_TIME_TDLS_MGMT);
20655
Hoonki Leed37cbb32013-04-20 00:31:14 -070020656 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20657 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20658
20659 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020660 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020662 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020663 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020664 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020665
20666 if (pHddCtx->isLogpInProgress)
20667 {
20668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20669 "%s: LOGP in Progress. Ignore!!!", __func__);
20670 return -EAGAIN;
20671 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020672 if (rc <= 0)
20673 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20674 WLAN_LOG_INDICATOR_HOST_DRIVER,
20675 WLAN_LOG_REASON_HDD_TIME_OUT,
20676 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020677
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020678 ret = -EINVAL;
20679 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020680 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020681 else
20682 {
20683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20684 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20685 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20686 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020687
Gopichand Nakkala05922802013-03-14 12:23:19 -070020688 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020689 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020690 ret = max_sta_failed;
20691 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020692 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020693
Hoonki Leea34dd892013-02-05 22:56:02 -080020694 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20695 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020696 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020697 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20698 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020699 }
20700 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20701 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020702 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20704 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020705 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020706
20707 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020708
20709tx_failed:
20710 /* add_station will be called before sending TDLS_SETUP_REQ and
20711 * TDLS_SETUP_RSP and as part of add_station driver will enable
20712 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20713 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20714 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20715 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20716 */
20717
20718 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20719 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20720 wlan_hdd_tdls_check_bmps(pAdapter);
20721 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020722}
20723
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020724#if TDLS_MGMT_VERSION2
20725static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20726 u8 *peer, u8 action_code, u8 dialog_token,
20727 u16 status_code, u32 peer_capability,
20728 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020729#else /* TDLS_MGMT_VERSION2 */
20730#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20731static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20732 struct net_device *dev,
20733 const u8 *peer, u8 action_code,
20734 u8 dialog_token, u16 status_code,
20735 u32 peer_capability, bool initiator,
20736 const u8 *buf, size_t len)
20737#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20738static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20739 struct net_device *dev,
20740 const u8 *peer, u8 action_code,
20741 u8 dialog_token, u16 status_code,
20742 u32 peer_capability, const u8 *buf,
20743 size_t len)
20744#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20745static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20746 struct net_device *dev,
20747 u8 *peer, u8 action_code,
20748 u8 dialog_token,
20749 u16 status_code, u32 peer_capability,
20750 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020751#else
20752static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20753 u8 *peer, u8 action_code, u8 dialog_token,
20754 u16 status_code, const u8 *buf, size_t len)
20755#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020756#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020757{
20758 int ret;
20759
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020760 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020761#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020762 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20763 dialog_token, status_code,
20764 peer_capability, buf, len);
20765#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020766#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20767 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020768 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20769 dialog_token, status_code,
20770 peer_capability, initiator,
20771 buf, len);
20772#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20773 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20774 dialog_token, status_code,
20775 peer_capability, buf, len);
20776#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20777 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20778 dialog_token, status_code,
20779 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020780#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020781 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20782 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020783#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020784#endif
20785 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020786
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020787 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020788}
Atul Mittal115287b2014-07-08 13:26:33 +053020789
20790int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020791#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20792 const u8 *peer,
20793#else
Atul Mittal115287b2014-07-08 13:26:33 +053020794 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020795#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020796 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020797 cfg80211_exttdls_callback callback)
20798{
20799
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020800 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020801 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020802 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20804 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20805 __func__, MAC_ADDR_ARRAY(peer));
20806
20807 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20808 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20809
20810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020811 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20812 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20813 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020814 return -ENOTSUPP;
20815 }
20816
20817 /* To cater the requirement of establishing the TDLS link
20818 * irrespective of the data traffic , get an entry of TDLS peer.
20819 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020820 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020821 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20822 if (pTdlsPeer == NULL) {
20823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20824 "%s: peer " MAC_ADDRESS_STR " not existing",
20825 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020826 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020827 return -EINVAL;
20828 }
20829
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020830 /* check FW TDLS Off Channel capability */
20831 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020832 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020833 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020834 {
20835 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20836 pTdlsPeer->peerParams.global_operating_class =
20837 tdls_peer_params->global_operating_class;
20838 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20839 pTdlsPeer->peerParams.min_bandwidth_kbps =
20840 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020841 /* check configured channel is valid, non dfs and
20842 * not current operating channel */
20843 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20844 tdls_peer_params->channel)) &&
20845 (pHddStaCtx) &&
20846 (tdls_peer_params->channel !=
20847 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020848 {
20849 pTdlsPeer->isOffChannelConfigured = TRUE;
20850 }
20851 else
20852 {
20853 pTdlsPeer->isOffChannelConfigured = FALSE;
20854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20855 "%s: Configured Tdls Off Channel is not valid", __func__);
20856
20857 }
20858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020859 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20860 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020861 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020862 pTdlsPeer->isOffChannelConfigured,
20863 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020864 }
20865 else
20866 {
20867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020868 "%s: TDLS off channel FW capability %d, "
20869 "host capab %d or Invalid TDLS Peer Params", __func__,
20870 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20871 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020872 }
20873
Atul Mittal115287b2014-07-08 13:26:33 +053020874 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20875
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020876 mutex_unlock(&pHddCtx->tdls_lock);
20877
Atul Mittal115287b2014-07-08 13:26:33 +053020878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20879 " %s TDLS Add Force Peer Failed",
20880 __func__);
20881 return -EINVAL;
20882 }
20883 /*EXT TDLS*/
20884
20885 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020886 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20888 " %s TDLS set callback Failed",
20889 __func__);
20890 return -EINVAL;
20891 }
20892
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020893 mutex_unlock(&pHddCtx->tdls_lock);
20894
Atul Mittal115287b2014-07-08 13:26:33 +053020895 return(0);
20896
20897}
20898
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020899int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20900#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20901 const u8 *peer
20902#else
20903 u8 *peer
20904#endif
20905)
Atul Mittal115287b2014-07-08 13:26:33 +053020906{
20907
20908 hddTdlsPeer_t *pTdlsPeer;
20909 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020910
Atul Mittal115287b2014-07-08 13:26:33 +053020911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20912 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20913 __func__, MAC_ADDR_ARRAY(peer));
20914
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020915 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20917 return -EINVAL;
20918 }
20919
Atul Mittal115287b2014-07-08 13:26:33 +053020920 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20921 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20922
20923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020924 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20925 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20926 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020927 return -ENOTSUPP;
20928 }
20929
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020930 mutex_lock(&pHddCtx->tdls_lock);
20931 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020932
20933 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020934 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020935 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020936 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020937 __func__, MAC_ADDR_ARRAY(peer));
20938 return -EINVAL;
20939 }
20940 else {
20941 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20942 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020943 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20944 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020945 /* if channel switch is configured, reset
20946 the channel for this peer */
20947 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20948 {
20949 pTdlsPeer->peerParams.channel = 0;
20950 pTdlsPeer->isOffChannelConfigured = FALSE;
20951 }
Atul Mittal115287b2014-07-08 13:26:33 +053020952 }
20953
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020954 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020955 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020956 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020957 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020958 }
Atul Mittal115287b2014-07-08 13:26:33 +053020959
20960 /*EXT TDLS*/
20961
20962 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020963 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20965 " %s TDLS set callback Failed",
20966 __func__);
20967 return -EINVAL;
20968 }
Atul Mittal115287b2014-07-08 13:26:33 +053020969
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020970 mutex_unlock(&pHddCtx->tdls_lock);
20971
20972 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020973}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020974static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020975#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20976 const u8 *peer,
20977#else
20978 u8 *peer,
20979#endif
20980 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020981{
20982 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20983 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020984 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020985 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020986
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020987 ENTER();
20988
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020989 if (!pAdapter) {
20990 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20991 return -EINVAL;
20992 }
20993
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020994 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20995 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20996 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020997 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020998 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070021000 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021001 return -EINVAL;
21002 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080021003
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021004 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021005 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080021006 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021007 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080021008 }
21009
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021010
21011 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080021012 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021013 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080021014 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021015 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
21016 "Cannot process TDLS commands",
21017 pHddCtx->cfg_ini->fEnableTDLSSupport,
21018 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021019 return -ENOTSUPP;
21020 }
21021
21022 switch (oper) {
21023 case NL80211_TDLS_ENABLE_LINK:
21024 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021025 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021026 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053021027 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
21028 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053021029 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021030 tANI_U16 numCurrTdlsPeers = 0;
21031 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021032 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021033 tSirMacAddr peerMac;
21034 int channel;
21035 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021036
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21038 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
21039 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021040
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021041 mutex_lock(&pHddCtx->tdls_lock);
21042 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053021043 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053021044 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021045 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021046 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21047 " (oper %d) not exsting. ignored",
21048 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21049 return -EINVAL;
21050 }
21051
21052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21053 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21054 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21055 "NL80211_TDLS_ENABLE_LINK");
21056
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070021057 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
21058 {
21059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
21060 MAC_ADDRESS_STR " failed",
21061 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021062 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070021063 return -EINVAL;
21064 }
21065
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021066 /* before starting tdls connection, set tdls
21067 * off channel established status to default value */
21068 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021069
21070 mutex_unlock(&pHddCtx->tdls_lock);
21071
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053021072 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021073 /* TDLS Off Channel, Disable tdls channel switch,
21074 when there are more than one tdls link */
21075 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053021076 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021077 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021078 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021079 /* get connected peer and send disable tdls off chan */
21080 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021081 if ((connPeer) &&
21082 (connPeer->isOffChannelSupported == TRUE) &&
21083 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021084 {
21085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21086 "%s: More then one peer connected, Disable "
21087 "TDLS channel switch", __func__);
21088
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021089 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021090 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
21091 channel = connPeer->peerParams.channel;
21092
21093 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021094
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021095 ret = sme_SendTdlsChanSwitchReq(
21096 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021097 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021098 peerMac,
21099 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021100 TDLS_OFF_CHANNEL_BW_OFFSET,
21101 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021102 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021103 hddLog(VOS_TRACE_LEVEL_ERROR,
21104 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021105 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021106 }
21107 else
21108 {
21109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21110 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021111 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021112 "isOffChannelConfigured %d",
21113 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021114 (connPeer ? (connPeer->isOffChannelSupported)
21115 : -1),
21116 (connPeer ? (connPeer->isOffChannelConfigured)
21117 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021118 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021119 }
21120 }
21121
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021122 mutex_lock(&pHddCtx->tdls_lock);
21123 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21124 if ( NULL == pTdlsPeer ) {
21125 mutex_unlock(&pHddCtx->tdls_lock);
21126 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21127 "%s: " MAC_ADDRESS_STR
21128 " (oper %d) peer got freed in other context. ignored",
21129 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21130 return -EINVAL;
21131 }
21132 peer_status = pTdlsPeer->link_status;
21133 mutex_unlock(&pHddCtx->tdls_lock);
21134
21135 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021136 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021137 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053021138
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021139 if (0 != wlan_hdd_tdls_get_link_establish_params(
21140 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021142 return -EINVAL;
21143 }
21144 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021145
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021146 ret = sme_SendTdlsLinkEstablishParams(
21147 WLAN_HDD_GET_HAL_CTX(pAdapter),
21148 pAdapter->sessionId, peer,
21149 &tdlsLinkEstablishParams);
21150 if (ret != VOS_STATUS_SUCCESS) {
21151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
21152 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021153 /* Send TDLS peer UAPSD capabilities to the firmware and
21154 * register with the TL on after the response for this operation
21155 * is received .
21156 */
21157 ret = wait_for_completion_interruptible_timeout(
21158 &pAdapter->tdls_link_establish_req_comp,
21159 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053021160
21161 mutex_lock(&pHddCtx->tdls_lock);
21162 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21163 if ( NULL == pTdlsPeer ) {
21164 mutex_unlock(&pHddCtx->tdls_lock);
21165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21166 "%s %d: " MAC_ADDRESS_STR
21167 " (oper %d) peer got freed in other context. ignored",
21168 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
21169 (int)oper);
21170 return -EINVAL;
21171 }
21172 peer_status = pTdlsPeer->link_status;
21173 mutex_unlock(&pHddCtx->tdls_lock);
21174
21175 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021176 {
21177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021178 FL("Link Establish Request Failed Status %ld"),
21179 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021180 return -EINVAL;
21181 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021182 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021183
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021184 mutex_lock(&pHddCtx->tdls_lock);
21185 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21186 if ( NULL == pTdlsPeer ) {
21187 mutex_unlock(&pHddCtx->tdls_lock);
21188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21189 "%s: " MAC_ADDRESS_STR
21190 " (oper %d) peer got freed in other context. ignored",
21191 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21192 return -EINVAL;
21193 }
21194
Atul Mittal115287b2014-07-08 13:26:33 +053021195 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21196 eTDLS_LINK_CONNECTED,
21197 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053021198 staDesc.ucSTAId = pTdlsPeer->staId;
21199 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053021200
21201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21202 "%s: tdlsLinkEstablishParams of peer "
21203 MAC_ADDRESS_STR "uapsdQueues: %d"
21204 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
21205 "isResponder: %d peerstaId: %d",
21206 __func__,
21207 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
21208 tdlsLinkEstablishParams.uapsdQueues,
21209 tdlsLinkEstablishParams.qos,
21210 tdlsLinkEstablishParams.maxSp,
21211 tdlsLinkEstablishParams.isBufSta,
21212 tdlsLinkEstablishParams.isOffChannelSupported,
21213 tdlsLinkEstablishParams.isResponder,
21214 pTdlsPeer->staId);
21215
21216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21217 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
21218 __func__,
21219 staDesc.ucSTAId,
21220 staDesc.ucQosEnabled);
21221
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021222 ret = WLANTL_UpdateTdlsSTAClient(
21223 pHddCtx->pvosContext,
21224 &staDesc);
21225 if (ret != VOS_STATUS_SUCCESS) {
21226 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
21227 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053021228
Gopichand Nakkala471708b2013-06-04 20:03:01 +053021229 /* Mark TDLS client Authenticated .*/
21230 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
21231 pTdlsPeer->staId,
21232 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070021233 if (VOS_STATUS_SUCCESS == status)
21234 {
Hoonki Lee14621352013-04-16 17:51:19 -070021235 if (pTdlsPeer->is_responder == 0)
21236 {
21237 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053021238 tdlsConnInfo_t *tdlsInfo;
21239
21240 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
21241
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053021242 if (!vos_timer_is_initialized(
21243 &pTdlsPeer->initiatorWaitTimeoutTimer))
21244 {
21245 /* Initialize initiator wait callback */
21246 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053021247 &pTdlsPeer->initiatorWaitTimeoutTimer,
21248 VOS_TIMER_TYPE_SW,
21249 wlan_hdd_tdls_initiator_wait_cb,
21250 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053021251 }
Hoonki Lee14621352013-04-16 17:51:19 -070021252 wlan_hdd_tdls_timer_restart(pAdapter,
21253 &pTdlsPeer->initiatorWaitTimeoutTimer,
21254 WAIT_TIME_TDLS_INITIATOR);
21255 /* suspend initiator TX until it receives direct packet from the
21256 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021257 ret = WLANTL_SuspendDataTx(
21258 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21259 &staId, NULL);
21260 if (ret != VOS_STATUS_SUCCESS) {
21261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
21262 }
Hoonki Lee14621352013-04-16 17:51:19 -070021263 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021264
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021265 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021266 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021267 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021268 suppChannelLen =
21269 tdlsLinkEstablishParams.supportedChannelsLen;
21270
21271 if ((suppChannelLen > 0) &&
21272 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
21273 {
21274 tANI_U8 suppPeerChannel = 0;
21275 int i = 0;
21276 for (i = 0U; i < suppChannelLen; i++)
21277 {
21278 suppPeerChannel =
21279 tdlsLinkEstablishParams.supportedChannels[i];
21280
21281 pTdlsPeer->isOffChannelSupported = FALSE;
21282 if (suppPeerChannel ==
21283 pTdlsPeer->peerParams.channel)
21284 {
21285 pTdlsPeer->isOffChannelSupported = TRUE;
21286 break;
21287 }
21288 }
21289 }
21290 else
21291 {
21292 pTdlsPeer->isOffChannelSupported = FALSE;
21293 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021294 }
21295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21296 "%s: TDLS channel switch request for channel "
21297 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021298 "%d isOffChannelSupported %d", __func__,
21299 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021300 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021301 suppChannelLen,
21302 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021303
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021304 /* TDLS Off Channel, Enable tdls channel switch,
21305 when their is only one tdls link and it supports */
21306 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21307 if ((numCurrTdlsPeers == 1) &&
21308 (TRUE == pTdlsPeer->isOffChannelSupported) &&
21309 (TRUE == pTdlsPeer->isOffChannelConfigured))
21310 {
21311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21312 "%s: Send TDLS channel switch request for channel %d",
21313 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021314
21315 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021316 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
21317 channel = pTdlsPeer->peerParams.channel;
21318
21319 mutex_unlock(&pHddCtx->tdls_lock);
21320
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021321 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
21322 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021323 peerMac,
21324 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021325 TDLS_OFF_CHANNEL_BW_OFFSET,
21326 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021327 if (ret != VOS_STATUS_SUCCESS) {
21328 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
21329 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021330 }
21331 else
21332 {
21333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21334 "%s: TDLS channel switch request not sent"
21335 " numCurrTdlsPeers %d "
21336 "isOffChannelSupported %d "
21337 "isOffChannelConfigured %d",
21338 __func__, numCurrTdlsPeers,
21339 pTdlsPeer->isOffChannelSupported,
21340 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021341 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021342 }
21343
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070021344 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021345 else
21346 mutex_unlock(&pHddCtx->tdls_lock);
21347
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021348 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021349
21350 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021351 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
21352 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021353 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021354 int ac;
21355 uint8 ucAc[4] = { WLANTL_AC_VO,
21356 WLANTL_AC_VI,
21357 WLANTL_AC_BK,
21358 WLANTL_AC_BE };
21359 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
21360 for(ac=0; ac < 4; ac++)
21361 {
21362 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21363 pTdlsPeer->staId, ucAc[ac],
21364 tlTid[ac], tlTid[ac], 0, 0,
21365 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021366 if (status != VOS_STATUS_SUCCESS) {
21367 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
21368 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021369 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021370 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021371 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021372
Bhargav Shah66896792015-10-01 18:17:37 +053021373 /* stop TCP delack timer if TDLS is enable */
21374 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21375 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053021376 hdd_wlan_tdls_enable_link_event(peer,
21377 pTdlsPeer->isOffChannelSupported,
21378 pTdlsPeer->isOffChannelConfigured,
21379 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021380 }
21381 break;
21382 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080021383 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021384 tANI_U16 numCurrTdlsPeers = 0;
21385 hddTdlsPeer_t *connPeer = NULL;
21386
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21388 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
21389 __func__, MAC_ADDR_ARRAY(peer));
21390
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021391 mutex_lock(&pHddCtx->tdls_lock);
21392 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021393
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021394
Sunil Dutt41de4e22013-11-14 18:09:02 +053021395 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021396 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021397 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21398 " (oper %d) not exsting. ignored",
21399 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21400 return -EINVAL;
21401 }
21402
21403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21404 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21405 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21406 "NL80211_TDLS_DISABLE_LINK");
21407
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021408 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080021409 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021410 long status;
21411
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021412 /* set tdls off channel status to false for this peer */
21413 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053021414 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21415 eTDLS_LINK_TEARING,
21416 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
21417 eTDLS_LINK_UNSPECIFIED:
21418 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021419 mutex_unlock(&pHddCtx->tdls_lock);
21420
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021421 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21422
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021423 status = sme_DeleteTdlsPeerSta(
21424 WLAN_HDD_GET_HAL_CTX(pAdapter),
21425 pAdapter->sessionId, peer );
21426 if (status != VOS_STATUS_SUCCESS) {
21427 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21428 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021429
21430 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21431 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021432
21433 mutex_lock(&pHddCtx->tdls_lock);
21434 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21435 if ( NULL == pTdlsPeer ) {
21436 mutex_unlock(&pHddCtx->tdls_lock);
21437 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21438 " peer was freed in other context",
21439 __func__, MAC_ADDR_ARRAY(peer));
21440 return -EINVAL;
21441 }
21442
Atul Mittal271a7652014-09-12 13:18:22 +053021443 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021444 eTDLS_LINK_IDLE,
21445 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021446 mutex_unlock(&pHddCtx->tdls_lock);
21447
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021448 if (status <= 0)
21449 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21451 "%s: Del station failed status %ld",
21452 __func__, status);
21453 return -EPERM;
21454 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021455
21456 /* TDLS Off Channel, Enable tdls channel switch,
21457 when their is only one tdls link and it supports */
21458 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21459 if (numCurrTdlsPeers == 1)
21460 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021461 tSirMacAddr peerMac;
21462 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021463
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021464 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021465 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021466
21467 if (connPeer == NULL) {
21468 mutex_unlock(&pHddCtx->tdls_lock);
21469 hddLog(VOS_TRACE_LEVEL_ERROR,
21470 "%s connPeer is NULL", __func__);
21471 return -EINVAL;
21472 }
21473
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021474 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21475 channel = connPeer->peerParams.channel;
21476
21477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21478 "%s: TDLS channel switch "
21479 "isOffChannelSupported %d "
21480 "isOffChannelConfigured %d "
21481 "isOffChannelEstablished %d",
21482 __func__,
21483 (connPeer ? connPeer->isOffChannelSupported : -1),
21484 (connPeer ? connPeer->isOffChannelConfigured : -1),
21485 (connPeer ? connPeer->isOffChannelEstablished : -1));
21486
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021487 if ((connPeer) &&
21488 (connPeer->isOffChannelSupported == TRUE) &&
21489 (connPeer->isOffChannelConfigured == TRUE))
21490 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021491 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021492 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021493 status = sme_SendTdlsChanSwitchReq(
21494 WLAN_HDD_GET_HAL_CTX(pAdapter),
21495 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021496 peerMac,
21497 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021498 TDLS_OFF_CHANNEL_BW_OFFSET,
21499 TDLS_CHANNEL_SWITCH_ENABLE);
21500 if (status != VOS_STATUS_SUCCESS) {
21501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21502 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021503 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021504 else
21505 mutex_unlock(&pHddCtx->tdls_lock);
21506 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021507 else
21508 {
21509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21510 "%s: TDLS channel switch request not sent "
21511 "numCurrTdlsPeers %d ",
21512 __func__, numCurrTdlsPeers);
21513 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021514 }
21515 else
21516 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021517 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21519 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021520 }
Bhargav Shah66896792015-10-01 18:17:37 +053021521 if (numCurrTdlsPeers == 0) {
21522 /* start TCP delack timer if TDLS is disable */
21523 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21524 hdd_manage_delack_timer(pHddCtx);
21525 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021526 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021527 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021528 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021529 {
Atul Mittal115287b2014-07-08 13:26:33 +053021530 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021531
Atul Mittal115287b2014-07-08 13:26:33 +053021532 if (0 != status)
21533 {
21534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021535 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021536 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021537 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021538 break;
21539 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021540 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021541 {
Atul Mittal115287b2014-07-08 13:26:33 +053021542 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21543 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021544 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021545 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021546
Atul Mittal115287b2014-07-08 13:26:33 +053021547 if (0 != status)
21548 {
21549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021550 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021551 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021552 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021553 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021554 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021555 case NL80211_TDLS_DISCOVERY_REQ:
21556 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021558 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021559 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021560 return -ENOTSUPP;
21561 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21563 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021564 return -ENOTSUPP;
21565 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021566
21567 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021568 return 0;
21569}
Chilam NG571c65a2013-01-19 12:27:36 +053021570
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021571static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021572#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21573 const u8 *peer,
21574#else
21575 u8 *peer,
21576#endif
21577 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021578{
21579 int ret;
21580
21581 vos_ssr_protect(__func__);
21582 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21583 vos_ssr_unprotect(__func__);
21584
21585 return ret;
21586}
21587
Chilam NG571c65a2013-01-19 12:27:36 +053021588int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21589 struct net_device *dev, u8 *peer)
21590{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021591 hddLog(VOS_TRACE_LEVEL_INFO,
21592 "tdls send discover req: "MAC_ADDRESS_STR,
21593 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021594#if TDLS_MGMT_VERSION2
21595 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21596 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21597#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021598#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21599 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21600 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21601#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21602 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21603 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21604#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21605 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21606 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21607#else
Chilam NG571c65a2013-01-19 12:27:36 +053021608 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21609 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021610#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021611#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021612}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021613#endif
21614
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021615#ifdef WLAN_FEATURE_GTK_OFFLOAD
21616/*
21617 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21618 * Callback rountine called upon receiving response for
21619 * get offload info
21620 */
21621void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21622 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21623{
21624
21625 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021626 tANI_U8 tempReplayCounter[8];
21627 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021628
21629 ENTER();
21630
21631 if (NULL == pAdapter)
21632 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021634 "%s: HDD adapter is Null", __func__);
21635 return ;
21636 }
21637
21638 if (NULL == pGtkOffloadGetInfoRsp)
21639 {
21640 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21641 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21642 return ;
21643 }
21644
21645 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21646 {
21647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21648 "%s: wlan Failed to get replay counter value",
21649 __func__);
21650 return ;
21651 }
21652
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021653 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21654 /* Update replay counter */
21655 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21656 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21657
21658 {
21659 /* changing from little to big endian since supplicant
21660 * works on big endian format
21661 */
21662 int i;
21663 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21664
21665 for (i = 0; i < 8; i++)
21666 {
21667 tempReplayCounter[7-i] = (tANI_U8)p[i];
21668 }
21669 }
21670
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021671 /* Update replay counter to NL */
21672 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021673 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021674}
21675
21676/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021677 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021678 * This function is used to offload GTK rekeying job to the firmware.
21679 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021680int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021681 struct cfg80211_gtk_rekey_data *data)
21682{
21683 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21684 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21685 hdd_station_ctx_t *pHddStaCtx;
21686 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021687 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021688 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021689 eHalStatus status = eHAL_STATUS_FAILURE;
21690
21691 ENTER();
21692
21693 if (NULL == pAdapter)
21694 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021696 "%s: HDD adapter is Null", __func__);
21697 return -ENODEV;
21698 }
21699
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021700 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21701 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21702 pAdapter->sessionId, pAdapter->device_mode));
21703
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021704 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021705 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021706 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021707 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021708 }
21709
21710 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21711 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21712 if (NULL == hHal)
21713 {
21714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21715 "%s: HAL context is Null!!!", __func__);
21716 return -EAGAIN;
21717 }
21718
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021719 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21720 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21721 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21722 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021723 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021724 {
21725 /* changing from big to little endian since driver
21726 * works on little endian format
21727 */
21728 tANI_U8 *p =
21729 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21730 int i;
21731
21732 for (i = 0; i < 8; i++)
21733 {
21734 p[7-i] = data->replay_ctr[i];
21735 }
21736 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021737
21738 if (TRUE == pHddCtx->hdd_wlan_suspended)
21739 {
21740 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021741 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21742 sizeof (tSirGtkOffloadParams));
21743 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021744 pAdapter->sessionId);
21745
21746 if (eHAL_STATUS_SUCCESS != status)
21747 {
21748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21749 "%s: sme_SetGTKOffload failed, returned %d",
21750 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021751
21752 /* Need to clear any trace of key value in the memory.
21753 * Thus zero out the memory even though it is local
21754 * variable.
21755 */
21756 vos_mem_zero(&hddGtkOffloadReqParams,
21757 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021758 return status;
21759 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21761 "%s: sme_SetGTKOffload successfull", __func__);
21762 }
21763 else
21764 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21766 "%s: wlan not suspended GTKOffload request is stored",
21767 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021768 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021769
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021770 /* Need to clear any trace of key value in the memory.
21771 * Thus zero out the memory even though it is local
21772 * variable.
21773 */
21774 vos_mem_zero(&hddGtkOffloadReqParams,
21775 sizeof(hddGtkOffloadReqParams));
21776
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021777 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021778 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021779}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021780
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021781int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21782 struct cfg80211_gtk_rekey_data *data)
21783{
21784 int ret;
21785
21786 vos_ssr_protect(__func__);
21787 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21788 vos_ssr_unprotect(__func__);
21789
21790 return ret;
21791}
21792#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021793/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021794 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021795 * This function is used to set access control policy
21796 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021797static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21798 struct net_device *dev,
21799 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021800{
21801 int i;
21802 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21803 hdd_hostapd_state_t *pHostapdState;
21804 tsap_Config_t *pConfig;
21805 v_CONTEXT_t pVosContext = NULL;
21806 hdd_context_t *pHddCtx;
21807 int status;
21808
21809 ENTER();
21810
21811 if (NULL == pAdapter)
21812 {
21813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21814 "%s: HDD adapter is Null", __func__);
21815 return -ENODEV;
21816 }
21817
21818 if (NULL == params)
21819 {
21820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21821 "%s: params is Null", __func__);
21822 return -EINVAL;
21823 }
21824
21825 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21826 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021827 if (0 != status)
21828 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021829 return status;
21830 }
21831
21832 pVosContext = pHddCtx->pvosContext;
21833 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21834
21835 if (NULL == pHostapdState)
21836 {
21837 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21838 "%s: pHostapdState is Null", __func__);
21839 return -EINVAL;
21840 }
21841
21842 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21843 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021844 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21845 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21846 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021847
21848 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21849 {
21850 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21851
21852 /* default value */
21853 pConfig->num_accept_mac = 0;
21854 pConfig->num_deny_mac = 0;
21855
21856 /**
21857 * access control policy
21858 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21859 * listed in hostapd.deny file.
21860 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21861 * listed in hostapd.accept file.
21862 */
21863 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21864 {
21865 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21866 }
21867 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21868 {
21869 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21870 }
21871 else
21872 {
21873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21874 "%s:Acl Policy : %d is not supported",
21875 __func__, params->acl_policy);
21876 return -ENOTSUPP;
21877 }
21878
21879 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21880 {
21881 pConfig->num_accept_mac = params->n_acl_entries;
21882 for (i = 0; i < params->n_acl_entries; i++)
21883 {
21884 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21885 "** Add ACL MAC entry %i in WhiletList :"
21886 MAC_ADDRESS_STR, i,
21887 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21888
21889 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21890 sizeof(qcmacaddr));
21891 }
21892 }
21893 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21894 {
21895 pConfig->num_deny_mac = params->n_acl_entries;
21896 for (i = 0; i < params->n_acl_entries; i++)
21897 {
21898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21899 "** Add ACL MAC entry %i in BlackList :"
21900 MAC_ADDRESS_STR, i,
21901 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21902
21903 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21904 sizeof(qcmacaddr));
21905 }
21906 }
21907
21908 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21909 {
21910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21911 "%s: SAP Set Mac Acl fail", __func__);
21912 return -EINVAL;
21913 }
21914 }
21915 else
21916 {
21917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021918 "%s: Invalid device_mode = %s (%d)",
21919 __func__, hdd_device_modetoString(pAdapter->device_mode),
21920 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021921 return -EINVAL;
21922 }
21923
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021924 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021925 return 0;
21926}
21927
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021928static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21929 struct net_device *dev,
21930 const struct cfg80211_acl_data *params)
21931{
21932 int ret;
21933 vos_ssr_protect(__func__);
21934 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21935 vos_ssr_unprotect(__func__);
21936
21937 return ret;
21938}
21939
Leo Chang9056f462013-08-01 19:21:11 -070021940#ifdef WLAN_NL80211_TESTMODE
21941#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021942void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021943(
21944 void *pAdapter,
21945 void *indCont
21946)
21947{
Leo Changd9df8aa2013-09-26 13:32:26 -070021948 tSirLPHBInd *lphbInd;
21949 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021950 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021951
21952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021953 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021954
c_hpothu73f35e62014-04-18 13:40:08 +053021955 if (pAdapter == NULL)
21956 {
21957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21958 "%s: pAdapter is NULL\n",__func__);
21959 return;
21960 }
21961
Leo Chang9056f462013-08-01 19:21:11 -070021962 if (NULL == indCont)
21963 {
21964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021965 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021966 return;
21967 }
21968
c_hpothu73f35e62014-04-18 13:40:08 +053021969 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021970 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021971 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021972 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021973 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021974 GFP_ATOMIC);
21975 if (!skb)
21976 {
21977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21978 "LPHB timeout, NL buffer alloc fail");
21979 return;
21980 }
21981
Leo Changac3ba772013-10-07 09:47:04 -070021982 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021983 {
21984 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21985 "WLAN_HDD_TM_ATTR_CMD put fail");
21986 goto nla_put_failure;
21987 }
Leo Changac3ba772013-10-07 09:47:04 -070021988 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021989 {
21990 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21991 "WLAN_HDD_TM_ATTR_TYPE put fail");
21992 goto nla_put_failure;
21993 }
Leo Changac3ba772013-10-07 09:47:04 -070021994 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021995 sizeof(tSirLPHBInd), lphbInd))
21996 {
21997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21998 "WLAN_HDD_TM_ATTR_DATA put fail");
21999 goto nla_put_failure;
22000 }
Leo Chang9056f462013-08-01 19:21:11 -070022001 cfg80211_testmode_event(skb, GFP_ATOMIC);
22002 return;
22003
22004nla_put_failure:
22005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22006 "NLA Put fail");
22007 kfree_skb(skb);
22008
22009 return;
22010}
22011#endif /* FEATURE_WLAN_LPHB */
22012
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022013static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070022014{
22015 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
22016 int err = 0;
22017#ifdef FEATURE_WLAN_LPHB
22018 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070022019 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022020
22021 ENTER();
22022
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022023 err = wlan_hdd_validate_context(pHddCtx);
22024 if (0 != err)
22025 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022026 return err;
22027 }
Leo Chang9056f462013-08-01 19:21:11 -070022028#endif /* FEATURE_WLAN_LPHB */
22029
22030 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
22031 if (err)
22032 {
22033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22034 "%s Testmode INV ATTR", __func__);
22035 return err;
22036 }
22037
22038 if (!tb[WLAN_HDD_TM_ATTR_CMD])
22039 {
22040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22041 "%s Testmode INV CMD", __func__);
22042 return -EINVAL;
22043 }
22044
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022045 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22046 TRACE_CODE_HDD_CFG80211_TESTMODE,
22047 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070022048 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
22049 {
22050#ifdef FEATURE_WLAN_LPHB
22051 /* Low Power Heartbeat configuration request */
22052 case WLAN_HDD_TM_CMD_WLAN_HB:
22053 {
22054 int buf_len;
22055 void *buf;
22056 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080022057 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070022058
22059 if (!tb[WLAN_HDD_TM_ATTR_DATA])
22060 {
22061 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22062 "%s Testmode INV DATA", __func__);
22063 return -EINVAL;
22064 }
22065
22066 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
22067 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080022068
Manjeet Singh3c577442017-02-10 19:03:38 +053022069 if (buf_len > sizeof(*hb_params)) {
22070 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
22071 buf_len);
22072 return -ERANGE;
22073 }
22074
Amar Singhal05852702014-02-04 14:40:00 -080022075 hb_params_temp =(tSirLPHBReq *)buf;
22076 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
22077 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
22078 return -EINVAL;
22079
Leo Chang9056f462013-08-01 19:21:11 -070022080 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
22081 if (NULL == hb_params)
22082 {
22083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22084 "%s Request Buffer Alloc Fail", __func__);
22085 return -EINVAL;
22086 }
22087
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053022088 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070022089 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070022090 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
22091 hb_params,
22092 wlan_hdd_cfg80211_lphb_ind_handler);
22093 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070022094 {
Leo Changd9df8aa2013-09-26 13:32:26 -070022095 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22096 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070022097 vos_mem_free(hb_params);
22098 }
Leo Chang9056f462013-08-01 19:21:11 -070022099 return 0;
22100 }
22101#endif /* FEATURE_WLAN_LPHB */
22102 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053022103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22104 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070022105 return -EOPNOTSUPP;
22106 }
22107
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022108 EXIT();
22109 return err;
Leo Chang9056f462013-08-01 19:21:11 -070022110}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022111
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053022112static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
22113#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
22114 struct wireless_dev *wdev,
22115#endif
22116 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022117{
22118 int ret;
22119
22120 vos_ssr_protect(__func__);
22121 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
22122 vos_ssr_unprotect(__func__);
22123
22124 return ret;
22125}
Leo Chang9056f462013-08-01 19:21:11 -070022126#endif /* CONFIG_NL80211_TESTMODE */
22127
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022128extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022129static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022130 struct net_device *dev,
22131 int idx, struct survey_info *survey)
22132{
22133 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
22134 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053022135 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022136 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053022137 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022138 v_S7_t snr,rssi;
22139 int status, i, j, filled = 0;
22140
22141 ENTER();
22142
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022143 if (NULL == pAdapter)
22144 {
22145 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
22146 "%s: HDD adapter is Null", __func__);
22147 return -ENODEV;
22148 }
22149
22150 if (NULL == wiphy)
22151 {
22152 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
22153 "%s: wiphy is Null", __func__);
22154 return -ENODEV;
22155 }
22156
22157 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
22158 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022159 if (0 != status)
22160 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022161 return status;
22162 }
22163
Mihir Sheted9072e02013-08-21 17:02:29 +053022164 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
22165
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022166 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053022167 0 != pAdapter->survey_idx ||
22168 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022169 {
22170 /* The survey dump ops when implemented completely is expected to
22171 * return a survey of all channels and the ops is called by the
22172 * kernel with incremental values of the argument 'idx' till it
22173 * returns -ENONET. But we can only support the survey for the
22174 * operating channel for now. survey_idx is used to track
22175 * that the ops is called only once and then return -ENONET for
22176 * the next iteration
22177 */
22178 pAdapter->survey_idx = 0;
22179 return -ENONET;
22180 }
22181
Mukul Sharma9d5233b2015-06-11 20:28:20 +053022182 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
22183 {
22184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22185 "%s: Roaming in progress, hence return ", __func__);
22186 return -ENONET;
22187 }
22188
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022189 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
22190
22191 wlan_hdd_get_snr(pAdapter, &snr);
22192 wlan_hdd_get_rssi(pAdapter, &rssi);
22193
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022194 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22195 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
22196 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022197 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
22198 hdd_wlan_get_freq(channel, &freq);
22199
22200
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053022201 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022202 {
22203 if (NULL == wiphy->bands[i])
22204 {
22205 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
22206 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
22207 continue;
22208 }
22209
22210 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
22211 {
22212 struct ieee80211_supported_band *band = wiphy->bands[i];
22213
22214 if (band->channels[j].center_freq == (v_U16_t)freq)
22215 {
22216 survey->channel = &band->channels[j];
22217 /* The Rx BDs contain SNR values in dB for the received frames
22218 * while the supplicant expects noise. So we calculate and
22219 * return the value of noise (dBm)
22220 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
22221 */
22222 survey->noise = rssi - snr;
22223 survey->filled = SURVEY_INFO_NOISE_DBM;
22224 filled = 1;
22225 }
22226 }
22227 }
22228
22229 if (filled)
22230 pAdapter->survey_idx = 1;
22231 else
22232 {
22233 pAdapter->survey_idx = 0;
22234 return -ENONET;
22235 }
22236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022237 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022238 return 0;
22239}
22240
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022241static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
22242 struct net_device *dev,
22243 int idx, struct survey_info *survey)
22244{
22245 int ret;
22246
22247 vos_ssr_protect(__func__);
22248 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
22249 vos_ssr_unprotect(__func__);
22250
22251 return ret;
22252}
22253
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022254/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022255 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022256 * this is called when cfg80211 driver resume
22257 * driver updates latest sched_scan scan result(if any) to cfg80211 database
22258 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022259int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022260{
22261 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
22262 hdd_adapter_t *pAdapter;
22263 hdd_adapter_list_node_t *pAdapterNode, *pNext;
22264 VOS_STATUS status = VOS_STATUS_SUCCESS;
22265
22266 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022267
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053022268 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022269 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022270 return 0;
22271 }
22272
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022273 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
22274 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022275
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022276 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022277 {
22278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22279 "%s: Resume SoftAP", __func__);
22280 hdd_set_wlan_suspend_mode(false);
22281 }
22282
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022283 spin_lock(&pHddCtx->schedScan_lock);
22284 pHddCtx->isWiphySuspended = FALSE;
22285 if (TRUE != pHddCtx->isSchedScanUpdatePending)
22286 {
22287 spin_unlock(&pHddCtx->schedScan_lock);
22288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22289 "%s: Return resume is not due to PNO indication", __func__);
22290 return 0;
22291 }
22292 // Reset flag to avoid updatating cfg80211 data old results again
22293 pHddCtx->isSchedScanUpdatePending = FALSE;
22294 spin_unlock(&pHddCtx->schedScan_lock);
22295
22296 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
22297
22298 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
22299 {
22300 pAdapter = pAdapterNode->pAdapter;
22301 if ( (NULL != pAdapter) &&
22302 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
22303 {
22304 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022305 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
22307 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022308 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022309 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022310 {
22311 /* Acquire wakelock to handle the case where APP's tries to
22312 * suspend immediately after updating the scan results. Whis
22313 * results in app's is in suspended state and not able to
22314 * process the connect request to AP
22315 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053022316 hdd_prevent_suspend_timeout(2000,
22317 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022318 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022319 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022320
22321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22322 "%s : cfg80211 scan result database updated", __func__);
22323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022324 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022325 return 0;
22326
22327 }
22328 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
22329 pAdapterNode = pNext;
22330 }
22331
22332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22333 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022334 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022335 return 0;
22336}
22337
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022338int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
22339{
22340 int ret;
22341
22342 vos_ssr_protect(__func__);
22343 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
22344 vos_ssr_unprotect(__func__);
22345
22346 return ret;
22347}
22348
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022349/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022350 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022351 * this is called when cfg80211 driver suspends
22352 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022353int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022354 struct cfg80211_wowlan *wow)
22355{
22356 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022357 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022358
22359 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022360
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022361 ret = wlan_hdd_validate_context(pHddCtx);
22362 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022363 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022364 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022365 }
22366
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022367 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022368 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22369 "%s: Suspend SoftAP", __func__);
22370 hdd_set_wlan_suspend_mode(true);
22371 }
22372
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022373
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022374 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22375 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
22376 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022377 pHddCtx->isWiphySuspended = TRUE;
22378
22379 EXIT();
22380
22381 return 0;
22382}
22383
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022384int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
22385 struct cfg80211_wowlan *wow)
22386{
22387 int ret;
22388
22389 vos_ssr_protect(__func__);
22390 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
22391 vos_ssr_unprotect(__func__);
22392
22393 return ret;
22394}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022395
22396#ifdef FEATURE_OEM_DATA_SUPPORT
22397static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022398 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022399{
22400 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22401
22402 ENTER();
22403
22404 if (wlan_hdd_validate_context(pHddCtx)) {
22405 return;
22406 }
22407 if (!pMsg)
22408 {
22409 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
22410 return;
22411 }
22412
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022413 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022414
22415 EXIT();
22416 return;
22417
22418}
22419
22420void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022421 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022422{
22423 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22424
22425 ENTER();
22426
22427 if (wlan_hdd_validate_context(pHddCtx)) {
22428 return;
22429 }
22430
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022431 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022432
22433 switch(evType) {
22434 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022435 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022436 break;
22437 default:
22438 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22439 break;
22440 }
22441 EXIT();
22442}
22443#endif
22444
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022445#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22446 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022447/**
22448 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22449 * @wiphy: Pointer to wiphy
22450 * @wdev: Pointer to wireless device structure
22451 *
22452 * This function is used to abort an ongoing scan
22453 *
22454 * Return: None
22455 */
22456static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22457 struct wireless_dev *wdev)
22458{
22459 struct net_device *dev = wdev->netdev;
22460 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22461 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22462 int ret;
22463
22464 ENTER();
22465
22466 if (NULL == adapter) {
22467 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22468 return;
22469 }
22470
22471 ret = wlan_hdd_validate_context(hdd_ctx);
22472 if (0 != ret)
22473 return;
22474
22475 wlan_hdd_scan_abort(adapter);
22476
22477 return;
22478}
22479
22480/**
22481 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22482 * @wiphy: Pointer to wiphy
22483 * @wdev: Pointer to wireless device structure
22484 *
22485 * Return: None
22486 */
22487void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22488 struct wireless_dev *wdev)
22489{
22490 vos_ssr_protect(__func__);
22491 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22492 vos_ssr_unprotect(__func__);
22493
22494 return;
22495}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022496#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022497
Abhishek Singh936c6932017-11-07 17:28:23 +053022498#ifdef CHANNEL_SWITCH_SUPPORTED
22499/**
22500 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22501 * channel in SAP/GO
22502 * @wiphy: wiphy pointer
22503 * @dev: dev pointer.
22504 * @csa_params: Change channel params
22505 *
22506 * This function is called to switch channel in SAP/GO
22507 *
22508 * Return: 0 if success else return non zero
22509 */
22510static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22511 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22512{
22513 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22514 hdd_context_t *hdd_ctx;
22515 uint8_t channel;
22516 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022517 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022518 v_CONTEXT_t vos_ctx;
22519
22520 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22521
22522 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22523 ret = wlan_hdd_validate_context(hdd_ctx);
22524 if (ret)
22525 return ret;
22526
22527 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22528 if (!vos_ctx) {
22529 hddLog(LOGE, FL("Vos ctx is null"));
22530 return -EINVAL;
22531 }
22532
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022533 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022534 return -ENOTSUPP;
22535
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022536 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22537 if (!sap_ctx) {
22538 hddLog(LOGE, FL("sap_ctx is NULL"));
22539 return -EINVAL;
22540 }
22541
22542 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22543 if (ret)
22544 return ret;
22545
22546 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22547
Abhishek Singh936c6932017-11-07 17:28:23 +053022548 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022549 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022550
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022551 if (ret) {
22552 wlansap_reset_chan_change_in_progress(sap_ctx);
22553 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22554 }
22555
Abhishek Singh936c6932017-11-07 17:28:23 +053022556 return ret;
22557}
22558
22559/**
22560 * wlan_hdd_cfg80211_channel_switch()- function to switch
22561 * channel in SAP/GO
22562 * @wiphy: wiphy pointer
22563 * @dev: dev pointer.
22564 * @csa_params: Change channel params
22565 *
22566 * This function is called to switch channel in SAP/GO
22567 *
22568 * Return: 0 if success else return non zero
22569 */
22570static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22571 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22572{
22573 int ret;
22574
22575 vos_ssr_protect(__func__);
22576 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22577 vos_ssr_unprotect(__func__);
22578
22579 return ret;
22580}
22581#endif
22582
Jeff Johnson295189b2012-06-20 16:38:30 -070022583/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022584static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022585{
22586 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22587 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22588 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22589 .change_station = wlan_hdd_change_station,
22590#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22591 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22592 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22593 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022594#else
22595 .start_ap = wlan_hdd_cfg80211_start_ap,
22596 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22597 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022598#endif
22599 .change_bss = wlan_hdd_cfg80211_change_bss,
22600 .add_key = wlan_hdd_cfg80211_add_key,
22601 .get_key = wlan_hdd_cfg80211_get_key,
22602 .del_key = wlan_hdd_cfg80211_del_key,
22603 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022604#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022605 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022606#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022607 .scan = wlan_hdd_cfg80211_scan,
22608 .connect = wlan_hdd_cfg80211_connect,
22609 .disconnect = wlan_hdd_cfg80211_disconnect,
22610 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22611 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22612 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22613 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22614 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022615 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22616 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022617 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022618#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22619 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22620 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22621 .set_txq_params = wlan_hdd_set_txq_params,
22622#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022623 .get_station = wlan_hdd_cfg80211_get_station,
22624 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22625 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022626 .add_station = wlan_hdd_cfg80211_add_station,
22627#ifdef FEATURE_WLAN_LFR
22628 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22629 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22630 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22631#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022632#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22633 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22634#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022635#ifdef FEATURE_WLAN_TDLS
22636 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22637 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22638#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022639#ifdef WLAN_FEATURE_GTK_OFFLOAD
22640 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22641#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022642#ifdef FEATURE_WLAN_SCAN_PNO
22643 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22644 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22645#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022646 .resume = wlan_hdd_cfg80211_resume_wlan,
22647 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022648 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022649#ifdef WLAN_NL80211_TESTMODE
22650 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22651#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022652 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022653#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22654 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022655 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022656#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022657#ifdef CHANNEL_SWITCH_SUPPORTED
22658 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22659#endif
22660
Abhinav Kumar118efd02019-08-07 16:41:07 +053022661#if defined(WLAN_FEATURE_SAE) && \
22662 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
22663 .external_auth = wlan_hdd_cfg80211_external_auth,
22664#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022665};
22666