blob: c448ba5a273807e6096f1ad5326b6aa463d7e180 [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
c_manjeecfd1efb2015-09-25 19:32:34 +05306368
6369static int
6370__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6371 struct wireless_dev *wdev,
6372 const void *data, int data_len)
6373{
6374 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6375 int ret;
6376 ENTER();
6377
6378 ret = wlan_hdd_validate_context(pHddCtx);
6379 if (0 != ret)
6380 {
6381 return ret;
6382 }
6383
6384 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6385 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6386 {
6387 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306388 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306389 }
6390 /*call common API for FW mem dump req*/
6391 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6392
Abhishek Singhc783fa72015-12-09 18:07:34 +05306393 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306394 {
6395 /*indicate to userspace the status of fw mem dump */
6396 wlan_indicate_mem_dump_complete(true);
6397 }
6398 else
6399 {
6400 /*else send failure to userspace */
6401 wlan_indicate_mem_dump_complete(false);
6402 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306403 EXIT();
6404 return ret;
6405}
6406
6407/**
6408 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6409 * @wiphy: pointer to wireless wiphy structure.
6410 * @wdev: pointer to wireless_dev structure.
6411 * @data: Pointer to the NL data.
6412 * @data_len:Length of @data
6413 *
6414 * This is called when wlan driver needs to get the firmware memory dump
6415 * via vendor specific command.
6416 *
6417 * Return: 0 on success, error number otherwise.
6418 */
6419
6420static int
6421wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6422 struct wireless_dev *wdev,
6423 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306424{
6425 int ret = 0;
6426 vos_ssr_protect(__func__);
6427 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6428 data_len);
6429 vos_ssr_unprotect(__func__);
6430 return ret;
6431}
c_manjeecfd1efb2015-09-25 19:32:34 +05306432
Sushant Kaushik8e644982015-09-23 12:18:54 +05306433static const struct
6434nla_policy
6435qca_wlan_vendor_wifi_logger_start_policy
6436[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6437 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6438 = {.type = NLA_U32 },
6439 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6440 = {.type = NLA_U32 },
6441 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6442 = {.type = NLA_U32 },
6443};
6444
6445/**
6446 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6447 * or disable the collection of packet statistics from the firmware
6448 * @wiphy: WIPHY structure pointer
6449 * @wdev: Wireless device structure pointer
6450 * @data: Pointer to the data received
6451 * @data_len: Length of the data received
6452 *
6453 * This function is used to enable or disable the collection of packet
6454 * statistics from the firmware
6455 *
6456 * Return: 0 on success and errno on failure
6457 */
6458static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6459 struct wireless_dev *wdev,
6460 const void *data,
6461 int data_len)
6462{
6463 eHalStatus status;
6464 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6465 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6466 tAniWifiStartLog start_log;
6467
6468 status = wlan_hdd_validate_context(hdd_ctx);
6469 if (0 != status) {
6470 return -EINVAL;
6471 }
6472
6473 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6474 data, data_len,
6475 qca_wlan_vendor_wifi_logger_start_policy)) {
6476 hddLog(LOGE, FL("Invalid attribute"));
6477 return -EINVAL;
6478 }
6479
6480 /* Parse and fetch ring id */
6481 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6482 hddLog(LOGE, FL("attr ATTR failed"));
6483 return -EINVAL;
6484 }
6485 start_log.ringId = nla_get_u32(
6486 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6487 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6488
6489 /* Parse and fetch verbose level */
6490 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6491 hddLog(LOGE, FL("attr verbose_level failed"));
6492 return -EINVAL;
6493 }
6494 start_log.verboseLevel = nla_get_u32(
6495 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6496 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6497
6498 /* Parse and fetch flag */
6499 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6500 hddLog(LOGE, FL("attr flag failed"));
6501 return -EINVAL;
6502 }
6503 start_log.flag = nla_get_u32(
6504 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6505 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6506
6507 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306508 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6509 !vos_isPktStatsEnabled()))
6510
Sushant Kaushik8e644982015-09-23 12:18:54 +05306511 {
6512 hddLog(LOGE, FL("per pkt stats not enabled"));
6513 return -EINVAL;
6514 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306515
Sushant Kaushik33200572015-08-05 16:46:20 +05306516 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306517 return 0;
6518}
6519
6520/**
6521 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6522 * or disable the collection of packet statistics from the firmware
6523 * @wiphy: WIPHY structure pointer
6524 * @wdev: Wireless device structure pointer
6525 * @data: Pointer to the data received
6526 * @data_len: Length of the data received
6527 *
6528 * This function is used to enable or disable the collection of packet
6529 * statistics from the firmware
6530 *
6531 * Return: 0 on success and errno on failure
6532 */
6533static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6534 struct wireless_dev *wdev,
6535 const void *data,
6536 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306537{
6538 int ret = 0;
6539
6540 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306541
6542 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6543 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306544 vos_ssr_unprotect(__func__);
6545
6546 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306547}
6548
6549
Agarwal Ashish738843c2014-09-25 12:27:56 +05306550static const struct nla_policy
6551wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6552 +1] =
6553{
6554 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6555};
6556
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306557static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306558 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306559 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306560 int data_len)
6561{
6562 struct net_device *dev = wdev->netdev;
6563 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6564 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6565 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6566 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6567 eHalStatus status;
6568 u32 dfsFlag = 0;
6569
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306570 ENTER();
6571
Agarwal Ashish738843c2014-09-25 12:27:56 +05306572 status = wlan_hdd_validate_context(pHddCtx);
6573 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306574 return -EINVAL;
6575 }
6576 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6577 data, data_len,
6578 wlan_hdd_set_no_dfs_flag_config_policy)) {
6579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6580 return -EINVAL;
6581 }
6582
6583 /* Parse and fetch required bandwidth kbps */
6584 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6586 return -EINVAL;
6587 }
6588
6589 dfsFlag = nla_get_u32(
6590 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6591 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6592 dfsFlag);
6593
6594 pHddCtx->disable_dfs_flag = dfsFlag;
6595
6596 sme_disable_dfs_channel(hHal, dfsFlag);
6597 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306598
6599 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306600 return 0;
6601}
Atul Mittal115287b2014-07-08 13:26:33 +05306602
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306603static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6604 struct wireless_dev *wdev,
6605 const void *data,
6606 int data_len)
6607{
6608 int ret = 0;
6609
6610 vos_ssr_protect(__func__);
6611 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6612 vos_ssr_unprotect(__func__);
6613
6614 return ret;
6615
6616}
6617
Mukul Sharma2a271632014-10-13 14:59:01 +05306618const struct
6619nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6620{
6621 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306622 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6623 .type = NLA_UNSPEC,
6624 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306625};
6626
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306627static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306628 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306629{
6630
6631 u8 bssid[6] = {0};
6632 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6633 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6634 eHalStatus status = eHAL_STATUS_SUCCESS;
6635 v_U32_t isFwrRoamEnabled = FALSE;
6636 int ret;
6637
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306638 ENTER();
6639
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306640 ret = wlan_hdd_validate_context(pHddCtx);
6641 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306642 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306643 }
6644
6645 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6646 data, data_len,
6647 qca_wlan_vendor_attr);
6648 if (ret){
6649 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6650 return -EINVAL;
6651 }
6652
6653 /* Parse and fetch Enable flag */
6654 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6655 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6656 return -EINVAL;
6657 }
6658
6659 isFwrRoamEnabled = nla_get_u32(
6660 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6661
6662 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6663
6664 /* Parse and fetch bssid */
6665 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6666 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6667 return -EINVAL;
6668 }
6669
6670 memcpy(bssid, nla_data(
6671 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6672 sizeof(bssid));
6673 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6674
6675 //Update roaming
6676 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306677 if (!HAL_STATUS_SUCCESS(status)) {
6678 hddLog(LOGE,
6679 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6680 return -EINVAL;
6681 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306682 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306683 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306684}
6685
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306686static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6687 struct wireless_dev *wdev, const void *data, int data_len)
6688{
6689 int ret = 0;
6690
6691 vos_ssr_protect(__func__);
6692 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6693 vos_ssr_unprotect(__func__);
6694
6695 return ret;
6696}
6697
Sushant Kaushik847890c2015-09-28 16:05:17 +05306698static const struct
6699nla_policy
6700qca_wlan_vendor_get_wifi_info_policy[
6701 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6702 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6703 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6704};
6705
6706
6707/**
6708 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6709 * @wiphy: pointer to wireless wiphy structure.
6710 * @wdev: pointer to wireless_dev structure.
6711 * @data: Pointer to the data to be passed via vendor interface
6712 * @data_len:Length of the data to be passed
6713 *
6714 * This is called when wlan driver needs to send wifi driver related info
6715 * (driver/fw version) to the user space application upon request.
6716 *
6717 * Return: Return the Success or Failure code.
6718 */
6719static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6720 struct wireless_dev *wdev,
6721 const void *data, int data_len)
6722{
6723 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6724 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6725 tSirVersionString version;
6726 uint32 version_len;
6727 uint8 attr;
6728 int status;
6729 struct sk_buff *reply_skb = NULL;
6730
6731 if (VOS_FTM_MODE == hdd_get_conparam()) {
6732 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6733 return -EINVAL;
6734 }
6735
6736 status = wlan_hdd_validate_context(hdd_ctx);
6737 if (0 != status) {
6738 hddLog(LOGE, FL("HDD context is not valid"));
6739 return -EINVAL;
6740 }
6741
6742 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6743 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6744 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6745 return -EINVAL;
6746 }
6747
6748 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6749 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6750 QWLAN_VERSIONSTR);
6751 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6752 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6753 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6754 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6755 hdd_ctx->fw_Version);
6756 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6757 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6758 } else {
6759 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6760 return -EINVAL;
6761 }
6762
6763 version_len = strlen(version);
6764 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6765 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6766 if (!reply_skb) {
6767 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6768 return -ENOMEM;
6769 }
6770
6771 if (nla_put(reply_skb, attr, version_len, version)) {
6772 hddLog(LOGE, FL("nla put fail"));
6773 kfree_skb(reply_skb);
6774 return -EINVAL;
6775 }
6776
6777 return cfg80211_vendor_cmd_reply(reply_skb);
6778}
6779
6780/**
6781 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6782 * @wiphy: pointer to wireless wiphy structure.
6783 * @wdev: pointer to wireless_dev structure.
6784 * @data: Pointer to the data to be passed via vendor interface
6785 * @data_len:Length of the data to be passed
6786 * @data_len: Length of the data received
6787 *
6788 * This function is used to enable or disable the collection of packet
6789 * statistics from the firmware
6790 *
6791 * Return: 0 on success and errno on failure
6792 */
6793
6794static int
6795wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6796 struct wireless_dev *wdev,
6797 const void *data, int data_len)
6798
6799
6800{
6801 int ret = 0;
6802
6803 vos_ssr_protect(__func__);
6804 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6805 wdev, data, data_len);
6806 vos_ssr_unprotect(__func__);
6807
6808 return ret;
6809}
6810
6811
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306812/*
6813 * define short names for the global vendor params
6814 * used by __wlan_hdd_cfg80211_monitor_rssi()
6815 */
6816#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6817#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6818#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6819#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6820#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6821
6822/**---------------------------------------------------------------------------
6823
6824 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6825 monitor start is completed successfully.
6826
6827 \return - None
6828
6829 --------------------------------------------------------------------------*/
6830void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6831{
6832 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6833
6834 if (NULL == pHddCtx)
6835 {
6836 hddLog(VOS_TRACE_LEVEL_ERROR,
6837 "%s: HDD context is NULL",__func__);
6838 return;
6839 }
6840
6841 if (VOS_STATUS_SUCCESS == status)
6842 {
6843 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6844 }
6845 else
6846 {
6847 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6848 }
6849
6850 return;
6851}
6852
6853/**---------------------------------------------------------------------------
6854
6855 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6856 stop is completed successfully.
6857
6858 \return - None
6859
6860 --------------------------------------------------------------------------*/
6861void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6862{
6863 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6864
6865 if (NULL == pHddCtx)
6866 {
6867 hddLog(VOS_TRACE_LEVEL_ERROR,
6868 "%s: HDD context is NULL",__func__);
6869 return;
6870 }
6871
6872 if (VOS_STATUS_SUCCESS == status)
6873 {
6874 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6875 }
6876 else
6877 {
6878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6879 }
6880
6881 return;
6882}
6883
6884/**
6885 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6886 * @wiphy: Pointer to wireless phy
6887 * @wdev: Pointer to wireless device
6888 * @data: Pointer to data
6889 * @data_len: Data length
6890 *
6891 * Return: 0 on success, negative errno on failure
6892 */
6893
6894static int
6895__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6896 struct wireless_dev *wdev,
6897 const void *data,
6898 int data_len)
6899{
6900 struct net_device *dev = wdev->netdev;
6901 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6902 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6903 hdd_station_ctx_t *pHddStaCtx;
6904 struct nlattr *tb[PARAM_MAX + 1];
6905 tpSirRssiMonitorReq pReq;
6906 eHalStatus status;
6907 int ret;
6908 uint32_t control;
6909 static const struct nla_policy policy[PARAM_MAX + 1] = {
6910 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6911 [PARAM_CONTROL] = { .type = NLA_U32 },
6912 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6913 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6914 };
6915
6916 ENTER();
6917
6918 ret = wlan_hdd_validate_context(hdd_ctx);
6919 if (0 != ret) {
6920 return -EINVAL;
6921 }
6922
6923 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6924 hddLog(LOGE, FL("Not in Connected state!"));
6925 return -ENOTSUPP;
6926 }
6927
6928 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6929 hddLog(LOGE, FL("Invalid ATTR"));
6930 return -EINVAL;
6931 }
6932
6933 if (!tb[PARAM_REQUEST_ID]) {
6934 hddLog(LOGE, FL("attr request id failed"));
6935 return -EINVAL;
6936 }
6937
6938 if (!tb[PARAM_CONTROL]) {
6939 hddLog(LOGE, FL("attr control failed"));
6940 return -EINVAL;
6941 }
6942
6943 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6944
6945 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6946 if(NULL == pReq)
6947 {
6948 hddLog(LOGE,
6949 FL("vos_mem_alloc failed "));
6950 return eHAL_STATUS_FAILED_ALLOC;
6951 }
6952 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6953
6954 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6955 pReq->sessionId = pAdapter->sessionId;
6956 pReq->rssiMonitorCbContext = hdd_ctx;
6957 control = nla_get_u32(tb[PARAM_CONTROL]);
6958 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6959
6960 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6961 pReq->requestId, pReq->sessionId, control);
6962
6963 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6964 if (!tb[PARAM_MIN_RSSI]) {
6965 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306966 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306967 }
6968
6969 if (!tb[PARAM_MAX_RSSI]) {
6970 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306971 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306972 }
6973
6974 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6975 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6976 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6977
6978 if (!(pReq->minRssi < pReq->maxRssi)) {
6979 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6980 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306981 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306982 }
6983 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6984 pReq->minRssi, pReq->maxRssi);
6985 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6986
6987 }
6988 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6989 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6990 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6991 }
6992 else {
6993 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306994 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306995 }
6996
6997 if (!HAL_STATUS_SUCCESS(status)) {
6998 hddLog(LOGE,
6999 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307000 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307001 }
7002
7003 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307004fail:
7005 vos_mem_free(pReq);
7006 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307007}
7008
7009/*
7010 * done with short names for the global vendor params
7011 * used by __wlan_hdd_cfg80211_monitor_rssi()
7012 */
7013#undef PARAM_MAX
7014#undef PARAM_CONTROL
7015#undef PARAM_REQUEST_ID
7016#undef PARAM_MAX_RSSI
7017#undef PARAM_MIN_RSSI
7018
7019/**
7020 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7021 * @wiphy: wiphy structure pointer
7022 * @wdev: Wireless device structure pointer
7023 * @data: Pointer to the data received
7024 * @data_len: Length of @data
7025 *
7026 * Return: 0 on success; errno on failure
7027 */
7028static int
7029wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7030 const void *data, int data_len)
7031{
7032 int ret;
7033
7034 vos_ssr_protect(__func__);
7035 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7036 vos_ssr_unprotect(__func__);
7037
7038 return ret;
7039}
7040
7041/**
7042 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7043 * @hddctx: HDD context
7044 * @data: rssi breached event data
7045 *
7046 * This function reads the rssi breached event %data and fill in the skb with
7047 * NL attributes and send up the NL event.
7048 * This callback execute in atomic context and must not invoke any
7049 * blocking calls.
7050 *
7051 * Return: none
7052 */
7053void hdd_rssi_threshold_breached_cb(void *hddctx,
7054 struct rssi_breach_event *data)
7055{
7056 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7057 int status;
7058 struct sk_buff *skb;
7059
7060 ENTER();
7061 status = wlan_hdd_validate_context(pHddCtx);
7062
7063 if (0 != status) {
7064 return;
7065 }
7066
7067 if (!data) {
7068 hddLog(LOGE, FL("data is null"));
7069 return;
7070 }
7071
7072 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7073#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7074 NULL,
7075#endif
7076 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7077 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7078 GFP_KERNEL);
7079
7080 if (!skb) {
7081 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7082 return;
7083 }
7084
7085 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7086 data->request_id, data->curr_rssi);
7087 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7088 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7089
7090 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7091 data->request_id) ||
7092 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7093 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7094 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7095 data->curr_rssi)) {
7096 hddLog(LOGE, FL("nla put fail"));
7097 goto fail;
7098 }
7099
7100 cfg80211_vendor_event(skb, GFP_KERNEL);
7101 return;
7102
7103fail:
7104 kfree_skb(skb);
7105 return;
7106}
7107
7108
7109
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307110/**
7111 * __wlan_hdd_cfg80211_setband() - set band
7112 * @wiphy: Pointer to wireless phy
7113 * @wdev: Pointer to wireless device
7114 * @data: Pointer to data
7115 * @data_len: Data length
7116 *
7117 * Return: 0 on success, negative errno on failure
7118 */
7119static int
7120__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7121 struct wireless_dev *wdev,
7122 const void *data,
7123 int data_len)
7124{
7125 struct net_device *dev = wdev->netdev;
7126 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7127 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7128 int ret;
7129 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7130 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7131
7132 ENTER();
7133
7134 ret = wlan_hdd_validate_context(hdd_ctx);
7135 if (0 != ret) {
7136 hddLog(LOGE, FL("HDD context is not valid"));
7137 return ret;
7138 }
7139
7140 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7141 policy)) {
7142 hddLog(LOGE, FL("Invalid ATTR"));
7143 return -EINVAL;
7144 }
7145
7146 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7147 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7148 return -EINVAL;
7149 }
7150
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307151 hdd_ctx->isSetBandByNL = TRUE;
7152 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307153 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307154 hdd_ctx->isSetBandByNL = FALSE;
7155
7156 EXIT();
7157 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307158}
7159
7160/**
7161 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7162 * @wiphy: wiphy structure pointer
7163 * @wdev: Wireless device structure pointer
7164 * @data: Pointer to the data received
7165 * @data_len: Length of @data
7166 *
7167 * Return: 0 on success; errno on failure
7168 */
7169static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7170 struct wireless_dev *wdev,
7171 const void *data,
7172 int data_len)
7173{
7174 int ret = 0;
7175
7176 vos_ssr_protect(__func__);
7177 ret = __wlan_hdd_cfg80211_setband(wiphy,
7178 wdev, data, data_len);
7179 vos_ssr_unprotect(__func__);
7180
7181 return ret;
7182}
7183
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307184#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7185/**
7186 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7187 * @hdd_ctx: HDD context
7188 * @request_id: [input] request id
7189 * @pattern_id: [output] pattern id
7190 *
7191 * This function loops through request id to pattern id array
7192 * if the slot is available, store the request id and return pattern id
7193 * if entry exists, return the pattern id
7194 *
7195 * Return: 0 on success and errno on failure
7196 */
7197static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7198 uint32_t request_id,
7199 uint8_t *pattern_id)
7200{
7201 uint32_t i;
7202
7203 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7204 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7205 {
7206 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7207 {
7208 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7209 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7210 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7211 return 0;
7212 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7213 request_id) {
7214 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7215 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7216 return 0;
7217 }
7218 }
7219 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7220 return -EINVAL;
7221}
7222
7223/**
7224 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7225 * @hdd_ctx: HDD context
7226 * @request_id: [input] request id
7227 * @pattern_id: [output] pattern id
7228 *
7229 * This function loops through request id to pattern id array
7230 * reset request id to 0 (slot available again) and
7231 * return pattern id
7232 *
7233 * Return: 0 on success and errno on failure
7234 */
7235static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7236 uint32_t request_id,
7237 uint8_t *pattern_id)
7238{
7239 uint32_t i;
7240
7241 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7242 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7243 {
7244 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7245 {
7246 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7247 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7248 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7249 return 0;
7250 }
7251 }
7252 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7253 return -EINVAL;
7254}
7255
7256
7257/*
7258 * define short names for the global vendor params
7259 * used by __wlan_hdd_cfg80211_offloaded_packets()
7260 */
7261#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7262#define PARAM_REQUEST_ID \
7263 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7264#define PARAM_CONTROL \
7265 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7266#define PARAM_IP_PACKET \
7267 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7268#define PARAM_SRC_MAC_ADDR \
7269 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7270#define PARAM_DST_MAC_ADDR \
7271 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7272#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7273
7274/**
7275 * wlan_hdd_add_tx_ptrn() - add tx pattern
7276 * @adapter: adapter pointer
7277 * @hdd_ctx: hdd context
7278 * @tb: nl attributes
7279 *
7280 * This function reads the NL attributes and forms a AddTxPtrn message
7281 * posts it to SME.
7282 *
7283 */
7284static int
7285wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7286 struct nlattr **tb)
7287{
7288 struct sSirAddPeriodicTxPtrn *add_req;
7289 eHalStatus status;
7290 uint32_t request_id, ret, len;
7291 uint8_t pattern_id = 0;
7292 v_MACADDR_t dst_addr;
7293 uint16_t eth_type = htons(ETH_P_IP);
7294
7295 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7296 {
7297 hddLog(LOGE, FL("Not in Connected state!"));
7298 return -ENOTSUPP;
7299 }
7300
7301 add_req = vos_mem_malloc(sizeof(*add_req));
7302 if (!add_req)
7303 {
7304 hddLog(LOGE, FL("memory allocation failed"));
7305 return -ENOMEM;
7306 }
7307
7308 /* Parse and fetch request Id */
7309 if (!tb[PARAM_REQUEST_ID])
7310 {
7311 hddLog(LOGE, FL("attr request id failed"));
7312 goto fail;
7313 }
7314
7315 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7316 hddLog(LOG1, FL("Request Id: %u"), request_id);
7317 if (request_id == 0)
7318 {
7319 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307320 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307321 }
7322
7323 if (!tb[PARAM_PERIOD])
7324 {
7325 hddLog(LOGE, FL("attr period failed"));
7326 goto fail;
7327 }
7328 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7329 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7330 if (add_req->usPtrnIntervalMs == 0)
7331 {
7332 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7333 goto fail;
7334 }
7335
7336 if (!tb[PARAM_SRC_MAC_ADDR])
7337 {
7338 hddLog(LOGE, FL("attr source mac address failed"));
7339 goto fail;
7340 }
7341 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7342 VOS_MAC_ADDR_SIZE);
7343 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7344 MAC_ADDR_ARRAY(add_req->macAddress));
7345
7346 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7347 VOS_MAC_ADDR_SIZE))
7348 {
7349 hddLog(LOGE,
7350 FL("input src mac address and connected ap bssid are different"));
7351 goto fail;
7352 }
7353
7354 if (!tb[PARAM_DST_MAC_ADDR])
7355 {
7356 hddLog(LOGE, FL("attr dst mac address failed"));
7357 goto fail;
7358 }
7359 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7360 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7361 MAC_ADDR_ARRAY(dst_addr.bytes));
7362
7363 if (!tb[PARAM_IP_PACKET])
7364 {
7365 hddLog(LOGE, FL("attr ip packet failed"));
7366 goto fail;
7367 }
7368 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7369 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7370
7371 if (add_req->ucPtrnSize < 0 ||
7372 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7373 HDD_ETH_HEADER_LEN))
7374 {
7375 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7376 add_req->ucPtrnSize);
7377 goto fail;
7378 }
7379
7380 len = 0;
7381 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7382 len += VOS_MAC_ADDR_SIZE;
7383 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7384 VOS_MAC_ADDR_SIZE);
7385 len += VOS_MAC_ADDR_SIZE;
7386 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7387 len += 2;
7388
7389 /*
7390 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7391 * ------------------------------------------------------------
7392 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7393 * ------------------------------------------------------------
7394 */
7395 vos_mem_copy(&add_req->ucPattern[len],
7396 nla_data(tb[PARAM_IP_PACKET]),
7397 add_req->ucPtrnSize);
7398 add_req->ucPtrnSize += len;
7399
7400 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7401 add_req->ucPattern, add_req->ucPtrnSize);
7402
7403 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7404 if (ret)
7405 {
7406 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7407 goto fail;
7408 }
7409 add_req->ucPtrnId = pattern_id;
7410 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7411
7412 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7413 if (!HAL_STATUS_SUCCESS(status))
7414 {
7415 hddLog(LOGE,
7416 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7417 goto fail;
7418 }
7419
7420 EXIT();
7421 vos_mem_free(add_req);
7422 return 0;
7423
7424fail:
7425 vos_mem_free(add_req);
7426 return -EINVAL;
7427}
7428
7429/**
7430 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7431 * @adapter: adapter pointer
7432 * @hdd_ctx: hdd context
7433 * @tb: nl attributes
7434 *
7435 * This function reads the NL attributes and forms a DelTxPtrn message
7436 * posts it to SME.
7437 *
7438 */
7439static int
7440wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7441 struct nlattr **tb)
7442{
7443 struct sSirDelPeriodicTxPtrn *del_req;
7444 eHalStatus status;
7445 uint32_t request_id, ret;
7446 uint8_t pattern_id = 0;
7447
7448 /* Parse and fetch request Id */
7449 if (!tb[PARAM_REQUEST_ID])
7450 {
7451 hddLog(LOGE, FL("attr request id failed"));
7452 return -EINVAL;
7453 }
7454 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7455 if (request_id == 0)
7456 {
7457 hddLog(LOGE, FL("request_id cannot be zero"));
7458 return -EINVAL;
7459 }
7460
7461 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7462 if (ret)
7463 {
7464 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7465 return -EINVAL;
7466 }
7467
7468 del_req = vos_mem_malloc(sizeof(*del_req));
7469 if (!del_req)
7470 {
7471 hddLog(LOGE, FL("memory allocation failed"));
7472 return -ENOMEM;
7473 }
7474
7475 vos_mem_set(del_req, sizeof(*del_req), 0);
7476 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7477 VOS_MAC_ADDR_SIZE);
7478 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7479 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7480 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7481 request_id, pattern_id, del_req->ucPatternIdBitmap);
7482
7483 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7484 if (!HAL_STATUS_SUCCESS(status))
7485 {
7486 hddLog(LOGE,
7487 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7488 goto fail;
7489 }
7490
7491 EXIT();
7492 vos_mem_free(del_req);
7493 return 0;
7494
7495fail:
7496 vos_mem_free(del_req);
7497 return -EINVAL;
7498}
7499
7500
7501/**
7502 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7503 * @wiphy: Pointer to wireless phy
7504 * @wdev: Pointer to wireless device
7505 * @data: Pointer to data
7506 * @data_len: Data length
7507 *
7508 * Return: 0 on success, negative errno on failure
7509 */
7510static int
7511__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7512 struct wireless_dev *wdev,
7513 const void *data,
7514 int data_len)
7515{
7516 struct net_device *dev = wdev->netdev;
7517 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7518 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7519 struct nlattr *tb[PARAM_MAX + 1];
7520 uint8_t control;
7521 int ret;
7522 static const struct nla_policy policy[PARAM_MAX + 1] =
7523 {
7524 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7525 [PARAM_CONTROL] = { .type = NLA_U32 },
7526 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7527 .len = VOS_MAC_ADDR_SIZE },
7528 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7529 .len = VOS_MAC_ADDR_SIZE },
7530 [PARAM_PERIOD] = { .type = NLA_U32 },
7531 };
7532
7533 ENTER();
7534
7535 ret = wlan_hdd_validate_context(hdd_ctx);
7536 if (0 != ret)
7537 {
7538 hddLog(LOGE, FL("HDD context is not valid"));
7539 return ret;
7540 }
7541
7542 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7543 {
7544 hddLog(LOGE,
7545 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7546 return -ENOTSUPP;
7547 }
7548
7549 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7550 {
7551 hddLog(LOGE, FL("Invalid ATTR"));
7552 return -EINVAL;
7553 }
7554
7555 if (!tb[PARAM_CONTROL])
7556 {
7557 hddLog(LOGE, FL("attr control failed"));
7558 return -EINVAL;
7559 }
7560 control = nla_get_u32(tb[PARAM_CONTROL]);
7561 hddLog(LOG1, FL("Control: %d"), control);
7562
7563 if (control == WLAN_START_OFFLOADED_PACKETS)
7564 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7565 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7566 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7567 else
7568 {
7569 hddLog(LOGE, FL("Invalid control: %d"), control);
7570 return -EINVAL;
7571 }
7572}
7573
7574/*
7575 * done with short names for the global vendor params
7576 * used by __wlan_hdd_cfg80211_offloaded_packets()
7577 */
7578#undef PARAM_MAX
7579#undef PARAM_REQUEST_ID
7580#undef PARAM_CONTROL
7581#undef PARAM_IP_PACKET
7582#undef PARAM_SRC_MAC_ADDR
7583#undef PARAM_DST_MAC_ADDR
7584#undef PARAM_PERIOD
7585
7586/**
7587 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7588 * @wiphy: wiphy structure pointer
7589 * @wdev: Wireless device structure pointer
7590 * @data: Pointer to the data received
7591 * @data_len: Length of @data
7592 *
7593 * Return: 0 on success; errno on failure
7594 */
7595static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7596 struct wireless_dev *wdev,
7597 const void *data,
7598 int data_len)
7599{
7600 int ret = 0;
7601
7602 vos_ssr_protect(__func__);
7603 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7604 wdev, data, data_len);
7605 vos_ssr_unprotect(__func__);
7606
7607 return ret;
7608}
7609#endif
7610
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307611static const struct
7612nla_policy
7613qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307614 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7615 .type = NLA_BINARY,
7616 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307617};
7618
7619/**
7620 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7621 * get link properties like nss, rate flags and operating frequency for
7622 * the connection with the given peer.
7623 * @wiphy: WIPHY structure pointer
7624 * @wdev: Wireless device structure pointer
7625 * @data: Pointer to the data received
7626 * @data_len: Length of the data received
7627 *
7628 * This function return the above link properties on success.
7629 *
7630 * Return: 0 on success and errno on failure
7631 */
7632static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7633 struct wireless_dev *wdev,
7634 const void *data,
7635 int data_len)
7636{
7637 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7638 struct net_device *dev = wdev->netdev;
7639 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7640 hdd_station_ctx_t *hdd_sta_ctx;
7641 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7642 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7643 uint32_t sta_id;
7644 struct sk_buff *reply_skb;
7645 uint32_t rate_flags = 0;
7646 uint8_t nss;
7647 uint8_t final_rate_flags = 0;
7648 uint32_t freq;
7649 v_CONTEXT_t pVosContext = NULL;
7650 ptSapContext pSapCtx = NULL;
7651
7652 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7654 return -EINVAL;
7655 }
7656
7657 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7658 qca_wlan_vendor_attr_policy)) {
7659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7660 return -EINVAL;
7661 }
7662
7663 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7664 hddLog(VOS_TRACE_LEVEL_ERROR,
7665 FL("Attribute peerMac not provided for mode=%d"),
7666 adapter->device_mode);
7667 return -EINVAL;
7668 }
7669
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307670 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7671 hddLog(VOS_TRACE_LEVEL_ERROR,
7672 FL("Attribute peerMac is invalid=%d"),
7673 adapter->device_mode);
7674 return -EINVAL;
7675 }
7676
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307677 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7678 sizeof(peer_mac));
7679 hddLog(VOS_TRACE_LEVEL_INFO,
7680 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7681 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7682
7683 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7684 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7685 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7686 if ((hdd_sta_ctx->conn_info.connState !=
7687 eConnectionState_Associated) ||
7688 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7689 VOS_MAC_ADDRESS_LEN)) {
7690 hddLog(VOS_TRACE_LEVEL_ERROR,
7691 FL("Not Associated to mac "MAC_ADDRESS_STR),
7692 MAC_ADDR_ARRAY(peer_mac));
7693 return -EINVAL;
7694 }
7695
7696 nss = 1; //pronto supports only one spatial stream
7697 freq = vos_chan_to_freq(
7698 hdd_sta_ctx->conn_info.operationChannel);
7699 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7700
7701 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7702 adapter->device_mode == WLAN_HDD_SOFTAP) {
7703
7704 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7705 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7706 if(pSapCtx == NULL){
7707 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7708 FL("psapCtx is NULL"));
7709 return -ENOENT;
7710 }
7711
7712
7713 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7714 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7715 !vos_is_macaddr_broadcast(
7716 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7717 vos_mem_compare(
7718 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7719 peer_mac, VOS_MAC_ADDRESS_LEN))
7720 break;
7721 }
7722
7723 if (WLAN_MAX_STA_COUNT == sta_id) {
7724 hddLog(VOS_TRACE_LEVEL_ERROR,
7725 FL("No active peer with mac="MAC_ADDRESS_STR),
7726 MAC_ADDR_ARRAY(peer_mac));
7727 return -EINVAL;
7728 }
7729
7730 nss = 1; //pronto supports only one spatial stream
7731 freq = vos_chan_to_freq(
7732 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7733 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7734 } else {
7735 hddLog(VOS_TRACE_LEVEL_ERROR,
7736 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7737 MAC_ADDR_ARRAY(peer_mac));
7738 return -EINVAL;
7739 }
7740
7741 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7742 if (rate_flags & eHAL_TX_RATE_VHT80) {
7743 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307744#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7745 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307746 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307747#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307748 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7749 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307750#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7751 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307752 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307753#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307754 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7755 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7756 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7757 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307758#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7759 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307760 if (rate_flags & eHAL_TX_RATE_HT40)
7761 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307762#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307763 }
7764
7765 if (rate_flags & eHAL_TX_RATE_SGI) {
7766 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7767 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7768 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7769 }
7770 }
7771
7772 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7773 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7774
7775 if (NULL == reply_skb) {
7776 hddLog(VOS_TRACE_LEVEL_ERROR,
7777 FL("getLinkProperties: skb alloc failed"));
7778 return -EINVAL;
7779 }
7780
7781 if (nla_put_u8(reply_skb,
7782 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7783 nss) ||
7784 nla_put_u8(reply_skb,
7785 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7786 final_rate_flags) ||
7787 nla_put_u32(reply_skb,
7788 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7789 freq)) {
7790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7791 kfree_skb(reply_skb);
7792 return -EINVAL;
7793 }
7794
7795 return cfg80211_vendor_cmd_reply(reply_skb);
7796}
7797
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307798#define BEACON_MISS_THRESH_2_4 \
7799 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7800#define BEACON_MISS_THRESH_5_0 \
7801 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307802#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7803#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7804#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7805#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307806#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7807 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307808#define PARAM_FORCE_RSN_IE \
7809 QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307810/*
7811 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7812 * @hdd_ctx: hdd context
7813 * @enable: Value received in the command, 1 for disable and 2 for enable
7814 *
7815 * Return: void
7816 */
7817static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7818{
7819 if (!hdd_ctx) {
7820 hddLog(LOGE, "hdd_ctx NULL");
7821 return;
7822 }
7823
7824 sme_set_qpower(hdd_ctx->hHal, enable);
7825}
7826
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307827/**
7828 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7829 * vendor command
7830 *
7831 * @wiphy: wiphy device pointer
7832 * @wdev: wireless device pointer
7833 * @data: Vendor command data buffer
7834 * @data_len: Buffer length
7835 *
7836 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7837 *
7838 * Return: EOK or other error codes.
7839 */
7840
7841static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7842 struct wireless_dev *wdev,
7843 const void *data,
7844 int data_len)
7845{
7846 struct net_device *dev = wdev->netdev;
7847 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7848 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7849 hdd_station_ctx_t *pHddStaCtx;
7850 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7851 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307852 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307853 eHalStatus status;
7854 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307855 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307856 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307857
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307858 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7859 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7860 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307861 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7862 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7863 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307864 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7865 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307866 [PARAM_FORCE_RSN_IE] = {.type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307867 };
7868
7869 ENTER();
7870
7871 if (VOS_FTM_MODE == hdd_get_conparam()) {
7872 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7873 return -EINVAL;
7874 }
7875
7876 ret_val = wlan_hdd_validate_context(pHddCtx);
7877 if (ret_val) {
7878 return ret_val;
7879 }
7880
7881 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7882
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307883 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7884 hddLog(LOGE, FL("Invalid ATTR"));
7885 return -EINVAL;
7886 }
7887
7888 /* check the Wifi Capability */
7889 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7890 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7891 {
7892 hddLog(VOS_TRACE_LEVEL_ERROR,
7893 FL("WIFICONFIG not supported by Firmware"));
7894 return -EINVAL;
7895 }
7896
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307897 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7898 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7899 modifyRoamParamsReq.value =
7900 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7901
7902 if (eHAL_STATUS_SUCCESS !=
7903 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7904 {
7905 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7906 ret_val = -EINVAL;
7907 }
7908 return ret_val;
7909 }
7910
7911 /* Moved this down in order to provide provision to set beacon
7912 * miss penalty count irrespective of connection state.
7913 */
7914 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7915 hddLog(LOGE, FL("Not in Connected state!"));
7916 return -ENOTSUPP;
7917 }
7918
7919 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307920
7921 if (!pReq) {
7922 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7923 "%s: Not able to allocate memory for tSetWifiConfigParams",
7924 __func__);
7925 return eHAL_STATUS_E_MALLOC_FAILED;
7926 }
7927
7928 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7929
7930 pReq->sessionId = pAdapter->sessionId;
7931 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7932
7933 if (tb[PARAM_MODULATED_DTIM]) {
7934 pReq->paramValue = nla_get_u32(
7935 tb[PARAM_MODULATED_DTIM]);
7936 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7937 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307938 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307939 hdd_set_pwrparams(pHddCtx);
7940 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7941 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7942
7943 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7944 iw_full_power_cbfn, pAdapter,
7945 eSME_FULL_PWR_NEEDED_BY_HDD);
7946 }
7947 else
7948 {
7949 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7950 }
7951 }
7952
7953 if (tb[PARAM_STATS_AVG_FACTOR]) {
7954 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7955 pReq->paramValue = nla_get_u16(
7956 tb[PARAM_STATS_AVG_FACTOR]);
7957 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7958 pReq->paramType, pReq->paramValue);
7959 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7960
7961 if (eHAL_STATUS_SUCCESS != status)
7962 {
7963 vos_mem_free(pReq);
7964 pReq = NULL;
7965 ret_val = -EPERM;
7966 return ret_val;
7967 }
7968 }
7969
7970
7971 if (tb[PARAM_GUARD_TIME]) {
7972 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7973 pReq->paramValue = nla_get_u32(
7974 tb[PARAM_GUARD_TIME]);
7975 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7976 pReq->paramType, pReq->paramValue);
7977 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7978
7979 if (eHAL_STATUS_SUCCESS != status)
7980 {
7981 vos_mem_free(pReq);
7982 pReq = NULL;
7983 ret_val = -EPERM;
7984 return ret_val;
7985 }
7986
7987 }
7988
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307989 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7990 hb_thresh_val = nla_get_u8(
7991 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7992
7993 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7994 hb_thresh_val);
7995 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7996 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7997 NULL, eANI_BOOLEAN_FALSE);
7998
7999 status = sme_update_hb_threshold(
8000 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8001 WNI_CFG_HEART_BEAT_THRESHOLD,
8002 hb_thresh_val, eCSR_BAND_24);
8003 if (eHAL_STATUS_SUCCESS != status) {
8004 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8005 vos_mem_free(pReq);
8006 pReq = NULL;
8007 return -EPERM;
8008 }
8009 }
8010
8011 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
8012 hb_thresh_val = nla_get_u8(
8013 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
8014
8015 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8016 hb_thresh_val);
8017 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8018 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8019 NULL, eANI_BOOLEAN_FALSE);
8020
8021 status = sme_update_hb_threshold(
8022 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8023 WNI_CFG_HEART_BEAT_THRESHOLD,
8024 hb_thresh_val, eCSR_BAND_5G);
8025 if (eHAL_STATUS_SUCCESS != status) {
8026 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8027 vos_mem_free(pReq);
8028 pReq = NULL;
8029 return -EPERM;
8030 }
8031 }
8032
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05308033 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
8034 qpower = nla_get_u8(
8035 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
8036
8037 if(qpower > 1) {
8038 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
8039 vos_mem_free(pReq);
8040 pReq = NULL;
8041 return -EINVAL;
8042 }
8043 /* FW is expacting qpower as 1 for Disable and 2 for enable */
8044 qpower++;
8045 hdd_set_qpower(pHddCtx, qpower);
8046 }
8047
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05308048 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] &&
8049 pHddCtx->cfg_ini->force_rsne_override) {
8050 uint8_t force_rsne_override;
8051
8052 force_rsne_override =
8053 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
8054 if (force_rsne_override > 1) {
8055 hddLog(LOGE, "Invalid test_mode %d", force_rsne_override);
8056 ret_val = -EINVAL;
8057 }
8058 pHddCtx->force_rsne_override = force_rsne_override;
8059 hddLog(LOG1, "force_rsne_override - %d",
8060 pHddCtx->force_rsne_override);
8061 }
8062
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308063 EXIT();
8064 return ret_val;
8065}
8066
8067/**
8068 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8069 * vendor command
8070 *
8071 * @wiphy: wiphy device pointer
8072 * @wdev: wireless device pointer
8073 * @data: Vendor command data buffer
8074 * @data_len: Buffer length
8075 *
8076 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8077 *
8078 * Return: EOK or other error codes.
8079 */
8080static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8081 struct wireless_dev *wdev,
8082 const void *data,
8083 int data_len)
8084{
8085 int ret;
8086
8087 vos_ssr_protect(__func__);
8088 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8089 data, data_len);
8090 vos_ssr_unprotect(__func__);
8091
8092 return ret;
8093}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308094
8095/*
8096 * define short names for the global vendor params
8097 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8098 */
8099#define STATS_SET_INVALID \
8100 QCA_ATTR_NUD_STATS_SET_INVALID
8101#define STATS_SET_START \
8102 QCA_ATTR_NUD_STATS_SET_START
8103#define STATS_GW_IPV4 \
8104 QCA_ATTR_NUD_STATS_GW_IPV4
8105#define STATS_SET_MAX \
8106 QCA_ATTR_NUD_STATS_SET_MAX
8107
8108const struct nla_policy
8109qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8110{
8111 [STATS_SET_START] = {.type = NLA_FLAG },
8112 [STATS_GW_IPV4] = {.type = NLA_U32 },
8113};
8114
8115/**
8116 * hdd_set_nud_stats_cb() - hdd callback api to get status
8117 * @data: pointer to adapter
8118 * @rsp: status
8119 *
8120 * Return: None
8121 */
8122static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8123{
8124
8125 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8126
8127 if (NULL == adapter)
8128 return;
8129
8130 if (VOS_STATUS_SUCCESS == rsp) {
8131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8132 "%s success received STATS_SET_START", __func__);
8133 } else {
8134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8135 "%s STATS_SET_START Failed!!", __func__);
8136 }
8137 return;
8138}
8139
8140/**
8141 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8142 * @wiphy: pointer to wireless wiphy structure.
8143 * @wdev: pointer to wireless_dev structure.
8144 * @data: pointer to apfind configuration data.
8145 * @data_len: the length in byte of apfind data.
8146 *
8147 * This is called when wlan driver needs to send arp stats to
8148 * firmware.
8149 *
8150 * Return: An error code or 0 on success.
8151 */
8152static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8153 struct wireless_dev *wdev,
8154 const void *data, int data_len)
8155{
8156 struct nlattr *tb[STATS_SET_MAX + 1];
8157 struct net_device *dev = wdev->netdev;
8158 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8159 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308160 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308161 setArpStatsParams arp_stats_params;
8162 int err = 0;
8163
8164 ENTER();
8165
8166 err = wlan_hdd_validate_context(hdd_ctx);
8167 if (0 != err)
8168 return err;
8169
8170 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8172 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8173 return -EINVAL;
8174 }
8175
8176 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8177 qca_wlan_vendor_set_nud_stats);
8178 if (err)
8179 {
8180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8181 "%s STATS_SET_START ATTR", __func__);
8182 return err;
8183 }
8184
8185 if (tb[STATS_SET_START])
8186 {
8187 if (!tb[STATS_GW_IPV4]) {
8188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8189 "%s STATS_SET_START CMD", __func__);
8190 return -EINVAL;
8191 }
8192 arp_stats_params.flag = true;
8193 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8194 } else {
8195 arp_stats_params.flag = false;
8196 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308197 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8199 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308200 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8201 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308202
8203 arp_stats_params.pkt_type = 1; // ARP packet type
8204
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308205 if (arp_stats_params.flag) {
8206 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8207 WLANTL_SetARPFWDatapath(pVosContext, true);
8208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8209 "%s Set FW in data path for ARP with tgt IP :%d",
8210 __func__, hdd_ctx->track_arp_ip);
8211 }
8212 else {
8213 WLANTL_SetARPFWDatapath(pVosContext, false);
8214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8215 "%s Remove FW from data path", __func__);
8216 }
8217
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308218 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8219 arp_stats_params.data_ctx = adapter;
8220
8221 if (eHAL_STATUS_SUCCESS !=
8222 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8223 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8224 "%s STATS_SET_START CMD Failed!!", __func__);
8225 return -EINVAL;
8226 }
8227
8228 EXIT();
8229
8230 return err;
8231}
8232
8233/**
8234 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8235 * @wiphy: pointer to wireless wiphy structure.
8236 * @wdev: pointer to wireless_dev structure.
8237 * @data: pointer to apfind configuration data.
8238 * @data_len: the length in byte of apfind data.
8239 *
8240 * This is called when wlan driver needs to send arp stats to
8241 * firmware.
8242 *
8243 * Return: An error code or 0 on success.
8244 */
8245static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8246 struct wireless_dev *wdev,
8247 const void *data, int data_len)
8248{
8249 int ret;
8250
8251 vos_ssr_protect(__func__);
8252 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8253 vos_ssr_unprotect(__func__);
8254
8255 return ret;
8256}
8257#undef STATS_SET_INVALID
8258#undef STATS_SET_START
8259#undef STATS_GW_IPV4
8260#undef STATS_SET_MAX
8261
8262/*
8263 * define short names for the global vendor params
8264 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8265 */
8266#define STATS_GET_INVALID \
8267 QCA_ATTR_NUD_STATS_SET_INVALID
8268#define COUNT_FROM_NETDEV \
8269 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8270#define COUNT_TO_LOWER_MAC \
8271 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8272#define RX_COUNT_BY_LOWER_MAC \
8273 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8274#define COUNT_TX_SUCCESS \
8275 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8276#define RSP_RX_COUNT_BY_LOWER_MAC \
8277 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8278#define RSP_RX_COUNT_BY_UPPER_MAC \
8279 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8280#define RSP_COUNT_TO_NETDEV \
8281 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8282#define RSP_COUNT_OUT_OF_ORDER_DROP \
8283 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8284#define AP_LINK_ACTIVE \
8285 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8286#define AP_LINK_DAD \
8287 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8288#define STATS_GET_MAX \
8289 QCA_ATTR_NUD_STATS_GET_MAX
8290
8291const struct nla_policy
8292qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8293{
8294 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8295 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8296 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8297 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8298 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8299 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8300 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8301 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8302 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8303 [AP_LINK_DAD] = {.type = NLA_FLAG },
8304};
8305
8306static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8307{
8308
8309 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308310 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308311 struct hdd_nud_stats_context *context;
8312 int status;
8313
8314 ENTER();
8315
8316 if (NULL == adapter)
8317 return;
8318
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308319 if (!rsp) {
8320 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308321 return;
8322 }
8323
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308324 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8325 status = wlan_hdd_validate_context(hdd_ctx);
8326 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308327 return;
8328 }
8329
8330 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8331 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8332 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8333 adapter->dad |= rsp->dad;
8334
8335 spin_lock(&hdd_context_lock);
8336 context = &hdd_ctx->nud_stats_context;
8337 complete(&context->response_event);
8338 spin_unlock(&hdd_context_lock);
8339
8340 return;
8341}
8342static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8343 struct wireless_dev *wdev,
8344 const void *data, int data_len)
8345{
8346 int err = 0;
8347 unsigned long rc;
8348 struct hdd_nud_stats_context *context;
8349 struct net_device *dev = wdev->netdev;
8350 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8351 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8352 getArpStatsParams arp_stats_params;
8353 struct sk_buff *skb;
8354
8355 ENTER();
8356
8357 err = wlan_hdd_validate_context(hdd_ctx);
8358 if (0 != err)
8359 return err;
8360
8361 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8362 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8363 arp_stats_params.data_ctx = adapter;
8364
8365 spin_lock(&hdd_context_lock);
8366 context = &hdd_ctx->nud_stats_context;
8367 INIT_COMPLETION(context->response_event);
8368 spin_unlock(&hdd_context_lock);
8369
8370 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8372 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8373 return -EINVAL;
8374 }
8375
8376 if (eHAL_STATUS_SUCCESS !=
8377 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8379 "%s STATS_SET_START CMD Failed!!", __func__);
8380 return -EINVAL;
8381 }
8382
8383 rc = wait_for_completion_timeout(&context->response_event,
8384 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8385 if (!rc)
8386 {
8387 hddLog(LOGE,
8388 FL("Target response timed out request "));
8389 return -ETIMEDOUT;
8390 }
8391
8392 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8393 WLAN_NUD_STATS_LEN);
8394 if (!skb)
8395 {
8396 hddLog(VOS_TRACE_LEVEL_ERROR,
8397 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8398 __func__);
8399 return -ENOMEM;
8400 }
8401
8402 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8403 adapter->hdd_stats.hddArpStats.txCount) ||
8404 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8405 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8406 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8407 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8408 nla_put_u16(skb, COUNT_TX_SUCCESS,
8409 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8410 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8411 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8412 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8413 adapter->hdd_stats.hddArpStats.rxCount) ||
8414 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8415 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8416 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8417 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8418 hddLog(LOGE, FL("nla put fail"));
8419 kfree_skb(skb);
8420 return -EINVAL;
8421 }
8422 if (adapter->con_status)
8423 nla_put_flag(skb, AP_LINK_ACTIVE);
8424 if (adapter->dad)
8425 nla_put_flag(skb, AP_LINK_DAD);
8426
8427 cfg80211_vendor_cmd_reply(skb);
8428 return err;
8429}
8430
8431static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8432 struct wireless_dev *wdev,
8433 const void *data, int data_len)
8434{
8435 int ret;
8436
8437 vos_ssr_protect(__func__);
8438 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8439 vos_ssr_unprotect(__func__);
8440
8441 return ret;
8442}
8443
8444#undef QCA_ATTR_NUD_STATS_SET_INVALID
8445#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8446#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8447#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8448#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8449#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8450#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8451#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8452#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8453#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8454#undef QCA_ATTR_NUD_STATS_GET_MAX
8455
8456
8457
Kapil Guptaee33bf12016-12-20 18:27:37 +05308458#ifdef WLAN_FEATURE_APFIND
8459/**
8460 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8461 * @wiphy: pointer to wireless wiphy structure.
8462 * @wdev: pointer to wireless_dev structure.
8463 * @data: pointer to apfind configuration data.
8464 * @data_len: the length in byte of apfind data.
8465 *
8466 * This is called when wlan driver needs to send APFIND configurations to
8467 * firmware.
8468 *
8469 * Return: An error code or 0 on success.
8470 */
8471static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8472 struct wireless_dev *wdev,
8473 const void *data, int data_len)
8474{
8475 struct sme_ap_find_request_req apfind_req;
8476 VOS_STATUS status;
8477 int ret_val;
8478 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8479
8480 ENTER();
8481
8482 ret_val = wlan_hdd_validate_context(hdd_ctx);
8483 if (ret_val)
8484 return ret_val;
8485
8486 if (VOS_FTM_MODE == hdd_get_conparam()) {
8487 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8488 return -EPERM;
8489 }
8490
8491 apfind_req.request_data_len = data_len;
8492 apfind_req.request_data = data;
8493
8494 status = sme_apfind_set_cmd(&apfind_req);
8495 if (VOS_STATUS_SUCCESS != status) {
8496 ret_val = -EIO;
8497 }
8498 return ret_val;
8499}
8500
8501/**
8502 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8503 * @wiphy: pointer to wireless wiphy structure.
8504 * @wdev: pointer to wireless_dev structure.
8505 * @data: pointer to apfind configuration data.
8506 * @data_len: the length in byte of apfind data.
8507 *
8508 * This is called when wlan driver needs to send APFIND configurations to
8509 * firmware.
8510 *
8511 * Return: An error code or 0 on success.
8512 */
8513static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8514 struct wireless_dev *wdev,
8515 const void *data, int data_len)
8516{
8517 int ret;
8518
8519 vos_ssr_protect(__func__);
8520 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8521 vos_ssr_unprotect(__func__);
8522
8523 return ret;
8524}
8525#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308526
8527/**
8528 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8529 * @wiphy: pointer to wireless wiphy structure.
8530 * @wdev: pointer to wireless_dev structure.
8531 * @data: Pointer to the data to be passed via vendor interface
8532 * @data_len:Length of the data to be passed
8533 *
8534 * This is called by userspace to know the supported logger features
8535 *
8536 * Return: Return the Success or Failure code.
8537 */
8538static int
8539__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8540 struct wireless_dev *wdev,
8541 const void *data, int data_len)
8542{
8543 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8544 int status;
8545 uint32_t features;
8546 struct sk_buff *reply_skb = NULL;
8547
8548 if (VOS_FTM_MODE == hdd_get_conparam()) {
8549 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8550 return -EINVAL;
8551 }
8552
8553 status = wlan_hdd_validate_context(hdd_ctx);
8554 if (0 != status)
8555 return -EINVAL;
8556
8557 features = 0;
8558
8559 if (hdd_is_memdump_supported())
8560 features |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
8561
8562 if (hdd_ctx->cfg_ini->wlanLoggingEnable &&
8563 hdd_ctx->cfg_ini->enableFatalEvent &&
8564 hdd_ctx->is_fatal_event_log_sup) {
8565 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
8566 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
8567 }
8568
8569 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8570 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8571 if (!reply_skb) {
8572 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8573 return -ENOMEM;
8574 }
8575
8576 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8577 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8578 features)) {
8579 hddLog(LOGE, FL("nla put fail"));
8580 kfree_skb(reply_skb);
8581 return -EINVAL;
8582 }
8583
8584 return cfg80211_vendor_cmd_reply(reply_skb);
8585}
8586
8587/**
8588 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8589 * @wiphy: pointer to wireless wiphy structure.
8590 * @wdev: pointer to wireless_dev structure.
8591 * @data: Pointer to the data to be passed via vendor interface
8592 * @data_len:Length of the data to be passed
8593 *
8594 * This is called by userspace to know the supported logger features
8595 *
8596 * Return: Return the Success or Failure code.
8597 */
8598static int
8599wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8600 struct wireless_dev *wdev,
8601 const void *data, int data_len)
8602{
8603 int ret;
8604
8605 vos_ssr_protect(__func__);
8606 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8607 data, data_len);
8608 vos_ssr_unprotect(__func__);
8609
8610 return ret;
8611}
8612
Sunil Duttc69bccb2014-05-26 21:30:20 +05308613const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8614{
Mukul Sharma2a271632014-10-13 14:59:01 +05308615 {
8616 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8617 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8618 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8619 WIPHY_VENDOR_CMD_NEED_NETDEV |
8620 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308621 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308622 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308623
8624 {
8625 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8626 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8627 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8628 WIPHY_VENDOR_CMD_NEED_NETDEV |
8629 WIPHY_VENDOR_CMD_NEED_RUNNING,
8630 .doit = wlan_hdd_cfg80211_nan_request
8631 },
8632
Sunil Duttc69bccb2014-05-26 21:30:20 +05308633#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8634 {
8635 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8636 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
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_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308641 },
8642
8643 {
8644 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8645 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8646 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8647 WIPHY_VENDOR_CMD_NEED_NETDEV |
8648 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308649 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308650 },
8651
8652 {
8653 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8654 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
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_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308659 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308660#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308661#ifdef WLAN_FEATURE_EXTSCAN
8662 {
8663 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8664 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8665 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8666 WIPHY_VENDOR_CMD_NEED_NETDEV |
8667 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308668 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308669 },
8670 {
8671 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8672 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8673 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8674 WIPHY_VENDOR_CMD_NEED_NETDEV |
8675 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308676 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308677 },
8678 {
8679 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8680 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8681 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8682 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308683 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308684 },
8685 {
8686 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8687 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8688 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8689 WIPHY_VENDOR_CMD_NEED_NETDEV |
8690 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308691 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308692 },
8693 {
8694 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8695 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8696 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8697 WIPHY_VENDOR_CMD_NEED_NETDEV |
8698 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308699 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308700 },
8701 {
8702 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8703 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8704 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8705 WIPHY_VENDOR_CMD_NEED_NETDEV |
8706 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308707 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308708 },
8709 {
8710 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8711 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8712 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8713 WIPHY_VENDOR_CMD_NEED_NETDEV |
8714 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308715 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308716 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308717#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308718/*EXT TDLS*/
8719 {
8720 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8721 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8722 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8723 WIPHY_VENDOR_CMD_NEED_NETDEV |
8724 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308725 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308726 },
8727 {
8728 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8729 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8730 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8731 WIPHY_VENDOR_CMD_NEED_NETDEV |
8732 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308733 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308734 },
8735 {
8736 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8737 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8738 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8739 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308740 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308741 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308742 {
8743 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8744 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8745 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8746 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308747 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308748 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308749 {
8750 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8751 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8752 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8753 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308754 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308755 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308756 {
8757 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8758 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8759 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8760 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308761 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308762 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308763 {
8764 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8765 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8766 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8767 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308768 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308769 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308770 {
8771 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308772 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8773 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8774 WIPHY_VENDOR_CMD_NEED_NETDEV |
8775 WIPHY_VENDOR_CMD_NEED_RUNNING,
8776 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8777 },
8778 {
8779 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308780 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8781 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8782 WIPHY_VENDOR_CMD_NEED_NETDEV |
8783 WIPHY_VENDOR_CMD_NEED_RUNNING,
8784 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308785 },
8786 {
8787 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8788 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8789 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8790 WIPHY_VENDOR_CMD_NEED_NETDEV,
8791 .doit = wlan_hdd_cfg80211_wifi_logger_start
8792 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308793 {
8794 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8795 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8796 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8797 WIPHY_VENDOR_CMD_NEED_NETDEV|
8798 WIPHY_VENDOR_CMD_NEED_RUNNING,
8799 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308800 },
8801 {
8802 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8803 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8804 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8805 WIPHY_VENDOR_CMD_NEED_NETDEV |
8806 WIPHY_VENDOR_CMD_NEED_RUNNING,
8807 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308808 },
8809 {
8810 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8811 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8812 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8813 WIPHY_VENDOR_CMD_NEED_NETDEV |
8814 WIPHY_VENDOR_CMD_NEED_RUNNING,
8815 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308816 },
8817#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8818 {
8819 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8820 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8821 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8822 WIPHY_VENDOR_CMD_NEED_NETDEV |
8823 WIPHY_VENDOR_CMD_NEED_RUNNING,
8824 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308825 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308826#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308827 {
8828 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8829 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8830 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8831 WIPHY_VENDOR_CMD_NEED_NETDEV |
8832 WIPHY_VENDOR_CMD_NEED_RUNNING,
8833 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308834 },
8835 {
8836 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8837 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8838 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8839 WIPHY_VENDOR_CMD_NEED_NETDEV |
8840 WIPHY_VENDOR_CMD_NEED_RUNNING,
8841 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308842 },
8843#ifdef WLAN_FEATURE_APFIND
8844 {
8845 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8846 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8847 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8848 WIPHY_VENDOR_CMD_NEED_NETDEV,
8849 .doit = wlan_hdd_cfg80211_apfind_cmd
8850 },
8851#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308852 {
8853 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8854 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8855 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8856 WIPHY_VENDOR_CMD_NEED_NETDEV |
8857 WIPHY_VENDOR_CMD_NEED_RUNNING,
8858 .doit = wlan_hdd_cfg80211_set_nud_stats
8859 },
8860 {
8861 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8862 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8863 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8864 WIPHY_VENDOR_CMD_NEED_NETDEV |
8865 WIPHY_VENDOR_CMD_NEED_RUNNING,
8866 .doit = wlan_hdd_cfg80211_get_nud_stats
8867 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308868 {
8869 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8870 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8871 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8872 WIPHY_VENDOR_CMD_NEED_NETDEV |
8873 WIPHY_VENDOR_CMD_NEED_RUNNING,
8874 .doit = hdd_cfg80211_get_station_cmd
8875 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308876 {
8877 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8878 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8879 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Hanumanth Reddy Pothula07c95582018-05-23 12:41:22 +05308880 WIPHY_VENDOR_CMD_NEED_NETDEV,
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308881 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8882 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308883};
8884
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008885/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308886static const
8887struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008888{
8889#ifdef FEATURE_WLAN_CH_AVOID
8890 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308891 .vendor_id = QCA_NL80211_VENDOR_ID,
8892 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008893 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308894#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8895#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8896 {
8897 /* Index = 1*/
8898 .vendor_id = QCA_NL80211_VENDOR_ID,
8899 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8900 },
8901 {
8902 /* Index = 2*/
8903 .vendor_id = QCA_NL80211_VENDOR_ID,
8904 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8905 },
8906 {
8907 /* Index = 3*/
8908 .vendor_id = QCA_NL80211_VENDOR_ID,
8909 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8910 },
8911 {
8912 /* Index = 4*/
8913 .vendor_id = QCA_NL80211_VENDOR_ID,
8914 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8915 },
8916 {
8917 /* Index = 5*/
8918 .vendor_id = QCA_NL80211_VENDOR_ID,
8919 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8920 },
8921 {
8922 /* Index = 6*/
8923 .vendor_id = QCA_NL80211_VENDOR_ID,
8924 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8925 },
8926#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308927#ifdef WLAN_FEATURE_EXTSCAN
8928 {
8929 .vendor_id = QCA_NL80211_VENDOR_ID,
8930 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8931 },
8932 {
8933 .vendor_id = QCA_NL80211_VENDOR_ID,
8934 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8935 },
8936 {
8937 .vendor_id = QCA_NL80211_VENDOR_ID,
8938 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8939 },
8940 {
8941 .vendor_id = QCA_NL80211_VENDOR_ID,
8942 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8943 },
8944 {
8945 .vendor_id = QCA_NL80211_VENDOR_ID,
8946 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8947 },
8948 {
8949 .vendor_id = QCA_NL80211_VENDOR_ID,
8950 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8951 },
8952 {
8953 .vendor_id = QCA_NL80211_VENDOR_ID,
8954 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8955 },
8956 {
8957 .vendor_id = QCA_NL80211_VENDOR_ID,
8958 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8959 },
8960 {
8961 .vendor_id = QCA_NL80211_VENDOR_ID,
8962 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8963 },
8964 {
8965 .vendor_id = QCA_NL80211_VENDOR_ID,
8966 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8967 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308968#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308969/*EXT TDLS*/
8970 {
8971 .vendor_id = QCA_NL80211_VENDOR_ID,
8972 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8973 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308974 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8975 .vendor_id = QCA_NL80211_VENDOR_ID,
8976 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8977 },
8978
Srinivas Dasari030bad32015-02-18 23:23:54 +05308979
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308980 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308981 .vendor_id = QCA_NL80211_VENDOR_ID,
8982 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8983 },
8984
Sushant Kaushik084f6592015-09-10 13:11:56 +05308985 {
8986 .vendor_id = QCA_NL80211_VENDOR_ID,
8987 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308988 },
8989 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8990 .vendor_id = QCA_NL80211_VENDOR_ID,
8991 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8992 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308993 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8994 .vendor_id = QCA_NL80211_VENDOR_ID,
8995 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8996 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308997 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8998 .vendor_id = QCA_NL80211_VENDOR_ID,
8999 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
9000 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05309001 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
9002 .vendor_id = QCA_NL80211_VENDOR_ID,
9003 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
9004 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05309005 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
9006 .vendor_id = QCA_NL80211_VENDOR_ID,
9007 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
9008 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009009};
9010
Jeff Johnson295189b2012-06-20 16:38:30 -07009011/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309012 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309013 * This function is called by hdd_wlan_startup()
9014 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309015 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07009016 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309017struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07009018{
9019 struct wiphy *wiphy;
9020 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309021 /*
9022 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07009023 */
9024 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
9025
9026 if (!wiphy)
9027 {
9028 /* Print error and jump into err label and free the memory */
9029 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
9030 return NULL;
9031 }
9032
Sunil Duttc69bccb2014-05-26 21:30:20 +05309033
Jeff Johnson295189b2012-06-20 16:38:30 -07009034 return wiphy;
9035}
9036
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309037#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
9038 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
9039/**
9040 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
9041 * @wiphy: pointer to wiphy
9042 * @config: pointer to config
9043 *
9044 * Return: None
9045 */
9046static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9047 hdd_config_t *config)
9048{
9049 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
9050 if (config->max_sched_scan_plan_interval)
9051 wiphy->max_sched_scan_plan_interval =
9052 config->max_sched_scan_plan_interval;
9053 if (config->max_sched_scan_plan_iterations)
9054 wiphy->max_sched_scan_plan_iterations =
9055 config->max_sched_scan_plan_iterations;
9056}
9057#else
9058static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9059 hdd_config_t *config)
9060{
9061}
9062#endif
9063
Jeff Johnson295189b2012-06-20 16:38:30 -07009064/*
9065 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309066 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07009067 * private ioctl to change the band value
9068 */
9069int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
9070{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309071 int i, j;
9072 eNVChannelEnabledType channelEnabledState;
9073
Jeff Johnsone7245742012-09-05 17:12:55 -07009074 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309075
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309076 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009077 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309078
9079 if (NULL == wiphy->bands[i])
9080 {
9081 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
9082 __func__, i);
9083 continue;
9084 }
9085
9086 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9087 {
9088 struct ieee80211_supported_band *band = wiphy->bands[i];
9089
9090 channelEnabledState = vos_nv_getChannelEnabledState(
9091 band->channels[j].hw_value);
9092
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309093 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309094 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309095 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309096 continue;
9097 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309098 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309099 {
9100 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9101 continue;
9102 }
9103
9104 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9105 NV_CHANNEL_INVALID == channelEnabledState)
9106 {
9107 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9108 }
9109 else if (NV_CHANNEL_DFS == channelEnabledState)
9110 {
9111 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9112 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9113 }
9114 else
9115 {
9116 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9117 |IEEE80211_CHAN_RADAR);
9118 }
9119 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009120 }
9121 return 0;
9122}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309123
9124/**
9125 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9126 * @wiphy: Pointer to the wiphy.
9127 *
9128 * This Function adds Channel Switch support flag, if channel switch is
9129 * supported by kernel.
9130 * Return: void.
9131 */
9132#ifdef CHANNEL_SWITCH_SUPPORTED
9133static inline
9134void hdd_add_channel_switch_support(struct wiphy *wiphy)
9135{
9136 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9137 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9138}
9139#else
9140static inline
9141void hdd_add_channel_switch_support(struct wiphy *wiphy)
9142{
9143}
9144#endif
9145
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +05309146#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
9147 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
9148void wlan_hdd_cfg80211_scan_randomization_init(struct wiphy *wiphy)
9149{
9150 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
9151 hdd_config_t *config = hdd_ctx->cfg_ini;
9152
9153 if (config->enableMacSpoofing != MAC_ADDR_SPOOFING_FW_HOST_ENABLE)
9154 return;
9155
9156 wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
9157}
9158#endif
9159
Abhinav Kumar118efd02019-08-07 16:41:07 +05309160#if defined(WLAN_FEATURE_SAE) && \
9161 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
Abhinav Kumar97821072019-08-02 14:29:48 +05309162/**
9163 * wlan_hdd_cfg80211_set_wiphy_sae_feature() - Indicates support of SAE feature
9164 * @wiphy: Pointer to wiphy
9165 * @config: pointer to config
9166 *
9167 * This function is used to indicate the support of SAE
9168 *
9169 * Return: None
9170 */
9171static
9172void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy,
9173 hdd_config_t *config)
9174{
9175 if (config->is_sae_enabled)
9176 wiphy->features |= NL80211_FEATURE_SAE;
9177}
9178#else
9179static
9180void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy,
9181 hdd_config_t *config)
9182{
9183}
9184#endif
9185
Jeff Johnson295189b2012-06-20 16:38:30 -07009186/*
9187 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309188 * This function is called by hdd_wlan_startup()
9189 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009190 * This function is used to initialize and register wiphy structure.
9191 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309192int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009193 struct wiphy *wiphy,
9194 hdd_config_t *pCfg
9195 )
9196{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309197 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309198 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9199
Jeff Johnsone7245742012-09-05 17:12:55 -07009200 ENTER();
9201
Jeff Johnson295189b2012-06-20 16:38:30 -07009202 /* Now bind the underlying wlan device with wiphy */
9203 set_wiphy_dev(wiphy, dev);
9204
9205 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009206
Kiet Lam6c583332013-10-14 05:37:09 +05309207#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009208 /* the flag for the other case would be initialzed in
9209 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309210#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9211 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9212#else
Amar Singhal0a402232013-10-11 20:57:16 -07009213 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309214#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309215#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009216
Amar Singhalfddc28c2013-09-05 13:03:40 -07009217 /* This will disable updating of NL channels from passive to
9218 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309219#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9220 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9221#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009222 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309223#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009224
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309225#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9226 wiphy->wowlan = &wowlan_support_cfg80211_init;
9227#else
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +05309228 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
9229 WIPHY_WOWLAN_MAGIC_PKT;
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309230 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9231 wiphy->wowlan.pattern_min_len = 1;
9232 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9233#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009234
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009235#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009236 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9237 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9238 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009239 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309240#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309241 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309242#else
9243 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9244#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009245#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009246
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009247#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009248 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009249#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009250 || pCfg->isFastRoamIniFeatureEnabled
9251#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009252#ifdef FEATURE_WLAN_ESE
9253 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009254#endif
9255 )
9256 {
9257 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9258 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009259#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009260#ifdef FEATURE_WLAN_TDLS
9261 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9262 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9263#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309264#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309265 if (pCfg->configPNOScanSupport)
9266 {
9267 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9268 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9269 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9270 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9271 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309272#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009273
Abhishek Singh10d85972015-04-17 10:27:23 +05309274#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9275 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9276#endif
9277
Amar Singhalfddc28c2013-09-05 13:03:40 -07009278#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009279 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9280 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009281 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009282 driver need to determine what to do with both
9283 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009284
9285 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009286#else
9287 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009288#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009289
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309290 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9291
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309292 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009293
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309294 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9295
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309297 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9298 | BIT(NL80211_IFTYPE_ADHOC)
9299 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9300 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309301 | BIT(NL80211_IFTYPE_AP)
9302 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009303
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309304 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009305 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9307 if( pCfg->enableMCC )
9308 {
9309 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309310 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009311
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309312 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309313 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009314
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309315 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309316 wiphy->iface_combinations = wlan_hdd_iface_combination;
9317 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009318#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309319 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009320
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 /* Before registering we need to update the ht capabilitied based
9322 * on ini values*/
9323 if( !pCfg->ShortGI20MhzEnable )
9324 {
9325 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9326 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009327 }
9328
9329 if( !pCfg->ShortGI40MhzEnable )
9330 {
9331 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9332 }
9333
9334 if( !pCfg->nChannelBondingMode5GHz )
9335 {
9336 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9337 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309338 /*
9339 * In case of static linked driver at the time of driver unload,
9340 * module exit doesn't happens. Module cleanup helps in cleaning
9341 * of static memory.
9342 * If driver load happens statically, at the time of driver unload,
9343 * wiphy flags don't get reset because of static memory.
9344 * It's better not to store channel in static memory.
9345 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309346 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9347 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309348 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309349 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309350 {
9351 hddLog(VOS_TRACE_LEVEL_ERROR,
9352 FL("Not enough memory to allocate channels"));
9353 return -ENOMEM;
9354 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309355 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309356 &hdd_channels_2_4_GHZ[0],
9357 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009358
Agrawal Ashish97dec502015-11-26 20:20:58 +05309359 if (true == hdd_is_5g_supported(pHddCtx))
9360 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309361 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9362 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309363 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309364 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309365 {
9366 hddLog(VOS_TRACE_LEVEL_ERROR,
9367 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309368 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9369 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309370 return -ENOMEM;
9371 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309372 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309373 &hdd_channels_5_GHZ[0],
9374 sizeof(hdd_channels_5_GHZ));
9375 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309376
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309377 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309378 {
9379
9380 if (NULL == wiphy->bands[i])
9381 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309382 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309383 __func__, i);
9384 continue;
9385 }
9386
9387 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9388 {
9389 struct ieee80211_supported_band *band = wiphy->bands[i];
9390
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309391 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309392 {
9393 // Enable social channels for P2P
9394 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9395 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9396 else
9397 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9398 continue;
9399 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309400 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309401 {
9402 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9403 continue;
9404 }
9405 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009406 }
9407 /*Initialise the supported cipher suite details*/
9408 wiphy->cipher_suites = hdd_cipher_suites;
9409 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9410
9411 /*signal strength in mBm (100*dBm) */
9412 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9413
9414#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309415 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009416#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009417
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309418 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309419 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9420 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009421 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9422 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9423
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309424 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
Abhinav Kumar97821072019-08-02 14:29:48 +05309425 wlan_hdd_cfg80211_set_wiphy_sae_feature(wiphy, pCfg);
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309426
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309427 EXIT();
9428 return 0;
9429}
9430
9431/* In this function we are registering wiphy. */
9432int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9433{
9434 ENTER();
9435 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 if (0 > wiphy_register(wiphy))
9437 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309438 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009439 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9440 return -EIO;
9441 }
9442
9443 EXIT();
9444 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309445}
Jeff Johnson295189b2012-06-20 16:38:30 -07009446
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309447/* In this function we are updating channel list when,
9448 regulatory domain is FCC and country code is US.
9449 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9450 As per FCC smart phone is not a indoor device.
9451 GO should not opeate on indoor channels */
9452void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9453{
9454 int j;
9455 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9456 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9457 //Default counrtycode from NV at the time of wiphy initialization.
9458 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9459 &defaultCountryCode[0]))
9460 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009461 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309462 }
9463 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9464 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309465 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309466 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309467 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309468 return;
9469 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309470 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309471 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309472 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309473 // Mark UNII -1 band channel as passive
9474 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9475 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9476 }
9477 }
9478}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309479/* This function registers for all frame which supplicant is interested in */
9480void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009481{
Jeff Johnson295189b2012-06-20 16:38:30 -07009482 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9483 /* Register for all P2P action, public action etc frames */
9484 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009485 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309486 /* Register frame indication call back */
9487 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009488 /* Right now we are registering these frame when driver is getting
9489 initialized. Once we will move to 2.6.37 kernel, in which we have
9490 frame register ops, we will move this code as a part of that */
9491 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309492 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009493 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9494
9495 /* GAS Initial Response */
9496 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9497 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309498
Jeff Johnson295189b2012-06-20 16:38:30 -07009499 /* GAS Comeback Request */
9500 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9501 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9502
9503 /* GAS Comeback Response */
9504 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9505 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9506
9507 /* P2P Public Action */
9508 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309509 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009510 P2P_PUBLIC_ACTION_FRAME_SIZE );
9511
9512 /* P2P Action */
9513 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9514 (v_U8_t*)P2P_ACTION_FRAME,
9515 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009516
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309517 /* WNM BSS Transition Request frame */
9518 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9519 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9520 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009521
9522 /* WNM-Notification */
9523 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9524 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9525 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009526}
9527
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309528void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009529{
Jeff Johnson295189b2012-06-20 16:38:30 -07009530 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9531 /* Register for all P2P action, public action etc frames */
9532 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9533
Jeff Johnsone7245742012-09-05 17:12:55 -07009534 ENTER();
9535
Jeff Johnson295189b2012-06-20 16:38:30 -07009536 /* Right now we are registering these frame when driver is getting
9537 initialized. Once we will move to 2.6.37 kernel, in which we have
9538 frame register ops, we will move this code as a part of that */
9539 /* GAS Initial Request */
9540
9541 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9542 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9543
9544 /* GAS Initial Response */
9545 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9546 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309547
Jeff Johnson295189b2012-06-20 16:38:30 -07009548 /* GAS Comeback Request */
9549 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9550 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9551
9552 /* GAS Comeback Response */
9553 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9554 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9555
9556 /* P2P Public Action */
9557 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309558 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009559 P2P_PUBLIC_ACTION_FRAME_SIZE );
9560
9561 /* P2P Action */
9562 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9563 (v_U8_t*)P2P_ACTION_FRAME,
9564 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009565 /* WNM-Notification */
9566 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9567 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9568 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009569}
9570
9571#ifdef FEATURE_WLAN_WAPI
9572void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309573 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009574{
9575 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9576 tCsrRoamSetKey setKey;
9577 v_BOOL_t isConnected = TRUE;
9578 int status = 0;
9579 v_U32_t roamId= 0xFF;
9580 tANI_U8 *pKeyPtr = NULL;
9581 int n = 0;
9582
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309583 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9584 __func__, hdd_device_modetoString(pAdapter->device_mode),
9585 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009586
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309587 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 setKey.keyId = key_index; // Store Key ID
9589 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9590 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9591 setKey.paeRole = 0 ; // the PAE role
9592 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9593 {
9594 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9595 }
9596 else
9597 {
9598 isConnected = hdd_connIsConnected(pHddStaCtx);
9599 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9600 }
9601 setKey.keyLength = key_Len;
9602 pKeyPtr = setKey.Key;
9603 memcpy( pKeyPtr, key, key_Len);
9604
Arif Hussain6d2a3322013-11-17 19:50:10 -08009605 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009606 __func__, key_Len);
9607 for (n = 0 ; n < key_Len; n++)
9608 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9609 __func__,n,setKey.Key[n]);
9610
9611 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9612 if ( isConnected )
9613 {
9614 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9615 pAdapter->sessionId, &setKey, &roamId );
9616 }
9617 if ( status != 0 )
9618 {
9619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9620 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9621 __LINE__, status );
9622 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9623 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309624 /* Need to clear any trace of key value in the memory.
9625 * Thus zero out the memory even though it is local
9626 * variable.
9627 */
9628 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009629}
9630#endif /* FEATURE_WLAN_WAPI*/
9631
9632#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309633int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009634 beacon_data_t **ppBeacon,
9635 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009636#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309637int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009638 beacon_data_t **ppBeacon,
9639 struct cfg80211_beacon_data *params,
9640 int dtim_period)
9641#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309642{
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 int size;
9644 beacon_data_t *beacon = NULL;
9645 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309646 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9647 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009648
Jeff Johnsone7245742012-09-05 17:12:55 -07009649 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309651 {
9652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9653 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009654 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309655 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009656
9657 old = pAdapter->sessionCtx.ap.beacon;
9658
9659 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309660 {
9661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9662 FL("session(%d) old and new heads points to NULL"),
9663 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009664 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309665 }
9666
9667 if (params->tail && !params->tail_len)
9668 {
9669 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9670 FL("tail_len is zero but tail is not NULL"));
9671 return -EINVAL;
9672 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009673
Jeff Johnson295189b2012-06-20 16:38:30 -07009674#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9675 /* Kernel 3.0 is not updating dtim_period for set beacon */
9676 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309677 {
9678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9679 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309681 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009682#endif
9683
Kapil Gupta137ef892016-12-13 19:38:00 +05309684 if (params->head)
9685 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309687 head = params->head;
9688 } else
9689 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009690 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309691 head = old->head;
9692 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009693
Kapil Gupta137ef892016-12-13 19:38:00 +05309694 if (params->tail || !old)
9695 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009696 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309697 tail = params->tail;
9698 } else
9699 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009700 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309701 tail = old->tail;
9702 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009703
Kapil Gupta137ef892016-12-13 19:38:00 +05309704 if (params->proberesp_ies || !old)
9705 {
9706 proberesp_ies_len = params->proberesp_ies_len;
9707 proberesp_ies = params->proberesp_ies;
9708 } else
9709 {
9710 proberesp_ies_len = old->proberesp_ies_len;
9711 proberesp_ies = old->proberesp_ies;
9712 }
9713
9714 if (params->assocresp_ies || !old)
9715 {
9716 assocresp_ies_len = params->assocresp_ies_len;
9717 assocresp_ies = params->assocresp_ies;
9718 } else
9719 {
9720 assocresp_ies_len = old->assocresp_ies_len;
9721 assocresp_ies = old->assocresp_ies;
9722 }
9723
9724 size = sizeof(beacon_data_t) + head_len + tail_len +
9725 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009726
9727 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009728 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309729 {
9730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9731 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009732 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309733 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009734
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009735#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309736 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009737 beacon->dtim_period = params->dtim_period;
9738 else
9739 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009740#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309741 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009742 beacon->dtim_period = dtim_period;
9743 else
9744 beacon->dtim_period = old->dtim_period;
9745#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309746
Jeff Johnson295189b2012-06-20 16:38:30 -07009747 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9748 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309749 beacon->proberesp_ies = beacon->tail + tail_len;
9750 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9751
Jeff Johnson295189b2012-06-20 16:38:30 -07009752 beacon->head_len = head_len;
9753 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309754 beacon->proberesp_ies_len = proberesp_ies_len;
9755 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009756
c_manjee527ecac2017-01-25 12:25:27 +05309757 if (head && head_len)
9758 memcpy(beacon->head, head, head_len);
9759 if (tail && tail_len)
9760 memcpy(beacon->tail, tail, tail_len);
9761 if (proberesp_ies && proberesp_ies_len)
9762 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9763 if (assocresp_ies && assocresp_ies_len)
9764 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009765
9766 *ppBeacon = beacon;
9767
9768 kfree(old);
9769
9770 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009771}
Jeff Johnson295189b2012-06-20 16:38:30 -07009772
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309773v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9774#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9775 const v_U8_t *pIes,
9776#else
9777 v_U8_t *pIes,
9778#endif
9779 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009780{
9781 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309782 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309784
Jeff Johnson295189b2012-06-20 16:38:30 -07009785 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309786 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009787 elem_id = ptr[0];
9788 elem_len = ptr[1];
9789 left -= 2;
9790 if(elem_len > left)
9791 {
9792 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009793 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009794 eid,elem_len,left);
9795 return NULL;
9796 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309797 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009798 {
9799 return ptr;
9800 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309801
Jeff Johnson295189b2012-06-20 16:38:30 -07009802 left -= elem_len;
9803 ptr += (elem_len + 2);
9804 }
9805 return NULL;
9806}
9807
Jeff Johnson295189b2012-06-20 16:38:30 -07009808/* Check if rate is 11g rate or not */
9809static int wlan_hdd_rate_is_11g(u8 rate)
9810{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009811 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 u8 i;
9813 for (i = 0; i < 8; i++)
9814 {
9815 if(rate == gRateArray[i])
9816 return TRUE;
9817 }
9818 return FALSE;
9819}
9820
9821/* Check for 11g rate and set proper 11g only mode */
9822static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9823 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9824{
9825 u8 i, num_rates = pIe[0];
9826
9827 pIe += 1;
9828 for ( i = 0; i < num_rates; i++)
9829 {
9830 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9831 {
9832 /* If rate set have 11g rate than change the mode to 11G */
9833 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9834 if (pIe[i] & BASIC_RATE_MASK)
9835 {
9836 /* If we have 11g rate as basic rate, it means mode
9837 is 11g only mode.
9838 */
9839 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9840 *pCheckRatesfor11g = FALSE;
9841 }
9842 }
9843 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9844 {
9845 *require_ht = TRUE;
9846 }
9847 }
9848 return;
9849}
9850
9851static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9852{
9853 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9854 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9855 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9856 u8 checkRatesfor11g = TRUE;
9857 u8 require_ht = FALSE;
9858 u8 *pIe=NULL;
9859
9860 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9861
9862 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9863 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9864 if (pIe != NULL)
9865 {
9866 pIe += 1;
9867 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9868 &pConfig->SapHw_mode);
9869 }
9870
9871 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9872 WLAN_EID_EXT_SUPP_RATES);
9873 if (pIe != NULL)
9874 {
9875
9876 pIe += 1;
9877 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9878 &pConfig->SapHw_mode);
9879 }
9880
9881 if( pConfig->channel > 14 )
9882 {
9883 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9884 }
9885
9886 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9887 WLAN_EID_HT_CAPABILITY);
9888
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309889 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009890 {
9891 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9892 if(require_ht)
9893 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9894 }
9895}
9896
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309897static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9898 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9899{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009900 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309901 v_U8_t *pIe = NULL;
9902 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9903
9904 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9905 pBeacon->tail, pBeacon->tail_len);
9906
9907 if (pIe)
9908 {
9909 ielen = pIe[1] + 2;
9910 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9911 {
9912 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9913 }
9914 else
9915 {
9916 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9917 return -EINVAL;
9918 }
9919 *total_ielen += ielen;
9920 }
9921 return 0;
9922}
9923
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009924static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9925 v_U8_t *genie, v_U8_t *total_ielen)
9926{
9927 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9928 int left = pBeacon->tail_len;
9929 v_U8_t *ptr = pBeacon->tail;
9930 v_U8_t elem_id, elem_len;
9931 v_U16_t ielen = 0;
9932
9933 if ( NULL == ptr || 0 == left )
9934 return;
9935
9936 while (left >= 2)
9937 {
9938 elem_id = ptr[0];
9939 elem_len = ptr[1];
9940 left -= 2;
9941 if (elem_len > left)
9942 {
9943 hddLog( VOS_TRACE_LEVEL_ERROR,
9944 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9945 elem_id, elem_len, left);
9946 return;
9947 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309948 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009949 {
9950 /* skipping the VSIE's which we don't want to include or
9951 * it will be included by existing code
9952 */
9953 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9954#ifdef WLAN_FEATURE_WFD
9955 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9956#endif
9957 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9958 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9959 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9960 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9961 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9962 {
9963 ielen = ptr[1] + 2;
9964 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9965 {
9966 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9967 *total_ielen += ielen;
9968 }
9969 else
9970 {
9971 hddLog( VOS_TRACE_LEVEL_ERROR,
9972 "IE Length is too big "
9973 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9974 elem_id, elem_len, *total_ielen);
9975 }
9976 }
9977 }
9978
9979 left -= elem_len;
9980 ptr += (elem_len + 2);
9981 }
9982 return;
9983}
9984
Kapil Gupta137ef892016-12-13 19:38:00 +05309985int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009986{
9987 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309988 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009990 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309991 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009992
9993 genie = vos_mem_malloc(MAX_GENIE_LEN);
9994
9995 if(genie == NULL) {
9996
9997 return -ENOMEM;
9998 }
9999
Kapil Gupta137ef892016-12-13 19:38:00 +053010000 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010001 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
10002 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010004 hddLog(LOGE,
10005 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010006 ret = -EINVAL;
10007 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010008 }
10009
10010#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010011 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
10012 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
10013 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010014 hddLog(LOGE,
10015 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010016 ret = -EINVAL;
10017 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 }
10019#endif
10020
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010021 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
10022 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010023 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010024 hddLog(LOGE,
10025 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010026 ret = -EINVAL;
10027 goto done;
10028 }
10029
10030 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
10031 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -070010032 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -070010033 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010034
10035 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10036 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
10037 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10038 {
10039 hddLog(LOGE,
10040 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010041 ret = -EINVAL;
10042 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010043 }
10044
10045 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10046 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10047 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10048 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10049 ==eHAL_STATUS_FAILURE)
10050 {
10051 hddLog(LOGE,
10052 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010053 ret = -EINVAL;
10054 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010055 }
10056
10057 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010058 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010059 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010060 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 u8 probe_rsp_ie_len[3] = {0};
10062 u8 counter = 0;
10063 /* Check Probe Resp Length if it is greater then 255 then Store
10064 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
10065 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
10066 Store More then 255 bytes into One Variable.
10067 */
10068 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10069 {
10070 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10071 {
10072 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10073 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10074 }
10075 else
10076 {
10077 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10078 rem_probe_resp_ie_len = 0;
10079 }
10080 }
10081
10082 rem_probe_resp_ie_len = 0;
10083
10084 if (probe_rsp_ie_len[0] > 0)
10085 {
10086 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10087 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +053010088 (tANI_U8*)&pBeacon->
10089 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010090 probe_rsp_ie_len[0], NULL,
10091 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10092 {
10093 hddLog(LOGE,
10094 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010095 ret = -EINVAL;
10096 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010097 }
10098 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10099 }
10100
10101 if (probe_rsp_ie_len[1] > 0)
10102 {
10103 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10104 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +053010105 (tANI_U8*)&pBeacon->
10106 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010107 probe_rsp_ie_len[1], NULL,
10108 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10109 {
10110 hddLog(LOGE,
10111 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010112 ret = -EINVAL;
10113 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010114 }
10115 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10116 }
10117
10118 if (probe_rsp_ie_len[2] > 0)
10119 {
10120 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10121 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010122 (tANI_U8*)&pBeacon->
10123 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010124 probe_rsp_ie_len[2], NULL,
10125 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10126 {
10127 hddLog(LOGE,
10128 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010129 ret = -EINVAL;
10130 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010131 }
10132 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10133 }
10134
10135 if (probe_rsp_ie_len[1] == 0 )
10136 {
10137 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10138 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10139 eANI_BOOLEAN_FALSE) )
10140 {
10141 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010142 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010143 }
10144 }
10145
10146 if (probe_rsp_ie_len[2] == 0 )
10147 {
10148 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10149 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10150 eANI_BOOLEAN_FALSE) )
10151 {
10152 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010153 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010154 }
10155 }
10156
10157 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10158 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10159 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10160 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10161 == eHAL_STATUS_FAILURE)
10162 {
10163 hddLog(LOGE,
10164 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010165 ret = -EINVAL;
10166 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010167 }
10168 }
10169 else
10170 {
10171 // Reset WNI_CFG_PROBE_RSP Flags
10172 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10173
10174 hddLog(VOS_TRACE_LEVEL_INFO,
10175 "%s: No Probe Response IE received in set beacon",
10176 __func__);
10177 }
10178
10179 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010180 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 {
10182 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010183 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10184 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010185 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10186 {
10187 hddLog(LOGE,
10188 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010189 ret = -EINVAL;
10190 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010191 }
10192
10193 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10194 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10195 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10196 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10197 == eHAL_STATUS_FAILURE)
10198 {
10199 hddLog(LOGE,
10200 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010201 ret = -EINVAL;
10202 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010203 }
10204 }
10205 else
10206 {
10207 hddLog(VOS_TRACE_LEVEL_INFO,
10208 "%s: No Assoc Response IE received in set beacon",
10209 __func__);
10210
10211 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10212 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10213 eANI_BOOLEAN_FALSE) )
10214 {
10215 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010216 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 }
10218 }
10219
Jeff Johnsone7245742012-09-05 17:12:55 -070010220done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010221 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010222 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010223}
Jeff Johnson295189b2012-06-20 16:38:30 -070010224
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010225/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010226 * FUNCTION: wlan_hdd_validate_operation_channel
10227 * called by wlan_hdd_cfg80211_start_bss() and
10228 * wlan_hdd_cfg80211_set_channel()
10229 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010230 * channel list.
10231 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010232VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010233{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010234
Jeff Johnson295189b2012-06-20 16:38:30 -070010235 v_U32_t num_ch = 0;
10236 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10237 u32 indx = 0;
10238 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010239 v_U8_t fValidChannel = FALSE, count = 0;
10240 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010241
Jeff Johnson295189b2012-06-20 16:38:30 -070010242 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10243
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010244 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010245 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010246 /* Validate the channel */
10247 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010248 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010249 if ( channel == rfChannels[count].channelNum )
10250 {
10251 fValidChannel = TRUE;
10252 break;
10253 }
10254 }
10255 if (fValidChannel != TRUE)
10256 {
10257 hddLog(VOS_TRACE_LEVEL_ERROR,
10258 "%s: Invalid Channel [%d]", __func__, channel);
10259 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010260 }
10261 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010262 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010263 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010264 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10265 valid_ch, &num_ch))
10266 {
10267 hddLog(VOS_TRACE_LEVEL_ERROR,
10268 "%s: failed to get valid channel list", __func__);
10269 return VOS_STATUS_E_FAILURE;
10270 }
10271 for (indx = 0; indx < num_ch; indx++)
10272 {
10273 if (channel == valid_ch[indx])
10274 {
10275 break;
10276 }
10277 }
10278
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010279 if (indx >= num_ch)
10280 {
10281 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10282 {
10283 eCsrBand band;
10284 unsigned int freq;
10285
10286 sme_GetFreqBand(hHal, &band);
10287
10288 if (eCSR_BAND_5G == band)
10289 {
10290#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10291 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10292 {
10293 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010294 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010295 }
10296 else
10297 {
10298 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010299 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010300 }
10301#else
10302 freq = ieee80211_channel_to_frequency(channel);
10303#endif
10304 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10305 return VOS_STATUS_SUCCESS;
10306 }
10307 }
10308
10309 hddLog(VOS_TRACE_LEVEL_ERROR,
10310 "%s: Invalid Channel [%d]", __func__, channel);
10311 return VOS_STATUS_E_FAILURE;
10312 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010313 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010314
Jeff Johnson295189b2012-06-20 16:38:30 -070010315 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010316
Jeff Johnson295189b2012-06-20 16:38:30 -070010317}
10318
Viral Modi3a32cc52013-02-08 11:14:52 -080010319/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010320 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010321 * This function is used to set the channel number
10322 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010323static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010324 struct ieee80211_channel *chan,
10325 enum nl80211_channel_type channel_type
10326 )
10327{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010328 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010329 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010330 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010331 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010332 hdd_context_t *pHddCtx;
10333 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010334
10335 ENTER();
10336
10337 if( NULL == dev )
10338 {
10339 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010340 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010341 return -ENODEV;
10342 }
10343 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010344
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010345 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10346 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10347 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010348 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010349 "%s: device_mode = %s (%d) freq = %d", __func__,
10350 hdd_device_modetoString(pAdapter->device_mode),
10351 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010352
10353 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10354 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010355 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010356 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010357 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010358 }
10359
10360 /*
10361 * Do freq to chan conversion
10362 * TODO: for 11a
10363 */
10364
10365 channel = ieee80211_frequency_to_channel(freq);
10366
10367 /* Check freq range */
10368 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10369 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10370 {
10371 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010372 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010373 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10374 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10375 return -EINVAL;
10376 }
10377
10378 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10379
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010380 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10381 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010382 {
10383 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10384 {
10385 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010386 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010387 return -EINVAL;
10388 }
10389 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10390 "%s: set channel to [%d] for device mode =%d",
10391 __func__, channel,pAdapter->device_mode);
10392 }
10393 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010394 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010395 )
10396 {
10397 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10398 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10399 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10400
10401 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10402 {
10403 /* Link is up then return cant set channel*/
10404 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010405 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010406 return -EINVAL;
10407 }
10408
10409 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10410 pHddStaCtx->conn_info.operationChannel = channel;
10411 pRoamProfile->ChannelInfo.ChannelList =
10412 &pHddStaCtx->conn_info.operationChannel;
10413 }
10414 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010415 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010416 )
10417 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010418 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10419 {
10420 if(VOS_STATUS_SUCCESS !=
10421 wlan_hdd_validate_operation_channel(pAdapter,channel))
10422 {
10423 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010424 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010425 return -EINVAL;
10426 }
10427 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10428 }
10429 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010430 {
10431 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10432
10433 /* If auto channel selection is configured as enable/ 1 then ignore
10434 channel set by supplicant
10435 */
10436 if ( cfg_param->apAutoChannelSelection )
10437 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010438 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10439 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010440 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010441 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10442 __func__, hdd_device_modetoString(pAdapter->device_mode),
10443 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010444 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010445 else
10446 {
10447 if(VOS_STATUS_SUCCESS !=
10448 wlan_hdd_validate_operation_channel(pAdapter,channel))
10449 {
10450 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010451 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010452 return -EINVAL;
10453 }
10454 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10455 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010456 }
10457 }
10458 else
10459 {
10460 hddLog(VOS_TRACE_LEVEL_FATAL,
10461 "%s: Invalid device mode failed to set valid channel", __func__);
10462 return -EINVAL;
10463 }
10464 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010465 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010466}
10467
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010468static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10469 struct net_device *dev,
10470 struct ieee80211_channel *chan,
10471 enum nl80211_channel_type channel_type
10472 )
10473{
10474 int ret;
10475
10476 vos_ssr_protect(__func__);
10477 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10478 vos_ssr_unprotect(__func__);
10479
10480 return ret;
10481}
10482
Anurag Chouhan83026002016-12-13 22:46:21 +053010483#ifdef DHCP_SERVER_OFFLOAD
10484void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10485 VOS_STATUS status)
10486{
10487 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10488
10489 ENTER();
10490
10491 if (NULL == adapter)
10492 {
10493 hddLog(VOS_TRACE_LEVEL_ERROR,
10494 "%s: adapter is NULL",__func__);
10495 return;
10496 }
10497
10498 adapter->dhcp_status.dhcp_offload_status = status;
10499 vos_event_set(&adapter->dhcp_status.vos_event);
10500 return;
10501}
10502
10503/**
10504 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10505 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010506 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010507 *
10508 * Return: None
10509 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010510VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10511 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010512{
10513 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10514 sir_dhcp_srv_offload_info dhcp_srv_info;
10515 tANI_U8 num_entries = 0;
10516 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10517 tANI_U8 num;
10518 tANI_U32 temp;
10519 VOS_STATUS ret;
10520
10521 ENTER();
10522
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010523 if (!re_init) {
10524 ret = wlan_hdd_validate_context(hdd_ctx);
10525 if (0 != ret)
10526 return VOS_STATUS_E_INVAL;
10527 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010528
10529 /* Prepare the request to send to SME */
10530 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10531 if (NULL == dhcp_srv_info) {
10532 hddLog(VOS_TRACE_LEVEL_ERROR,
10533 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10534 return VOS_STATUS_E_NOMEM;
10535 }
10536
10537 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10538
10539 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10540 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10541 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10542 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10543 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10544 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10545
10546 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10547 srv_ip,
10548 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010549 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010550 if (num_entries != IPADDR_NUM_ENTRIES) {
10551 hddLog(VOS_TRACE_LEVEL_ERROR,
10552 "%s: incorrect IP address (%s) assigned for DHCP server!",
10553 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10554 vos_mem_free(dhcp_srv_info);
10555 return VOS_STATUS_E_FAILURE;
10556 }
10557
10558 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10559 hddLog(VOS_TRACE_LEVEL_ERROR,
10560 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10561 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10562 vos_mem_free(dhcp_srv_info);
10563 return VOS_STATUS_E_FAILURE;
10564 }
10565
10566 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10567 hddLog(VOS_TRACE_LEVEL_ERROR,
10568 "%s: invalid IP address (%s)! The last field must be less than 100!",
10569 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10570 vos_mem_free(dhcp_srv_info);
10571 return VOS_STATUS_E_FAILURE;
10572 }
10573
10574 for (num = 0; num < num_entries; num++) {
10575 temp = srv_ip[num];
10576 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10577 }
10578
10579 if (eHAL_STATUS_SUCCESS !=
10580 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10581 hddLog(VOS_TRACE_LEVEL_ERROR,
10582 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10583 vos_mem_free(dhcp_srv_info);
10584 return VOS_STATUS_E_FAILURE;
10585 }
10586
10587 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10588 "%s: enable DHCP Server offload successfully!", __func__);
10589
10590 vos_mem_free(dhcp_srv_info);
10591 return 0;
10592}
10593#endif /* DHCP_SERVER_OFFLOAD */
10594
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010595/*
10596 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10597 * @wiphy_chan: wiphy channel number
10598 * @rfChannel: channel hw value
10599 * @disable: Disable/enable the flags
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010600 * @hdd_ctx: The HDD context handler
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010601 *
10602 * Modify wiphy flags and cds state if channel is indoor.
10603 *
10604 * Return: void
10605 */
10606void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010607 v_U32_t rfChannel, bool disable, hdd_context_t *hdd_ctx)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010608{
10609 v_U32_t channelLoop;
10610 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10611
10612 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10613
10614 if (rfChannels[channelLoop].channelNum == rfChannel) {
10615 channelEnum = (eRfChannels)channelLoop;
10616 break;
10617 }
10618 }
10619
10620 if (INVALID_RF_CHANNEL == channelEnum)
10621 return;
10622
10623 if (disable) {
10624 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10625 wiphy_chan->flags |=
10626 IEEE80211_CHAN_DISABLED;
10627 regChannels[channelEnum].enabled =
10628 NV_CHANNEL_DISABLE;
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010629 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DISABLE",
10630 channelEnum);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010631 }
10632 } else {
10633 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10634 wiphy_chan->flags &=
10635 ~IEEE80211_CHAN_DISABLED;
10636 /*
10637 * Indoor channels are marked as DFS
10638 * during regulatory processing
10639 */
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010640 if ((wiphy_chan->flags & (IEEE80211_CHAN_RADAR |
10641 IEEE80211_CHAN_PASSIVE_SCAN)) ||
10642 ((hdd_ctx->cfg_ini->indoor_channel_support == false)
10643 && (wiphy_chan->flags &
10644 IEEE80211_CHAN_INDOOR_ONLY))) {
10645 regChannels[channelEnum].enabled = NV_CHANNEL_DFS;
10646 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DFS",
10647 channelEnum);
10648 } else {
10649 regChannels[channelEnum].enabled =
10650 NV_CHANNEL_ENABLE;
10651 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as ENABLE",
10652 channelEnum);
10653 }
10654 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010655
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010656 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010657}
10658
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010659void hdd_update_indoor_channel(hdd_context_t *hdd_ctx, bool disable)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010660{
10661 int band_num;
10662 int chan_num;
10663 v_U32_t rfChannel;
10664 struct ieee80211_channel *wiphy_chan;
10665 struct wiphy *wiphy;
10666
10667 ENTER();
10668 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10669
10670 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010671 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010672
10673 if (wiphy->bands[band_num] == NULL)
10674 continue;
10675
10676 for (chan_num = 0;
10677 chan_num < wiphy->bands[band_num]->n_channels;
10678 chan_num++) {
10679
10680 wiphy_chan =
10681 &(wiphy->bands[band_num]->channels[chan_num]);
10682 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10683
10684 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010685 disable, hdd_ctx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010686 }
10687 }
10688 EXIT();
10689}
10690
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010691int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10692{
Dundi Raviteja49de66b2018-07-27 12:22:57 +053010693 eHalStatus status;
10694 int result = 0;
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010695 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10696 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10697 long ret;
10698 eConnectionState prev_conn_state;
10699 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10700
10701 ENTER();
10702
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010703 /* Indicate sme of disconnect so that in progress connection or preauth
10704 * can be aborted
10705 */
10706 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10707 pAdapter->sessionId);
10708 pHddCtx->isAmpAllowed = VOS_TRUE;
10709
10710 /* Need to apply spin lock before decreasing active sessions
10711 * as there can be chance for double decrement if context switch
10712 * Calls hdd_DisConnectHandler.
10713 */
10714
10715 prev_conn_state = pHddStaCtx->conn_info.connState;
10716
10717 spin_lock_bh(&pAdapter->lock_for_active_session);
10718 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10719 {
10720 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10721 }
10722 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10723 spin_unlock_bh(&pAdapter->lock_for_active_session);
10724 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10725
10726 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10727 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10728
10729 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10730
10731 /*
10732 * stop tx queues before deleting STA/BSS context from the firmware.
10733 * tx has to be disabled because the firmware can get busy dropping
10734 * the tx frames after BSS/STA has been deleted and will not send
10735 * back a response resulting in WDI timeout
10736 */
10737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10738 netif_tx_disable(pAdapter->dev);
10739 netif_carrier_off(pAdapter->dev);
10740
10741 wlan_hdd_check_and_stop_mon(pAdapter, true);
10742
10743 /*issue disconnect*/
10744 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10745 pAdapter->sessionId, reason);
10746 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10747 prev_conn_state != eConnectionState_Connecting)
10748 {
10749 hddLog(LOG1,
10750 FL("status = %d, already disconnected"), status);
10751 result = 0;
10752 /*
10753 * Wait here instead of returning directly. This will block the
10754 * next connect command and allow processing of the disconnect
10755 * in SME else we might hit some race conditions leading to SME
10756 * and HDD out of sync. As disconnect is already in progress,
10757 * wait here for 1 sec instead of 5 sec.
10758 */
10759 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10760 goto wait_for_disconnect;
10761 }
10762 /*
10763 * Wait here instead of returning directly, this will block the next
10764 * connect command and allow processing of the scan for ssid and
10765 * the previous connect command in CSR. Else we might hit some
10766 * race conditions leading to SME and HDD out of sync.
10767 */
10768 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10769 {
10770 hddLog(LOG1,
10771 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10772 }
10773 else if ( 0 != status )
10774 {
10775 hddLog(LOGE,
10776 FL("csrRoamDisconnect failure, returned %d"),
10777 (int)status);
10778 result = -EINVAL;
10779 goto disconnected;
10780 }
10781wait_for_disconnect:
10782 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10783 msecs_to_jiffies(wait_time));
10784 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10785 {
10786 hddLog(LOGE,
10787 "%s: Failed to disconnect, timed out", __func__);
10788 result = -ETIMEDOUT;
10789 }
10790disconnected:
10791 hddLog(LOG1,
10792 FL("Set HDD connState to eConnectionState_NotConnected"));
10793 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10794#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10795 /* Sending disconnect event to userspace for kernel version < 3.11
10796 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10797 */
10798 hddLog(LOG1, FL("Send disconnected event to userspace"));
10799
10800 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10801 WLAN_REASON_UNSPECIFIED);
10802#endif
10803
10804 EXIT();
10805 return result;
10806}
10807
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010808void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10809{
10810
10811 hdd_adapter_t *sta_adapter;
10812 tANI_U8 sta_chan;
10813
10814 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10815
10816 if (!sta_chan) {
10817 hddLog(LOG1, FL("STA not connected"));
10818 return;
10819 }
10820
10821 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10822
10823 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10824 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10825 sta_chan);
10826 return;
10827 }
10828
10829 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10830
10831 if (!sta_adapter) {
10832 hddLog(LOG1, FL("STA adapter doesn't exist"));
10833 return;
10834 }
10835
10836 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10837 /* Issue Disconnect request */
10838 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10839}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010840
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010841int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10842{
10843 struct hdd_cache_channels *cache_chann;
10844 struct wiphy *wiphy;
10845 int freq, status, rfChannel;
10846 int i, band_num, channel_num;
10847 struct ieee80211_channel *wiphy_channel;
10848
10849 ENTER();
10850
10851 if (!hdd_ctx) {
10852 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10853 return -EINVAL;
10854 }
10855
10856 wiphy = hdd_ctx->wiphy;
10857
10858 mutex_lock(&hdd_ctx->cache_channel_lock);
10859
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010860 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010861
10862 if (!cache_chann || !cache_chann->num_channels) {
10863 hddLog(VOS_TRACE_LEVEL_INFO,
10864 "%s channel list is NULL or num channels are zero",
10865 __func__);
10866 mutex_unlock(&hdd_ctx->cache_channel_lock);
10867 return -EINVAL;
10868 }
10869
10870 for (i = 0; i < cache_chann->num_channels; i++) {
10871 status = hdd_wlan_get_freq(
10872 cache_chann->channel_info[i].channel_num,
10873 &freq);
10874
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010875 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10876 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010877 if (!wiphy->bands[band_num])
10878 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010879 for (channel_num = 0; channel_num <
10880 wiphy->bands[band_num]->n_channels;
10881 channel_num++) {
10882 wiphy_channel = &(wiphy->bands[band_num]->
10883 channels[channel_num]);
10884 if (wiphy_channel->center_freq == freq) {
10885 rfChannel = wiphy_channel->hw_value;
10886 /*
10887 *Restore the orginal states
10888 *of the channels
10889 */
10890 vos_nv_set_channel_state(
10891 rfChannel,
10892 cache_chann->
10893 channel_info[i].reg_status);
10894 wiphy_channel->flags =
10895 cache_chann->
10896 channel_info[i].wiphy_status;
Ashish Kumar Dhanotiya1cf97dd2019-03-11 16:59:25 +053010897 hddLog(VOS_TRACE_LEVEL_DEBUG,
10898 "Restore channel %d reg_stat %d wiphy_stat 0x%x",
10899 cache_chann->
10900 channel_info[i].channel_num,
10901 cache_chann->
10902 channel_info[i].reg_status,
10903 wiphy_channel->flags);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010904 break;
10905 }
10906 }
10907 if (channel_num < wiphy->bands[band_num]->n_channels)
10908 break;
10909 }
10910 }
10911
10912 mutex_unlock(&hdd_ctx->cache_channel_lock);
10913
10914 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10915 if (status)
10916 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10917 EXIT();
10918
10919 return 0;
10920}
10921
Ashish Kumar Dhanotiya1cf97dd2019-03-11 16:59:25 +053010922int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010923{
10924 struct hdd_cache_channels *cache_chann;
10925 struct wiphy *wiphy;
10926 int freq, status, rfChannel;
10927 int i, band_num, band_ch_num;
10928 struct ieee80211_channel *wiphy_channel;
10929
10930 if (!hdd_ctx) {
10931 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10932 return -EINVAL;
10933 }
10934
10935 wiphy = hdd_ctx->wiphy;
10936
10937 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010938 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010939
10940 if (!cache_chann || !cache_chann->num_channels) {
10941 hddLog(VOS_TRACE_LEVEL_INFO,
10942 "%s channel list is NULL or num channels are zero",
10943 __func__);
10944 mutex_unlock(&hdd_ctx->cache_channel_lock);
10945 return -EINVAL;
10946 }
10947
10948 for (i = 0; i < cache_chann->num_channels; i++) {
10949 status = hdd_wlan_get_freq(
10950 cache_chann->channel_info[i].channel_num,
10951 &freq);
10952
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010953 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010954 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010955 if (!wiphy->bands[band_num])
10956 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010957 for (band_ch_num = 0; band_ch_num <
10958 wiphy->bands[band_num]->n_channels;
10959 band_ch_num++) {
10960 wiphy_channel = &(wiphy->bands[band_num]->
10961 channels[band_ch_num]);
10962 if (wiphy_channel->center_freq == freq) {
10963 rfChannel = wiphy_channel->hw_value;
10964 /*
10965 * Cache the current states of
10966 * the channels
10967 */
10968 cache_chann->
10969 channel_info[i].reg_status =
10970 vos_nv_getChannelEnabledState(
10971 rfChannel);
10972
10973 cache_chann->
10974 channel_info[i].wiphy_status =
10975 wiphy_channel->flags;
10976 hddLog(VOS_TRACE_LEVEL_INFO,
10977 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10978 cache_chann->
10979 channel_info[i].channel_num,
10980 cache_chann->
10981 channel_info[i].reg_status,
10982 wiphy_channel->flags);
10983
10984 vos_nv_set_channel_state(
10985 rfChannel,
10986 NV_CHANNEL_DISABLE);
10987 wiphy_channel->flags |=
10988 IEEE80211_CHAN_DISABLED;
10989 break;
10990 }
10991 }
10992 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10993 break;
10994 }
10995 }
10996
10997 mutex_unlock(&hdd_ctx->cache_channel_lock);
10998 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10999 return 0;
11000}
11001
Jeff Johnson295189b2012-06-20 16:38:30 -070011002#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11003static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
11004 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011005#else
11006static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
11007 struct cfg80211_beacon_data *params,
11008 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011009 enum nl80211_hidden_ssid hidden_ssid,
11010 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011011#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011012{
11013 tsap_Config_t *pConfig;
11014 beacon_data_t *pBeacon = NULL;
11015 struct ieee80211_mgmt *pMgmt_frame;
11016 v_U8_t *pIe=NULL;
11017 v_U16_t capab_info;
11018 eCsrAuthType RSNAuthType;
11019 eCsrEncryptionType RSNEncryptType;
11020 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011021 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011022 tpWLAN_SAPEventCB pSapEventCallback;
11023 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070011024 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011025 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011026 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011027 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070011028 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080011029 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053011030 hdd_adapter_t *sta_adapter;
Peng Xu2446a892014-09-05 17:21:18 +053011031 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070011032 v_BOOL_t MFPCapable = VOS_FALSE;
11033 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011034 v_BOOL_t sapEnable11AC =
11035 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053011036 u_int16_t prev_rsn_length = 0;
11037
Jeff Johnson295189b2012-06-20 16:38:30 -070011038 ENTER();
11039
Nitesh Shah9b066282017-06-06 18:05:52 +053011040 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053011041
11042 /*
11043 * For STA+SAP concurrency support from GUI, first STA connection gets
11044 * triggered and while it is in progress, SAP start also comes up.
11045 * Once STA association is successful, STA connect event is sent to
11046 * kernel which gets queued in kernel workqueue and supplicant won't
11047 * process M1 received from AP and send M2 until this NL80211_CONNECT
11048 * event is received. Workqueue is not scheduled as RTNL lock is already
11049 * taken by hostapd thread which has issued start_bss command to driver.
11050 * Driver cannot complete start_bss as the pending command at the head
11051 * of the SME command pending list is hw_mode_update for STA session
11052 * which cannot be processed as SME is in WAITforKey state for STA
11053 * interface. The start_bss command for SAP interface is queued behind
11054 * the hw_mode_update command and so it cannot be processed until
11055 * hw_mode_update command is processed. This is causing a deadlock so
11056 * disconnect the STA interface first if connection or key exchange is
11057 * in progress and then start SAP interface.
11058 */
11059 sta_adapter = hdd_get_sta_connection_in_progress(pHddCtx);
11060 if (sta_adapter) {
11061 hddLog(LOG1, FL("Disconnecting STA with session id: %d"),
11062 sta_adapter->sessionId);
11063 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
11064 }
11065
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011066 iniConfig = pHddCtx->cfg_ini;
11067
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011068 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011069 if (iniConfig->disable_indoor_channel &&
11070 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011071 hdd_update_indoor_channel(pHddCtx, true);
11072
11073 if (!VOS_IS_STATUS_SUCCESS(
11074 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
11075 hdd_update_indoor_channel(pHddCtx, false);
11076 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
11077 FL("Can't start BSS: update channel list failed"));
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011078 ret = eHAL_STATUS_FAILURE;
11079 goto tdls_enable;
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011080 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053011081
11082 /* check if STA is on indoor channel */
11083 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
11084 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011085 }
11086
Jeff Johnson295189b2012-06-20 16:38:30 -070011087 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11088
11089 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11090
11091 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11092
11093 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11094
11095 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11096
11097 //channel is already set in the set_channel Call back
11098 //pConfig->channel = pCommitConfig->channel;
11099
11100 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011101 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011102 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11103
11104 pConfig->dtim_period = pBeacon->dtim_period;
11105
Arif Hussain6d2a3322013-11-17 19:50:10 -080011106 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011107 pConfig->dtim_period);
11108
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011109 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011110 {
11111 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011112 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011113 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11114 {
11115 tANI_BOOLEAN restartNeeded;
11116 pConfig->ieee80211d = 1;
11117 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11118 sme_setRegInfo(hHal, pConfig->countryCode);
11119 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11120 }
11121 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011122 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011123 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011124 pConfig->ieee80211d = 1;
11125 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11126 sme_setRegInfo(hHal, pConfig->countryCode);
11127 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011128 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011129 else
11130 {
11131 pConfig->ieee80211d = 0;
11132 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011133 /*
11134 * If auto channel is configured i.e. channel is 0,
11135 * so skip channel validation.
11136 */
11137 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11138 {
11139 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11140 {
11141 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011142 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011143 ret = -EINVAL;
11144 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011145 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011146 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011147 }
11148 else
11149 {
11150 if(1 != pHddCtx->is_dynamic_channel_range_set)
11151 {
11152 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11153 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11154 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11155 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011156 pHddCtx->is_dynamic_channel_range_set = 0;
11157 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011158 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011160 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011161 {
11162 pConfig->ieee80211d = 0;
11163 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011164
11165#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11166 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11167 pConfig->authType = eSAP_OPEN_SYSTEM;
11168 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11169 pConfig->authType = eSAP_SHARED_KEY;
11170 else
11171 pConfig->authType = eSAP_AUTO_SWITCH;
11172#else
11173 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11174 pConfig->authType = eSAP_OPEN_SYSTEM;
11175 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11176 pConfig->authType = eSAP_SHARED_KEY;
11177 else
11178 pConfig->authType = eSAP_AUTO_SWITCH;
11179#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011180
11181 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011182
11183 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011184 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011185#ifdef SAP_AUTH_OFFLOAD
11186 /* In case of sap offload, hostapd.conf is configuted with open mode and
11187 * security is configured from ini file. Due to open mode in hostapd.conf
11188 * privacy bit is set to false which will result in not sending,
11189 * data packets as encrypted.
11190 * If enable_sap_auth_offload is enabled in ini and
11191 * sap_auth_offload_sec_type is type of WPA2-PSK,
11192 * driver will set privacy bit to 1.
11193 */
11194 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11195 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11196 pConfig->privacy = VOS_TRUE;
11197#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011198
11199 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11200
11201 /*Set wps station to configured*/
11202 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11203
11204 if(pIe)
11205 {
11206 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11207 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011208 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011209 ret = -EINVAL;
11210 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011211 }
11212 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11213 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011214 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011215 /* Check 15 bit of WPS IE as it contain information for wps state
11216 * WPS state
11217 */
11218 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11219 {
11220 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11221 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11222 {
11223 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11224 }
11225 }
11226 }
11227 else
11228 {
11229 pConfig->wps_state = SAP_WPS_DISABLED;
11230 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011231 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011232
c_hpothufe599e92014-06-16 11:38:55 +053011233 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11234 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11235 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11236 eCSR_ENCRYPT_TYPE_NONE;
11237
Jeff Johnson295189b2012-06-20 16:38:30 -070011238 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011239 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011240 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011241 WLAN_EID_RSN);
11242 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011243 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011244 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011245 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11246 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11247 pConfig->RSNWPAReqIELength);
11248 else
11249 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11250 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011251 /* The actual processing may eventually be more extensive than
11252 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 * by the app.
11254 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011255 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011256 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11257 &RSNEncryptType,
11258 &mcRSNEncryptType,
11259 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011260 &MFPCapable,
11261 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011262 pConfig->RSNWPAReqIE[1]+2,
11263 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011264
11265 if( VOS_STATUS_SUCCESS == status )
11266 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011267 /* Now copy over all the security attributes you have
11268 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011269 * */
11270 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11271 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11272 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11273 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011274 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011275 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011276 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11277 }
11278 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011279
Jeff Johnson295189b2012-06-20 16:38:30 -070011280 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11281 pBeacon->tail, pBeacon->tail_len);
11282
11283 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11284 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011285 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011286 {
11287 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011288 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011289 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011290 if (pConfig->RSNWPAReqIELength <=
11291 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11292 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11293 pIe[1] + 2);
11294 else
11295 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11296 pConfig->RSNWPAReqIELength);
11297
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 }
11299 else
11300 {
11301 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011302 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11303 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11304 pConfig->RSNWPAReqIELength);
11305 else
11306 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11307 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011308 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011309 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11310 &RSNEncryptType,
11311 &mcRSNEncryptType,
11312 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011313 &MFPCapable,
11314 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011315 pConfig->RSNWPAReqIE[1]+2,
11316 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011317
11318 if( VOS_STATUS_SUCCESS == status )
11319 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011320 /* Now copy over all the security attributes you have
11321 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011322 * */
11323 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11324 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11325 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11326 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011327 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011328 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011329 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11330 }
11331 }
11332 }
11333
Kapil Gupta137ef892016-12-13 19:38:00 +053011334 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011335 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011336 ret = -EINVAL;
11337 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011338 }
11339
Jeff Johnson295189b2012-06-20 16:38:30 -070011340 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11341
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011342#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011343 if (params->ssid != NULL)
11344 {
11345 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11346 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11347 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11348 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11349 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011350#else
11351 if (ssid != NULL)
11352 {
11353 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11354 pConfig->SSIDinfo.ssid.length = ssid_len;
11355 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11356 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11357 }
11358#endif
11359
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011360 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011361 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011362
Jeff Johnson295189b2012-06-20 16:38:30 -070011363 /* default value */
11364 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11365 pConfig->num_accept_mac = 0;
11366 pConfig->num_deny_mac = 0;
11367
11368 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11369 pBeacon->tail, pBeacon->tail_len);
11370
11371 /* pIe for black list is following form:
11372 type : 1 byte
11373 length : 1 byte
11374 OUI : 4 bytes
11375 acl type : 1 byte
11376 no of mac addr in black list: 1 byte
11377 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011378 */
11379 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011380 {
11381 pConfig->SapMacaddr_acl = pIe[6];
11382 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011383 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011384 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011385 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11386 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011387 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11388 for (i = 0; i < pConfig->num_deny_mac; i++)
11389 {
11390 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11391 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011392 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011393 }
11394 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11395 pBeacon->tail, pBeacon->tail_len);
11396
11397 /* pIe for white list is following form:
11398 type : 1 byte
11399 length : 1 byte
11400 OUI : 4 bytes
11401 acl type : 1 byte
11402 no of mac addr in white list: 1 byte
11403 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011404 */
11405 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 {
11407 pConfig->SapMacaddr_acl = pIe[6];
11408 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011409 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011410 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011411 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11412 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11414 for (i = 0; i < pConfig->num_accept_mac; i++)
11415 {
11416 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11417 acl_entry++;
11418 }
11419 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011420
Jeff Johnson295189b2012-06-20 16:38:30 -070011421 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11422
Jeff Johnsone7245742012-09-05 17:12:55 -070011423#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011424 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011425 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11426 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011427 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11428 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011429 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11430 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011431 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11432 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011433 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011434 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011435 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011436 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011437
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011438 /* If ACS disable and selected channel <= 14
11439 * OR
11440 * ACS enabled and ACS operating band is choosen as 2.4
11441 * AND
11442 * VHT in 2.4G Disabled
11443 * THEN
11444 * Fallback to 11N mode
11445 */
11446 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11447 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011448 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011449 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011450 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011451 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11452 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011453 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11454 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011455 }
11456#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011457
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 // ht_capab is not what the name conveys,this is used for protection bitmap
11459 pConfig->ht_capab =
11460 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11461
Kapil Gupta137ef892016-12-13 19:38:00 +053011462 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011463 {
11464 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011465 ret = -EINVAL;
11466 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 }
11468
11469 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011470 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011471 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11472 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011473 pConfig->obssProtEnabled =
11474 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011475
Chet Lanctot8cecea22014-02-11 19:09:36 -080011476#ifdef WLAN_FEATURE_11W
11477 pConfig->mfpCapable = MFPCapable;
11478 pConfig->mfpRequired = MFPRequired;
11479 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11480 pConfig->mfpCapable, pConfig->mfpRequired);
11481#endif
11482
Arif Hussain6d2a3322013-11-17 19:50:10 -080011483 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011484 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011485 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11486 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11487 (int)pConfig->channel);
11488 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11489 pConfig->SapHw_mode, pConfig->privacy,
11490 pConfig->authType);
11491 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11492 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11493 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11494 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011495
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011496 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011497 {
11498 //Bss already started. just return.
11499 //TODO Probably it should update some beacon params.
11500 hddLog( LOGE, "Bss Already started...Ignore the request");
11501 EXIT();
11502 return 0;
11503 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011504
Agarwal Ashish51325b52014-06-16 16:50:49 +053011505 if (vos_max_concurrent_connections_reached()) {
11506 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011507 ret = -EINVAL;
11508 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011509 }
11510
Jeff Johnson295189b2012-06-20 16:38:30 -070011511 pConfig->persona = pHostapdAdapter->device_mode;
11512
Peng Xu2446a892014-09-05 17:21:18 +053011513 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11514 if ( NULL != psmeConfig)
11515 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011516 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011517 sme_GetConfigParam(hHal, psmeConfig);
11518 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011519#ifdef WLAN_FEATURE_AP_HT40_24G
11520 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11521 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11522 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11523 {
11524 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11525 sme_UpdateConfig (hHal, psmeConfig);
11526 }
11527#endif
Peng Xu2446a892014-09-05 17:21:18 +053011528 vos_mem_free(psmeConfig);
11529 }
Peng Xuafc34e32014-09-25 13:23:55 +053011530 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011531
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011532 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -070011533 pSapEventCallback = hdd_hostapd_SAPEventCB;
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011534
11535 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070011536 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11537 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11538 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011539 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011540 ret = -EINVAL;
11541 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011542 }
11543
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011544 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011545 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11546
11547 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011548
Jeff Johnson295189b2012-06-20 16:38:30 -070011549 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011550 {
11551 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011552 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011553 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011554 VOS_ASSERT(0);
11555 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011556
Jeff Johnson295189b2012-06-20 16:38:30 -070011557 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011558 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11559 VOS_STATUS_SUCCESS)
11560 {
11561 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11562 VOS_ASSERT(0);
11563 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011564 /* Initialize WMM configuation */
11565 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011566 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011567
Anurag Chouhan83026002016-12-13 22:46:21 +053011568#ifdef DHCP_SERVER_OFFLOAD
11569 /* set dhcp server offload */
11570 if (iniConfig->enable_dhcp_srv_offload &&
11571 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011572 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011573 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011574 if (!VOS_IS_STATUS_SUCCESS(status))
11575 {
11576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11577 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011578 vos_event_reset(&pHostapdState->vosEvent);
11579 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11580 status = vos_wait_single_event(&pHostapdState->vosEvent,
11581 10000);
11582 if (!VOS_IS_STATUS_SUCCESS(status)) {
11583 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011584 ret = -EINVAL;
11585 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011586 }
11587 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011588 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011589 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11590 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11591 {
11592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11593 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11594 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011595 vos_event_reset(&pHostapdState->vosEvent);
11596 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11597 status = vos_wait_single_event(&pHostapdState->vosEvent,
11598 10000);
11599 if (!VOS_IS_STATUS_SUCCESS(status)) {
11600 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011601 ret = -EINVAL;
11602 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011603 }
11604 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011605 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011606#ifdef MDNS_OFFLOAD
11607 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011608 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011609 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11610 if (VOS_IS_STATUS_SUCCESS(status))
11611 {
11612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11613 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011614 vos_event_reset(&pHostapdState->vosEvent);
11615 if (VOS_STATUS_SUCCESS ==
11616 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11617 status = vos_wait_single_event(&pHostapdState->vosEvent,
11618 10000);
11619 if (!VOS_IS_STATUS_SUCCESS(status)) {
11620 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011621 ret = -EINVAL;
11622 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011623 }
11624 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011625 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011626 status = vos_wait_single_event(&pHostapdAdapter->
11627 mdns_status.vos_event, 2000);
11628 if (!VOS_IS_STATUS_SUCCESS(status) ||
11629 pHostapdAdapter->mdns_status.mdns_enable_status ||
11630 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11631 pHostapdAdapter->mdns_status.mdns_resp_status)
11632 {
11633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11634 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11635 pHostapdAdapter->mdns_status.mdns_enable_status,
11636 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11637 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011638 vos_event_reset(&pHostapdState->vosEvent);
11639 if (VOS_STATUS_SUCCESS ==
11640 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11641 status = vos_wait_single_event(&pHostapdState->vosEvent,
11642 10000);
11643 if (!VOS_IS_STATUS_SUCCESS(status)) {
11644 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011645 ret = -EINVAL;
11646 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011647 }
11648 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011649 }
11650 }
11651#endif /* MDNS_OFFLOAD */
11652 } else {
11653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11654 ("DHCP Disabled ini %d, FW %d"),
11655 iniConfig->enable_dhcp_srv_offload,
11656 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011657 }
11658#endif /* DHCP_SERVER_OFFLOAD */
11659
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011660#ifdef WLAN_FEATURE_P2P_DEBUG
11661 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11662 {
11663 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11664 {
11665 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11666 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011667 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011668 }
11669 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11670 {
11671 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11672 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011673 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011674 }
11675 }
11676#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011677 /* Check and restart SAP if it is on Unsafe channel */
11678 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011679
Jeff Johnson295189b2012-06-20 16:38:30 -070011680 pHostapdState->bCommit = TRUE;
11681 EXIT();
11682
11683 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011684error:
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011685 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011686 if (iniConfig->disable_indoor_channel &&
11687 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011688 hdd_update_indoor_channel(pHddCtx, false);
11689 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11690 }
11691
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011692 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011693
11694tdls_enable:
11695 if (ret != eHAL_STATUS_SUCCESS)
11696 wlan_hdd_tdls_reenable(pHddCtx);
11697
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011698 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011699}
11700
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011701#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011702static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011703 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011704 struct beacon_parameters *params)
11705{
11706 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011707 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011708 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011709
11710 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011711
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011712 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11713 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11714 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011715 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11716 hdd_device_modetoString(pAdapter->device_mode),
11717 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011718
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011719 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11720 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011721 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011722 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011723 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011724 }
11725
Agarwal Ashish51325b52014-06-16 16:50:49 +053011726 if (vos_max_concurrent_connections_reached()) {
11727 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11728 return -EINVAL;
11729 }
11730
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011731 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011732 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 )
11734 {
11735 beacon_data_t *old,*new;
11736
11737 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011738
Jeff Johnson295189b2012-06-20 16:38:30 -070011739 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011740 {
11741 hddLog(VOS_TRACE_LEVEL_WARN,
11742 FL("already beacon info added to session(%d)"),
11743 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011744 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011745 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011746
11747 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11748
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011749 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011750 {
11751 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011752 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 return -EINVAL;
11754 }
11755
11756 pAdapter->sessionCtx.ap.beacon = new;
11757
11758 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11759 }
11760
11761 EXIT();
11762 return status;
11763}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011764
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011765static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11766 struct net_device *dev,
11767 struct beacon_parameters *params)
11768{
11769 int ret;
11770
11771 vos_ssr_protect(__func__);
11772 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11773 vos_ssr_unprotect(__func__);
11774
11775 return ret;
11776}
11777
11778static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 struct net_device *dev,
11780 struct beacon_parameters *params)
11781{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011782 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011783 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11784 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011785 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011786
11787 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011788
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011789 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11790 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11791 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11792 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11793 __func__, hdd_device_modetoString(pAdapter->device_mode),
11794 pAdapter->device_mode);
11795
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011796 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11797 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011798 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011799 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011800 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011801 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011802
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011803 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011804 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011805 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011806 {
11807 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011808
Jeff Johnson295189b2012-06-20 16:38:30 -070011809 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011810
Jeff Johnson295189b2012-06-20 16:38:30 -070011811 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011812 {
11813 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11814 FL("session(%d) old and new heads points to NULL"),
11815 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011817 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011818
11819 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11820
11821 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011822 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011823 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 return -EINVAL;
11825 }
11826
11827 pAdapter->sessionCtx.ap.beacon = new;
11828
11829 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11830 }
11831
11832 EXIT();
11833 return status;
11834}
11835
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011836static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11837 struct net_device *dev,
11838 struct beacon_parameters *params)
11839{
11840 int ret;
11841
11842 vos_ssr_protect(__func__);
11843 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11844 vos_ssr_unprotect(__func__);
11845
11846 return ret;
11847}
11848
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011849#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11850
11851#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011852static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011853 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011854#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011855static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011856 struct net_device *dev)
11857#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011858{
11859 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011860 hdd_adapter_t *staAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011861 hdd_context_t *pHddCtx = NULL;
11862 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011863 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011864 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011865
11866 ENTER();
11867
11868 if (NULL == pAdapter)
11869 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011871 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011872 return -ENODEV;
11873 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011874
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011875 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11876 TRACE_CODE_HDD_CFG80211_STOP_AP,
11877 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011878 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11879 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011880 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011881 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011882 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011883 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011884
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011885 pScanInfo = &pHddCtx->scan_info;
11886
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011887 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11888 __func__, hdd_device_modetoString(pAdapter->device_mode),
11889 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011890
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011891 /*
11892 * if a sta connection is in progress in another adapter, disconnect
11893 * the sta and complete the sap operation. sta will reconnect
11894 * after sap stop is done.
11895 */
11896 staAdapter = hdd_get_sta_connection_in_progress(pHddCtx);
11897 if (staAdapter) {
11898 hddLog(LOG1, FL("disconnecting sta with session id: %d"),
11899 staAdapter->sessionId);
11900 wlan_hdd_disconnect(staAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
11901 }
11902
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011903 ret = wlan_hdd_scan_abort(pAdapter);
11904
Girish Gowli4bf7a632014-06-12 13:42:11 +053011905 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011906 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11908 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011909
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011910 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011911 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011912 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11913 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011914
Jeff Johnsone7245742012-09-05 17:12:55 -070011915 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011916 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011917 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011918 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011919 }
11920
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011921 /* Delete all associated STAs before stopping AP/P2P GO */
11922 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011923 hdd_hostapd_stop(dev);
11924
Jeff Johnson295189b2012-06-20 16:38:30 -070011925 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011926 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011927 )
11928 {
11929 beacon_data_t *old;
11930
11931 old = pAdapter->sessionCtx.ap.beacon;
11932
11933 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011934 {
11935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11936 FL("session(%d) beacon data points to NULL"),
11937 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011938 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011939 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011940
Jeff Johnson295189b2012-06-20 16:38:30 -070011941 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011942
11943 mutex_lock(&pHddCtx->sap_lock);
11944 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11945 {
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011946 hdd_hostapd_state_t *pHostapdState =
11947 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11948
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011949 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11950 hdd_wait_for_ecsa_complete(pHddCtx);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011951 vos_event_reset(&pHostapdState->vosEvent);
11952
Jeff Johnson4416a782013-03-25 14:17:50 -070011953 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011954 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011955 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11956
11957 if (!VOS_IS_STATUS_SUCCESS(status))
11958 {
11959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011960 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011961 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011962 }
11963 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011964 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011965 /* BSS stopped, clear the active sessions for this device mode */
11966 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011967 }
11968 mutex_unlock(&pHddCtx->sap_lock);
11969
11970 if(status != VOS_STATUS_SUCCESS)
11971 {
11972 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011973 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011974 return -EINVAL;
11975 }
11976
Jeff Johnson4416a782013-03-25 14:17:50 -070011977 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011978 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11979 ==eHAL_STATUS_FAILURE)
11980 {
11981 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011982 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011983 }
11984
Jeff Johnson4416a782013-03-25 14:17:50 -070011985 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011986 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11987 eANI_BOOLEAN_FALSE) )
11988 {
11989 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011990 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011991 }
11992
11993 // Reset WNI_CFG_PROBE_RSP Flags
11994 wlan_hdd_reset_prob_rspies(pAdapter);
11995
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011996 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11997
Jeff Johnson295189b2012-06-20 16:38:30 -070011998 pAdapter->sessionCtx.ap.beacon = NULL;
11999 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070012000#ifdef WLAN_FEATURE_P2P_DEBUG
12001 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
12002 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
12003 {
12004 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
12005 "GO got removed");
12006 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
12007 }
12008#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012009 }
12010 EXIT();
12011 return status;
12012}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012013
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012014#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12015static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
12016 struct net_device *dev)
12017{
12018 int ret;
12019
12020 vos_ssr_protect(__func__);
12021 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
12022 vos_ssr_unprotect(__func__);
12023
12024 return ret;
12025}
12026#else
12027static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
12028 struct net_device *dev)
12029{
12030 int ret;
12031
12032 vos_ssr_protect(__func__);
12033 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
12034 vos_ssr_unprotect(__func__);
12035
12036 return ret;
12037}
12038#endif
12039
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012040#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
12041
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012042static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012043 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012044 struct cfg80211_ap_settings *params)
12045{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012046 hdd_adapter_t *pAdapter;
12047 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012048 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012049
12050 ENTER();
12051
Girish Gowlib143d7a2015-02-18 19:39:55 +053012052 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012053 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012054 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053012055 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012056 return -ENODEV;
12057 }
12058
12059 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12060 if (NULL == pAdapter)
12061 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012063 "%s: HDD adapter is Null", __func__);
12064 return -ENODEV;
12065 }
12066
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012067 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12068 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
12069 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012070 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
12071 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012072 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012073 "%s: HDD adapter magic is invalid", __func__);
12074 return -ENODEV;
12075 }
12076
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053012077 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
12078
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012079 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012080 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012081 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012082 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012083 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012084 }
12085
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012086 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12087 __func__, hdd_device_modetoString(pAdapter->device_mode),
12088 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012089
12090 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012091 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012092 )
12093 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012094 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012095
12096 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +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_WARN,
12101 FL("already beacon info added to session(%d)"),
12102 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012103 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012104 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012105
Girish Gowlib143d7a2015-02-18 19:39:55 +053012106#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12107 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12108 &new,
12109 &params->beacon);
12110#else
12111 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12112 &new,
12113 &params->beacon,
12114 params->dtim_period);
12115#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012116
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012117 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012118 {
12119 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012120 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012121 return -EINVAL;
12122 }
12123 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012124#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012125 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12126#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12127 params->channel, params->channel_type);
12128#else
12129 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12130#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012131#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012132 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012133 params->ssid_len, params->hidden_ssid,
12134 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012135 }
12136
12137 EXIT();
12138 return status;
12139}
12140
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012141static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12142 struct net_device *dev,
12143 struct cfg80211_ap_settings *params)
12144{
12145 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012146
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012147 vos_ssr_protect(__func__);
12148 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12149 vos_ssr_unprotect(__func__);
12150
12151 return ret;
12152}
12153
12154static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012155 struct net_device *dev,
12156 struct cfg80211_beacon_data *params)
12157{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012158 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012159 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012160 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012161
12162 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012163
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012164 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12165 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12166 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012167 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012168 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012169
12170 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12171 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012172 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012173 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012174 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012175 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012176
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012177 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012178 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012179 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012180 {
12181 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012182
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012183 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012184
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012185 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012186 {
12187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12188 FL("session(%d) beacon data points to NULL"),
12189 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012190 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012191 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012192
12193 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12194
12195 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012196 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012197 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012198 return -EINVAL;
12199 }
12200
12201 pAdapter->sessionCtx.ap.beacon = new;
12202
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012203 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12204 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012205 }
12206
12207 EXIT();
12208 return status;
12209}
12210
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012211static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12212 struct net_device *dev,
12213 struct cfg80211_beacon_data *params)
12214{
12215 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012216
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012217 vos_ssr_protect(__func__);
12218 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12219 vos_ssr_unprotect(__func__);
12220
12221 return ret;
12222}
12223
12224#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012225
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012226static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012227 struct net_device *dev,
12228 struct bss_parameters *params)
12229{
12230 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012231 hdd_context_t *pHddCtx;
12232 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012233
12234 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012235
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012236 if (NULL == pAdapter)
12237 {
12238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12239 "%s: HDD adapter is Null", __func__);
12240 return -ENODEV;
12241 }
12242 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012243 ret = wlan_hdd_validate_context(pHddCtx);
12244 if (0 != ret)
12245 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012246 return ret;
12247 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012248 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12249 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12250 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012251 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12252 __func__, hdd_device_modetoString(pAdapter->device_mode),
12253 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012254
12255 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012256 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012257 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012258 {
12259 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12260 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012261 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012262 {
12263 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012264 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012265 }
12266
12267 EXIT();
12268 return 0;
12269}
12270
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012271static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12272 struct net_device *dev,
12273 struct bss_parameters *params)
12274{
12275 int ret;
12276
12277 vos_ssr_protect(__func__);
12278 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12279 vos_ssr_unprotect(__func__);
12280
12281 return ret;
12282}
Kiet Lam10841362013-11-01 11:36:50 +053012283/* FUNCTION: wlan_hdd_change_country_code_cd
12284* to wait for contry code completion
12285*/
12286void* wlan_hdd_change_country_code_cb(void *pAdapter)
12287{
12288 hdd_adapter_t *call_back_pAdapter = pAdapter;
12289 complete(&call_back_pAdapter->change_country_code);
12290 return NULL;
12291}
12292
Jeff Johnson295189b2012-06-20 16:38:30 -070012293/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012294 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012295 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12296 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012297int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012298 struct net_device *ndev,
12299 enum nl80211_iftype type,
12300 u32 *flags,
12301 struct vif_params *params
12302 )
12303{
12304 struct wireless_dev *wdev;
12305 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012306 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012307 tCsrRoamProfile *pRoamProfile = NULL;
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012308 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012309 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012310 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012311 eMib_dot11DesiredBssType connectedBssType;
12312 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012313 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012314
12315 ENTER();
12316
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012317 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012318 {
12319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12320 "%s: Adapter context is null", __func__);
12321 return VOS_STATUS_E_FAILURE;
12322 }
12323
12324 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12325 if (!pHddCtx)
12326 {
12327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12328 "%s: HDD context is null", __func__);
12329 return VOS_STATUS_E_FAILURE;
12330 }
12331
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012332 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12333 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12334 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012335 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012336 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012337 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012338 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012339 }
12340
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012341 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12342 __func__, hdd_device_modetoString(pAdapter->device_mode),
12343 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012344
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012345 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12346 hddLog(VOS_TRACE_LEVEL_FATAL,
12347 "%s: STA + MON is in progress, cannot change interface",
12348 __func__);
12349 }
12350
Agarwal Ashish51325b52014-06-16 16:50:49 +053012351 if (vos_max_concurrent_connections_reached()) {
12352 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12353 return -EINVAL;
12354 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012355 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012356 wdev = ndev->ieee80211_ptr;
12357
12358#ifdef WLAN_BTAMP_FEATURE
12359 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12360 (NL80211_IFTYPE_ADHOC == type)||
12361 (NL80211_IFTYPE_AP == type)||
12362 (NL80211_IFTYPE_P2P_GO == type))
12363 {
12364 pHddCtx->isAmpAllowed = VOS_FALSE;
12365 // stop AMP traffic
12366 status = WLANBAP_StopAmp();
12367 if(VOS_STATUS_SUCCESS != status )
12368 {
12369 pHddCtx->isAmpAllowed = VOS_TRUE;
12370 hddLog(VOS_TRACE_LEVEL_FATAL,
12371 "%s: Failed to stop AMP", __func__);
12372 return -EINVAL;
12373 }
12374 }
12375#endif //WLAN_BTAMP_FEATURE
12376 /* Reset the current device mode bit mask*/
12377 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12378
Bala Venkatesh5c06a252018-07-12 16:08:04 +053012379 if (((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12380 (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)) ||
12381 type == NL80211_IFTYPE_AP)
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012382 {
12383 /* Notify Mode change in case of concurrency.
12384 * Below function invokes TDLS teardown Functionality Since TDLS is
12385 * not Supported in case of concurrency i.e Once P2P session
12386 * is detected disable offchannel and teardown TDLS links
12387 */
12388 hddLog(LOG1,
12389 FL("Device mode = %d Interface type = %d"),
12390 pAdapter->device_mode, type);
12391 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12392 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012393
Jeff Johnson295189b2012-06-20 16:38:30 -070012394 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012395 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012396 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012397 )
12398 {
12399 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012400 if (!pWextState)
12401 {
12402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12403 "%s: pWextState is null", __func__);
12404 return VOS_STATUS_E_FAILURE;
12405 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012406 pRoamProfile = &pWextState->roamProfile;
12407 LastBSSType = pRoamProfile->BSSType;
12408
12409 switch (type)
12410 {
12411 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012412 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012413 hddLog(VOS_TRACE_LEVEL_INFO,
12414 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12415 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012416#ifdef WLAN_FEATURE_11AC
12417 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12418 {
12419 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12420 }
12421#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012422 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012423 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012424 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012425 //Check for sub-string p2p to confirm its a p2p interface
12426 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012427 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012428#ifdef FEATURE_WLAN_TDLS
12429 mutex_lock(&pHddCtx->tdls_lock);
12430 wlan_hdd_tdls_exit(pAdapter, TRUE);
12431 mutex_unlock(&pHddCtx->tdls_lock);
12432#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012433 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12434 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12435 }
12436 else
12437 {
12438 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012439 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012440 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012441 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012442
Jeff Johnson295189b2012-06-20 16:38:30 -070012443 case NL80211_IFTYPE_ADHOC:
12444 hddLog(VOS_TRACE_LEVEL_INFO,
12445 "%s: setting interface Type to ADHOC", __func__);
12446 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12447 pRoamProfile->phyMode =
12448 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012449 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012450 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012451 hdd_set_ibss_ops( pAdapter );
12452 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012453
12454 status = hdd_sta_id_hash_attach(pAdapter);
12455 if (VOS_STATUS_SUCCESS != status) {
12456 hddLog(VOS_TRACE_LEVEL_ERROR,
12457 FL("Failed to initialize hash for IBSS"));
12458 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012459 break;
12460
12461 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012462 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012463 {
12464 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12465 "%s: setting interface Type to %s", __func__,
12466 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12467
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012468 //Cancel any remain on channel for GO mode
12469 if (NL80211_IFTYPE_P2P_GO == type)
12470 {
12471 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12472 }
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012473 if (NL80211_IFTYPE_AP == type)
12474 {
12475 /*
12476 * As Loading WLAN Driver one interface being created
12477 * for p2p device address. This will take one HW STA and
12478 * the max number of clients that can connect to softAP
12479 * will be reduced by one. so while changing the interface
12480 * type to NL80211_IFTYPE_AP (SoftAP) remove p2p0 interface
12481 * as it is not required in SoftAP mode.
12482 */
12483
12484 // Get P2P Adapter
12485 pP2pAdapter = hdd_get_adapter(pHddCtx,
12486 WLAN_HDD_P2P_DEVICE);
12487 if (pP2pAdapter)
12488 {
Min Liuf3481952018-12-10 16:01:14 +080012489 wlan_hdd_release_intf_addr(pHddCtx,
12490 pP2pAdapter->macAddressCurrent.bytes);
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012491 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12492 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
12493 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12494 }
12495 }
12496
Swaroop Goltia2e32212014-04-09 23:37:33 +053012497 //Disable IMPS & BMPS for SAP/GO
12498 if(VOS_STATUS_E_FAILURE ==
12499 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12500 {
12501 //Fail to Exit BMPS
12502 VOS_ASSERT(0);
12503 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012504
12505 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12506
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012507#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012508
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012509 /* A Mutex Lock is introduced while changing the mode to
12510 * protect the concurrent access for the Adapters by TDLS
12511 * module.
12512 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012513 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012514#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012515 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012516 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012517 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012518 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12519 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012520#ifdef FEATURE_WLAN_TDLS
12521 mutex_unlock(&pHddCtx->tdls_lock);
12522#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012523 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12524 (pConfig->apRandomBssidEnabled))
12525 {
12526 /* To meet Android requirements create a randomized
12527 MAC address of the form 02:1A:11:Fx:xx:xx */
12528 get_random_bytes(&ndev->dev_addr[3], 3);
12529 ndev->dev_addr[0] = 0x02;
12530 ndev->dev_addr[1] = 0x1A;
12531 ndev->dev_addr[2] = 0x11;
12532 ndev->dev_addr[3] |= 0xF0;
12533 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12534 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012535 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12536 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012537 }
12538
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 hdd_set_ap_ops( pAdapter->dev );
12540
Kiet Lam10841362013-11-01 11:36:50 +053012541 /* This is for only SAP mode where users can
12542 * control country through ini.
12543 * P2P GO follows station country code
12544 * acquired during the STA scanning. */
12545 if((NL80211_IFTYPE_AP == type) &&
12546 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12547 {
12548 int status = 0;
12549 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12550 "%s: setting country code from INI ", __func__);
12551 init_completion(&pAdapter->change_country_code);
12552 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12553 (void *)(tSmeChangeCountryCallback)
12554 wlan_hdd_change_country_code_cb,
12555 pConfig->apCntryCode, pAdapter,
12556 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012557 eSIR_FALSE,
12558 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012559 if (eHAL_STATUS_SUCCESS == status)
12560 {
12561 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012562 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012563 &pAdapter->change_country_code,
12564 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012565 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012566 {
12567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012568 FL("SME Timed out while setting country code %ld"),
12569 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012570
12571 if (pHddCtx->isLogpInProgress)
12572 {
12573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12574 "%s: LOGP in Progress. Ignore!!!", __func__);
12575 return -EAGAIN;
12576 }
Kiet Lam10841362013-11-01 11:36:50 +053012577 }
12578 }
12579 else
12580 {
12581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012582 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012583 return -EINVAL;
12584 }
12585 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012586 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012587 if(status != VOS_STATUS_SUCCESS)
12588 {
12589 hddLog(VOS_TRACE_LEVEL_FATAL,
12590 "%s: Error initializing the ap mode", __func__);
12591 return -EINVAL;
12592 }
12593 hdd_set_conparam(1);
12594
Nirav Shah7e3c8132015-06-22 23:51:42 +053012595 status = hdd_sta_id_hash_attach(pAdapter);
12596 if (VOS_STATUS_SUCCESS != status)
12597 {
12598 hddLog(VOS_TRACE_LEVEL_ERROR,
12599 FL("Failed to initialize hash for AP"));
12600 return -EINVAL;
12601 }
12602
Jeff Johnson295189b2012-06-20 16:38:30 -070012603 /*interface type changed update in wiphy structure*/
12604 if(wdev)
12605 {
12606 wdev->iftype = type;
12607 pHddCtx->change_iface = type;
12608 }
12609 else
12610 {
12611 hddLog(VOS_TRACE_LEVEL_ERROR,
12612 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12613 return -EINVAL;
12614 }
12615 goto done;
12616 }
12617
12618 default:
12619 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12620 __func__);
12621 return -EOPNOTSUPP;
12622 }
12623 }
12624 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012625 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012626 )
12627 {
12628 switch(type)
12629 {
12630 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012632 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012633
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012634 if (pAdapter->device_mode == WLAN_HDD_SOFTAP
12635 && !hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE)) {
12636 /*
12637 * The p2p interface was deleted while SoftAP mode was init,
12638 * create that interface now that the SoftAP is going down.
12639 */
12640 pP2pAdapter = hdd_open_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE,
12641 "p2p%d", wlan_hdd_get_intf_addr(pHddCtx),
12642 VOS_TRUE);
12643 }
12644
Deepthi Gowri500fc472014-08-11 19:53:10 +053012645 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012646
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012647#ifdef FEATURE_WLAN_TDLS
12648
12649 /* A Mutex Lock is introduced while changing the mode to
12650 * protect the concurrent access for the Adapters by TDLS
12651 * module.
12652 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012653 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012654#endif
c_hpothu002231a2015-02-05 14:58:51 +053012655 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012656 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012657 //Check for sub-string p2p to confirm its a p2p interface
12658 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012659 {
12660 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12661 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12662 }
12663 else
12664 {
12665 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012667 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012668
12669 /* set con_mode to STA only when no SAP concurrency mode */
12670 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12671 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012672 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012673 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12674 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012675#ifdef FEATURE_WLAN_TDLS
12676 mutex_unlock(&pHddCtx->tdls_lock);
12677#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012678 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012679 if( VOS_STATUS_SUCCESS != status )
12680 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012681 /* In case of JB, for P2P-GO, only change interface will be called,
12682 * This is the right place to enable back bmps_imps()
12683 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012684 if (pHddCtx->hdd_wlan_suspended)
12685 {
12686 hdd_set_pwrparams(pHddCtx);
12687 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012688 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012689 goto done;
12690 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012691 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012692 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012693 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12694 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012695 goto done;
12696 default:
12697 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12698 __func__);
12699 return -EOPNOTSUPP;
12700
12701 }
12702
12703 }
12704 else
12705 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012706 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12707 __func__, hdd_device_modetoString(pAdapter->device_mode),
12708 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012709 return -EOPNOTSUPP;
12710 }
12711
12712
12713 if(pRoamProfile)
12714 {
12715 if ( LastBSSType != pRoamProfile->BSSType )
12716 {
12717 /*interface type changed update in wiphy structure*/
12718 wdev->iftype = type;
12719
12720 /*the BSS mode changed, We need to issue disconnect
12721 if connected or in IBSS disconnect state*/
12722 if ( hdd_connGetConnectedBssType(
12723 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12724 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12725 {
12726 /*need to issue a disconnect to CSR.*/
12727 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12728 if( eHAL_STATUS_SUCCESS ==
12729 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12730 pAdapter->sessionId,
12731 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12732 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012733 ret = wait_for_completion_interruptible_timeout(
12734 &pAdapter->disconnect_comp_var,
12735 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12736 if (ret <= 0)
12737 {
12738 hddLog(VOS_TRACE_LEVEL_ERROR,
12739 FL("wait on disconnect_comp_var failed %ld"), ret);
12740 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012741 }
12742 }
12743 }
12744 }
12745
12746done:
12747 /*set bitmask based on updated value*/
12748 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012749
12750 /* Only STA mode support TM now
12751 * all other mode, TM feature should be disabled */
12752 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12753 (~VOS_STA & pHddCtx->concurrency_mode) )
12754 {
12755 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12756 }
12757
Jeff Johnson295189b2012-06-20 16:38:30 -070012758#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012759 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012760 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012761 {
12762 //we are ok to do AMP
12763 pHddCtx->isAmpAllowed = VOS_TRUE;
12764 }
12765#endif //WLAN_BTAMP_FEATURE
12766 EXIT();
12767 return 0;
12768}
12769
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012770/*
12771 * FUNCTION: wlan_hdd_cfg80211_change_iface
12772 * wrapper function to protect the actual implementation from SSR.
12773 */
12774int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12775 struct net_device *ndev,
12776 enum nl80211_iftype type,
12777 u32 *flags,
12778 struct vif_params *params
12779 )
12780{
12781 int ret;
12782
12783 vos_ssr_protect(__func__);
12784 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12785 vos_ssr_unprotect(__func__);
12786
12787 return ret;
12788}
12789
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012790#ifdef FEATURE_WLAN_TDLS
12791static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012792 struct net_device *dev,
12793#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12794 const u8 *mac,
12795#else
12796 u8 *mac,
12797#endif
12798 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012799{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012800 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012801 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012802 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012803 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012804 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012805 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012806
12807 ENTER();
12808
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012809 if (!dev) {
12810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12811 return -EINVAL;
12812 }
12813
12814 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12815 if (!pAdapter) {
12816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12817 return -EINVAL;
12818 }
12819
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012820 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012821 {
12822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12823 "Invalid arguments");
12824 return -EINVAL;
12825 }
Hoonki Lee27511902013-03-14 18:19:06 -070012826
12827 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12828 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12829 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012830 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012831 "%s: TDLS mode is disabled OR not enabled in FW."
12832 MAC_ADDRESS_STR " Request declined.",
12833 __func__, MAC_ADDR_ARRAY(mac));
12834 return -ENOTSUPP;
12835 }
12836
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012837 if (pHddCtx->isLogpInProgress)
12838 {
12839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12840 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012841 wlan_hdd_tdls_set_link_status(pAdapter,
12842 mac,
12843 eTDLS_LINK_IDLE,
12844 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012845 return -EBUSY;
12846 }
12847
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012848 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012849 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012850
12851 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012853 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12854 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012855 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012856 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012857 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012858
12859 /* in add station, we accept existing valid staId if there is */
12860 if ((0 == update) &&
12861 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12862 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012863 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012865 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012866 " link_status %d. staId %d. add station ignored.",
12867 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012868 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012869 return 0;
12870 }
12871 /* in change station, we accept only when staId is valid */
12872 if ((1 == update) &&
12873 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12874 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12875 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012876 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012878 "%s: " MAC_ADDRESS_STR
12879 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012880 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12881 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12882 mutex_unlock(&pHddCtx->tdls_lock);
12883 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012884 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012885 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012886
12887 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012888 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012889 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012890 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12891 "%s: " MAC_ADDRESS_STR
12892 " TDLS setup is ongoing. Request declined.",
12893 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012894 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012895 }
12896
12897 /* first to check if we reached to maximum supported TDLS peer.
12898 TODO: for now, return -EPERM looks working fine,
12899 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012900 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12901 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012902 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12904 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012905 " TDLS Max peer already connected. Request declined."
12906 " Num of peers (%d), Max allowed (%d).",
12907 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12908 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012909 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012910 }
12911 else
12912 {
12913 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012914 mutex_lock(&pHddCtx->tdls_lock);
12915 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012916 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012917 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012918 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12920 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12921 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012922 return -EPERM;
12923 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012924 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012925 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012926 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012927 wlan_hdd_tdls_set_link_status(pAdapter,
12928 mac,
12929 eTDLS_LINK_CONNECTING,
12930 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012931
Jeff Johnsond75fe012013-04-06 10:53:06 -070012932 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012933 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012934 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012936 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012937 if(StaParams->htcap_present)
12938 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012939 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012940 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012942 "ht_capa->extended_capabilities: %0x",
12943 StaParams->HTCap.extendedHtCapInfo);
12944 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012946 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012948 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012949 if(StaParams->vhtcap_present)
12950 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012952 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12953 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12954 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12955 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012956 {
12957 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012959 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012961 "[%d]: %x ", i, StaParams->supported_rates[i]);
12962 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012963 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012964 else if ((1 == update) && (NULL == StaParams))
12965 {
12966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12967 "%s : update is true, but staParams is NULL. Error!", __func__);
12968 return -EPERM;
12969 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012970
12971 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12972
12973 if (!update)
12974 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012975 /*Before adding sta make sure that device exited from BMPS*/
12976 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12977 {
12978 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12979 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12980 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12981 if (status != VOS_STATUS_SUCCESS) {
12982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12983 }
12984 }
12985
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012986 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012987 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012988 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012989 hddLog(VOS_TRACE_LEVEL_ERROR,
12990 FL("Failed to add TDLS peer STA. Enable Bmps"));
12991 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012992 return -EPERM;
12993 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012994 }
12995 else
12996 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012997 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012998 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012999 if (ret != eHAL_STATUS_SUCCESS) {
13000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
13001 return -EPERM;
13002 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013003 }
13004
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013005 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013006 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
13007
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053013008 mutex_lock(&pHddCtx->tdls_lock);
13009 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
13010
Masti, Narayanraddi07262462016-01-19 12:40:06 +053013011 if ((pTdlsPeer != NULL) &&
13012 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013013 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053013014 hddLog(VOS_TRACE_LEVEL_ERROR,
13015 FL("peer link status %u"), pTdlsPeer->link_status);
13016 mutex_unlock(&pHddCtx->tdls_lock);
13017 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013018 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053013019 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013020
Masti, Narayanraddi07262462016-01-19 12:40:06 +053013021 if (ret <= 0)
13022 {
13023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13024 "%s: timeout waiting for tdls add station indication %ld",
13025 __func__, ret);
13026 goto error;
13027 }
13028
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013029 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
13030 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013032 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013033 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013034 }
13035
13036 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013037
13038error:
Atul Mittal115287b2014-07-08 13:26:33 +053013039 wlan_hdd_tdls_set_link_status(pAdapter,
13040 mac,
13041 eTDLS_LINK_IDLE,
13042 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013043 return -EPERM;
13044
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013045}
13046#endif
13047
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013048VOS_STATUS wlan_hdd_send_sta_authorized_event(
13049 hdd_adapter_t *adapter,
13050 hdd_context_t *hdd_ctx,
13051 const v_MACADDR_t *mac_addr)
13052{
13053 struct sk_buff *vendor_event;
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013054 VOS_STATUS status;
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053013055 struct nl80211_sta_flag_update sta_flags;
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013056
13057 ENTER();
13058
13059 if (!hdd_ctx) {
13060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
13061 return -EINVAL;
13062 }
13063
13064 vendor_event =
13065 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053013066 hdd_ctx->wiphy,
13067#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
13068 &adapter->wdev,
13069#endif
13070 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013071 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
13072 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
13073 GFP_KERNEL);
13074 if (!vendor_event) {
13075 hddLog(VOS_TRACE_LEVEL_ERROR,
13076 FL("cfg80211_vendor_event_alloc failed"));
13077 return -EINVAL;
13078 }
13079
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053013080 sta_flags.mask |= BIT(NL80211_STA_FLAG_AUTHORIZED);
13081 sta_flags.set = true;
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013082
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053013083 status = nla_put(vendor_event,
13084 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
13085 sizeof(struct nl80211_sta_flag_update),
13086 &sta_flags);
13087
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013088 if (status) {
13089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
13090 kfree_skb(vendor_event);
13091 return VOS_STATUS_E_FAILURE;
13092 }
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053013093
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013094 status = nla_put(vendor_event,
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053013095 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR,
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013096 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
13097 if (status) {
13098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
13099 kfree_skb(vendor_event);
13100 return VOS_STATUS_E_FAILURE;
13101 }
13102
13103 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13104
13105 EXIT();
13106 return 0;
13107}
13108
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013109static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013110 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013111#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13112 const u8 *mac,
13113#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013114 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013115#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013116 struct station_parameters *params)
13117{
13118 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013119 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013120 hdd_context_t *pHddCtx;
13121 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013122 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013123 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013124#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013125 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013126 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013127 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013128 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013129#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013130
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013131 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013132
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013133 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013134 if ((NULL == pAdapter))
13135 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013137 "invalid adapter ");
13138 return -EINVAL;
13139 }
13140
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013141 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13142 TRACE_CODE_HDD_CHANGE_STATION,
13143 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013144 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013145
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013146 ret = wlan_hdd_validate_context(pHddCtx);
13147 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013148 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013149 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013150 }
13151
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013152 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13153
13154 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013155 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13157 "invalid HDD station context");
13158 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013159 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013160 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13161
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013162 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13163 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013164 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013165 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013166 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013167 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013168 WLANTL_STA_AUTHENTICATED);
13169
Gopichand Nakkala29149562013-05-10 21:43:41 +053013170 if (status != VOS_STATUS_SUCCESS)
13171 {
13172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13173 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13174 return -EINVAL;
13175 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013176 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13177 &STAMacAddress);
13178 if (status != VOS_STATUS_SUCCESS)
13179 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013180 }
13181 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013182 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13183 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013184#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013185 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13186 StaParams.capability = params->capability;
13187 StaParams.uapsd_queues = params->uapsd_queues;
13188 StaParams.max_sp = params->max_sp;
13189
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013190 /* Convert (first channel , number of channels) tuple to
13191 * the total list of channels. This goes with the assumption
13192 * that if the first channel is < 14, then the next channels
13193 * are an incremental of 1 else an incremental of 4 till the number
13194 * of channels.
13195 */
13196 if (0 != params->supported_channels_len) {
13197 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013198 for ( i = 0 ; i < params->supported_channels_len
13199 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013200 {
13201 int wifi_chan_index;
13202 StaParams.supported_channels[j] = params->supported_channels[i];
13203 wifi_chan_index =
13204 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13205 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013206 for(k=1; k <= no_of_channels
13207 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013208 {
13209 StaParams.supported_channels[j+1] =
13210 StaParams.supported_channels[j] + wifi_chan_index;
13211 j+=1;
13212 }
13213 }
13214 StaParams.supported_channels_len = j;
13215 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013216 if (params->supported_oper_classes_len >
13217 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13218 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13219 "received oper classes:%d, resetting it to max supported %d",
13220 params->supported_oper_classes_len,
13221 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13222 params->supported_oper_classes_len =
13223 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13224 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013225 vos_mem_copy(StaParams.supported_oper_classes,
13226 params->supported_oper_classes,
13227 params->supported_oper_classes_len);
13228 StaParams.supported_oper_classes_len =
13229 params->supported_oper_classes_len;
13230
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013231 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13233 "received extn capabilities:%d, resetting it to max supported",
13234 params->ext_capab_len);
13235 params->ext_capab_len = sizeof(StaParams.extn_capability);
13236 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013237 if (0 != params->ext_capab_len)
13238 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013239 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013240
13241 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013242 {
13243 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013244 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013245 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013246
13247 StaParams.supported_rates_len = params->supported_rates_len;
13248
13249 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13250 * The supported_rates array , for all the structures propogating till Add Sta
13251 * to the firmware has to be modified , if the supplicant (ieee80211) is
13252 * modified to send more rates.
13253 */
13254
13255 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13256 */
13257 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13258 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13259
13260 if (0 != StaParams.supported_rates_len) {
13261 int i = 0;
13262 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13263 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013265 "Supported Rates with Length %d", StaParams.supported_rates_len);
13266 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013268 "[%d]: %0x", i, StaParams.supported_rates[i]);
13269 }
13270
13271 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013272 {
13273 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013274 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013275 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013276
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013277 if (0 != params->ext_capab_len ) {
13278 /*Define A Macro : TODO Sunil*/
13279 if ((1<<4) & StaParams.extn_capability[3]) {
13280 isBufSta = 1;
13281 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013282 /* TDLS Channel Switching Support */
13283 if ((1<<6) & StaParams.extn_capability[3]) {
13284 isOffChannelSupported = 1;
13285 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013286 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013287
13288 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013289 (params->ht_capa || params->vht_capa ||
13290 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013291 /* TDLS Peer is WME/QoS capable */
13292 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013293
13294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13295 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13296 __func__, isQosWmmSta, StaParams.htcap_present);
13297
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013298 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13299 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013300 isOffChannelSupported,
13301 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013302
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013303 if (VOS_STATUS_SUCCESS != status) {
13304 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13305 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13306 return -EINVAL;
13307 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013308 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13309
13310 if (VOS_STATUS_SUCCESS != status) {
13311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13312 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13313 return -EINVAL;
13314 }
13315 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013316#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013317 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013318 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013319 return status;
13320}
13321
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013322#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13323static int wlan_hdd_change_station(struct wiphy *wiphy,
13324 struct net_device *dev,
13325 const u8 *mac,
13326 struct station_parameters *params)
13327#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013328static int wlan_hdd_change_station(struct wiphy *wiphy,
13329 struct net_device *dev,
13330 u8 *mac,
13331 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013332#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013333{
13334 int ret;
13335
13336 vos_ssr_protect(__func__);
13337 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13338 vos_ssr_unprotect(__func__);
13339
13340 return ret;
13341}
13342
Jeff Johnson295189b2012-06-20 16:38:30 -070013343/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013344 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013345 * This function is used to initialize the key information
13346 */
13347#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013348static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013349 struct net_device *ndev,
13350 u8 key_index, bool pairwise,
13351 const u8 *mac_addr,
13352 struct key_params *params
13353 )
13354#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013355static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013356 struct net_device *ndev,
13357 u8 key_index, const u8 *mac_addr,
13358 struct key_params *params
13359 )
13360#endif
13361{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013362 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013363 tCsrRoamSetKey setKey;
13364 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013365 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013366 v_U32_t roamId= 0xFF;
13367 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013368 hdd_hostapd_state_t *pHostapdState;
13369 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013370 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013371 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013372 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013373 v_MACADDR_t *peerMacAddr;
13374 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013375 uint8_t staid = HDD_MAX_STA_COUNT;
13376 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013377
13378 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013379
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013380 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13381 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13382 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013383 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13384 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013385 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013386 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013387 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013388 }
13389
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013390 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13391 __func__, hdd_device_modetoString(pAdapter->device_mode),
13392 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013393
13394 if (CSR_MAX_NUM_KEY <= key_index)
13395 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013396 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013397 key_index);
13398
13399 return -EINVAL;
13400 }
13401
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013402 if (CSR_MAX_KEY_LEN < params->key_len)
13403 {
13404 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13405 params->key_len);
13406
13407 return -EINVAL;
13408 }
13409
Jingxiang Gec438aea2017-10-26 16:44:00 +080013410 if (CSR_MAX_RSC_LEN < params->seq_len)
13411 {
13412 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13413 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013414
13415 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013416 }
13417
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013418 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013419 "%s: called with key index = %d & key length %d & seq length %d",
13420 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013421
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013422 peerMacAddr = (v_MACADDR_t *)mac_addr;
13423
Jeff Johnson295189b2012-06-20 16:38:30 -070013424 /*extract key idx, key len and key*/
13425 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13426 setKey.keyId = key_index;
13427 setKey.keyLength = params->key_len;
13428 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013429 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013430
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013431 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013432 {
13433 case WLAN_CIPHER_SUITE_WEP40:
13434 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13435 break;
13436
13437 case WLAN_CIPHER_SUITE_WEP104:
13438 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13439 break;
13440
13441 case WLAN_CIPHER_SUITE_TKIP:
13442 {
13443 u8 *pKey = &setKey.Key[0];
13444 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13445
13446 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13447
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013448 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013449
13450 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013451 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013452 |--------------|----------|----------|
13453 <---16bytes---><--8bytes--><--8bytes-->
13454
13455 */
13456 /*Sme expects the 32 bytes key to be in the below order
13457
13458 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013459 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013460 |--------------|----------|----------|
13461 <---16bytes---><--8bytes--><--8bytes-->
13462 */
13463 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013464 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013465
13466 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013467 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013468
13469 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013470 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013471
13472
13473 break;
13474 }
13475
13476 case WLAN_CIPHER_SUITE_CCMP:
13477 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13478 break;
13479
13480#ifdef FEATURE_WLAN_WAPI
13481 case WLAN_CIPHER_SUITE_SMS4:
13482 {
13483 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13484 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13485 params->key, params->key_len);
13486 return 0;
13487 }
13488#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013489
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013490#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013491 case WLAN_CIPHER_SUITE_KRK:
13492 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13493 break;
13494#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013495
13496#ifdef WLAN_FEATURE_11W
13497 case WLAN_CIPHER_SUITE_AES_CMAC:
13498 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013499 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013500#endif
13501
Jeff Johnson295189b2012-06-20 16:38:30 -070013502 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013503 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013504 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013505 status = -EOPNOTSUPP;
13506 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013507 }
13508
13509 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13510 __func__, setKey.encType);
13511
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013512 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013513#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13514 (!pairwise)
13515#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013516 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013517#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013518 )
13519 {
13520 /* set group key*/
13521 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13522 "%s- %d: setting Broadcast key",
13523 __func__, __LINE__);
13524 setKey.keyDirection = eSIR_RX_ONLY;
13525 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13526 }
13527 else
13528 {
13529 /* set pairwise key*/
13530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13531 "%s- %d: setting pairwise key",
13532 __func__, __LINE__);
13533 setKey.keyDirection = eSIR_TX_RX;
13534 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013535 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013536 }
13537 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13538 {
13539 setKey.keyDirection = eSIR_TX_RX;
13540 /*Set the group key*/
13541 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13542 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013543
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013544 if ( 0 != status )
13545 {
13546 hddLog(VOS_TRACE_LEVEL_ERROR,
13547 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013548 status = -EINVAL;
13549 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013550 }
13551 /*Save the keys here and call sme_RoamSetKey for setting
13552 the PTK after peer joins the IBSS network*/
13553 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13554 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013555 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013556 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013557 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13558 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13559 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013560 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013561 if( pHostapdState->bssState == BSS_START )
13562 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013563 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13564 vos_status = wlan_hdd_check_ula_done(pAdapter);
13565
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013566 if (peerMacAddr && (pairwise_set_key == true))
13567 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013568
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013569 if ( vos_status != VOS_STATUS_SUCCESS )
13570 {
13571 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13572 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13573 __LINE__, vos_status );
13574
13575 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13576
13577 status = -EINVAL;
13578 goto end;
13579 }
13580
Jeff Johnson295189b2012-06-20 16:38:30 -070013581 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13582
13583 if ( status != eHAL_STATUS_SUCCESS )
13584 {
13585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13586 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13587 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013588 status = -EINVAL;
13589 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 }
13591 }
13592
13593 /* Saving WEP keys */
13594 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13595 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13596 {
13597 //Save the wep key in ap context. Issue setkey after the BSS is started.
13598 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13599 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13600 }
13601 else
13602 {
13603 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013604 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013605 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13606 }
13607 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013608 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13609 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013610 {
13611 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13612 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13613
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13615 if (!pairwise)
13616#else
13617 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13618#endif
13619 {
13620 /* set group key*/
13621 if (pHddStaCtx->roam_info.deferKeyComplete)
13622 {
13623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13624 "%s- %d: Perform Set key Complete",
13625 __func__, __LINE__);
13626 hdd_PerformRoamSetKeyComplete(pAdapter);
13627 }
13628 }
13629
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013630 if (pairwise_set_key == true)
13631 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013632
Jeff Johnson295189b2012-06-20 16:38:30 -070013633 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13634
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013635 pWextState->roamProfile.Keys.defaultIndex = key_index;
13636
13637
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013638 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013639 params->key, params->key_len);
13640
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013641
Jeff Johnson295189b2012-06-20 16:38:30 -070013642 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13643
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013644 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013645 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013646 __func__, setKey.peerMac[0], setKey.peerMac[1],
13647 setKey.peerMac[2], setKey.peerMac[3],
13648 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013649 setKey.keyDirection);
13650
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013651 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013652
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013653 if ( vos_status != VOS_STATUS_SUCCESS )
13654 {
13655 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013656 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13657 __LINE__, vos_status );
13658
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013659 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013660
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013661 status = -EINVAL;
13662 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013663
13664 }
13665
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013666#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013667 /* The supplicant may attempt to set the PTK once pre-authentication
13668 is done. Save the key in the UMAC and include it in the ADD BSS
13669 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013670 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013671 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013672 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013673 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13674 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013675 status = 0;
13676 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013677 }
13678 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13679 {
13680 hddLog(VOS_TRACE_LEVEL_ERROR,
13681 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013682 status = -EINVAL;
13683 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013684 }
13685#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013686
13687 /* issue set key request to SME*/
13688 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13689 pAdapter->sessionId, &setKey, &roamId );
13690
13691 if ( 0 != status )
13692 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013693 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013694 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13695 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013696 status = -EINVAL;
13697 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013698 }
13699
13700
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013701 /* in case of IBSS as there was no information available about WEP keys during
13702 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013703 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013704 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13705 !( ( IW_AUTH_KEY_MGMT_802_1X
13706 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013707 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13708 )
13709 &&
13710 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13711 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13712 )
13713 )
13714 {
13715 setKey.keyDirection = eSIR_RX_ONLY;
13716 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13717
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013718 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013719 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013720 __func__, setKey.peerMac[0], setKey.peerMac[1],
13721 setKey.peerMac[2], setKey.peerMac[3],
13722 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013723 setKey.keyDirection);
13724
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013725 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013726 pAdapter->sessionId, &setKey, &roamId );
13727
13728 if ( 0 != status )
13729 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013730 hddLog(VOS_TRACE_LEVEL_ERROR,
13731 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013732 __func__, status);
13733 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013734 status = -EINVAL;
13735 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013736 }
13737 }
13738 }
13739
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013740 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013741 for (i = 0; i < params->seq_len; i++) {
13742 rsc_counter |= (params->seq[i] << i*8);
13743 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013744 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13745 }
13746
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013747end:
13748 /* Need to clear any trace of key value in the memory.
13749 * Thus zero out the memory even though it is local
13750 * variable.
13751 */
13752 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013753 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013754 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013755}
13756
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013757#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13758static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13759 struct net_device *ndev,
13760 u8 key_index, bool pairwise,
13761 const u8 *mac_addr,
13762 struct key_params *params
13763 )
13764#else
13765static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13766 struct net_device *ndev,
13767 u8 key_index, const u8 *mac_addr,
13768 struct key_params *params
13769 )
13770#endif
13771{
13772 int ret;
13773 vos_ssr_protect(__func__);
13774#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13775 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13776 mac_addr, params);
13777#else
13778 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13779 params);
13780#endif
13781 vos_ssr_unprotect(__func__);
13782
13783 return ret;
13784}
13785
Jeff Johnson295189b2012-06-20 16:38:30 -070013786/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013787 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013788 * This function is used to get the key information
13789 */
13790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013791static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013792 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013793 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013794 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013795 const u8 *mac_addr, void *cookie,
13796 void (*callback)(void *cookie, struct key_params*)
13797 )
13798#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013799static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013800 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013801 struct net_device *ndev,
13802 u8 key_index, const u8 *mac_addr, void *cookie,
13803 void (*callback)(void *cookie, struct key_params*)
13804 )
13805#endif
13806{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013807 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013808 hdd_wext_state_t *pWextState = NULL;
13809 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013810 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013811 hdd_context_t *pHddCtx;
13812 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013813
13814 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013815
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013816 if (NULL == pAdapter)
13817 {
13818 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13819 "%s: HDD adapter is Null", __func__);
13820 return -ENODEV;
13821 }
13822
13823 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13824 ret = wlan_hdd_validate_context(pHddCtx);
13825 if (0 != ret)
13826 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013827 return ret;
13828 }
13829
13830 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13831 pRoamProfile = &(pWextState->roamProfile);
13832
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013833 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13834 __func__, hdd_device_modetoString(pAdapter->device_mode),
13835 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013836
Jeff Johnson295189b2012-06-20 16:38:30 -070013837 memset(&params, 0, sizeof(params));
13838
13839 if (CSR_MAX_NUM_KEY <= key_index)
13840 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013842 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013843 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013844
13845 switch(pRoamProfile->EncryptionType.encryptionType[0])
13846 {
13847 case eCSR_ENCRYPT_TYPE_NONE:
13848 params.cipher = IW_AUTH_CIPHER_NONE;
13849 break;
13850
13851 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13852 case eCSR_ENCRYPT_TYPE_WEP40:
13853 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13854 break;
13855
13856 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13857 case eCSR_ENCRYPT_TYPE_WEP104:
13858 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13859 break;
13860
13861 case eCSR_ENCRYPT_TYPE_TKIP:
13862 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13863 break;
13864
13865 case eCSR_ENCRYPT_TYPE_AES:
13866 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13867 break;
13868
13869 default:
13870 params.cipher = IW_AUTH_CIPHER_NONE;
13871 break;
13872 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013873
c_hpothuaaf19692014-05-17 17:01:48 +053013874 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13875 TRACE_CODE_HDD_CFG80211_GET_KEY,
13876 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013877
Jeff Johnson295189b2012-06-20 16:38:30 -070013878 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13879 params.seq_len = 0;
13880 params.seq = NULL;
13881 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13882 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013883 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013884 return 0;
13885}
13886
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13888static int wlan_hdd_cfg80211_get_key(
13889 struct wiphy *wiphy,
13890 struct net_device *ndev,
13891 u8 key_index, bool pairwise,
13892 const u8 *mac_addr, void *cookie,
13893 void (*callback)(void *cookie, struct key_params*)
13894 )
13895#else
13896static int wlan_hdd_cfg80211_get_key(
13897 struct wiphy *wiphy,
13898 struct net_device *ndev,
13899 u8 key_index, const u8 *mac_addr, void *cookie,
13900 void (*callback)(void *cookie, struct key_params*)
13901 )
13902#endif
13903{
13904 int ret;
13905
13906 vos_ssr_protect(__func__);
13907#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13908 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13909 mac_addr, cookie, callback);
13910#else
13911 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13912 callback);
13913#endif
13914 vos_ssr_unprotect(__func__);
13915
13916 return ret;
13917}
13918
Jeff Johnson295189b2012-06-20 16:38:30 -070013919/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013920 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 * This function is used to delete the key information
13922 */
13923#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013924static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013925 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013926 u8 key_index,
13927 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013928 const u8 *mac_addr
13929 )
13930#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013931static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013932 struct net_device *ndev,
13933 u8 key_index,
13934 const u8 *mac_addr
13935 )
13936#endif
13937{
13938 int status = 0;
13939
13940 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013941 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013942 //it is observed that this is invalidating peer
13943 //key index whenever re-key is done. This is affecting data link.
13944 //It should be ok to ignore del_key.
13945#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013946 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13947 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013948 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13949 tCsrRoamSetKey setKey;
13950 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013951
Jeff Johnson295189b2012-06-20 16:38:30 -070013952 ENTER();
13953
13954 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13955 __func__,pAdapter->device_mode);
13956
13957 if (CSR_MAX_NUM_KEY <= key_index)
13958 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013959 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013960 key_index);
13961
13962 return -EINVAL;
13963 }
13964
13965 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13966 setKey.keyId = key_index;
13967
13968 if (mac_addr)
13969 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13970 else
13971 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13972
13973 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13974
13975 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013976 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013977 )
13978 {
13979
13980 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013981 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13982 if( pHostapdState->bssState == BSS_START)
13983 {
13984 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013985
Jeff Johnson295189b2012-06-20 16:38:30 -070013986 if ( status != eHAL_STATUS_SUCCESS )
13987 {
13988 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13989 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13990 __LINE__, status );
13991 }
13992 }
13993 }
13994 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013995 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013996 )
13997 {
13998 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13999
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014000 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
14001
14002 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070014003 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014004 __func__, setKey.peerMac[0], setKey.peerMac[1],
14005 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070014006 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014007 if(pAdapter->sessionCtx.station.conn_info.connState ==
14008 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070014009 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014010 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014011 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014012
Jeff Johnson295189b2012-06-20 16:38:30 -070014013 if ( 0 != status )
14014 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014015 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 "%s: sme_RoamSetKey failure, returned %d",
14017 __func__, status);
14018 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
14019 return -EINVAL;
14020 }
14021 }
14022 }
14023#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014024 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014025 return status;
14026}
14027
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014028#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14029static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
14030 struct net_device *ndev,
14031 u8 key_index,
14032 bool pairwise,
14033 const u8 *mac_addr
14034 )
14035#else
14036static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
14037 struct net_device *ndev,
14038 u8 key_index,
14039 const u8 *mac_addr
14040 )
14041#endif
14042{
14043 int ret;
14044
14045 vos_ssr_protect(__func__);
14046#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14047 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
14048 mac_addr);
14049#else
14050 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
14051#endif
14052 vos_ssr_unprotect(__func__);
14053
14054 return ret;
14055}
14056
Jeff Johnson295189b2012-06-20 16:38:30 -070014057/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014058 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070014059 * This function is used to set the default tx key index
14060 */
14061#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014062static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014063 struct net_device *ndev,
14064 u8 key_index,
14065 bool unicast, bool multicast)
14066#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014067static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014068 struct net_device *ndev,
14069 u8 key_index)
14070#endif
14071{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014072 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014073 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053014074 hdd_wext_state_t *pWextState;
14075 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014076 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014077
14078 ENTER();
14079
Gopichand Nakkala29149562013-05-10 21:43:41 +053014080 if ((NULL == pAdapter))
14081 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053014083 "invalid adapter");
14084 return -EINVAL;
14085 }
14086
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014087 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14088 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
14089 pAdapter->sessionId, key_index));
14090
Gopichand Nakkala29149562013-05-10 21:43:41 +053014091 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14092 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14093
14094 if ((NULL == pWextState) || (NULL == pHddStaCtx))
14095 {
14096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14097 "invalid Wext state or HDD context");
14098 return -EINVAL;
14099 }
14100
Arif Hussain6d2a3322013-11-17 19:50:10 -080014101 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014102 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014103
Jeff Johnson295189b2012-06-20 16:38:30 -070014104 if (CSR_MAX_NUM_KEY <= key_index)
14105 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014106 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014107 key_index);
14108
14109 return -EINVAL;
14110 }
14111
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014112 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14113 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014114 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014115 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014116 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014117 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014118
Jeff Johnson295189b2012-06-20 16:38:30 -070014119 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014120 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014121 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014122 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014123 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014124 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014125#ifdef FEATURE_WLAN_WAPI
14126 (eCSR_ENCRYPT_TYPE_WPI !=
14127 pHddStaCtx->conn_info.ucEncryptionType) &&
14128#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014129 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014130 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014131 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014132 {
14133 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014134 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014135
Jeff Johnson295189b2012-06-20 16:38:30 -070014136 tCsrRoamSetKey setKey;
14137 v_U32_t roamId= 0xFF;
14138 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014139
14140 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014141 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014142
Jeff Johnson295189b2012-06-20 16:38:30 -070014143 Keys->defaultIndex = (u8)key_index;
14144 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14145 setKey.keyId = key_index;
14146 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014147
14148 vos_mem_copy(&setKey.Key[0],
14149 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014150 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014151
Gopichand Nakkala29149562013-05-10 21:43:41 +053014152 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014153
14154 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014155 &pHddStaCtx->conn_info.bssId[0],
14156 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014157
Gopichand Nakkala29149562013-05-10 21:43:41 +053014158 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14159 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14160 eCSR_ENCRYPT_TYPE_WEP104)
14161 {
14162 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14163 even though ap is configured for WEP-40 encryption. In this canse the key length
14164 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14165 type(104) and switching encryption type to 40*/
14166 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14167 eCSR_ENCRYPT_TYPE_WEP40;
14168 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14169 eCSR_ENCRYPT_TYPE_WEP40;
14170 }
14171
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014172 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014173 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014174
Jeff Johnson295189b2012-06-20 16:38:30 -070014175 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014176 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014177 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014178
Jeff Johnson295189b2012-06-20 16:38:30 -070014179 if ( 0 != status )
14180 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014181 hddLog(VOS_TRACE_LEVEL_ERROR,
14182 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014183 status);
14184 return -EINVAL;
14185 }
14186 }
14187 }
14188
14189 /* In SoftAp mode setting key direction for default mode */
14190 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14191 {
14192 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14193 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14194 (eCSR_ENCRYPT_TYPE_AES !=
14195 pWextState->roamProfile.EncryptionType.encryptionType[0])
14196 )
14197 {
14198 /* Saving key direction for default key index to TX default */
14199 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14200 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14201 }
14202 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014203 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014204 return status;
14205}
14206
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014207#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14208static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14209 struct net_device *ndev,
14210 u8 key_index,
14211 bool unicast, bool multicast)
14212#else
14213static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14214 struct net_device *ndev,
14215 u8 key_index)
14216#endif
14217{
14218 int ret;
14219 vos_ssr_protect(__func__);
14220#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14221 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14222 multicast);
14223#else
14224 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14225#endif
14226 vos_ssr_unprotect(__func__);
14227
14228 return ret;
14229}
14230
Jeff Johnson295189b2012-06-20 16:38:30 -070014231/*
14232 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14233 * This function is used to inform the BSS details to nl80211 interface.
14234 */
14235static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14236 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14237{
14238 struct net_device *dev = pAdapter->dev;
14239 struct wireless_dev *wdev = dev->ieee80211_ptr;
14240 struct wiphy *wiphy = wdev->wiphy;
14241 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14242 int chan_no;
14243 int ie_length;
14244 const char *ie;
14245 unsigned int freq;
14246 struct ieee80211_channel *chan;
14247 int rssi = 0;
14248 struct cfg80211_bss *bss = NULL;
14249
Jeff Johnson295189b2012-06-20 16:38:30 -070014250 if( NULL == pBssDesc )
14251 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014252 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014253 return bss;
14254 }
14255
14256 chan_no = pBssDesc->channelId;
14257 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14258 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14259
14260 if( NULL == ie )
14261 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014262 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014263 return bss;
14264 }
14265
14266#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14267 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14268 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014269 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014270 }
14271 else
14272 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014273 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014274 }
14275#else
14276 freq = ieee80211_channel_to_frequency(chan_no);
14277#endif
14278
14279 chan = __ieee80211_get_channel(wiphy, freq);
14280
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014281 if (!chan) {
14282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14283 return NULL;
14284 }
14285
Abhishek Singhaee43942014-06-16 18:55:47 +053014286 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014287
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014288 return cfg80211_inform_bss(wiphy, chan,
14289#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14290 CFG80211_BSS_FTYPE_UNKNOWN,
14291#endif
14292 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014293 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014294 pBssDesc->capabilityInfo,
14295 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014296 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014297}
14298
Abhishek Singhe6137b82019-03-22 20:06:09 +053014299void wlan_hdd_cfg80211_unlink_bss(hdd_adapter_t *pAdapter, tSirMacAddr bssid)
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014300{
14301 struct net_device *dev = pAdapter->dev;
14302 struct wireless_dev *wdev = dev->ieee80211_ptr;
14303 struct wiphy *wiphy = wdev->wiphy;
14304 struct cfg80211_bss *bss = NULL;
14305
Abhishek Singh5a597e62016-12-05 15:16:30 +053014306 bss = hdd_get_bss_entry(wiphy,
14307 NULL, bssid,
14308 NULL, 0);
Abhishek Singhe6137b82019-03-22 20:06:09 +053014309 if (!bss) {
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014310 hddLog(LOGE, FL("BSS not present"));
14311 } else {
14312 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14313 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14314 cfg80211_unlink_bss(wiphy, bss);
Abhishek Singhe6137b82019-03-22 20:06:09 +053014315 /* cfg80211_get_bss get bss with ref count so release it */
14316 cfg80211_put_bss(wiphy, bss);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014317 }
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014318}
Jeff Johnson295189b2012-06-20 16:38:30 -070014319
14320
14321/*
14322 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14323 * This function is used to inform the BSS details to nl80211 interface.
14324 */
14325struct cfg80211_bss*
14326wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14327 tSirBssDescription *bss_desc
14328 )
14329{
14330 /*
14331 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14332 already exists in bss data base of cfg80211 for that particular BSS ID.
14333 Using cfg80211_inform_bss_frame to update the bss entry instead of
14334 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14335 now there is no possibility to get the mgmt(probe response) frame from PE,
14336 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14337 cfg80211_inform_bss_frame.
14338 */
14339 struct net_device *dev = pAdapter->dev;
14340 struct wireless_dev *wdev = dev->ieee80211_ptr;
14341 struct wiphy *wiphy = wdev->wiphy;
14342 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014343#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14344 qcom_ie_age *qie_age = NULL;
14345 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14346#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014347 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014348#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014349 const char *ie =
14350 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14351 unsigned int freq;
14352 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014353 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014354 struct cfg80211_bss *bss_status = NULL;
Hanumanth Reddy Pothulae04e06c2018-05-31 14:41:36 +053014355 size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
14356 u.probe_resp.variable);
Jeff Johnson295189b2012-06-20 16:38:30 -070014357 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014358 hdd_context_t *pHddCtx;
14359 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014360#ifdef WLAN_OPEN_SOURCE
14361 struct timespec ts;
14362#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014363
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014364
Wilson Yangf80a0542013-10-07 13:02:37 -070014365 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14366 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014367 if (0 != status)
14368 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014369 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014370 }
14371
Hanumanth Reddy Pothula33548e22018-05-31 13:28:51 +053014372 mgmt = kzalloc(frame_len, GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014373 if (!mgmt)
14374 {
14375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14376 "%s: memory allocation failed ", __func__);
14377 return NULL;
14378 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014379
Jeff Johnson295189b2012-06-20 16:38:30 -070014380 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014381
14382#ifdef WLAN_OPEN_SOURCE
14383 /* Android does not want the timestamp from the frame.
14384 Instead it wants a monotonic increasing value */
14385 get_monotonic_boottime(&ts);
14386 mgmt->u.probe_resp.timestamp =
14387 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14388#else
14389 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014390 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14391 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014392
14393#endif
14394
Jeff Johnson295189b2012-06-20 16:38:30 -070014395 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14396 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014397
14398#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14399 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14400 /* Assuming this is the last IE, copy at the end */
14401 ie_length -=sizeof(qcom_ie_age);
14402 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14403 qie_age->element_id = QCOM_VENDOR_IE_ID;
14404 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14405 qie_age->oui_1 = QCOM_OUI1;
14406 qie_age->oui_2 = QCOM_OUI2;
14407 qie_age->oui_3 = QCOM_OUI3;
14408 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014409 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14410 * bss related timestamp is in units of ms. Due to this when scan results
14411 * are sent to lowi the scan age is high.To address this, send age in units
14412 * of 1/10 ms.
14413 */
14414 qie_age->age = (vos_timer_get_system_time() -
14415 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014416#endif
14417
Jeff Johnson295189b2012-06-20 16:38:30 -070014418 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014419 if (bss_desc->fProbeRsp)
14420 {
14421 mgmt->frame_control |=
14422 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14423 }
14424 else
14425 {
14426 mgmt->frame_control |=
14427 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14428 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014429
14430#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014431 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014432 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014433 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014434 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014435 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014436 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014437 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014438
14439 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014440 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014441 }
14442 else
14443 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014444 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14445 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014446 kfree(mgmt);
14447 return NULL;
14448 }
14449#else
14450 freq = ieee80211_channel_to_frequency(chan_no);
14451#endif
14452 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014453 /*when the band is changed on the fly using the GUI, three things are done
14454 * 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)
14455 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14456 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14457 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14458 * and discards the channels correponding to previous band and calls back with zero bss results.
14459 * 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
14460 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14461 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14462 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14463 * So drop the bss and continue to next bss.
14464 */
14465 if(chan == NULL)
14466 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014467 hddLog(VOS_TRACE_LEVEL_ERROR,
14468 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14469 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014470 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014471 return NULL;
14472 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014473 /*To keep the rssi icon of the connected AP in the scan window
14474 *and the rssi icon of the wireless networks in sync
14475 * */
14476 if (( eConnectionState_Associated ==
14477 pAdapter->sessionCtx.station.conn_info.connState ) &&
14478 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14479 pAdapter->sessionCtx.station.conn_info.bssId,
14480 WNI_CFG_BSSID_LEN)) &&
14481 (pHddCtx->hdd_wlan_suspended == FALSE))
14482 {
14483 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14484 rssi = (pAdapter->rssi * 100);
14485 }
14486 else
14487 {
14488 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14489 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014490
Nirav Shah20ac06f2013-12-12 18:14:06 +053014491 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014492 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14493 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014494
Jeff Johnson295189b2012-06-20 16:38:30 -070014495 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14496 frame_len, rssi, GFP_KERNEL);
14497 kfree(mgmt);
14498 return bss_status;
14499}
14500
14501/*
14502 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14503 * This function is used to update the BSS data base of CFG8011
14504 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014505struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014506 tCsrRoamInfo *pRoamInfo
14507 )
14508{
14509 tCsrRoamConnectedProfile roamProfile;
14510 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14511 struct cfg80211_bss *bss = NULL;
14512
14513 ENTER();
14514
14515 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14516 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14517
14518 if (NULL != roamProfile.pBssDesc)
14519 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014520 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14521 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014522
14523 if (NULL == bss)
14524 {
14525 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14526 __func__);
14527 }
14528
14529 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14530 }
14531 else
14532 {
14533 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14534 __func__);
14535 }
14536 return bss;
14537}
14538
14539/*
14540 * FUNCTION: wlan_hdd_cfg80211_update_bss
14541 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014542static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14543 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014544 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014545{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014546 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014547 tCsrScanResultInfo *pScanResult;
14548 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014549 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014550 tScanResultHandle pResult;
14551 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014552 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014553 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014554 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014555
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014556 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14557 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14558 NO_SESSION, pAdapter->sessionId));
14559
Wilson Yangf80a0542013-10-07 13:02:37 -070014560 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014561 ret = wlan_hdd_validate_context(pHddCtx);
14562 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014563 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014564 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014565 }
14566
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014567 if (pAdapter->request != NULL)
14568 {
14569 if ((pAdapter->request->n_ssids == 1)
14570 && (pAdapter->request->ssids != NULL)
14571 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14572 is_p2p_scan = true;
14573 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014574 /*
14575 * start getting scan results and populate cgf80211 BSS database
14576 */
14577 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14578
14579 /* no scan results */
14580 if (NULL == pResult)
14581 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014582 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14583 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014584 wlan_hdd_get_frame_logs(pAdapter,
14585 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014586 return status;
14587 }
14588
14589 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14590
14591 while (pScanResult)
14592 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014593 /*
14594 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14595 * entry already exists in bss data base of cfg80211 for that
14596 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14597 * bss entry instead of cfg80211_inform_bss, But this call expects
14598 * mgmt packet as input. As of now there is no possibility to get
14599 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014600 * ieee80211_mgmt(probe response) and passing to c
14601 * fg80211_inform_bss_frame.
14602 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014603 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14604 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14605 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014606 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14607 continue; //Skip the non p2p bss entries
14608 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014609 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14610 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014611
Jeff Johnson295189b2012-06-20 16:38:30 -070014612
14613 if (NULL == bss_status)
14614 {
14615 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014616 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014617 }
14618 else
14619 {
Yue Maf49ba872013-08-19 12:04:25 -070014620 cfg80211_put_bss(
14621#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14622 wiphy,
14623#endif
14624 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014625 }
14626
14627 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14628 }
14629
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014630 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014631 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014632 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014633}
14634
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014635void
14636hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14637{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014638 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014639 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014640} /****** end hddPrintMacAddr() ******/
14641
14642void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014643hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014644{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014645 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014646 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014647 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14648 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14649 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014650} /****** end hddPrintPmkId() ******/
14651
14652//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14653//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14654
14655//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14656//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14657
14658#define dump_bssid(bssid) \
14659 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014660 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14661 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014662 }
14663
14664#define dump_pmkid(pMac, pmkid) \
14665 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014666 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14667 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014668 }
14669
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014670#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014671/*
14672 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14673 * This function is used to notify the supplicant of a new PMKSA candidate.
14674 */
14675int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014676 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014677 int index, bool preauth )
14678{
Jeff Johnsone7245742012-09-05 17:12:55 -070014679#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014680 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014681 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014682
14683 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014684 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014685
14686 if( NULL == pRoamInfo )
14687 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014688 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014689 return -EINVAL;
14690 }
14691
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014692 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14693 {
14694 dump_bssid(pRoamInfo->bssid);
14695 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014696 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014697 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014698#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014699 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014700}
14701#endif //FEATURE_WLAN_LFR
14702
Yue Maef608272013-04-08 23:09:17 -070014703#ifdef FEATURE_WLAN_LFR_METRICS
14704/*
14705 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14706 * 802.11r/LFR metrics reporting function to report preauth initiation
14707 *
14708 */
14709#define MAX_LFR_METRICS_EVENT_LENGTH 100
14710VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14711 tCsrRoamInfo *pRoamInfo)
14712{
14713 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14714 union iwreq_data wrqu;
14715
14716 ENTER();
14717
14718 if (NULL == pAdapter)
14719 {
14720 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14721 return VOS_STATUS_E_FAILURE;
14722 }
14723
14724 /* create the event */
14725 memset(&wrqu, 0, sizeof(wrqu));
14726 memset(metrics_notification, 0, sizeof(metrics_notification));
14727
14728 wrqu.data.pointer = metrics_notification;
14729 wrqu.data.length = scnprintf(metrics_notification,
14730 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14731 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14732
14733 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14734
14735 EXIT();
14736
14737 return VOS_STATUS_SUCCESS;
14738}
14739
14740/*
14741 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14742 * 802.11r/LFR metrics reporting function to report preauth completion
14743 * or failure
14744 */
14745VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14746 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14747{
14748 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14749 union iwreq_data wrqu;
14750
14751 ENTER();
14752
14753 if (NULL == pAdapter)
14754 {
14755 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14756 return VOS_STATUS_E_FAILURE;
14757 }
14758
14759 /* create the event */
14760 memset(&wrqu, 0, sizeof(wrqu));
14761 memset(metrics_notification, 0, sizeof(metrics_notification));
14762
14763 scnprintf(metrics_notification, sizeof(metrics_notification),
14764 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14765 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14766
14767 if (1 == preauth_status)
14768 strncat(metrics_notification, " TRUE", 5);
14769 else
14770 strncat(metrics_notification, " FALSE", 6);
14771
14772 wrqu.data.pointer = metrics_notification;
14773 wrqu.data.length = strlen(metrics_notification);
14774
14775 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14776
14777 EXIT();
14778
14779 return VOS_STATUS_SUCCESS;
14780}
14781
14782/*
14783 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14784 * 802.11r/LFR metrics reporting function to report handover initiation
14785 *
14786 */
14787VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14788 tCsrRoamInfo *pRoamInfo)
14789{
14790 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14791 union iwreq_data wrqu;
14792
14793 ENTER();
14794
14795 if (NULL == pAdapter)
14796 {
14797 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14798 return VOS_STATUS_E_FAILURE;
14799 }
14800
14801 /* create the event */
14802 memset(&wrqu, 0, sizeof(wrqu));
14803 memset(metrics_notification, 0, sizeof(metrics_notification));
14804
14805 wrqu.data.pointer = metrics_notification;
14806 wrqu.data.length = scnprintf(metrics_notification,
14807 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14808 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14809
14810 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14811
14812 EXIT();
14813
14814 return VOS_STATUS_SUCCESS;
14815}
14816#endif
14817
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014818
14819/**
14820 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14821 * @scan_req: scan request to be checked
14822 *
14823 * Return: true or false
14824 */
14825#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14826static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14827 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014828 *scan_req, hdd_context_t
14829 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014830{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014831 if (!scan_req || !scan_req->wiphy ||
14832 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014833 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14834 return false;
14835 }
14836 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14837 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14838 return false;
14839 }
14840 return true;
14841}
14842#else
14843static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14844 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014845 *scan_req, hdd_context_t
14846 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014847{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014848 if (!scan_req || !scan_req->wiphy ||
14849 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014850 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14851 return false;
14852 }
14853 return true;
14854}
14855#endif
14856
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014857#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14858/**
14859 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14860 * @adapter: Pointer to the adapter
14861 * @req : Scan request
14862 * @aborted : true scan aborted false scan success
14863 *
14864 * This function notifies scan done to cfg80211
14865 *
14866 * Return: none
14867 */
14868static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14869 struct cfg80211_scan_request *req,
14870 bool aborted)
14871{
14872 struct cfg80211_scan_info info = {
14873 .aborted = aborted
14874 };
14875
14876 if (adapter->dev->flags & IFF_UP)
14877 cfg80211_scan_done(req, &info);
14878 else
14879 hddLog(LOGW,
14880 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14881}
14882#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14883/**
14884 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14885 * @adapter: Pointer to the adapter
14886 * @req : Scan request
14887 * @aborted : true scan aborted false scan success
14888 *
14889 * This function notifies scan done to cfg80211
14890 *
14891 * Return: none
14892 */
14893static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14894 struct cfg80211_scan_request *req,
14895 bool aborted)
14896{
14897 if (adapter->dev->flags & IFF_UP)
14898 cfg80211_scan_done(req, aborted);
14899 else
14900 hddLog(LOGW,
14901 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14902}
14903#else
14904/**
14905 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14906 * @adapter: Pointer to the adapter
14907 * @req : Scan request
14908 * @aborted : true scan aborted false scan success
14909 *
14910 * This function notifies scan done to cfg80211
14911 *
14912 * Return: none
14913 */
14914static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14915 struct cfg80211_scan_request *req,
14916 bool aborted)
14917{
14918 cfg80211_scan_done(req, aborted);
14919}
14920#endif
14921
Mukul Sharmab392b642017-08-17 17:45:29 +053014922#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014923/*
14924 * FUNCTION: hdd_cfg80211_scan_done_callback
14925 * scanning callback function, called after finishing scan
14926 *
14927 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014928static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014929 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14930{
14931 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014932 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014933 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014934 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014935 struct cfg80211_scan_request *req = NULL;
14936 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014937 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014938 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014939 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014940
14941 ENTER();
14942
c_manjee1b4ab9a2016-10-26 11:36:55 +053014943 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14944 !pAdapter->dev) {
14945 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14946 return 0;
14947 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014948 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014949 if (NULL == pHddCtx) {
14950 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014951 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014952 }
14953
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014954#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014955 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014956 {
14957 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014958 }
14959#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014960 pScanInfo = &pHddCtx->scan_info;
14961
Jeff Johnson295189b2012-06-20 16:38:30 -070014962 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014963 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014964 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014965 __func__, halHandle, pContext, (int) scanId, (int) status);
14966
Kiet Lamac06e2c2013-10-23 16:25:07 +053014967 pScanInfo->mScanPendingCounter = 0;
14968
Jeff Johnson295189b2012-06-20 16:38:30 -070014969 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014970 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014971 &pScanInfo->scan_req_completion_event,
14972 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014973 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014974 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014975 hddLog(VOS_TRACE_LEVEL_ERROR,
14976 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014977 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014978 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014979 }
14980
Yue Maef608272013-04-08 23:09:17 -070014981 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014982 {
14983 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014984 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014985 }
14986
14987 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014988 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014989 {
14990 hddLog(VOS_TRACE_LEVEL_INFO,
14991 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014992 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014993 (int) scanId);
14994 }
14995
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014996#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014997 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014998#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014999 {
15000 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
15001 pAdapter);
15002 if (0 > ret)
15003 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053015004 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015005
Jeff Johnson295189b2012-06-20 16:38:30 -070015006 /* If any client wait scan result through WEXT
15007 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015008 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070015009 {
15010 /* The other scan request waiting for current scan finish
15011 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015012 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070015013 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015014 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070015015 }
15016 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015017 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070015018 {
15019 struct net_device *dev = pAdapter->dev;
15020 union iwreq_data wrqu;
15021 int we_event;
15022 char *msg;
15023
15024 memset(&wrqu, '\0', sizeof(wrqu));
15025 we_event = SIOCGIWSCAN;
15026 msg = NULL;
15027 wireless_send_event(dev, we_event, &wrqu, msg);
15028 }
15029 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015030 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015031
15032 /* Get the Scan Req */
15033 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053015034 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015035
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015036 /* Scan is no longer pending */
15037 pScanInfo->mScanPending = VOS_FALSE;
15038
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053015039 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070015040 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
15042 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053015043 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015044#endif
15045
15046 if (pAdapter->dev) {
15047 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
15048 pAdapter->dev->name);
15049 }
mukul sharmae7041822015-12-03 15:09:21 +053015050 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070015051 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070015052 }
15053
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015054 /* last_scan_timestamp is used to decide if new scan
15055 * is needed or not on station interface. If last station
15056 * scan time and new station scan time is less then
15057 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015058 * Also only last_scan_timestamp is updated here last_scan_channellist
15059 * is updated on receiving scan request itself to make sure kernel
15060 * allocated scan request(scan_req) object is not dereferenced here,
15061 * because interface down, where kernel frees scan_req, may happen any
15062 * time while driver is processing scan_done_callback. So it's better
15063 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015064 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015065 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
15066 if (status == eCSR_SCAN_SUCCESS)
15067 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
15068 else {
15069 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
15070 sizeof(pHddCtx->scan_info.last_scan_channelList));
15071 pHddCtx->scan_info.last_scan_numChannels = 0;
15072 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015073 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015074 }
15075
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070015076 /*
15077 * cfg80211_scan_done informing NL80211 about completion
15078 * of scanning
15079 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015080 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
15081 {
15082 aborted = true;
15083 }
mukul sharmae7041822015-12-03 15:09:21 +053015084
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015085#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015086 if (NET_DEV_IS_IFF_UP(pAdapter) &&
15087 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015088#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015089 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053015090
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080015091 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070015092
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015093allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015094 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
15095 ) && (pHddCtx->spoofMacAddr.isEnabled
15096 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015097 /* Generate new random mac addr for next scan */
15098 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015099
15100 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15101 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015102 }
15103
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015104 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015105 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015106
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015107 /* Acquire wakelock to handle the case where APP's tries to suspend
15108 * immediatly after the driver gets connect request(i.e after scan)
15109 * from supplicant, this result in app's is suspending and not able
15110 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015111 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015112
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015113#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015114 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015115#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015116#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015117 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015118#endif
15119
Jeff Johnson295189b2012-06-20 16:38:30 -070015120 EXIT();
15121 return 0;
15122}
15123
15124/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015125 * FUNCTION: hdd_isConnectionInProgress
15126 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015127 *
15128 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015129v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15130 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015131{
15132 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15133 hdd_station_ctx_t *pHddStaCtx = NULL;
15134 hdd_adapter_t *pAdapter = NULL;
15135 VOS_STATUS status = 0;
15136 v_U8_t staId = 0;
15137 v_U8_t *staMac = NULL;
15138
15139 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15140
15141 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15142 {
15143 pAdapter = pAdapterNode->pAdapter;
15144
15145 if( pAdapter )
15146 {
15147 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015148 "%s: Adapter with device mode %s (%d) exists",
15149 __func__, hdd_device_modetoString(pAdapter->device_mode),
15150 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015151 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015152 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15153 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15154 (eConnectionState_Connecting ==
15155 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15156 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015157 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015158 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015159 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015160 if (session_id && reason)
15161 {
15162 *session_id = pAdapter->sessionId;
15163 *reason = eHDD_CONNECTION_IN_PROGRESS;
15164 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015165 return VOS_TRUE;
15166 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015167 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015168 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015169 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015170 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015171 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015172 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015173 if (session_id && reason)
15174 {
15175 *session_id = pAdapter->sessionId;
15176 *reason = eHDD_REASSOC_IN_PROGRESS;
15177 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015178 return VOS_TRUE;
15179 }
15180 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015181 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15182 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015183 {
15184 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15185 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Vignesh Viswanathan0ac8e562018-06-14 17:24:10 +053015186 sme_is_sta_key_exchange_in_progress(pHddCtx->hHal,
15187 pAdapter->sessionId))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015188 {
15189 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015190 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015191 "%s: client " MAC_ADDRESS_STR
15192 " is in the middle of WPS/EAPOL exchange.", __func__,
15193 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015194 if (session_id && reason)
15195 {
15196 *session_id = pAdapter->sessionId;
15197 *reason = eHDD_EAPOL_IN_PROGRESS;
15198 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015199 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015200 }
15201 }
15202 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15203 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15204 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015205 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15206 ptSapContext pSapCtx = NULL;
15207 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15208 if(pSapCtx == NULL){
15209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15210 FL("psapCtx is NULL"));
15211 return VOS_FALSE;
15212 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015213 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15214 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015215 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15216 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015217 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015218 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015219
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015220 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015221 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15222 "middle of WPS/EAPOL exchange.", __func__,
15223 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015224 if (session_id && reason)
15225 {
15226 *session_id = pAdapter->sessionId;
15227 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15228 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015229 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015230 }
15231 }
15232 }
15233 }
15234 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15235 pAdapterNode = pNext;
15236 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015237 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015238}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015239
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015240/**
15241 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15242 * to the Scan request
15243 * @scanRequest: Pointer to the csr scan request
15244 * @request: Pointer to the scan request from supplicant
15245 *
15246 * Return: None
15247 */
15248#ifdef CFG80211_SCAN_BSSID
15249static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15250 struct cfg80211_scan_request *request)
15251{
15252 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15253}
15254#else
15255static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15256 struct cfg80211_scan_request *request)
15257{
15258}
15259#endif
15260
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015261#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
15262 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
15263/**
15264 * hdd_is_wiphy_scan_random_support() - Check NL80211 scan randomization support
15265 * @wiphy: Pointer to wiphy structure
15266 *
15267 * This function is used to check whether @wiphy supports
15268 * NL80211 scan randomization feature.
15269 *
15270 * Return: If randomization is supported then return true else false.
15271 */
15272static bool
15273hdd_is_wiphy_scan_random_support(struct wiphy *wiphy)
15274{
15275 if (wiphy->features & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)
15276 return true;
15277
15278 return false;
15279}
15280
15281/**
15282 * hdd_is_nl_scan_random() - Check for randomization flag in cfg80211 scan
15283 * @nl_scan: cfg80211 scan request
15284 *
15285 * This function is used to check whether scan randomization flag is set for
15286 * current cfg80211 scan request identified by @nl_scan.
15287 *
15288 * Return: If randomization flag is set then return true else false.
15289 */
15290static bool
15291hdd_is_nl_scan_random(struct cfg80211_scan_request *nl_scan)
15292{
15293 if (nl_scan->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
15294 return true;
15295
15296 return false;
15297}
15298#else
15299static bool
15300hdd_is_wiphy_scan_random_support(struct wiphy *wiphy)
15301{
15302 return false;
15303}
15304
15305static bool
15306hdd_is_nl_scan_random(struct cfg80211_scan_request *nl_scan)
15307{
15308 return false;
15309}
15310#endif
15311
15312/**
15313 * hdd_generate_scan_random_mac() - Generate Random mac addr for cfg80211 scan
15314 * @mac_addr: Input mac-addr from which random-mac address is to be generated
15315 * @mac_mask: Bits of mac_addr which should not be randomized
15316 * @random_mac: Output pointer to hold generated random mac address
15317 *
15318 * This function is used generate random mac address using @mac_addr and
15319 * @mac_mask with following logic:
15320 * Bit value 0 in the mask means that we should randomize that bit.
15321 * Bit value 1 in the mask means that we should take specific bit value
15322 * from mac address provided.
15323 *
15324 * Return: None
15325 */
15326static void
15327hdd_generate_scan_random_mac(uint8_t *mac_addr, uint8_t *mac_mask,
15328 uint8_t *random_mac)
15329{
15330 uint32_t i;
15331 uint8_t random_byte;
15332
15333 for (i = 0; i < VOS_MAC_ADDRESS_LEN; i++) {
15334 random_byte = 0;
15335 get_random_bytes(&random_byte, 1);
15336 random_mac[i] = (mac_addr[i] & mac_mask[i]) |
15337 (random_byte & (~(mac_mask[i])));
15338 }
15339
15340 /*
15341 * Make sure locally administered bit is set if that
15342 * particular bit in the mask is 0
15343 */
15344 if (!(mac_mask[0] & 0x2))
15345 random_mac[0] |= 0x2;
15346
15347 /*
15348 * Make sure multicast/group address bit is NOT set if that
15349 * particular bit in the mask is 0
15350 */
15351 if (!(mac_mask[0] & 0x1))
15352 random_mac[0] &= ~0x1;
15353}
15354
15355/**
15356 * hdd_spoof_scan() - Spoof cfg80211 scan
15357 * @wiphy: Pointer to wiphy
15358 * @adapter: Pointer to adapter for which scan is requested
15359 * @nl_scan: Cfg80211 scan request
15360 * @is_p2p_scan: Check for p2p scan
15361 * @csr_scan: Pointer to internal (csr) scan request
15362 *
15363 * This function is used for following purposes:
15364 * (a) If cfg80211 supports scan randomization then this function invokes helper
15365 * functions to generate random-mac address.
15366 * (b) If the cfg80211 doesn't support scan randomization then randomize scans
15367 * using spoof mac received with VENDOR_SUBCMD_MAC_OUI.
15368 * (c) Configure the random-mac in transport layer.
15369 *
15370 * Return: For success return 0 else return negative value.
15371 */
15372static int
15373hdd_spoof_scan(struct wiphy *wiphy, hdd_adapter_t *adapter,
15374 struct cfg80211_scan_request *nl_scan,
15375 bool is_p2p_scan, tCsrScanRequest *csr_scan)
15376{
15377 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
15378 hdd_config_t *config = hdd_ctx->cfg_ini;
15379 uint8_t random_mac[VOS_MAC_ADDRESS_LEN];
15380 VOS_STATUS vos_status;
15381 eHalStatus hal_status;
15382
15383 csr_scan->nl_scan = true;
15384 csr_scan->scan_randomize = false;
15385
15386 if (config->enableMacSpoofing != MAC_ADDR_SPOOFING_FW_HOST_ENABLE ||
15387 !sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN))
15388 return 0;
15389
15390 vos_flush_delayed_work(&hdd_ctx->spoof_mac_addr_work);
15391
15392 if (hdd_is_wiphy_scan_random_support(wiphy)) {
15393 if (!hdd_is_nl_scan_random(nl_scan) || is_p2p_scan)
15394 return 0;
15395
15396 hdd_generate_scan_random_mac(nl_scan->mac_addr,
15397 nl_scan->mac_addr_mask,
15398 random_mac);
15399
15400 hddLog(VOS_TRACE_LEVEL_INFO,
15401 FL("cfg80211 scan random attributes:"));
15402 hddLog(VOS_TRACE_LEVEL_INFO, "mac-addr: "MAC_ADDRESS_STR
15403 " mac-mask: "MAC_ADDRESS_STR
15404 " random-mac: "MAC_ADDRESS_STR,
15405 MAC_ADDR_ARRAY(nl_scan->mac_addr),
15406 MAC_ADDR_ARRAY(nl_scan->mac_addr_mask),
15407 MAC_ADDR_ARRAY(random_mac));
15408
15409 hal_status = sme_SpoofMacAddrReq(hdd_ctx->hHal,
15410 (v_MACADDR_t *)random_mac,
15411 false);
15412 if (hal_status != eHAL_STATUS_SUCCESS) {
15413 hddLog(LOGE,
15414 FL("Send of Spoof request failed"));
15415 hddLog(LOGE,
15416 FL("Disable spoofing and use self-mac"));
15417 return 0;
15418 }
15419
15420 vos_status = WLANTL_updateSpoofMacAddr(hdd_ctx->pvosContext,
15421 (v_MACADDR_t*)random_mac,
15422 &adapter->macAddressCurrent);
15423 if(vos_status != VOS_STATUS_SUCCESS) {
15424 hddLog(VOS_TRACE_LEVEL_ERROR,
15425 FL("Failed to update spoof mac in TL"));
15426 return -EINVAL;
15427 }
15428
15429 csr_scan->scan_randomize = true;
15430
15431 return 0;
15432 }
15433
15434 /*
15435 * If wiphy does not support cfg80211 scan randomization then scan
15436 * will be randomized using the vendor MAC OUI.
15437 */
15438 if (!hdd_ctx->spoofMacAddr.isEnabled)
15439 return 0;
15440
15441 hddLog(VOS_TRACE_LEVEL_INFO,
15442 FL("MAC Spoofing enabled for current scan and spoof addr is:"
15443 MAC_ADDRESS_STR),
15444 MAC_ADDR_ARRAY(hdd_ctx->spoofMacAddr.randomMacAddr.bytes));
15445
15446 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15447 * to fill TxBds for probe request during current scan
15448 */
15449 vos_status = WLANTL_updateSpoofMacAddr(hdd_ctx->pvosContext,
15450 &hdd_ctx->spoofMacAddr.randomMacAddr, &adapter->macAddressCurrent);
15451 if(vos_status != VOS_STATUS_SUCCESS) {
15452 hddLog(VOS_TRACE_LEVEL_ERROR,
15453 FL("Failed to update spoof mac in TL"));
15454 return -EINVAL;
15455 }
15456
15457 csr_scan->scan_randomize = true;
15458
15459 return 0;
15460}
15461
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015462/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015463 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015464 * this scan respond to scan trigger and update cfg80211 scan database
15465 * later, scan dump command can be used to recieve scan results
15466 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015467int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015468#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15469 struct net_device *dev,
15470#endif
15471 struct cfg80211_scan_request *request)
15472{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015473 hdd_adapter_t *pAdapter = NULL;
15474 hdd_context_t *pHddCtx = NULL;
15475 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015476 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015477 tCsrScanRequest scanRequest;
15478 tANI_U8 *channelList = NULL, i;
15479 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015480 int status;
15481 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015482 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015483 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015484 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015485 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015486 v_U8_t curr_session_id;
15487 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015488
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015489#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15490 struct net_device *dev = NULL;
15491 if (NULL == request)
15492 {
15493 hddLog(VOS_TRACE_LEVEL_ERROR,
15494 "%s: scan req param null", __func__);
15495 return -EINVAL;
15496 }
15497 dev = request->wdev->netdev;
15498#endif
15499
15500 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15501 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15502 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15503
Jeff Johnson295189b2012-06-20 16:38:30 -070015504 ENTER();
15505
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015506 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15507 __func__, hdd_device_modetoString(pAdapter->device_mode),
15508 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015509
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015510 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015511 if (0 != status)
15512 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015513 return status;
15514 }
15515
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015516 if (NULL == pwextBuf)
15517 {
15518 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15519 __func__);
15520 return -EIO;
15521 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015522 cfg_param = pHddCtx->cfg_ini;
15523 pScanInfo = &pHddCtx->scan_info;
15524
Jeff Johnson295189b2012-06-20 16:38:30 -070015525#ifdef WLAN_BTAMP_FEATURE
15526 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015527 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015528 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015529 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015530 "%s: No scanning when AMP is on", __func__);
15531 return -EOPNOTSUPP;
15532 }
15533#endif
15534 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015535 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015536 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015537 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015538 "%s: Not scanning on device_mode = %s (%d)",
15539 __func__, hdd_device_modetoString(pAdapter->device_mode),
15540 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015541 return -EOPNOTSUPP;
15542 }
15543
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015544 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15545 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15546 return -EOPNOTSUPP;
15547 }
15548
Jeff Johnson295189b2012-06-20 16:38:30 -070015549 if (TRUE == pScanInfo->mScanPending)
15550 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015551 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15552 {
15553 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15554 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015555 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015556 }
15557
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015558 // Don't allow scan if PNO scan is going on.
15559 if (pHddCtx->isPnoEnable)
15560 {
15561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15562 FL("pno scan in progress"));
15563 return -EBUSY;
15564 }
15565
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015566 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015567 //Channel and action frame is pending
15568 //Otherwise Cancel Remain On Channel and allow Scan
15569 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015570 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015571 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015573 return -EBUSY;
15574 }
15575
Jeff Johnson295189b2012-06-20 16:38:30 -070015576 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15577 {
15578 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015579 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015580 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015581 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015582 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15583 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015584 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015585 "%s: MAX TM Level Scan not allowed", __func__);
15586 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015587 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015588 }
15589 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15590
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015591 /* Check if scan is allowed at this point of time.
15592 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015593 if (TRUE == pHddCtx->btCoexModeSet)
15594 {
15595 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15596 FL("BTCoex Mode operation in progress"));
15597 return -EBUSY;
15598 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015599 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015600 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015601
15602 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15603 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15604 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015605 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15606 pHddCtx->last_scan_reject_reason != curr_reason ||
15607 !pHddCtx->last_scan_reject_timestamp)
15608 {
15609 pHddCtx->last_scan_reject_session_id = curr_session_id;
15610 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015611 pHddCtx->last_scan_reject_timestamp =
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015612 jiffies + msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
Abhishek Singhe4b12562017-06-20 16:53:39 +053015613 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015614 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015615 else
15616 {
15617 pHddCtx->scan_reject_cnt++;
15618
Abhishek Singhe4b12562017-06-20 16:53:39 +053015619 if ((pHddCtx->scan_reject_cnt >=
15620 SCAN_REJECT_THRESHOLD) &&
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015621 vos_system_time_after(jiffies,
Abhishek Singh3e500772017-07-17 10:13:43 +053015622 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015623 {
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015624 hddLog(LOGE, FL("Session %d reason %d reject cnt %d reject timestamp %lu jiffies %lu"),
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015625 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015626 pHddCtx->last_scan_reject_timestamp, jiffies);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015627 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015628 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015629 if (pHddCtx->cfg_ini->enableFatalEvent)
15630 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15631 WLAN_LOG_INDICATOR_HOST_DRIVER,
15632 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15633 FALSE, FALSE);
15634 else
15635 {
15636 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015637 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015638 }
15639 }
15640 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015641 return -EBUSY;
15642 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015643 pHddCtx->last_scan_reject_timestamp = 0;
15644 pHddCtx->last_scan_reject_session_id = 0xFF;
15645 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015646 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015647
Jeff Johnson295189b2012-06-20 16:38:30 -070015648 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15649
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015650 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15651 * Becasue of this, driver is assuming that this is not wildcard scan and so
15652 * is not aging out the scan results.
15653 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015654 if ((request->ssids) && (request->n_ssids == 1) &&
15655 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015656 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015657 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015658
15659 if ((request->ssids) && (0 < request->n_ssids))
15660 {
15661 tCsrSSIDInfo *SsidInfo;
15662 int j;
15663 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15664 /* Allocate num_ssid tCsrSSIDInfo structure */
15665 SsidInfo = scanRequest.SSIDs.SSIDList =
15666 ( tCsrSSIDInfo *)vos_mem_malloc(
15667 request->n_ssids*sizeof(tCsrSSIDInfo));
15668
15669 if(NULL == scanRequest.SSIDs.SSIDList)
15670 {
15671 hddLog(VOS_TRACE_LEVEL_ERROR,
15672 "%s: memory alloc failed SSIDInfo buffer", __func__);
15673 return -ENOMEM;
15674 }
15675
15676 /* copy all the ssid's and their length */
15677 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15678 {
15679 /* get the ssid length */
15680 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15681 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15682 SsidInfo->SSID.length);
15683 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15684 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15685 j, SsidInfo->SSID.ssId);
15686 }
15687 /* set the scan type to active */
15688 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15689 }
15690 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015691 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015692 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15693 TRACE_CODE_HDD_CFG80211_SCAN,
15694 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015695 /* set the scan type to active */
15696 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015697 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015698 else
15699 {
15700 /*Set the scan type to default type, in this case it is ACTIVE*/
15701 scanRequest.scanType = pScanInfo->scan_mode;
15702 }
15703 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15704 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015705
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015706 csr_scan_request_assign_bssid(&scanRequest, request);
15707
Jeff Johnson295189b2012-06-20 16:38:30 -070015708 /* set BSSType to default type */
15709 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15710
15711 /*TODO: scan the requested channels only*/
15712
15713 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015714 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015715 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015716 hddLog(VOS_TRACE_LEVEL_WARN,
15717 "No of Scan Channels exceeded limit: %d", request->n_channels);
15718 request->n_channels = MAX_CHANNEL;
15719 }
15720
15721 hddLog(VOS_TRACE_LEVEL_INFO,
15722 "No of Scan Channels: %d", request->n_channels);
15723
15724
15725 if( request->n_channels )
15726 {
15727 char chList [(request->n_channels*5)+1];
15728 int len;
15729 channelList = vos_mem_malloc( request->n_channels );
15730 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015731 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015732 hddLog(VOS_TRACE_LEVEL_ERROR,
15733 "%s: memory alloc failed channelList", __func__);
15734 status = -ENOMEM;
15735 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015736 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015737
15738 for( i = 0, len = 0; i < request->n_channels ; i++ )
15739 {
15740 channelList[i] = request->channels[i]->hw_value;
15741 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15742 }
15743
Nirav Shah20ac06f2013-12-12 18:14:06 +053015744 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015745 "Channel-List: %s ", chList);
15746 }
c_hpothu53512302014-04-15 18:49:53 +053015747
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015748 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15749 scanRequest.ChannelInfo.ChannelList = channelList;
15750
15751 /* set requestType to full scan */
15752 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15753
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015754 /* if there is back to back scan happening in driver with in
15755 * nDeferScanTimeInterval interval driver should defer new scan request
15756 * and should provide last cached scan results instead of new channel list.
15757 * This rule is not applicable if scan is p2p scan.
15758 * This condition will work only in case when last request no of channels
15759 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015760 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015761 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015762 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015763
Sushant Kaushik86592172015-04-27 16:35:03 +053015764 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15765 /* if wps ie is NULL , then only defer scan */
15766 if ( pWpsIe == NULL &&
15767 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015768 {
15769 if ( pScanInfo->last_scan_timestamp !=0 &&
15770 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15771 {
15772 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15773 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15774 vos_mem_compare(pScanInfo->last_scan_channelList,
15775 channelList, pScanInfo->last_scan_numChannels))
15776 {
15777 hddLog(VOS_TRACE_LEVEL_WARN,
15778 " New and old station scan time differ is less then %u",
15779 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15780
15781 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015782 pAdapter);
15783
Agarwal Ashish57e84372014-12-05 18:26:53 +053015784 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015785 "Return old cached scan as all channels and no of channels are same");
15786
Agarwal Ashish57e84372014-12-05 18:26:53 +053015787 if (0 > ret)
15788 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015789
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015790 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015791
15792 status = eHAL_STATUS_SUCCESS;
15793 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015794 }
15795 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015796 }
15797
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015798 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15799 * search (Flush on both full scan and social scan but not on single
15800 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15801 */
15802
15803 /* Supplicant does single channel scan after 8-way handshake
15804 * and in that case driver shoudnt flush scan results. If
15805 * driver flushes the scan results here and unfortunately if
15806 * the AP doesnt respond to our probe req then association
15807 * fails which is not desired
15808 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015809 if ((request->n_ssids == 1)
15810 && (request->ssids != NULL)
15811 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15812 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015813
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015814 if( is_p2p_scan ||
15815 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015816 {
15817 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15818 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15819 pAdapter->sessionId );
15820 }
15821
15822 if( request->ie_len )
15823 {
15824 /* save this for future association (join requires this) */
15825 /*TODO: Array needs to be converted to dynamic allocation,
15826 * as multiple ie.s can be sent in cfg80211_scan_request structure
15827 * CR 597966
15828 */
15829 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15830 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15831 pScanInfo->scanAddIE.length = request->ie_len;
15832
15833 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15834 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15835 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015836 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015837 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015838 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015839 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15840 memcpy( pwextBuf->roamProfile.addIEScan,
15841 request->ie, request->ie_len);
15842 }
15843 else
15844 {
15845 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15846 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015847 }
15848
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015849 }
15850 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15851 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15852
15853 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15854 request->ie_len);
15855 if (pP2pIe != NULL)
15856 {
15857#ifdef WLAN_FEATURE_P2P_DEBUG
15858 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15859 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15860 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015861 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015862 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15863 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15864 "Go nego completed to Connection is started");
15865 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15866 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015867 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015868 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15869 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015870 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015871 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15872 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15873 "Disconnected state to Connection is started");
15874 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15875 "for 4way Handshake");
15876 }
15877#endif
15878
15879 /* no_cck will be set during p2p find to disable 11b rates */
15880 if(TRUE == request->no_cck)
15881 {
15882 hddLog(VOS_TRACE_LEVEL_INFO,
15883 "%s: This is a P2P Search", __func__);
15884 scanRequest.p2pSearch = 1;
15885
15886 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015887 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015888 /* set requestType to P2P Discovery */
15889 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15890 }
15891
15892 /*
15893 Skip Dfs Channel in case of P2P Search
15894 if it is set in ini file
15895 */
15896 if(cfg_param->skipDfsChnlInP2pSearch)
15897 {
15898 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015899 }
15900 else
15901 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015902 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015903 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015904
Agarwal Ashish4f616132013-12-30 23:32:50 +053015905 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015906 }
15907 }
15908
15909 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15910
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015911#ifdef FEATURE_WLAN_TDLS
15912 /* if tdls disagree scan right now, return immediately.
15913 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15914 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15915 */
15916 status = wlan_hdd_tdls_scan_callback (pAdapter,
15917 wiphy,
15918#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15919 dev,
15920#endif
15921 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015922 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015923 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015924 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15926 "scan rejected %d", __func__, status);
15927 else
15928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15929 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015930 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015931 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015932 }
15933#endif
15934
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015935 /* acquire the wakelock to avoid the apps suspend during the scan. To
15936 * address the following issues.
15937 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15938 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15939 * for long time, this result in apps running at full power for long time.
15940 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15941 * be stuck in full power because of resume BMPS
15942 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015943 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015944
Nirav Shah20ac06f2013-12-12 18:14:06 +053015945 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15946 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015947 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15948 scanRequest.requestType, scanRequest.scanType,
15949 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015950 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15951
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015952 ret = hdd_spoof_scan(wiphy, pAdapter, request, is_p2p_scan, &scanRequest);
15953 if(ret) {
15954 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
15955 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015956#ifdef FEATURE_WLAN_TDLS
15957 wlan_hdd_tdls_scan_done_callback(pAdapter);
15958#endif
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015959 goto free_mem;
Siddharth Bhal76972212014-10-15 16:22:51 +053015960 }
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015961
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015962 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015963 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015964 pAdapter->sessionId, &scanRequest, &scanId,
15965 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015966
Jeff Johnson295189b2012-06-20 16:38:30 -070015967 if (eHAL_STATUS_SUCCESS != status)
15968 {
15969 hddLog(VOS_TRACE_LEVEL_ERROR,
15970 "%s: sme_ScanRequest returned error %d", __func__, status);
15971 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015972 if(eHAL_STATUS_RESOURCES == status)
15973 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015974 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15975 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015976 status = -EBUSY;
15977 } else {
15978 status = -EIO;
15979 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015980 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015981
15982#ifdef FEATURE_WLAN_TDLS
15983 wlan_hdd_tdls_scan_done_callback(pAdapter);
15984#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015985 goto free_mem;
15986 }
15987
15988 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015989 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015990 pAdapter->request = request;
15991 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015992 pScanInfo->no_cck = request->no_cck;
15993 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15994 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15995 pHddCtx->scan_info.last_scan_channelList[i] =
15996 request->channels[i]->hw_value;
15997 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015998
15999 complete(&pScanInfo->scan_req_completion_event);
16000
16001free_mem:
16002 if( scanRequest.SSIDs.SSIDList )
16003 {
16004 vos_mem_free(scanRequest.SSIDs.SSIDList);
16005 }
16006
16007 if( channelList )
16008 vos_mem_free( channelList );
16009
16010 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016011 return status;
16012}
16013
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016014int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
16015#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
16016 struct net_device *dev,
16017#endif
16018 struct cfg80211_scan_request *request)
16019{
16020 int ret;
16021
16022 vos_ssr_protect(__func__);
16023 ret = __wlan_hdd_cfg80211_scan(wiphy,
16024#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
16025 dev,
16026#endif
16027 request);
16028 vos_ssr_unprotect(__func__);
16029
16030 return ret;
16031}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016032
16033void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
16034{
16035 v_U8_t iniDot11Mode =
16036 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
16037 eHddDot11Mode hddDot11Mode = iniDot11Mode;
16038
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016039 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
16040 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016041 switch ( iniDot11Mode )
16042 {
16043 case eHDD_DOT11_MODE_AUTO:
16044 case eHDD_DOT11_MODE_11ac:
16045 case eHDD_DOT11_MODE_11ac_ONLY:
16046#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053016047 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
16048 sme_IsFeatureSupportedByFW(DOT11AC) )
16049 hddDot11Mode = eHDD_DOT11_MODE_11ac;
16050 else
16051 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016052#else
16053 hddDot11Mode = eHDD_DOT11_MODE_11n;
16054#endif
16055 break;
16056 case eHDD_DOT11_MODE_11n:
16057 case eHDD_DOT11_MODE_11n_ONLY:
16058 hddDot11Mode = eHDD_DOT11_MODE_11n;
16059 break;
16060 default:
16061 hddDot11Mode = iniDot11Mode;
16062 break;
16063 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053016064#ifdef WLAN_FEATURE_AP_HT40_24G
16065 if (operationChannel > SIR_11B_CHANNEL_END)
16066#endif
16067 {
16068 /* This call decides required channel bonding mode */
16069 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016070 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053016071 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053016072 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016073}
16074
Jeff Johnson295189b2012-06-20 16:38:30 -070016075/*
16076 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016077 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016078 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016079int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053016080 const u8 *ssid, size_t ssid_len, const u8 *bssid,
16081 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070016082{
16083 int status = 0;
16084 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080016085 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016086 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016087 v_U32_t roamId;
16088 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070016089 eCsrAuthType RSNAuthType;
16090
16091 ENTER();
16092
16093 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080016094 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016095 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080016096
16097 status = wlan_hdd_validate_context(pHddCtx);
16098 if (status)
16099 {
Yue Mae36e3552014-03-05 17:06:20 -080016100 return status;
16101 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016102
Jeff Johnson295189b2012-06-20 16:38:30 -070016103 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
16104 {
16105 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
16106 return -EINVAL;
16107 }
16108
Nitesh Shah9b066282017-06-06 18:05:52 +053016109
Jeff Johnson295189b2012-06-20 16:38:30 -070016110 pRoamProfile = &pWextState->roamProfile;
16111
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016112 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070016113 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016114 hdd_station_ctx_t *pHddStaCtx;
16115 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053016116 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016117
Siddharth Bhalda0d1622015-04-24 15:47:49 +053016118 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
16119
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016120 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070016121 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
16122 {
16123 /*QoS not enabled in cfg file*/
16124 pRoamProfile->uapsd_mask = 0;
16125 }
16126 else
16127 {
16128 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016129 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070016130 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
16131 }
16132
16133 pRoamProfile->SSIDs.numOfSSIDs = 1;
16134 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
16135 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016136 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070016137 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
16138 ssid, ssid_len);
16139
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016140 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
16141 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
16142
Jeff Johnson295189b2012-06-20 16:38:30 -070016143 if (bssid)
16144 {
16145 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016146 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070016147 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016148 /* Save BSSID in seperate variable as well, as RoamProfile
16149 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070016150 case of join failure we should send valid BSSID to supplicant
16151 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016152 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070016153 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016154
Jeff Johnson295189b2012-06-20 16:38:30 -070016155 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016156 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070016157 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016158 /* Store bssid_hint to use in the scan filter. */
16159 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
16160 WNI_CFG_BSSID_LEN);
16161 /*
16162 * Save BSSID in seperate variable as well, as RoamProfile
16163 * BSSID is getting zeroed out in the association process. And in
16164 * case of join failure we should send valid BSSID to supplicant
16165 */
16166 vos_mem_copy(pWextState->req_bssId, bssid_hint,
16167 WNI_CFG_BSSID_LEN);
16168 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
16169 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070016170 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016171
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016172
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016173 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
16174 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016175 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
16176 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016177 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016178 /*set gen ie*/
16179 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
16180 /*set auth*/
16181 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
16182 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016183#ifdef FEATURE_WLAN_WAPI
16184 if (pAdapter->wapi_info.nWapiMode)
16185 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016186 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016187 switch (pAdapter->wapi_info.wapiAuthMode)
16188 {
16189 case WAPI_AUTH_MODE_PSK:
16190 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016191 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016192 pAdapter->wapi_info.wapiAuthMode);
16193 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
16194 break;
16195 }
16196 case WAPI_AUTH_MODE_CERT:
16197 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016198 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016199 pAdapter->wapi_info.wapiAuthMode);
16200 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
16201 break;
16202 }
16203 } // End of switch
16204 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
16205 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
16206 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016207 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016208 pRoamProfile->AuthType.numEntries = 1;
16209 pRoamProfile->EncryptionType.numEntries = 1;
16210 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
16211 pRoamProfile->mcEncryptionType.numEntries = 1;
16212 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
16213 }
16214 }
16215#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016216#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016217 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016218 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
16219 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
16220 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016221 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
16222 sizeof (tSirGtkOffloadParams));
16223 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016224 }
16225#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016226 pRoamProfile->csrPersona = pAdapter->device_mode;
16227
Jeff Johnson32d95a32012-09-10 13:15:23 -070016228 if( operatingChannel )
16229 {
16230 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
16231 pRoamProfile->ChannelInfo.numOfChannels = 1;
16232 }
Chet Lanctot186b5732013-03-18 10:26:30 -070016233 else
16234 {
16235 pRoamProfile->ChannelInfo.ChannelList = NULL;
16236 pRoamProfile->ChannelInfo.numOfChannels = 0;
16237 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016238 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
16239 {
16240 hdd_select_cbmode(pAdapter,operatingChannel);
16241 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016242
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016243 /*
16244 * Change conn_state to connecting before sme_RoamConnect(),
16245 * because sme_RoamConnect() has a direct path to call
16246 * hdd_smeRoamCallback(), which will change the conn_state
16247 * If direct path, conn_state will be accordingly changed
16248 * to NotConnected or Associated by either
16249 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
16250 * in sme_RoamCallback()
16251 * if sme_RomConnect is to be queued,
16252 * Connecting state will remain until it is completed.
16253 * If connection state is not changed,
16254 * connection state will remain in eConnectionState_NotConnected state.
16255 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
16256 * if conn state is eConnectionState_NotConnected.
16257 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
16258 * informed of connect result indication which is an issue.
16259 */
16260
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016261 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16262 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053016263 {
16264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016265 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016266 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
16267 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016268 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
16269 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053016270 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016271
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016272 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070016273 pAdapter->sessionId, pRoamProfile, &roamId);
16274
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016275 if ((eHAL_STATUS_SUCCESS != status) &&
16276 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16277 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016278
16279 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016280 hddLog(VOS_TRACE_LEVEL_ERROR,
16281 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
16282 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016283 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016284 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016285 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016286 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016287
16288 pRoamProfile->ChannelInfo.ChannelList = NULL;
16289 pRoamProfile->ChannelInfo.numOfChannels = 0;
16290
Jeff Johnson295189b2012-06-20 16:38:30 -070016291 }
16292 else
16293 {
16294 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16295 return -EINVAL;
16296 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016297 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016298 return status;
16299}
16300
16301/*
16302 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16303 * This function is used to set the authentication type (OPEN/SHARED).
16304 *
16305 */
16306static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16307 enum nl80211_auth_type auth_type)
16308{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016309 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016310 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16311
16312 ENTER();
16313
16314 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016315 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016316 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016317 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016318 hddLog(VOS_TRACE_LEVEL_INFO,
16319 "%s: set authentication type to AUTOSWITCH", __func__);
16320 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16321 break;
16322
16323 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016324#ifdef WLAN_FEATURE_VOWIFI_11R
16325 case NL80211_AUTHTYPE_FT:
16326#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016327 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016328 "%s: set authentication type to OPEN", __func__);
16329 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16330 break;
16331
16332 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016333 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016334 "%s: set authentication type to SHARED", __func__);
16335 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16336 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016337#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016338 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016339 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016340 "%s: set authentication type to CCKM WPA", __func__);
16341 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16342 break;
16343#endif
Abhinav Kumar4d44f632019-08-02 13:55:54 +053016344 case NL80211_AUTHTYPE_SAE:
16345 hddLog(LOG1, "set authentication type to SAE");
16346 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SAE;
16347 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016348
16349 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016350 hddLog(VOS_TRACE_LEVEL_ERROR,
16351 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016352 auth_type);
16353 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16354 return -EINVAL;
16355 }
16356
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016357 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016358 pHddStaCtx->conn_info.authType;
16359 return 0;
16360}
16361
16362/*
16363 * FUNCTION: wlan_hdd_set_akm_suite
16364 * This function is used to set the key mgmt type(PSK/8021x).
16365 *
16366 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016367static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016368 u32 key_mgmt
16369 )
16370{
16371 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16372 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016373 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016374#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016375#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016376#endif
16377#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016378#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016379#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016380 /*set key mgmt type*/
16381 switch(key_mgmt)
16382 {
16383 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016384 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016385#ifdef WLAN_FEATURE_VOWIFI_11R
16386 case WLAN_AKM_SUITE_FT_PSK:
16387#endif
16388 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016389 __func__);
16390 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16391 break;
16392
16393 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016394 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016395#ifdef WLAN_FEATURE_VOWIFI_11R
16396 case WLAN_AKM_SUITE_FT_8021X:
16397#endif
16398 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016399 __func__);
16400 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16401 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016402#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016403#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16404#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16405 case WLAN_AKM_SUITE_CCKM:
16406 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16407 __func__);
16408 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16409 break;
16410#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016411#ifndef WLAN_AKM_SUITE_OSEN
16412#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16413 case WLAN_AKM_SUITE_OSEN:
16414 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16415 __func__);
16416 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16417 break;
16418#endif
Abhinav Kumar4d44f632019-08-02 13:55:54 +053016419 case WLAN_AKM_SUITE_SAE:
16420 hddLog(LOG1, "setting key mgmt type to SAE");
16421 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16422 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016423
Abhinav Kumar487e49e2019-07-22 14:46:18 +053016424 case WLAN_AKM_SUITE_OWE_1:
16425 hddLog(LOG1, "setting key mgmt type to OWE");
16426 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16427 break;
16428
Jeff Johnson295189b2012-06-20 16:38:30 -070016429 default:
Abhinav Kumar487e49e2019-07-22 14:46:18 +053016430 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016431 __func__, key_mgmt);
16432 return -EINVAL;
16433
16434 }
16435 return 0;
16436}
16437
16438/*
16439 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016440 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016441 * (NONE/WEP40/WEP104/TKIP/CCMP).
16442 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016443static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16444 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016445 bool ucast
16446 )
16447{
16448 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016449 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016450 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16451
16452 ENTER();
16453
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016454 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016455 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016456 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016457 __func__, cipher);
16458 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16459 }
16460 else
16461 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016462
Jeff Johnson295189b2012-06-20 16:38:30 -070016463 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016464 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016465 {
16466 case IW_AUTH_CIPHER_NONE:
16467 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16468 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016469
Jeff Johnson295189b2012-06-20 16:38:30 -070016470 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016471 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016472 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016473
Jeff Johnson295189b2012-06-20 16:38:30 -070016474 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016475 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016476 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016477
Jeff Johnson295189b2012-06-20 16:38:30 -070016478 case WLAN_CIPHER_SUITE_TKIP:
16479 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16480 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016481
Jeff Johnson295189b2012-06-20 16:38:30 -070016482 case WLAN_CIPHER_SUITE_CCMP:
16483 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16484 break;
16485#ifdef FEATURE_WLAN_WAPI
16486 case WLAN_CIPHER_SUITE_SMS4:
16487 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16488 break;
16489#endif
16490
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016491#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016492 case WLAN_CIPHER_SUITE_KRK:
16493 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16494 break;
16495#endif
16496 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016497 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016498 __func__, cipher);
16499 return -EOPNOTSUPP;
16500 }
16501 }
16502
16503 if (ucast)
16504 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016505 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016506 __func__, encryptionType);
16507 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16508 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016509 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016510 encryptionType;
16511 }
16512 else
16513 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016514 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016515 __func__, encryptionType);
16516 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16517 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16518 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16519 }
16520
16521 return 0;
16522}
16523
16524
16525/*
16526 * FUNCTION: wlan_hdd_cfg80211_set_ie
16527 * This function is used to parse WPA/RSN IE's.
16528 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016529int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016530#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16531 const u8 *ie,
16532#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016533 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016534#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016535 size_t ie_len
16536 )
16537{
16538 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16540 const u8 *genie = ie;
16541#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016542 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016543#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016544 v_U16_t remLen = ie_len;
16545#ifdef FEATURE_WLAN_WAPI
16546 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16547 u16 *tmp;
16548 v_U16_t akmsuiteCount;
16549 int *akmlist;
16550#endif
16551 ENTER();
16552
16553 /* clear previous assocAddIE */
16554 pWextState->assocAddIE.length = 0;
16555 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016556 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016557
16558 while (remLen >= 2)
16559 {
16560 v_U16_t eLen = 0;
16561 v_U8_t elementId;
16562 elementId = *genie++;
16563 eLen = *genie++;
16564 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016565
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016566 /* Sanity check on eLen */
16567 if (eLen > remLen) {
16568 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16569 __func__, eLen, elementId);
16570 VOS_ASSERT(0);
16571 return -EINVAL;
16572 }
16573
Arif Hussain6d2a3322013-11-17 19:50:10 -080016574 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016575 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016576
16577 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016578 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016579 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016580 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 -070016581 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016582 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016583 "%s: Invalid WPA IE", __func__);
16584 return -EINVAL;
16585 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016586 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016587 {
16588 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016589 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016590 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016591
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016592 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016593 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016594 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16595 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016596 VOS_ASSERT(0);
16597 return -ENOMEM;
16598 }
16599 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16600 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16601 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016602
Jeff Johnson295189b2012-06-20 16:38:30 -070016603 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16604 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16605 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16606 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016607 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16608 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016609 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16610 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16611 __func__, eLen);
16612 VOS_ASSERT(0);
16613 return -EINVAL;
16614 }
16615
Jeff Johnson295189b2012-06-20 16:38:30 -070016616 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16617 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16618 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16619 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16620 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16621 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016622 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016623 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016624 {
16625 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016626 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016627 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016628
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016629 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016630 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016631 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16632 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016633 VOS_ASSERT(0);
16634 return -ENOMEM;
16635 }
16636 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16637 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16638 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016639
Jeff Johnson295189b2012-06-20 16:38:30 -070016640 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16641 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16642 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016643#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016644 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16645 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016646 /*Consider WFD IE, only for P2P Client */
16647 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16648 {
16649 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016650 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016651 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016652
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016653 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016654 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016655 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16656 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016657 VOS_ASSERT(0);
16658 return -ENOMEM;
16659 }
16660 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16661 // WPS IE + P2P IE + WFD IE
16662 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16663 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016664
Jeff Johnson295189b2012-06-20 16:38:30 -070016665 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16666 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16667 }
16668#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016669 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016670 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016671 HS20_OUI_TYPE_SIZE)) )
16672 {
16673 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016674 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016675 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016676
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016677 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016678 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016679 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16680 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016681 VOS_ASSERT(0);
16682 return -ENOMEM;
16683 }
16684 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16685 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016686
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016687 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16688 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16689 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016690 /* Appending OSEN Information Element in Assiciation Request */
16691 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16692 OSEN_OUI_TYPE_SIZE)) )
16693 {
16694 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16695 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16696 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016697
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016698 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016699 {
16700 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16701 "Need bigger buffer space");
16702 VOS_ASSERT(0);
16703 return -ENOMEM;
16704 }
16705 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16706 pWextState->assocAddIE.length += eLen + 2;
16707
16708 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16709 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16710 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16711 }
16712
Abhishek Singh4322e622015-06-10 15:42:54 +053016713 /* Update only for WPA IE */
16714 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16715 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016716
16717 /* populating as ADDIE in beacon frames */
16718 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016719 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016720 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16721 {
16722 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16723 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16724 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16725 {
16726 hddLog(LOGE,
16727 "Coldn't pass "
16728 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16729 }
16730 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16731 else
16732 hddLog(LOGE,
16733 "Could not pass on "
16734 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16735
16736 /* IBSS mode doesn't contain params->proberesp_ies still
16737 beaconIE's need to be populated in probe response frames */
16738 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16739 {
16740 u16 rem_probe_resp_ie_len = eLen + 2;
16741 u8 probe_rsp_ie_len[3] = {0};
16742 u8 counter = 0;
16743
16744 /* Check Probe Resp Length if it is greater then 255 then
16745 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16746 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16747 not able Store More then 255 bytes into One Variable */
16748
16749 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16750 {
16751 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16752 {
16753 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16754 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16755 }
16756 else
16757 {
16758 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16759 rem_probe_resp_ie_len = 0;
16760 }
16761 }
16762
16763 rem_probe_resp_ie_len = 0;
16764
16765 if (probe_rsp_ie_len[0] > 0)
16766 {
16767 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16768 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16769 (tANI_U8*)(genie - 2),
16770 probe_rsp_ie_len[0], NULL,
16771 eANI_BOOLEAN_FALSE)
16772 == eHAL_STATUS_FAILURE)
16773 {
16774 hddLog(LOGE,
16775 "Could not pass"
16776 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16777 }
16778 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16779 }
16780
16781 if (probe_rsp_ie_len[1] > 0)
16782 {
16783 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16784 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16785 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16786 probe_rsp_ie_len[1], NULL,
16787 eANI_BOOLEAN_FALSE)
16788 == eHAL_STATUS_FAILURE)
16789 {
16790 hddLog(LOGE,
16791 "Could not pass"
16792 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16793 }
16794 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16795 }
16796
16797 if (probe_rsp_ie_len[2] > 0)
16798 {
16799 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16800 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16801 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16802 probe_rsp_ie_len[2], NULL,
16803 eANI_BOOLEAN_FALSE)
16804 == eHAL_STATUS_FAILURE)
16805 {
16806 hddLog(LOGE,
16807 "Could not pass"
16808 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16809 }
16810 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16811 }
16812
16813 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16814 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16815 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16816 {
16817 hddLog(LOGE,
16818 "Could not pass"
16819 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16820 }
16821 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016822 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016823 break;
16824 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016825 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16826 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16827 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16828 VOS_ASSERT(0);
16829 return -EINVAL;
16830 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016831 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16832 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16833 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16834 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16835 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16836 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016837
Abhishek Singhb16f3562016-01-20 11:08:32 +053016838 /* Appending extended capabilities with Interworking or
16839 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016840 *
16841 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016842 * interworkingService or bsstransition bit is set to 1.
16843 * Driver is only interested in interworkingService and
16844 * bsstransition capability from supplicant.
16845 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016846 * required from supplicat, it needs to be handled while
16847 * sending Assoc Req in LIM.
16848 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016849 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016850 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016851 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016852 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016853 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016854
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016855 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016856 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016857 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16858 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016859 VOS_ASSERT(0);
16860 return -ENOMEM;
16861 }
16862 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16863 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016864
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016865 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16866 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16867 break;
16868 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016869#ifdef FEATURE_WLAN_WAPI
16870 case WLAN_EID_WAPI:
16871 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016872 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016873 pAdapter->wapi_info.nWapiMode);
16874 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016875 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016876 akmsuiteCount = WPA_GET_LE16(tmp);
16877 tmp = tmp + 1;
16878 akmlist = (int *)(tmp);
16879 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16880 {
16881 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16882 }
16883 else
16884 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016885 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016886 VOS_ASSERT(0);
16887 return -EINVAL;
16888 }
16889
16890 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16891 {
16892 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016893 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016894 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016895 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016896 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016897 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016898 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016899 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016900 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16901 }
16902 break;
16903#endif
Abhinav Kumar487e49e2019-07-22 14:46:18 +053016904 case SIR_MAC_REQUEST_EID_MAX:
16905 if (genie[0] == SIR_DH_PARAMETER_ELEMENT_EXT_EID)
16906 {
16907 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16908 if (SIR_MAC_MAX_ADD_IE_LENGTH <
16909 (pWextState->assocAddIE.length + eLen))
16910 {
16911 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16912 "Need bigger buffer space");
16913 VOS_ASSERT(0);
16914 return -ENOMEM;
16915 }
16916 hddLog(VOS_TRACE_LEVEL_INFO, "Set DH EXT IE(len %d)",
16917 eLen + 2);
16918 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen,
16919 genie - 2, eLen + 2);
16920 pWextState->assocAddIE.length += eLen + 2;
16921 pWextState->roamProfile.pAddIEAssoc =
16922 pWextState->assocAddIE.addIEdata;
16923 pWextState->roamProfile.nAddIEAssocLength =
16924 pWextState->assocAddIE.length;
16925 }else {
16926 hddLog(VOS_TRACE_LEVEL_FATAL, "UNKNOWN EID: %X", genie[0]);
16927 }
16928 break;
16929
Jeff Johnson295189b2012-06-20 16:38:30 -070016930 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016931 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016932 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016933 /* when Unknown IE is received we should break and continue
16934 * to the next IE in the buffer instead we were returning
16935 * so changing this to break */
16936 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016937 }
16938 genie += eLen;
16939 remLen -= eLen;
16940 }
16941 EXIT();
16942 return 0;
16943}
16944
16945/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016946 * FUNCTION: hdd_isWPAIEPresent
16947 * Parse the received IE to find the WPA IE
16948 *
16949 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016950static bool hdd_isWPAIEPresent(
16951#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16952 const u8 *ie,
16953#else
16954 u8 *ie,
16955#endif
16956 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016957{
16958 v_U8_t eLen = 0;
16959 v_U16_t remLen = ie_len;
16960 v_U8_t elementId = 0;
16961
16962 while (remLen >= 2)
16963 {
16964 elementId = *ie++;
16965 eLen = *ie++;
16966 remLen -= 2;
16967 if (eLen > remLen)
16968 {
16969 hddLog(VOS_TRACE_LEVEL_ERROR,
16970 "%s: IE length is wrong %d", __func__, eLen);
16971 return FALSE;
16972 }
16973 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16974 {
16975 /* OUI - 0x00 0X50 0XF2
16976 WPA Information Element - 0x01
16977 WPA version - 0x01*/
16978 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16979 return TRUE;
16980 }
16981 ie += eLen;
16982 remLen -= eLen;
16983 }
16984 return FALSE;
16985}
16986
16987/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016988 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016989 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016990 * parameters during connect operation.
16991 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016992int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016993 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016994 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016995{
16996 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016997 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016998 ENTER();
16999
17000 /*set wpa version*/
17001 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
17002
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017003 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070017004 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053017005 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070017006 {
17007 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
17008 }
17009 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
17010 {
17011 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17012 }
17013 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017014
17015 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017016 pWextState->wpaVersion);
17017
17018 /*set authentication type*/
17019 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
17020
17021 if (0 > status)
17022 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017023 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017024 "%s: failed to set authentication type ", __func__);
17025 return status;
17026 }
17027
17028 /*set key mgmt type*/
17029 if (req->crypto.n_akm_suites)
17030 {
17031 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
17032 if (0 > status)
17033 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017034 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070017035 __func__);
17036 return status;
17037 }
17038 }
17039
17040 /*set pairwise cipher type*/
17041 if (req->crypto.n_ciphers_pairwise)
17042 {
17043 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
17044 req->crypto.ciphers_pairwise[0], true);
17045 if (0 > status)
17046 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017047 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017048 "%s: failed to set unicast cipher type", __func__);
17049 return status;
17050 }
17051 }
17052 else
17053 {
17054 /*Reset previous cipher suite to none*/
17055 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
17056 if (0 > status)
17057 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017058 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017059 "%s: failed to set unicast cipher type", __func__);
17060 return status;
17061 }
17062 }
17063
17064 /*set group cipher type*/
17065 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
17066 false);
17067
17068 if (0 > status)
17069 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017070 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070017071 __func__);
17072 return status;
17073 }
17074
Chet Lanctot186b5732013-03-18 10:26:30 -070017075#ifdef WLAN_FEATURE_11W
17076 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
17077#endif
17078
Jeff Johnson295189b2012-06-20 16:38:30 -070017079 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
17080 if (req->ie_len)
17081 {
17082 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
17083 if ( 0 > status)
17084 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017085 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017086 __func__);
17087 return status;
17088 }
17089 }
17090
17091 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017092 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070017093 {
17094 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
17095 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
17096 )
17097 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017098 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070017099 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
17100 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017102 __func__);
17103 return -EOPNOTSUPP;
17104 }
17105 else
17106 {
17107 u8 key_len = req->key_len;
17108 u8 key_idx = req->key_idx;
17109
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017110 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070017111 && (CSR_MAX_NUM_KEY > key_idx)
17112 )
17113 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017114 hddLog(VOS_TRACE_LEVEL_INFO,
17115 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017116 __func__, key_idx, key_len);
17117 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017118 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070017119 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017120 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070017121 (u8)key_len;
17122 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
17123 }
17124 }
17125 }
17126 }
17127
17128 return status;
17129}
17130
17131/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017132 * FUNCTION: wlan_hdd_try_disconnect
17133 * This function is used to disconnect from previous
17134 * connection
17135 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053017136int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017137{
17138 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017139 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017140 hdd_station_ctx_t *pHddStaCtx;
17141 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053017142 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017143
Abhishek Singh19a7dd92015-12-30 16:31:51 +053017144 ret = wlan_hdd_validate_context(pHddCtx);
17145 if (0 != ret)
17146 {
17147 return ret;
17148 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017149 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17150
17151 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
17152
17153 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
17154 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053017155 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017156 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
17157 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053017158 /* Indicate disconnect to SME so that in-progress connection or preauth
17159 * can be aborted
17160 */
17161 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
17162 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053017163 spin_lock_bh(&pAdapter->lock_for_active_session);
17164 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
17165 {
17166 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
17167 }
17168 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053017169 hdd_connSetConnectionState(pHddStaCtx,
17170 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017171 /* Issue disconnect to CSR */
17172 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017173 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017174 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017175 eCSR_DISCONNECT_REASON_UNSPECIFIED);
17176 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
17177 hddLog(LOG1,
17178 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
17179 } else if ( 0 != status ) {
17180 hddLog(LOGE,
17181 FL("csrRoamDisconnect failure, returned %d"),
17182 (int)status );
17183 result = -EINVAL;
17184 goto disconnected;
17185 }
17186 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017187 &pAdapter->disconnect_comp_var,
17188 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017189 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
17190 hddLog(LOGE,
17191 "%s: Failed to disconnect, timed out", __func__);
17192 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017193 }
17194 }
17195 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
17196 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017197 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017198 &pAdapter->disconnect_comp_var,
17199 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017200 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017201 {
17202 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017203 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017204 }
17205 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017206disconnected:
17207 hddLog(LOG1,
17208 FL("Set HDD connState to eConnectionState_NotConnected"));
17209 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
17210 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017211}
17212
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017213/**
17214 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
17215 * @adapter: Pointer to the HDD adapter
17216 * @req: Pointer to the structure cfg_connect_params receieved from user space
17217 *
Abhinav Kumar42c34902018-09-27 19:00:35 +053017218 * This function will start reassociation if prev_bssid is set and bssid/
17219 * bssid_hint, channel/channel_hint parameters are present in connect request.
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017220 *
17221 * Return: success if reassociation is happening
17222 * Error code if reassociation is not permitted or not happening
17223 */
17224#ifdef CFG80211_CONNECT_PREV_BSSID
17225static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
17226 struct cfg80211_connect_params *req)
17227{
17228 int status = -EPERM;
Abhinav Kumar42c34902018-09-27 19:00:35 +053017229 const uint8_t *bssid = NULL;
17230 uint16_t channel = 0;
17231
17232 if (req->bssid)
17233 bssid = req->bssid;
17234 else if (req->bssid_hint)
17235 bssid = req->bssid_hint;
17236
17237 if (req->channel)
17238 channel = req->channel->hw_value;
17239 else if (req->channel_hint)
17240 channel = req->channel_hint->hw_value;
17241
17242 if (bssid && channel && req->prev_bssid) {
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017243 hddLog(VOS_TRACE_LEVEL_INFO,
17244 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
Abhinav Kumar42c34902018-09-27 19:00:35 +053017245 channel, MAC_ADDR_ARRAY(bssid));
17246 status = hdd_reassoc(adapter, bssid, channel,
17247 CONNECT_CMD_USERSPACE);
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017248 }
17249 return status;
17250}
17251#else
17252static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
17253 struct cfg80211_connect_params *req)
17254{
17255 return -EPERM;
17256}
17257#endif
17258
Abhishek Singhe3beee22017-07-31 15:35:40 +053017259/**
17260 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
17261 * connect in HT20 mode
17262 * @hdd_ctx: hdd context
17263 * @adapter: Pointer to the HDD adapter
17264 * @req: Pointer to the structure cfg_connect_params receieved from user space
17265 *
17266 * This function will check if supplicant has indicated to to connect in HT20
17267 * mode. this is currently applicable only for 2.4Ghz mode only.
17268 * if feature is enabled and supplicant indicate HT20 set
17269 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
17270 *
17271 * Return: void
17272 */
17273#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
17274static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17275 hdd_adapter_t *adapter,
17276 struct cfg80211_connect_params *req)
17277{
17278 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17279 tCsrRoamProfile *roam_profile;
17280
17281 roam_profile = &wext_state->roamProfile;
17282 roam_profile->force_24ghz_in_ht20 = false;
17283 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
17284 !(req->ht_capa.cap_info &
17285 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
17286 roam_profile->force_24ghz_in_ht20 = true;
17287
17288 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
17289 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
17290}
17291#else
17292static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17293 hdd_adapter_t *adapter,
17294 struct cfg80211_connect_params *req)
17295{
17296 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17297 tCsrRoamProfile *roam_profile;
17298
17299 roam_profile = &wext_state->roamProfile;
17300 roam_profile->force_24ghz_in_ht20 = false;
17301}
17302#endif
17303
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017304/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053017305 * FUNCTION: __wlan_hdd_cfg80211_connect
17306 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070017307 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017308static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017309 struct net_device *ndev,
17310 struct cfg80211_connect_params *req
17311 )
17312{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017313 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017314 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053017315#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
17316 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017317 const u8 *bssid_hint = req->bssid_hint;
17318#else
17319 const u8 *bssid_hint = NULL;
17320#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017321 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017322 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053017323 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017324
17325 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017326
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017327 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17328 TRACE_CODE_HDD_CFG80211_CONNECT,
17329 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017330 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017331 "%s: device_mode = %s (%d)", __func__,
17332 hdd_device_modetoString(pAdapter->device_mode),
17333 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017334
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017335 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017336 if (!pHddCtx)
17337 {
17338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17339 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017340 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017341 }
17342
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017343 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017344 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017345 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017346 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017347 }
17348
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017349 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17350 return -EINVAL;
17351
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017352 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17353 if (0 == status)
17354 return status;
17355
Agarwal Ashish51325b52014-06-16 16:50:49 +053017356
Jeff Johnson295189b2012-06-20 16:38:30 -070017357#ifdef WLAN_BTAMP_FEATURE
17358 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017359 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017360 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017361 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017362 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017363 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017364 }
17365#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017366
17367 //If Device Mode is Station Concurrent Sessions Exit BMps
17368 //P2P Mode will be taken care in Open/close adapter
17369 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017370 (vos_concurrent_open_sessions_running())) {
17371 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17372 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017373 }
17374
17375 /*Try disconnecting if already in connected state*/
17376 status = wlan_hdd_try_disconnect(pAdapter);
17377 if ( 0 > status)
17378 {
17379 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17380 " connection"));
17381 return -EALREADY;
17382 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017383 /* Check for max concurrent connections after doing disconnect if any*/
17384 if (vos_max_concurrent_connections_reached()) {
17385 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17386 return -ECONNREFUSED;
17387 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017388
Jeff Johnson295189b2012-06-20 16:38:30 -070017389 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017390 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017391
17392 if ( 0 > status)
17393 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017394 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017395 __func__);
17396 return status;
17397 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017398
17399 if (pHddCtx->spoofMacAddr.isEnabled)
17400 {
17401 hddLog(VOS_TRACE_LEVEL_INFO,
17402 "%s: MAC Spoofing enabled ", __func__);
17403 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17404 * to fill TxBds for probe request during SSID scan which may happen
17405 * as part of connect command
17406 */
17407 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17408 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17409 if (status != VOS_STATUS_SUCCESS)
17410 return -ECONNREFUSED;
17411 }
17412
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017413 if (req->channel)
17414 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017415 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017416 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017417
17418 /* Abort if any scan is going on */
17419 status = wlan_hdd_scan_abort(pAdapter);
17420 if (0 != status)
17421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17422
Abhishek Singhe3beee22017-07-31 15:35:40 +053017423 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17424
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017425 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17426 req->ssid_len, req->bssid,
17427 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017428
Sushant Kaushikd7083982015-03-18 14:33:24 +053017429 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017430 {
17431 //ReEnable BMPS if disabled
17432 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17433 (NULL != pHddCtx))
17434 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017435 if (pHddCtx->hdd_wlan_suspended)
17436 {
17437 hdd_set_pwrparams(pHddCtx);
17438 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017439 //ReEnable Bmps and Imps back
17440 hdd_enable_bmps_imps(pHddCtx);
17441 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017443 return status;
17444 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017445 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017446 EXIT();
17447 return status;
17448}
17449
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017450static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17451 struct net_device *ndev,
17452 struct cfg80211_connect_params *req)
17453{
17454 int ret;
17455 vos_ssr_protect(__func__);
17456 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17457 vos_ssr_unprotect(__func__);
17458
17459 return ret;
17460}
Jeff Johnson295189b2012-06-20 16:38:30 -070017461
17462/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017463 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017464 * This function is used to issue a disconnect request to SME
17465 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017466static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017467 struct net_device *dev,
17468 u16 reason
17469 )
17470{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017471 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017472 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017473 tCsrRoamProfile *pRoamProfile;
17474 hdd_station_ctx_t *pHddStaCtx;
17475 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017476#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017477 tANI_U8 staIdx;
17478#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017479
Jeff Johnson295189b2012-06-20 16:38:30 -070017480 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017481
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017482 if (!pAdapter) {
17483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17484 return -EINVAL;
17485 }
17486
17487 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17488 if (!pHddStaCtx) {
17489 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17490 return -EINVAL;
17491 }
17492
17493 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17494 status = wlan_hdd_validate_context(pHddCtx);
17495 if (0 != status)
17496 {
17497 return status;
17498 }
17499
17500 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17501
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017502 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17503 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17504 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017505 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17506 __func__, hdd_device_modetoString(pAdapter->device_mode),
17507 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017508
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017509 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17510 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017511
Jeff Johnson295189b2012-06-20 16:38:30 -070017512 if (NULL != pRoamProfile)
17513 {
17514 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017515 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17516 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017517 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017518 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017519 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017520 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017521 switch(reason)
17522 {
17523 case WLAN_REASON_MIC_FAILURE:
17524 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17525 break;
17526
17527 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17528 case WLAN_REASON_DISASSOC_AP_BUSY:
17529 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17530 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17531 break;
17532
17533 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17534 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017535 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017536 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17537 break;
17538
Jeff Johnson295189b2012-06-20 16:38:30 -070017539 default:
17540 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17541 break;
17542 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017543 pScanInfo = &pHddCtx->scan_info;
17544 if (pScanInfo->mScanPending)
17545 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017546 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017547 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017548 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017549 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017550 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017551 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017552#ifdef FEATURE_WLAN_TDLS
17553 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017554 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017555 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017556 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17557 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017558 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017559 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017560 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017562 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017563 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017564 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017565 status = sme_DeleteTdlsPeerSta(
17566 WLAN_HDD_GET_HAL_CTX(pAdapter),
17567 pAdapter->sessionId,
17568 mac);
17569 if (status != eHAL_STATUS_SUCCESS) {
17570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17571 return -EPERM;
17572 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017573 }
17574 }
17575#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017576
17577 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17578 reasonCode,
17579 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017580 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17581 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017582 {
17583 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017584 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017585 __func__, (int)status );
17586 return -EINVAL;
17587 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017588 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017589 else
17590 {
17591 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17592 "called while in %d state", __func__,
17593 pHddStaCtx->conn_info.connState);
17594 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017595 }
17596 else
17597 {
17598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17599 }
17600
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017601 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017602 return status;
17603}
17604
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017605static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17606 struct net_device *dev,
17607 u16 reason
17608 )
17609{
17610 int ret;
17611 vos_ssr_protect(__func__);
17612 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17613 vos_ssr_unprotect(__func__);
17614
17615 return ret;
17616}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017617
Jeff Johnson295189b2012-06-20 16:38:30 -070017618/*
17619 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017620 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017621 * settings in IBSS mode.
17622 */
17623static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017624 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017625 struct cfg80211_ibss_params *params
17626 )
17627{
17628 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017629 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017630 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017631 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17632 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017633
Jeff Johnson295189b2012-06-20 16:38:30 -070017634 ENTER();
17635
17636 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017637 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017638
17639 if (params->ie_len && ( NULL != params->ie) )
17640 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017641 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17642 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017643 {
17644 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17645 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17646 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017647 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017648 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017649 tDot11fIEWPA dot11WPAIE;
17650 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017651 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017652
Wilson Yang00256342013-10-10 23:13:38 -070017653 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017654 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17655 params->ie_len, DOT11F_EID_WPA);
17656 if ( NULL != ie )
17657 {
17658 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Hanumanth Reddy Pothulad6d2d2c2018-06-27 12:28:12 +053017659
17660 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
17661 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
17662 hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
17663 return -EINVAL;
17664 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017665 // Unpack the WPA IE
17666 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017667 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017668 &ie[2+4],
17669 ie[1] - 4,
17670 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017671 if (DOT11F_FAILED(ret))
17672 {
17673 hddLog(LOGE,
17674 FL("unpack failed status:(0x%08x)"),
17675 ret);
17676 return -EINVAL;
17677 }
17678
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017679 /*Extract the multicast cipher, the encType for unicast
17680 cipher for wpa-none is none*/
17681 encryptionType =
17682 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17683 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017684 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017685
Jeff Johnson295189b2012-06-20 16:38:30 -070017686 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17687
17688 if (0 > status)
17689 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017690 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017691 __func__);
17692 return status;
17693 }
17694 }
17695
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017696 pWextState->roamProfile.AuthType.authType[0] =
17697 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017698 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017699 if (params->privacy)
17700 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017701 /* Security enabled IBSS, At this time there is no information available
17702 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017703 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017704 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017705 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017706 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017707 *enable privacy bit in beacons */
17708
17709 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17710 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017711 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17712 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017713 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17714 pWextState->roamProfile.EncryptionType.numEntries = 1;
17715 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017716 return status;
17717}
17718
17719/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017720 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017721 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017722 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017723static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017724 struct net_device *dev,
17725 struct cfg80211_ibss_params *params
17726 )
17727{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017728 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017729 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17730 tCsrRoamProfile *pRoamProfile;
17731 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017732 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17733 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017734 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017735
17736 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017737
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017738 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17739 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17740 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017741 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017742 "%s: device_mode = %s (%d)", __func__,
17743 hdd_device_modetoString(pAdapter->device_mode),
17744 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017745
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017746 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017747 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017748 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017749 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017750 }
17751
17752 if (NULL == pWextState)
17753 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017754 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017755 __func__);
17756 return -EIO;
17757 }
17758
Agarwal Ashish51325b52014-06-16 16:50:49 +053017759 if (vos_max_concurrent_connections_reached()) {
17760 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17761 return -ECONNREFUSED;
17762 }
17763
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017764 /*Try disconnecting if already in connected state*/
17765 status = wlan_hdd_try_disconnect(pAdapter);
17766 if ( 0 > status)
17767 {
17768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17769 " IBSS connection"));
17770 return -EALREADY;
17771 }
17772
Jeff Johnson295189b2012-06-20 16:38:30 -070017773 pRoamProfile = &pWextState->roamProfile;
17774
17775 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17776 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017777 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017778 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017779 return -EINVAL;
17780 }
17781
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017782 /* BSSID is provided by upper layers hence no need to AUTO generate */
17783 if (NULL != params->bssid) {
17784 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17785 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17786 hddLog (VOS_TRACE_LEVEL_ERROR,
17787 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17788 return -EIO;
17789 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017790 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017791 }
krunal sonie9002db2013-11-25 14:24:17 -080017792 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17793 {
17794 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17795 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17796 {
17797 hddLog (VOS_TRACE_LEVEL_ERROR,
17798 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17799 return -EIO;
17800 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017801
17802 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017803 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017804 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017805 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017806
Jeff Johnson295189b2012-06-20 16:38:30 -070017807 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017808 if (NULL !=
17809#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17810 params->chandef.chan)
17811#else
17812 params->channel)
17813#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017814 {
17815 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017816 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17817 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17818 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17819 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017820
17821 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017822 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017823 ieee80211_frequency_to_channel(
17824#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17825 params->chandef.chan->center_freq);
17826#else
17827 params->channel->center_freq);
17828#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017829
17830 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17831 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017832 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017833 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17834 __func__);
17835 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017836 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017837
17838 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017839 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017840 if (channelNum == validChan[indx])
17841 {
17842 break;
17843 }
17844 }
17845 if (indx >= numChans)
17846 {
17847 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017848 __func__, channelNum);
17849 return -EINVAL;
17850 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017851 /* Set the Operational Channel */
17852 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17853 channelNum);
17854 pRoamProfile->ChannelInfo.numOfChannels = 1;
17855 pHddStaCtx->conn_info.operationChannel = channelNum;
17856 pRoamProfile->ChannelInfo.ChannelList =
17857 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017858 }
17859
17860 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017861 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017862 if (status < 0)
17863 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017864 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017865 __func__);
17866 return status;
17867 }
17868
17869 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017870 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017871 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017872 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017873
17874 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017875 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017876
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017877 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017878 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017879}
17880
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017881static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17882 struct net_device *dev,
17883 struct cfg80211_ibss_params *params
17884 )
17885{
17886 int ret = 0;
17887
17888 vos_ssr_protect(__func__);
17889 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17890 vos_ssr_unprotect(__func__);
17891
17892 return ret;
17893}
17894
Jeff Johnson295189b2012-06-20 16:38:30 -070017895/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017896 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017897 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017898 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017899static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017900 struct net_device *dev
17901 )
17902{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017903 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017904 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17905 tCsrRoamProfile *pRoamProfile;
17906 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017907 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017908 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017909#ifdef WLAN_FEATURE_RMC
17910 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17911#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017912
17913 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017914
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017915 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17916 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17917 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017918 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017919 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017920 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017921 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017922 }
17923
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017924 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17925 hdd_device_modetoString(pAdapter->device_mode),
17926 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017927 if (NULL == pWextState)
17928 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017929 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017930 __func__);
17931 return -EIO;
17932 }
17933
17934 pRoamProfile = &pWextState->roamProfile;
17935
17936 /* Issue disconnect only if interface type is set to IBSS */
17937 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017939 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017940 __func__);
17941 return -EINVAL;
17942 }
17943
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017944#ifdef WLAN_FEATURE_RMC
17945 /* Clearing add IE of beacon */
17946 if (ccmCfgSetStr(pHddCtx->hHal,
17947 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17948 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17949 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17950 {
17951 hddLog (VOS_TRACE_LEVEL_ERROR,
17952 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17953 return -EINVAL;
17954 }
17955 if (ccmCfgSetInt(pHddCtx->hHal,
17956 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17957 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17958 {
17959 hddLog (VOS_TRACE_LEVEL_ERROR,
17960 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17961 __func__);
17962 return -EINVAL;
17963 }
17964
17965 // Reset WNI_CFG_PROBE_RSP Flags
17966 wlan_hdd_reset_prob_rspies(pAdapter);
17967
17968 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17969 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17970 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17971 {
17972 hddLog (VOS_TRACE_LEVEL_ERROR,
17973 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17974 __func__);
17975 return -EINVAL;
17976 }
17977#endif
17978
Jeff Johnson295189b2012-06-20 16:38:30 -070017979 /* Issue Disconnect request */
17980 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017981 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17982 pAdapter->sessionId,
17983 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17984 if (!HAL_STATUS_SUCCESS(hal_status)) {
17985 hddLog(LOGE,
17986 FL("sme_RoamDisconnect failed hal_status(%d)"),
17987 hal_status);
17988 return -EAGAIN;
17989 }
17990 status = wait_for_completion_timeout(
17991 &pAdapter->disconnect_comp_var,
17992 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17993 if (!status) {
17994 hddLog(LOGE,
17995 FL("wait on disconnect_comp_var failed"));
17996 return -ETIMEDOUT;
17997 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017998
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017999 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018000 return 0;
18001}
18002
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018003static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
18004 struct net_device *dev
18005 )
18006{
18007 int ret = 0;
18008
18009 vos_ssr_protect(__func__);
18010 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
18011 vos_ssr_unprotect(__func__);
18012
18013 return ret;
18014}
18015
Jeff Johnson295189b2012-06-20 16:38:30 -070018016/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018017 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070018018 * This function is used to set the phy parameters
18019 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
18020 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018021static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070018022 u32 changed)
18023{
18024 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18025 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018026 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018027
18028 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018029
18030 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018031 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
18032 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018033
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018034 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018035 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018036 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018037 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018038 }
18039
Jeff Johnson295189b2012-06-20 16:38:30 -070018040 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
18041 {
18042 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
18043 WNI_CFG_RTS_THRESHOLD_STAMAX :
18044 wiphy->rts_threshold;
18045
18046 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018047 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070018048 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018049 hddLog(VOS_TRACE_LEVEL_ERROR,
18050 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018051 __func__, rts_threshold);
18052 return -EINVAL;
18053 }
18054
18055 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
18056 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018057 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018058 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018059 hddLog(VOS_TRACE_LEVEL_ERROR,
18060 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018061 __func__, rts_threshold);
18062 return -EIO;
18063 }
18064
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018065 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070018066 rts_threshold);
18067 }
18068
18069 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
18070 {
18071 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
18072 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
18073 wiphy->frag_threshold;
18074
18075 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018076 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070018077 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018078 hddLog(VOS_TRACE_LEVEL_ERROR,
18079 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070018080 frag_threshold);
18081 return -EINVAL;
18082 }
18083
18084 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
18085 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018086 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018087 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018088 hddLog(VOS_TRACE_LEVEL_ERROR,
18089 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018090 __func__, frag_threshold);
18091 return -EIO;
18092 }
18093
18094 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
18095 frag_threshold);
18096 }
18097
18098 if ((changed & WIPHY_PARAM_RETRY_SHORT)
18099 || (changed & WIPHY_PARAM_RETRY_LONG))
18100 {
18101 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
18102 wiphy->retry_short :
18103 wiphy->retry_long;
18104
18105 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
18106 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
18107 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018108 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018109 __func__, retry_value);
18110 return -EINVAL;
18111 }
18112
18113 if (changed & WIPHY_PARAM_RETRY_SHORT)
18114 {
18115 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
18116 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018117 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018118 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018119 hddLog(VOS_TRACE_LEVEL_ERROR,
18120 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018121 __func__, retry_value);
18122 return -EIO;
18123 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018124 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018125 __func__, retry_value);
18126 }
18127 else if (changed & WIPHY_PARAM_RETRY_SHORT)
18128 {
18129 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
18130 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018131 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018132 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018133 hddLog(VOS_TRACE_LEVEL_ERROR,
18134 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018135 __func__, retry_value);
18136 return -EIO;
18137 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018138 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018139 __func__, retry_value);
18140 }
18141 }
18142
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018143 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018144 return 0;
18145}
18146
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018147static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
18148 u32 changed)
18149{
18150 int ret;
18151
18152 vos_ssr_protect(__func__);
18153 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
18154 vos_ssr_unprotect(__func__);
18155
18156 return ret;
18157}
18158
Jeff Johnson295189b2012-06-20 16:38:30 -070018159/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018160 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070018161 * This function is used to set the txpower
18162 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018163static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070018164#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18165 struct wireless_dev *wdev,
18166#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018167#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018168 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070018169#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018170 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070018171#endif
18172 int dbm)
18173{
18174 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018175 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070018176 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
18177 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018178 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018179
18180 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018181
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018182 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18183 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
18184 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018185 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018186 if (0 != status)
18187 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018188 return status;
18189 }
18190
18191 hHal = pHddCtx->hHal;
18192
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018193 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
18194 dbm, ccmCfgSetCallback,
18195 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018196 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018197 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018198 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
18199 return -EIO;
18200 }
18201
18202 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
18203 dbm);
18204
18205 switch(type)
18206 {
18207 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
18208 /* Fall through */
18209 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
18210 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
18211 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018212 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
18213 __func__);
18214 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070018215 }
18216 break;
18217 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070018219 __func__);
18220 return -EOPNOTSUPP;
18221 break;
18222 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
18224 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070018225 return -EIO;
18226 }
18227
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018228 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018229 return 0;
18230}
18231
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018232static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
18233#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18234 struct wireless_dev *wdev,
18235#endif
18236#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
18237 enum tx_power_setting type,
18238#else
18239 enum nl80211_tx_power_setting type,
18240#endif
18241 int dbm)
18242{
18243 int ret;
18244 vos_ssr_protect(__func__);
18245 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
18246#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18247 wdev,
18248#endif
18249#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
18250 type,
18251#else
18252 type,
18253#endif
18254 dbm);
18255 vos_ssr_unprotect(__func__);
18256
18257 return ret;
18258}
18259
Jeff Johnson295189b2012-06-20 16:38:30 -070018260/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018261 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070018262 * This function is used to read the txpower
18263 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018264static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070018265#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18266 struct wireless_dev *wdev,
18267#endif
18268 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070018269{
18270
18271 hdd_adapter_t *pAdapter;
18272 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018273 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018274
Jeff Johnsone7245742012-09-05 17:12:55 -070018275 ENTER();
18276
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018277 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018278 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018279 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018280 *dbm = 0;
18281 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018282 }
18283
Jeff Johnson295189b2012-06-20 16:38:30 -070018284 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
18285 if (NULL == pAdapter)
18286 {
18287 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
18288 return -ENOENT;
18289 }
18290
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018291 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18292 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
18293 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070018294 wlan_hdd_get_classAstats(pAdapter);
18295 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
18296
Jeff Johnsone7245742012-09-05 17:12:55 -070018297 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018298 return 0;
18299}
18300
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018301static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
18302#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18303 struct wireless_dev *wdev,
18304#endif
18305 int *dbm)
18306{
18307 int ret;
18308
18309 vos_ssr_protect(__func__);
18310 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
18311#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18312 wdev,
18313#endif
18314 dbm);
18315 vos_ssr_unprotect(__func__);
18316
18317 return ret;
18318}
18319
Dustin Brown8c1d4092017-07-28 18:08:01 +053018320/*
18321 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
18322 * @stats: summary stats to use as a source
18323 * @info: kernel station_info struct to use as a destination
18324 *
18325 * Return: None
18326 */
18327static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
18328 struct station_info *info)
18329{
18330 int i;
18331
18332 info->rx_packets = stats->rx_frm_cnt;
18333 info->tx_packets = 0;
18334 info->tx_retries = 0;
18335 info->tx_failed = 0;
18336
18337 for (i = 0; i < 4; ++i) {
18338 info->tx_packets += stats->tx_frm_cnt[i];
18339 info->tx_retries += stats->multiple_retry_cnt[i];
18340 info->tx_failed += stats->fail_cnt[i];
18341 }
18342
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018343#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18344 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018345 info->filled |= STATION_INFO_TX_PACKETS |
18346 STATION_INFO_TX_RETRIES |
18347 STATION_INFO_TX_FAILED |
18348 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018349#else
18350 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18351 BIT(NL80211_STA_INFO_TX_RETRIES) |
18352 BIT(NL80211_STA_INFO_TX_FAILED) |
18353 BIT(NL80211_STA_INFO_RX_PACKETS);
18354#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018355}
18356
18357/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018358 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18359 * @adapter: sap adapter pointer
18360 * @staid: station id of the client
18361 * @rssi: rssi value to fill
18362 *
18363 * Return: None
18364 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018365void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018366wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18367{
18368 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18369
18370 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18371}
18372
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018373#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18374 !defined(WITH_BACKPORTS)
18375static inline void wlan_hdd_fill_station_info_signal(struct station_info
18376 *sinfo)
18377{
18378 sinfo->filled |= STATION_INFO_SIGNAL;
18379}
18380#else
18381static inline void wlan_hdd_fill_station_info_signal(struct station_info
18382 *sinfo)
18383{
18384 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18385}
18386#endif
18387
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018388/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018389 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18390 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018391 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018392 * @info: kernel station_info struct to populate
18393 *
18394 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18395 * support "station dump" and "station get" for SAP vdevs, even though they
18396 * aren't technically stations.
18397 *
18398 * Return: errno
18399 */
18400static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018401wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18402#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18403 const u8* mac,
18404#else
18405 u8* mac,
18406#endif
18407 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018408{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018409 v_MACADDR_t *peerMacAddr;
18410 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018411 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018412 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018413
18414 status = wlan_hdd_get_station_stats(adapter);
18415 if (!VOS_IS_STATUS_SUCCESS(status)) {
18416 hddLog(VOS_TRACE_LEVEL_ERROR,
18417 "Failed to get SAP stats; status:%d", status);
18418 return 0;
18419 }
18420
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018421 peerMacAddr = (v_MACADDR_t *)mac;
18422 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18423 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18424 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18425
18426 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18427 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018428 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018429 }
18430
Dustin Brown8c1d4092017-07-28 18:08:01 +053018431 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18432
18433 return 0;
18434}
18435
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018436static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018437#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18438 const u8* mac,
18439#else
18440 u8* mac,
18441#endif
18442 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018443{
18444 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18445 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
c_hpothu44ff4e02014-05-08 00:13:57 +053018446 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018447
18448 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18449 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018450
18451 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18452 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18453 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18454 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18455 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18456 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18457 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018458 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018459 tANI_U16 myRate;
18460 tANI_U16 currentRate = 0;
18461 tANI_U8 maxSpeedMCS = 0;
18462 tANI_U8 maxMCSIdx = 0;
18463 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018464 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018465 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018466 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018467
Leo Chang6f8870f2013-03-26 18:11:36 -070018468#ifdef WLAN_FEATURE_11AC
18469 tANI_U32 vht_mcs_map;
18470 eDataRate11ACMaxMcs vhtMaxMcs;
18471#endif /* WLAN_FEATURE_11AC */
18472
Jeff Johnsone7245742012-09-05 17:12:55 -070018473 ENTER();
18474
Dustin Brown8c1d4092017-07-28 18:08:01 +053018475 status = wlan_hdd_validate_context(pHddCtx);
18476 if (0 != status)
18477 {
18478 return status;
18479 }
18480
18481 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018482 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018483
Abhinav Kumarf70293b2019-09-19 12:33:43 +053018484 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -070018485 {
Abhinav Kumarf70293b2019-09-19 12:33:43 +053018486 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018487 /*To keep GUI happy*/
18488 return 0;
18489 }
18490
Mukul Sharma811205f2014-07-09 21:07:30 +053018491 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18492 {
18493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18494 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018495 /* return a cached value */
18496 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018497 return 0;
18498 }
18499
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018500 wlan_hdd_get_station_stats(pAdapter);
18501 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018502
Kiet Lam3b17fc82013-09-27 05:24:08 +053018503 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018504 wlan_hdd_get_snr(pAdapter, &snr);
18505 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018506 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018507 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018508 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018509 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018510
c_hpothu09f19542014-05-30 21:53:31 +053018511 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018512 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18513 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018514 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018515 {
18516 rate_flags = pAdapter->maxRateFlags;
18517 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018518
Jeff Johnson295189b2012-06-20 16:38:30 -070018519 //convert to the UI units of 100kbps
18520 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18521
18522#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018523 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 -070018524 sinfo->signal,
18525 pCfg->reportMaxLinkSpeed,
18526 myRate,
18527 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018528 (int) pCfg->linkSpeedRssiMid,
18529 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018530 (int) rate_flags,
18531 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018532#endif //LINKSPEED_DEBUG_ENABLED
18533
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18535 /* assume basic BW. anything else will override this later */
18536 sinfo->txrate.bw = RATE_INFO_BW_20;
18537#endif
18538
Jeff Johnson295189b2012-06-20 16:38:30 -070018539 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18540 {
18541 // we do not want to necessarily report the current speed
18542 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18543 {
18544 // report the max possible speed
18545 rssidx = 0;
18546 }
18547 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18548 {
18549 // report the max possible speed with RSSI scaling
18550 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18551 {
18552 // report the max possible speed
18553 rssidx = 0;
18554 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018555 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018556 {
18557 // report middle speed
18558 rssidx = 1;
18559 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018560 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18561 {
18562 // report middle speed
18563 rssidx = 2;
18564 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018565 else
18566 {
18567 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018568 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018569 }
18570 }
18571 else
18572 {
18573 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18574 hddLog(VOS_TRACE_LEVEL_ERROR,
18575 "%s: Invalid value for reportMaxLinkSpeed: %u",
18576 __func__, pCfg->reportMaxLinkSpeed);
18577 rssidx = 0;
18578 }
18579
18580 maxRate = 0;
18581
18582 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018583 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18584 OperationalRates, &ORLeng))
18585 {
18586 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18587 /*To keep GUI happy*/
18588 return 0;
18589 }
18590
Jeff Johnson295189b2012-06-20 16:38:30 -070018591 for (i = 0; i < ORLeng; i++)
18592 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018593 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018594 {
18595 /* Validate Rate Set */
18596 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18597 {
18598 currentRate = supported_data_rate[j].supported_rate[rssidx];
18599 break;
18600 }
18601 }
18602 /* Update MAX rate */
18603 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18604 }
18605
18606 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018607 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18608 ExtendedRates, &ERLeng))
18609 {
18610 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18611 /*To keep GUI happy*/
18612 return 0;
18613 }
18614
Jeff Johnson295189b2012-06-20 16:38:30 -070018615 for (i = 0; i < ERLeng; i++)
18616 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018617 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018618 {
18619 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18620 {
18621 currentRate = supported_data_rate[j].supported_rate[rssidx];
18622 break;
18623 }
18624 }
18625 /* Update MAX rate */
18626 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18627 }
c_hpothu79aab322014-07-14 21:11:01 +053018628
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018629 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018630 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018631 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018632 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018633 {
c_hpothu79aab322014-07-14 21:11:01 +053018634 if (rate_flags & eHAL_TX_RATE_VHT80)
18635 mode = 2;
18636 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18637 mode = 1;
18638 else
18639 mode = 0;
18640
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018641 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18642 MCSRates, &MCSLeng))
18643 {
18644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18645 /*To keep GUI happy*/
18646 return 0;
18647 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018648 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018649#ifdef WLAN_FEATURE_11AC
18650 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018651 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018652 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018653 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018654 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018655 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018656 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018657 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018658 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018659 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018660 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018661 maxMCSIdx = 7;
18662 }
18663 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18664 {
18665 maxMCSIdx = 8;
18666 }
18667 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18668 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018669 //VHT20 is supporting 0~8
18670 if (rate_flags & eHAL_TX_RATE_VHT20)
18671 maxMCSIdx = 8;
18672 else
18673 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018674 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018675
c_hpothu79aab322014-07-14 21:11:01 +053018676 if (0 != rssidx)/*check for scaled */
18677 {
18678 //get middle rate MCS index if rssi=1/2
18679 for (i=0; i <= maxMCSIdx; i++)
18680 {
18681 if (sinfo->signal <= rssiMcsTbl[mode][i])
18682 {
18683 maxMCSIdx = i;
18684 break;
18685 }
18686 }
18687 }
18688
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018689 if (rate_flags & eHAL_TX_RATE_VHT80)
18690 {
18691 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18692 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18693 }
18694 else if (rate_flags & eHAL_TX_RATE_VHT40)
18695 {
18696 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18697 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18698 }
18699 else if (rate_flags & eHAL_TX_RATE_VHT20)
18700 {
18701 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18702 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18703 }
18704
Leo Chang6f8870f2013-03-26 18:11:36 -070018705 maxSpeedMCS = 1;
18706 if (currentRate > maxRate)
18707 {
18708 maxRate = currentRate;
18709 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018710
Leo Chang6f8870f2013-03-26 18:11:36 -070018711 }
18712 else
18713#endif /* WLAN_FEATURE_11AC */
18714 {
18715 if (rate_flags & eHAL_TX_RATE_HT40)
18716 {
18717 rateFlag |= 1;
18718 }
18719 if (rate_flags & eHAL_TX_RATE_SGI)
18720 {
18721 rateFlag |= 2;
18722 }
18723
Girish Gowli01abcee2014-07-31 20:18:55 +053018724 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018725 if (rssidx == 1 || rssidx == 2)
18726 {
18727 //get middle rate MCS index if rssi=1/2
18728 for (i=0; i <= 7; i++)
18729 {
18730 if (sinfo->signal <= rssiMcsTbl[mode][i])
18731 {
18732 temp = i+1;
18733 break;
18734 }
18735 }
18736 }
c_hpothu79aab322014-07-14 21:11:01 +053018737
18738 for (i = 0; i < MCSLeng; i++)
18739 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018740 for (j = 0; j < temp; j++)
18741 {
18742 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18743 {
18744 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018745 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018746 break;
18747 }
18748 }
18749 if ((j < temp) && (currentRate > maxRate))
18750 {
18751 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018752 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018753 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018754 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018755 }
18756 }
18757
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018758 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18759 {
18760 maxRate = myRate;
18761 maxSpeedMCS = 1;
18762 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18763 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018764 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018765 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018766 {
18767 maxRate = myRate;
18768 if (rate_flags & eHAL_TX_RATE_LEGACY)
18769 {
18770 maxSpeedMCS = 0;
18771 }
18772 else
18773 {
18774 maxSpeedMCS = 1;
18775 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18776 }
18777 }
18778
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018779 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018780 {
18781 sinfo->txrate.legacy = maxRate;
18782#ifdef LINKSPEED_DEBUG_ENABLED
18783 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18784#endif //LINKSPEED_DEBUG_ENABLED
18785 }
18786 else
18787 {
18788 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018789#ifdef WLAN_FEATURE_11AC
18790 sinfo->txrate.nss = 1;
18791 if (rate_flags & eHAL_TX_RATE_VHT80)
18792 {
18793 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18795 defined(WITH_BACKPORTS)
18796 sinfo->txrate.bw = RATE_INFO_BW_80;
18797#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018798 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018799#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018800 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018801 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018802 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018803 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018804#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18805 defined(WITH_BACKPORTS)
18806 sinfo->txrate.bw = RATE_INFO_BW_40;
18807#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018808 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018809#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018810 }
18811 else if (rate_flags & eHAL_TX_RATE_VHT20)
18812 {
18813 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18814 }
18815#endif /* WLAN_FEATURE_11AC */
18816 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18817 {
18818 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18819 if (rate_flags & eHAL_TX_RATE_HT40)
18820 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018821#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18822 defined(WITH_BACKPORTS)
18823 sinfo->txrate.bw = RATE_INFO_BW_40;
18824#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018825 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018826#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018827 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018828 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018829 if (rate_flags & eHAL_TX_RATE_SGI)
18830 {
18831 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18832 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018833
Jeff Johnson295189b2012-06-20 16:38:30 -070018834#ifdef LINKSPEED_DEBUG_ENABLED
18835 pr_info("Reporting MCS rate %d flags %x\n",
18836 sinfo->txrate.mcs,
18837 sinfo->txrate.flags );
18838#endif //LINKSPEED_DEBUG_ENABLED
18839 }
18840 }
18841 else
18842 {
18843 // report current rate instead of max rate
18844
18845 if (rate_flags & eHAL_TX_RATE_LEGACY)
18846 {
18847 //provide to the UI in units of 100kbps
18848 sinfo->txrate.legacy = myRate;
18849#ifdef LINKSPEED_DEBUG_ENABLED
18850 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18851#endif //LINKSPEED_DEBUG_ENABLED
18852 }
18853 else
18854 {
18855 //must be MCS
18856 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018857#ifdef WLAN_FEATURE_11AC
18858 sinfo->txrate.nss = 1;
18859 if (rate_flags & eHAL_TX_RATE_VHT80)
18860 {
18861 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18862 }
18863 else
18864#endif /* WLAN_FEATURE_11AC */
18865 {
18866 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18867 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018868 if (rate_flags & eHAL_TX_RATE_SGI)
18869 {
18870 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18871 }
18872 if (rate_flags & eHAL_TX_RATE_HT40)
18873 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018874#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18875 defined(WITH_BACKPORTS)
18876 sinfo->txrate.bw = RATE_INFO_BW_40;
18877#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018878 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018879#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018880 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018881#ifdef WLAN_FEATURE_11AC
18882 else if (rate_flags & eHAL_TX_RATE_VHT80)
18883 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018884#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18885 defined(WITH_BACKPORTS)
18886 sinfo->txrate.bw = RATE_INFO_BW_80;
18887#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018888 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018889#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018890 }
18891#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018892#ifdef LINKSPEED_DEBUG_ENABLED
18893 pr_info("Reporting actual MCS rate %d flags %x\n",
18894 sinfo->txrate.mcs,
18895 sinfo->txrate.flags );
18896#endif //LINKSPEED_DEBUG_ENABLED
18897 }
18898 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018899
18900#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18901 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018902 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018903#else
18904 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18905#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018906
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018907 sinfo->tx_packets =
18908 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18909 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18910 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18911 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18912
18913 sinfo->tx_retries =
18914 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18915 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18916 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18917 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18918
18919 sinfo->tx_failed =
18920 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18921 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18922 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18923 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18924
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018925#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18926 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018927 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018928 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018929 STATION_INFO_TX_PACKETS |
18930 STATION_INFO_TX_RETRIES |
18931 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018932#else
18933 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18934 BIT(NL80211_STA_INFO_TX_PACKETS) |
18935 BIT(NL80211_STA_INFO_TX_RETRIES) |
18936 BIT(NL80211_STA_INFO_TX_FAILED);
18937#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018938
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018939 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018940
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018941 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18942 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018943 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18944 &sinfo->txrate, sizeof(sinfo->txrate));
18945
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018946 if (rate_flags & eHAL_TX_RATE_LEGACY)
18947 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18948 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18949 sinfo->rx_packets);
18950 else
18951 hddLog(LOG1,
18952 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18953 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18954 sinfo->tx_packets, sinfo->rx_packets);
18955
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018956 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18957 TRACE_CODE_HDD_CFG80211_GET_STA,
18958 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018959 EXIT();
18960 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018961}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018962#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18963static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18964 const u8* mac, struct station_info *sinfo)
18965#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018966static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18967 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018968#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018969{
18970 int ret;
18971
18972 vos_ssr_protect(__func__);
18973 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18974 vos_ssr_unprotect(__func__);
18975
18976 return ret;
18977}
18978
18979static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018980 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018981{
18982 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018983 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018984 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018985 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018986
Jeff Johnsone7245742012-09-05 17:12:55 -070018987 ENTER();
18988
Jeff Johnson295189b2012-06-20 16:38:30 -070018989 if (NULL == pAdapter)
18990 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018991 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018992 return -ENODEV;
18993 }
18994
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018995 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18996 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18997 pAdapter->sessionId, timeout));
18998
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019000 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019001 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019002 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019003 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019004 }
19005
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053019006 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
19007 (TRUE == pHddCtx->hdd_wlan_suspended) &&
19008 (pHddCtx->cfg_ini->fhostArpOffload) &&
19009 (eConnectionState_Associated ==
19010 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
19011 {
Amar Singhald53568e2013-09-26 11:03:45 -070019012
19013 hddLog(VOS_TRACE_LEVEL_INFO,
19014 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053019015 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053019016 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19017 {
19018 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080019019 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053019020 __func__, vos_status);
19021 }
19022 }
19023
Jeff Johnson295189b2012-06-20 16:38:30 -070019024 /**The get power cmd from the supplicant gets updated by the nl only
19025 *on successful execution of the function call
19026 *we are oppositely mapped w.r.t mode in the driver
19027 **/
19028 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
19029
19030 if (VOS_STATUS_E_FAILURE == vos_status)
19031 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019032 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19033 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070019034 return -EINVAL;
19035 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019036 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070019037 return 0;
19038}
19039
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019040static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
19041 struct net_device *dev, bool mode, int timeout)
19042{
19043 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070019044
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019045 vos_ssr_protect(__func__);
19046 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
19047 vos_ssr_unprotect(__func__);
19048
19049 return ret;
19050}
Sushant Kaushik084f6592015-09-10 13:11:56 +053019051
Jeff Johnson295189b2012-06-20 16:38:30 -070019052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019053static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
19054 struct net_device *netdev,
19055 u8 key_index)
19056{
19057 ENTER();
19058 return 0;
19059}
19060
Jeff Johnson295189b2012-06-20 16:38:30 -070019061static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019062 struct net_device *netdev,
19063 u8 key_index)
19064{
19065 int ret;
19066 vos_ssr_protect(__func__);
19067 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
19068 vos_ssr_unprotect(__func__);
19069 return ret;
19070}
19071#endif //LINUX_VERSION_CODE
19072
19073#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
19074static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
19075 struct net_device *dev,
19076 struct ieee80211_txq_params *params)
19077{
19078 ENTER();
19079 return 0;
19080}
19081#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19082static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
19083 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070019084{
Jeff Johnsone7245742012-09-05 17:12:55 -070019085 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070019086 return 0;
19087}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019088#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070019089
19090#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
19091static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019092 struct net_device *dev,
19093 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070019094{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019095 int ret;
19096
19097 vos_ssr_protect(__func__);
19098 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
19099 vos_ssr_unprotect(__func__);
19100 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070019101}
19102#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19103static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
19104 struct ieee80211_txq_params *params)
19105{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019106 int ret;
19107
19108 vos_ssr_protect(__func__);
19109 ret = __wlan_hdd_set_txq_params(wiphy, params);
19110 vos_ssr_unprotect(__func__);
19111 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070019112}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019113#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019114
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019115static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019116 struct net_device *dev,
19117 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070019118{
19119 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019120 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019121 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019122 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019123 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019124 v_CONTEXT_t pVosContext = NULL;
19125 ptSapContext pSapCtx = NULL;
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019126 hdd_hostapd_state_t *hostap_state;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019127
Jeff Johnsone7245742012-09-05 17:12:55 -070019128 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019129
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019130 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070019131 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019132 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070019133 return -EINVAL;
19134 }
19135
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019136 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19137 TRACE_CODE_HDD_CFG80211_DEL_STA,
19138 pAdapter->sessionId, pAdapter->device_mode));
19139
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019140 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19141 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019142 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019143 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019144 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019145 }
19146
Jeff Johnson295189b2012-06-20 16:38:30 -070019147 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070019148 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070019149 )
19150 {
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019151 hostap_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019152 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
19153 pSapCtx = VOS_GET_SAP_CB(pVosContext);
19154 if(pSapCtx == NULL){
19155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19156 FL("psapCtx is NULL"));
19157 return -ENOENT;
19158 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053019159 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
19160 {
19161 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
19162 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
19163 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
19164 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019165 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070019166 {
19167 v_U16_t i;
19168 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
19169 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019170 if ((pSapCtx->aStaInfo[i].isUsed) &&
19171 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070019172 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019173 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019174 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019175 ETHER_ADDR_LEN);
19176
Jeff Johnson295189b2012-06-20 16:38:30 -070019177 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080019178 "%s: Delete STA with MAC::"
19179 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019180 __func__,
19181 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019182 vos_event_reset(&hostap_state->sta_discon_event);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019183 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070019184 if (VOS_IS_STATUS_SUCCESS(vos_status))
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019185 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019186 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019187 vos_status =
19188 vos_wait_single_event(
19189 &hostap_state->sta_discon_event,
19190 WLAN_WAIT_TIME_DISCONNECT);
19191 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19192 hddLog(LOGE,"!!%s: ERROR: Deauth wait expired!!",
19193 __func__);
19194 }
Jeff Johnson295189b2012-06-20 16:38:30 -070019195 }
19196 }
19197 }
19198 else
19199 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019200
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019201 vos_status = hdd_softap_GetStaId(pAdapter,
19202 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019203 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19204 {
19205 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080019206 "%s: Skip this DEL STA as this is not used::"
19207 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019208 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019209 return -ENOENT;
19210 }
19211
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019212 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019213 {
19214 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080019215 "%s: Skip this DEL STA as deauth is in progress::"
19216 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019217 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019218 return -ENOENT;
19219 }
19220
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019221 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019222
Jeff Johnson295189b2012-06-20 16:38:30 -070019223 hddLog(VOS_TRACE_LEVEL_INFO,
19224 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080019225 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070019226 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019227 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019228
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019229 vos_event_reset(&hostap_state->sta_discon_event);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019230 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019231 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19232 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019233 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019234 hddLog(VOS_TRACE_LEVEL_INFO,
19235 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080019236 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019237 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019238 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019239 return -ENOENT;
19240 }
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019241 vos_status =
19242 vos_wait_single_event(&hostap_state->sta_discon_event,
19243 WLAN_WAIT_TIME_DISCONNECT);
19244 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19245 hddLog(LOGE,"!!%s: ERROR: Deauth wait expired!!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070019246 }
19247 }
19248
19249 EXIT();
19250
19251 return 0;
19252}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019253
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019254#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053019255int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019256 struct net_device *dev,
19257 struct station_del_parameters *param)
19258#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019259#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053019260int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019261 struct net_device *dev, const u8 *mac)
19262#else
Kapil Gupta137ef892016-12-13 19:38:00 +053019263int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019264 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019265#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019266#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019267{
19268 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019269 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070019270
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019271 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019272
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019273#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019274 if (NULL == param) {
19275 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019276 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019277 return -EINVAL;
19278 }
19279
19280 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
19281 param->subtype, &delStaParams);
19282
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019283#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053019284 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019285 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019286#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019287 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
19288
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019289 vos_ssr_unprotect(__func__);
19290
19291 return ret;
19292}
19293
19294static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019295 struct net_device *dev,
19296#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19297 const u8 *mac,
19298#else
19299 u8 *mac,
19300#endif
19301 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019302{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019303 hdd_adapter_t *pAdapter;
19304 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019305 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019306#ifdef FEATURE_WLAN_TDLS
19307 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019308
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019309 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019310
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019311 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19312 if (NULL == pAdapter)
19313 {
19314 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19315 "%s: Adapter is NULL",__func__);
19316 return -EINVAL;
19317 }
19318 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19319 status = wlan_hdd_validate_context(pHddCtx);
19320 if (0 != status)
19321 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019322 return status;
19323 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019324
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019325 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19326 TRACE_CODE_HDD_CFG80211_ADD_STA,
19327 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019328 mask = params->sta_flags_mask;
19329
19330 set = params->sta_flags_set;
19331
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019332 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019333 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
19334 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019335
19336 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19337 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080019338 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019339 }
19340 }
19341#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019342 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019343 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070019344}
19345
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019346#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19347static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19348 struct net_device *dev, const u8 *mac,
19349 struct station_parameters *params)
19350#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019351static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19352 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019353#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019354{
19355 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019356
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019357 vos_ssr_protect(__func__);
19358 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19359 vos_ssr_unprotect(__func__);
19360
19361 return ret;
19362}
Abhinav Kumar8c122592019-08-07 15:43:20 +053019363
19364#if defined(WLAN_FEATURE_SAE) && \
19365 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
19366/*
19367 * wlan_hdd_is_pmksa_valid: API to validate pmksa
19368 * @pmksa: pointer to cfg80211_pmksa structure
19369 *
19370 * Return: True if valid else false
19371 */
19372static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
19373{
19374 if (pmksa->bssid){
19375 return true;
19376 }
19377 else
19378 {
19379 hddLog(LOGE, FL(" Either of bssid (%p) is NULL"), pmksa->bssid);
19380 return false;
19381 }
19382}
19383
19384/*
19385 * hdd_update_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
19386 * @pmk_cache: pmksa from supplicant
19387 * @pmk_cache: pmk needs to be updated
19388 *
19389 * Return: None
19390 */
19391static void hdd_update_pmksa_info(tPmkidCacheInfo *pmk_cache,
19392 struct cfg80211_pmksa *pmksa, bool is_delete)
19393{
19394 if (pmksa->bssid) {
19395 hddLog(VOS_TRACE_LEVEL_DEBUG,"set PMKSA for " MAC_ADDRESS_STR,
19396 MAC_ADDR_ARRAY(pmksa->bssid));
19397 vos_mem_copy(pmk_cache->BSSID,
19398 pmksa->bssid, VOS_MAC_ADDR_SIZE);
19399 }
19400
19401 if (is_delete)
19402 return;
19403
19404 vos_mem_copy(pmk_cache->PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
19405 if (pmksa->pmk_len && (pmksa->pmk_len <= CSR_RSN_MAX_PMK_LEN)) {
19406 vos_mem_copy(pmk_cache->pmk, pmksa->pmk, pmksa->pmk_len);
19407 pmk_cache->pmk_len = pmksa->pmk_len;
19408 } else
19409 hddLog(VOS_TRACE_LEVEL_INFO, "pmk len is %zu", pmksa->pmk_len);
19410}
19411#else
19412/*
19413 * wlan_hdd_is_pmksa_valid: API to validate pmksa
19414 * @pmksa: pointer to cfg80211_pmksa structure
19415 *
19416 * Return: True if valid else false
19417 */
19418static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
19419{
19420 if (!pmksa->bssid) {
19421 hddLog(LOGE,FL("both bssid is NULL %p"), pmksa->bssid);
19422 return false;
19423 }
19424 return true;
19425}
19426
19427/*
19428 * hdd_update_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
19429 * @pmk_cache: pmksa from supplicant
19430 * @pmk_cache: pmk needs to be updated
19431 *
19432 * Return: None
19433 */
19434static void hdd_update_pmksa_info(tPmkidCacheInfo *pmk_cache,
19435 struct cfg80211_pmksa *pmksa, bool is_delete)
19436{
19437 hddLog(VOS_TRACE_LEVEL_INFO,"set PMKSA for " MAC_ADDRESS_STR,
19438 MAC_ADDR_ARRAY(pmksa->bssid));
19439 vos_mem_copy(pmk_cache->BSSID,
19440 pmksa->bssid, VOS_MAC_ADDR_SIZE);
19441
19442 if (is_delete)
19443 return;
19444
19445 vos_mem_copy(pmk_cache->PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
19446}
19447#endif
19448
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019449#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019450
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019451static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019452 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019453{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019454 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19455 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019456 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019457 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019458 hdd_context_t *pHddCtx;
Abhinav Kumar8c122592019-08-07 15:43:20 +053019459 tPmkidCacheInfo pmk_cache;
Jeff Johnsone7245742012-09-05 17:12:55 -070019460
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019461 ENTER();
19462
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019463 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019464 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019465 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019466 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019467 return -EINVAL;
19468 }
19469
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019470 if (!pmksa) {
19471 hddLog(LOGE, FL("pmksa is NULL"));
19472 return -EINVAL;
19473 }
19474
Abhinav Kumar8c122592019-08-07 15:43:20 +053019475 if (!pmksa->pmkid) {
19476 hddLog(LOGE, FL("pmksa->pmkid(%p) is NULL"), pmksa->pmkid);
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019477 return -EINVAL;
19478 }
19479
Abhinav Kumar8c122592019-08-07 15:43:20 +053019480 if (!wlan_hdd_is_pmksa_valid(pmksa))
19481 return -EINVAL;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019482
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019483 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19484 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019485 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019486 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019487 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019488 }
19489
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019490 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019491 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19492
Abhinav Kumar8c122592019-08-07 15:43:20 +053019493 vos_mem_zero(&pmk_cache, sizeof(pmk_cache));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019494
Abhinav Kumar8c122592019-08-07 15:43:20 +053019495 hdd_update_pmksa_info(&pmk_cache, pmksa, false);
19496
19497
19498 /* Add to the PMKSA ID Cache in CSR
19499 * PMKSA cache will be having following
19500 * 1. pmkid id
19501 * 2. pmk 15733
19502 * 3. bssid or cache identifier
19503 */
19504 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
19505 &pmk_cache, 1, FALSE);
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019506
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019507 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19508 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19509 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019510
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019511 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019512 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019513}
19514
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019515static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19516 struct cfg80211_pmksa *pmksa)
19517{
19518 int ret;
19519
19520 vos_ssr_protect(__func__);
19521 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19522 vos_ssr_unprotect(__func__);
19523
19524 return ret;
19525}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019526
Wilson Yang6507c4e2013-10-01 20:11:19 -070019527
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019528static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019529 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019530{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019531 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19532 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019533 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019534 int status = 0;
Abhinav Kumar8c122592019-08-07 15:43:20 +053019535 tPmkidCacheInfo pmk_cache;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019537 ENTER();
19538
Wilson Yang6507c4e2013-10-01 20:11:19 -070019539 /* Validate pAdapter */
19540 if (NULL == pAdapter)
19541 {
19542 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19543 return -EINVAL;
19544 }
19545
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019546 if (!pmksa) {
19547 hddLog(LOGE, FL("pmksa is NULL"));
19548 return -EINVAL;
19549 }
19550
Abhinav Kumar8c122592019-08-07 15:43:20 +053019551 if (!wlan_hdd_is_pmksa_valid(pmksa))
19552 return -EINVAL;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019553
Kiet Lam98c46a12014-10-31 15:34:57 -070019554
Wilson Yang6507c4e2013-10-01 20:11:19 -070019555 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19556 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019557 if (0 != status)
19558 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019559 return status;
19560 }
19561
19562 /*Retrieve halHandle*/
19563 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19564
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019565 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19566 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19567 pAdapter->sessionId, 0));
Abhinav Kumar8c122592019-08-07 15:43:20 +053019568
19569 vos_mem_zero(&pmk_cache, sizeof(pmk_cache));
19570
19571 hdd_update_pmksa_info(&pmk_cache, pmksa, true);
19572
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019573 /* Delete the PMKID CSR cache */
19574 if (eHAL_STATUS_SUCCESS !=
19575 sme_RoamDelPMKIDfromCache(halHandle,
Abhinav Kumar8c122592019-08-07 15:43:20 +053019576 pAdapter->sessionId, &pmk_cache, FALSE)) {
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019577 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19578 MAC_ADDR_ARRAY(pmksa->bssid));
19579 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019580 }
19581
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019582 EXIT();
19583 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019584}
19585
Wilson Yang6507c4e2013-10-01 20:11:19 -070019586
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019587static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19588 struct cfg80211_pmksa *pmksa)
19589{
19590 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019591
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019592 vos_ssr_protect(__func__);
19593 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19594 vos_ssr_unprotect(__func__);
19595
19596 return ret;
19597
19598}
19599
19600static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019601{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019602 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19603 tHalHandle halHandle;
19604 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019605 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019606
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019607 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019608
19609 /* Validate pAdapter */
19610 if (NULL == pAdapter)
19611 {
19612 hddLog(VOS_TRACE_LEVEL_ERROR,
19613 "%s: Invalid Adapter" ,__func__);
19614 return -EINVAL;
19615 }
19616
19617 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19618 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019619 if (0 != status)
19620 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019621 return status;
19622 }
19623
19624 /*Retrieve halHandle*/
19625 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19626
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019627 /* Flush the PMKID cache in CSR */
19628 if (eHAL_STATUS_SUCCESS !=
19629 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19630 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19631 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019632 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019633 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019634 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019635}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019636
19637static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19638{
19639 int ret;
19640
19641 vos_ssr_protect(__func__);
19642 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19643 vos_ssr_unprotect(__func__);
19644
19645 return ret;
19646}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019647#endif
19648
Abhinav Kumar118efd02019-08-07 16:41:07 +053019649#if defined(WLAN_FEATURE_SAE) && \
19650 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
19651/**
19652 * __wlan_hdd_cfg80211_external_auth() - Handle external auth
19653 * @wiphy: Pointer to wireless phy
19654 * @dev: net device
19655 * @params: Pointer to external auth params
19656 *
19657 * Return: 0 on success, negative errno on failure
19658 */
19659static int
19660__wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev,
19661 struct cfg80211_external_auth_params *params)
19662{
19663 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19664 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19665 int ret;
19666
19667 if (hdd_get_conparam() == VOS_FTM_MODE) {
19668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Command not allowed in FTM mode"));
19669 return -EPERM;
19670 }
19671
19672 ret = wlan_hdd_validate_context(hdd_ctx);
19673 if (ret)
19674 return ret;
19675
19676 hddLog(VOS_TRACE_LEVEL_DEBUG, FL("external_auth status: %d"),
19677 params->status);
19678
19679 sme_handle_sae_msg(hdd_ctx->hHal, adapter->sessionId, params->status);
19680
19681 return ret;
19682}
19683
19684/**
19685 * wlan_hdd_cfg80211_external_auth() - Handle external auth
19686 * @wiphy: Pointer to wireless phy
19687 * @dev: net device
19688 * @params: Pointer to external auth params
19689 *
19690 * Return: 0 on success, negative errno on failure
19691 */
19692static int
19693wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
19694 struct net_device *dev,
19695 struct cfg80211_external_auth_params *params)
19696{
19697 int ret;
19698
19699 vos_ssr_protect(__func__);
19700 ret = __wlan_hdd_cfg80211_external_auth(wiphy, dev, params);
19701 vos_ssr_unprotect(__func__);
19702
19703 return ret;
19704}
19705#endif
19706
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019707#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019708static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19709 struct net_device *dev,
19710 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019711{
19712 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19713 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019714 hdd_context_t *pHddCtx;
19715 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019716
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019717 ENTER();
19718
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019719 if (NULL == pAdapter)
19720 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019721 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019722 return -ENODEV;
19723 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019724 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19725 ret = wlan_hdd_validate_context(pHddCtx);
19726 if (0 != ret)
19727 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019728 return ret;
19729 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019730 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019731 if (NULL == pHddStaCtx)
19732 {
19733 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19734 return -EINVAL;
19735 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019736
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019737 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19738 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19739 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019740 // Added for debug on reception of Re-assoc Req.
19741 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19742 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019743 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019744 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019745 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019746 }
19747
19748#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Abhinav Kumar36177e12018-10-30 11:55:48 +053019749 hddLog(LOG1, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019750 ftie->ie_len);
19751#endif
19752
19753 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019754 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19755 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019756 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019757
19758 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019759 return 0;
19760}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019761
19762static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19763 struct net_device *dev,
19764 struct cfg80211_update_ft_ies_params *ftie)
19765{
19766 int ret;
19767
19768 vos_ssr_protect(__func__);
19769 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19770 vos_ssr_unprotect(__func__);
19771
19772 return ret;
19773}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019774#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019775
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019776#ifdef FEATURE_WLAN_SCAN_PNO
19777
19778void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19779 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19780{
19781 int ret;
19782 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19783 hdd_context_t *pHddCtx;
19784
Nirav Shah80830bf2013-12-31 16:35:12 +053019785 ENTER();
19786
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019787 if (NULL == pAdapter)
19788 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019789 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019790 "%s: HDD adapter is Null", __func__);
19791 return ;
19792 }
19793
19794 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19795 if (NULL == pHddCtx)
19796 {
19797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19798 "%s: HDD context is Null!!!", __func__);
19799 return ;
19800 }
19801
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019802 spin_lock(&pHddCtx->schedScan_lock);
19803 if (TRUE == pHddCtx->isWiphySuspended)
19804 {
19805 pHddCtx->isSchedScanUpdatePending = TRUE;
19806 spin_unlock(&pHddCtx->schedScan_lock);
19807 hddLog(VOS_TRACE_LEVEL_INFO,
19808 "%s: Update cfg80211 scan database after it resume", __func__);
19809 return ;
19810 }
19811 spin_unlock(&pHddCtx->schedScan_lock);
19812
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019813 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19814
19815 if (0 > ret)
19816 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019817 else
19818 {
19819 /* Acquire wakelock to handle the case where APP's tries to suspend
19820 * immediatly after the driver gets connect request(i.e after pno)
19821 * from supplicant, this result in app's is suspending and not able
19822 * to process the connect request to AP */
19823 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19824 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019825 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19827 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019828}
19829
19830/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019831 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019832 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019833 */
19834static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19835{
19836 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19837 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019838 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019839 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19840 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019841
19842 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19843 {
19844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19845 "%s: PNO is allowed only in STA interface", __func__);
19846 return eHAL_STATUS_FAILURE;
19847 }
19848
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019849 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19850
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019851 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019852 * active sessions. PNO is allowed only in case when sap session
19853 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019854 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019855 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19856 {
19857 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019858 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019859
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019860 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19861 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19862 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19863 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019864 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19865 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019866 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019867 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019868 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019869 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019870 }
19871 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19872 pAdapterNode = pNext;
19873 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019874 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019875}
19876
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019877void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19878{
19879 hdd_adapter_t *pAdapter = callbackContext;
19880 hdd_context_t *pHddCtx;
19881
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019882 ENTER();
19883
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019884 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19885 {
19886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19887 FL("Invalid adapter or adapter has invalid magic"));
19888 return;
19889 }
19890
19891 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19892 if (0 != wlan_hdd_validate_context(pHddCtx))
19893 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019894 return;
19895 }
19896
c_hpothub53c45d2014-08-18 16:53:14 +053019897 if (VOS_STATUS_SUCCESS != status)
19898 {
19899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019900 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019901 pHddCtx->isPnoEnable = FALSE;
19902 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019903
19904 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19905 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019906 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019907}
19908
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19910 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19911/**
19912 * hdd_config_sched_scan_plan() - configures the sched scan plans
19913 * from the framework.
19914 * @pno_req: pointer to PNO scan request
19915 * @request: pointer to scan request from framework
19916 *
19917 * Return: None
19918 */
19919static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19920 struct cfg80211_sched_scan_request *request,
19921 hdd_context_t *hdd_ctx)
19922{
19923 v_U32_t i = 0;
19924
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019925 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019926 for (i = 0; i < request->n_scan_plans; i++)
19927 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019928 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19929 request->scan_plans[i].iterations;
19930 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19931 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019932 }
19933}
19934#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019935static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019936 struct cfg80211_sched_scan_request *request,
19937 hdd_context_t *hdd_ctx)
19938{
19939 v_U32_t i, temp_int;
19940 /* Driver gets only one time interval which is hardcoded in
19941 * supplicant for 10000ms. Taking power consumption into account 6
19942 * timers will be used, Timervalue is increased exponentially
19943 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19944 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19945 * If it is set to 0 only one timer will be used and PNO scan cycle
19946 * will be repeated after each interval specified by supplicant
19947 * till PNO is disabled.
19948 */
19949 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019950 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019951 HDD_PNO_SCAN_TIMERS_SET_ONE;
19952 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019953 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019954 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19955
19956 temp_int = (request->interval)/1000;
19957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19958 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19959 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019960 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019961 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019962 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019963 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019964 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019965 temp_int *= 2;
19966 }
19967 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019968 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019969}
19970#endif
19971
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019972/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019973 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19974 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019975 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019976static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019977 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19978{
19979 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019980 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019981 hdd_context_t *pHddCtx;
19982 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019983 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019984 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19985 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019986 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19987 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019988 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019989 hdd_config_t *pConfig = NULL;
19990 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019991
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019992 ENTER();
19993
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019994 if (NULL == pAdapter)
19995 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019997 "%s: HDD adapter is Null", __func__);
19998 return -ENODEV;
19999 }
20000
20001 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020002 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020003
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020004 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020005 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020006 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020007 }
20008
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053020009 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020010 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20011 if (NULL == hHal)
20012 {
20013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20014 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020015 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020016 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020017 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20018 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
20019 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053020020 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053020021 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053020022 {
20023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20024 "%s: aborting the existing scan is unsuccessfull", __func__);
20025 return -EBUSY;
20026 }
20027
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053020028 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053020029 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053020030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053020031 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053020032 return -EBUSY;
20033 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020034
c_hpothu37f21312014-04-09 21:49:54 +053020035 if (TRUE == pHddCtx->isPnoEnable)
20036 {
20037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
20038 FL("already PNO is enabled"));
20039 return -EBUSY;
20040 }
c_hpothu225aa7c2014-10-22 17:45:13 +053020041
20042 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
20043 {
20044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20045 "%s: abort ROC failed ", __func__);
20046 return -EBUSY;
20047 }
20048
c_hpothu37f21312014-04-09 21:49:54 +053020049 pHddCtx->isPnoEnable = TRUE;
20050
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020051 pnoRequest.enable = 1; /*Enable PNO */
20052 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020053
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020054 if (( !pnoRequest.ucNetworksCount ) ||
20055 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020056 {
20057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053020058 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020059 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053020060 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020061 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020062 goto error;
20063 }
20064
20065 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
20066 {
20067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053020068 "%s: Incorrect number of channels %d",
20069 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020070 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020071 goto error;
20072 }
20073
20074 /* Framework provides one set of channels(all)
20075 * common for all saved profile */
20076 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
20077 channels_allowed, &num_channels_allowed))
20078 {
20079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20080 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020081 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020082 goto error;
20083 }
20084 /* Checking each channel against allowed channel list */
20085 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053020086 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020087 {
Nirav Shah80830bf2013-12-31 16:35:12 +053020088 char chList [(request->n_channels*5)+1];
20089 int len;
20090 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020091 {
Nirav Shah80830bf2013-12-31 16:35:12 +053020092 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020093 {
Nirav Shah80830bf2013-12-31 16:35:12 +053020094 if (request->channels[i]->hw_value == channels_allowed[indx])
20095 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053020096 if ((!pConfig->enableDFSPnoChnlScan) &&
20097 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
20098 {
20099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20100 "%s : Dropping DFS channel : %d",
20101 __func__,channels_allowed[indx]);
20102 num_ignore_dfs_ch++;
20103 break;
20104 }
20105
Nirav Shah80830bf2013-12-31 16:35:12 +053020106 valid_ch[num_ch++] = request->channels[i]->hw_value;
20107 len += snprintf(chList+len, 5, "%d ",
20108 request->channels[i]->hw_value);
20109 break ;
20110 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020111 }
20112 }
Nirav Shah80830bf2013-12-31 16:35:12 +053020113 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020114
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053020115 /*If all channels are DFS and dropped, then ignore the PNO request*/
20116 if (num_ignore_dfs_ch == request->n_channels)
20117 {
20118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20119 "%s : All requested channels are DFS channels", __func__);
20120 ret = -EINVAL;
20121 goto error;
20122 }
20123 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020124
20125 pnoRequest.aNetworks =
20126 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
20127 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020128 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020129 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
20130 FL("failed to allocate memory aNetworks %u"),
20131 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
20132 goto error;
20133 }
20134 vos_mem_zero(pnoRequest.aNetworks,
20135 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
20136
20137 /* Filling per profile params */
20138 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
20139 {
20140 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020141 request->match_sets[i].ssid.ssid_len;
20142
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020143 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
20144 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020145 {
20146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053020147 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020148 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020149 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020150 goto error;
20151 }
20152
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020153 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020154 request->match_sets[i].ssid.ssid,
20155 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053020156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20157 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020158 i, pnoRequest.aNetworks[i].ssId.ssId);
20159 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
20160 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
20161 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020162
20163 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020164 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
20165 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020166
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020167 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020168 }
20169
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020170 for (i = 0; i < request->n_ssids; i++)
20171 {
20172 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020173 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020174 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020175 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020176 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020177 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020178 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020179 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020180 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020181 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020182 break;
20183 }
20184 j++;
20185 }
20186 }
20187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20188 "Number of hidden networks being Configured = %d",
20189 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053020190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080020191 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020192
20193 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
20194 if (pnoRequest.p24GProbeTemplate == NULL)
20195 {
20196 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
20197 FL("failed to allocate memory p24GProbeTemplate %u"),
20198 SIR_PNO_MAX_PB_REQ_SIZE);
20199 goto error;
20200 }
20201
20202 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
20203 if (pnoRequest.p5GProbeTemplate == NULL)
20204 {
20205 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
20206 FL("failed to allocate memory p5GProbeTemplate %u"),
20207 SIR_PNO_MAX_PB_REQ_SIZE);
20208 goto error;
20209 }
20210
20211 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
20212 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
20213
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053020214 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
20215 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053020216 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020217 pnoRequest.us24GProbeTemplateLen = request->ie_len;
20218 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
20219 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053020220
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020221 pnoRequest.us5GProbeTemplateLen = request->ie_len;
20222 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
20223 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053020224 }
20225
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053020226 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053020227
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020228 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020229
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020230 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020231 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
20232 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020233 pAdapter->pno_req_status = 0;
20234
Nirav Shah80830bf2013-12-31 16:35:12 +053020235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20236 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020237 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
20238 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053020239
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020240 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020241 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020242 hdd_cfg80211_sched_scan_done_callback, pAdapter);
20243 if (eHAL_STATUS_SUCCESS != status)
20244 {
20245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053020246 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020247 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020248 goto error;
20249 }
20250
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020251 ret = wait_for_completion_timeout(
20252 &pAdapter->pno_comp_var,
20253 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
20254 if (0 >= ret)
20255 {
20256 // Did not receive the response for PNO enable in time.
20257 // Assuming the PNO enable was success.
20258 // Returning error from here, because we timeout, results
20259 // in side effect of Wifi (Wifi Setting) not to work.
20260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20261 FL("Timed out waiting for PNO to be Enabled"));
20262 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020263 }
20264
20265 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053020266 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020267
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020268error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20270 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053020271 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020272 if (pnoRequest.aNetworks)
20273 vos_mem_free(pnoRequest.aNetworks);
20274 if (pnoRequest.p24GProbeTemplate)
20275 vos_mem_free(pnoRequest.p24GProbeTemplate);
20276 if (pnoRequest.p5GProbeTemplate)
20277 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020278
20279 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020280 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020281}
20282
20283/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020284 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
20285 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020286 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020287static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
20288 struct net_device *dev, struct cfg80211_sched_scan_request *request)
20289{
20290 int ret;
20291
20292 vos_ssr_protect(__func__);
20293 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
20294 vos_ssr_unprotect(__func__);
20295
20296 return ret;
20297}
20298
20299/*
20300 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
20301 * Function to disable PNO
20302 */
20303static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020304 struct net_device *dev)
20305{
20306 eHalStatus status = eHAL_STATUS_FAILURE;
20307 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20308 hdd_context_t *pHddCtx;
20309 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020310 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020311 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020312
20313 ENTER();
20314
20315 if (NULL == pAdapter)
20316 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020318 "%s: HDD adapter is Null", __func__);
20319 return -ENODEV;
20320 }
20321
20322 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020323
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020324 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020325 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020326 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020327 "%s: HDD context is Null", __func__);
20328 return -ENODEV;
20329 }
20330
20331 /* The return 0 is intentional when isLogpInProgress and
20332 * isLoadUnloadInProgress. We did observe a crash due to a return of
20333 * failure in sched_scan_stop , especially for a case where the unload
20334 * of the happens at the same time. The function __cfg80211_stop_sched_scan
20335 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
20336 * success. If it returns a failure , then its next invocation due to the
20337 * clean up of the second interface will have the dev pointer corresponding
20338 * to the first one leading to a crash.
20339 */
20340 if (pHddCtx->isLogpInProgress)
20341 {
20342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20343 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053020344 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020345 return ret;
20346 }
20347
Mihir Shete18156292014-03-11 15:38:30 +053020348 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020349 {
20350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20351 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20352 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020353 }
20354
20355 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20356 if (NULL == hHal)
20357 {
20358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20359 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020360 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020361 }
20362
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020363 pnoRequest.enable = 0; /* Disable PNO */
20364 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020365
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020366 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20367 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
20368 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053020369
20370 INIT_COMPLETION(pAdapter->pno_comp_var);
20371 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
20372 pnoRequest.callbackContext = pAdapter;
20373 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020374 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020375 pAdapter->sessionId,
20376 NULL, pAdapter);
20377 if (eHAL_STATUS_SUCCESS != status)
20378 {
20379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20380 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020381 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020382 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020383 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053020384 ret = wait_for_completion_timeout(
20385 &pAdapter->pno_comp_var,
20386 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
20387 if (0 >= ret)
20388 {
20389 // Did not receive the response for PNO disable in time.
20390 // Assuming the PNO disable was success.
20391 // Returning error from here, because we timeout, results
20392 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053020393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053020394 FL("Timed out waiting for PNO to be disabled"));
20395 ret = 0;
20396 }
20397
20398 ret = pAdapter->pno_req_status;
20399 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020400
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020401error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020402 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020403 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020404
20405 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020406 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020407}
20408
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020409/*
20410 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
20411 * NL interface to disable PNO
20412 */
20413static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
20414 struct net_device *dev)
20415{
20416 int ret;
20417
20418 vos_ssr_protect(__func__);
20419 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
20420 vos_ssr_unprotect(__func__);
20421
20422 return ret;
20423}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020424#endif /*FEATURE_WLAN_SCAN_PNO*/
20425
20426
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020427#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020428#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020429static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20430 struct net_device *dev,
20431 u8 *peer, u8 action_code,
20432 u8 dialog_token,
20433 u16 status_code, u32 peer_capability,
20434 const u8 *buf, size_t len)
20435#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020436#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20437 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020438static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20439 struct net_device *dev,
20440 const u8 *peer, u8 action_code,
20441 u8 dialog_token, u16 status_code,
20442 u32 peer_capability, bool initiator,
20443 const u8 *buf, size_t len)
20444#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20445static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20446 struct net_device *dev,
20447 const u8 *peer, u8 action_code,
20448 u8 dialog_token, u16 status_code,
20449 u32 peer_capability, const u8 *buf,
20450 size_t len)
20451#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20452static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20453 struct net_device *dev,
20454 u8 *peer, u8 action_code,
20455 u8 dialog_token,
20456 u16 status_code, u32 peer_capability,
20457 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020458#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020459static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20460 struct net_device *dev,
20461 u8 *peer, u8 action_code,
20462 u8 dialog_token,
20463 u16 status_code, const u8 *buf,
20464 size_t len)
20465#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020466#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020467{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020468 hdd_adapter_t *pAdapter;
20469 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020470 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070020471 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080020472 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070020473 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020474 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020475 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020476#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020477 u32 peer_capability = 0;
20478#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020479 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020480 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020481 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020482
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020483 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20484 if (NULL == pAdapter)
20485 {
20486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20487 "%s: Adapter is NULL",__func__);
20488 return -EINVAL;
20489 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020490 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20491 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
20492 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020493
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020494 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020495 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020496 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020498 "Invalid arguments");
20499 return -EINVAL;
20500 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020501
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020502 if (pHddCtx->isLogpInProgress)
20503 {
20504 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20505 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053020506 wlan_hdd_tdls_set_link_status(pAdapter,
20507 peer,
20508 eTDLS_LINK_IDLE,
20509 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020510 return -EBUSY;
20511 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020512
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020513 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20514 {
20515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20516 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20517 return -EAGAIN;
20518 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020519
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020520 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20521 if (!pHddTdlsCtx) {
20522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20523 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020524 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020525 }
20526
Hoonki Lee27511902013-03-14 18:19:06 -070020527 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020528 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020530 "%s: TDLS mode is disabled OR not enabled in FW."
20531 MAC_ADDRESS_STR " action %d declined.",
20532 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020533 return -ENOTSUPP;
20534 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020535
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020536 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20537
20538 if( NULL == pHddStaCtx )
20539 {
20540 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20541 "%s: HDD station context NULL ",__func__);
20542 return -EINVAL;
20543 }
20544
20545 /* STA should be connected and authenticated
20546 * before sending any TDLS frames
20547 */
20548 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20549 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20550 {
20551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20552 "STA is not connected or unauthenticated. "
20553 "connState %u, uIsAuthenticated %u",
20554 pHddStaCtx->conn_info.connState,
20555 pHddStaCtx->conn_info.uIsAuthenticated);
20556 return -EAGAIN;
20557 }
20558
Hoonki Lee27511902013-03-14 18:19:06 -070020559 /* other than teardown frame, other mgmt frames are not sent if disabled */
20560 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20561 {
20562 /* if tdls_mode is disabled to respond to peer's request */
20563 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20564 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020566 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020567 " TDLS mode is disabled. action %d declined.",
20568 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020569
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020570 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020571 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020572
20573 if (vos_max_concurrent_connections_reached())
20574 {
20575 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20576 return -EINVAL;
20577 }
Hoonki Lee27511902013-03-14 18:19:06 -070020578 }
20579
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020580 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20581 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020582 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020583 {
20584 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020585 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020586 " TDLS setup is ongoing. action %d declined.",
20587 __func__, MAC_ADDR_ARRAY(peer), action_code);
20588 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020589 }
20590 }
20591
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020592 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20593 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020594 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020595 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20596 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020597 {
20598 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20599 we return error code at 'add_station()'. Hence we have this
20600 check again in addtion to add_station().
20601 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020602 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020603 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20605 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020606 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20607 __func__, MAC_ADDR_ARRAY(peer), action_code,
20608 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020609 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020610 }
20611 else
20612 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020613 /* maximum reached. tweak to send error code to peer and return
20614 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020615 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20617 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020618 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20619 __func__, MAC_ADDR_ARRAY(peer), status_code,
20620 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020621 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020622 /* fall through to send setup resp with failure status
20623 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020624 }
20625 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020626 else
20627 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020628 mutex_lock(&pHddCtx->tdls_lock);
20629 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020630 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020631 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020632 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020634 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20635 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020636 return -EPERM;
20637 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020638 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020639 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020640 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020641
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020642 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020643 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020644 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20645 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020646
Hoonki Leea34dd892013-02-05 22:56:02 -080020647 /*Except teardown responder will not be used so just make 0*/
20648 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020649 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020650 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020651
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020652 mutex_lock(&pHddCtx->tdls_lock);
20653 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020654
20655 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20656 responder = pTdlsPeer->is_responder;
20657 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020658 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020659 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020660 "%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 -070020661 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20662 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020663 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020664 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020665 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020666 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020667 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020668
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020669 /* Discard TDLS setup if peer is removed by user app */
20670 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20671 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20672 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20673 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20674
20675 mutex_lock(&pHddCtx->tdls_lock);
20676 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20677 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20678 mutex_unlock(&pHddCtx->tdls_lock);
20679 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20680 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20681 MAC_ADDR_ARRAY(peer), action_code);
20682 return -EINVAL;
20683 }
20684 mutex_unlock(&pHddCtx->tdls_lock);
20685 }
20686
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020687 /* For explicit trigger of DIS_REQ come out of BMPS for
20688 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020689 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020690 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020691 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20692 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020693 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020694 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020696 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20697 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020698 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20699 if (status != VOS_STATUS_SUCCESS) {
20700 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020701 } else {
20702 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020703 }
Hoonki Lee14621352013-04-16 17:51:19 -070020704 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020705 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020706 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20708 }
20709 }
Hoonki Lee14621352013-04-16 17:51:19 -070020710 }
20711
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020712 /* make sure doesn't call send_mgmt() while it is pending */
20713 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20714 {
20715 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020716 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020717 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020718 ret = -EBUSY;
20719 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020720 }
20721
20722 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020723 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20724
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020725 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20726 pAdapter->sessionId, peer, action_code, dialog_token,
20727 status_code, peer_capability, (tANI_U8 *)buf, len,
20728 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020729
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020730 if (VOS_STATUS_SUCCESS != status)
20731 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20733 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020734 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020735 ret = -EINVAL;
20736 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020737 }
20738
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20740 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20741 WAIT_TIME_TDLS_MGMT);
20742
Hoonki Leed37cbb32013-04-20 00:31:14 -070020743 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20744 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20745
20746 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020747 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020749 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020750 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020751 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020752
20753 if (pHddCtx->isLogpInProgress)
20754 {
20755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20756 "%s: LOGP in Progress. Ignore!!!", __func__);
20757 return -EAGAIN;
20758 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020759 if (rc <= 0)
20760 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20761 WLAN_LOG_INDICATOR_HOST_DRIVER,
20762 WLAN_LOG_REASON_HDD_TIME_OUT,
20763 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020764
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020765 ret = -EINVAL;
20766 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020767 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020768 else
20769 {
20770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20771 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20772 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20773 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020774
Gopichand Nakkala05922802013-03-14 12:23:19 -070020775 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020776 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020777 ret = max_sta_failed;
20778 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020779 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020780
Hoonki Leea34dd892013-02-05 22:56:02 -080020781 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20782 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020783 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20785 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020786 }
20787 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20788 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020789 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20791 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020792 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020793
20794 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020795
20796tx_failed:
20797 /* add_station will be called before sending TDLS_SETUP_REQ and
20798 * TDLS_SETUP_RSP and as part of add_station driver will enable
20799 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20800 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20801 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20802 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20803 */
20804
20805 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20806 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20807 wlan_hdd_tdls_check_bmps(pAdapter);
20808 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020809}
20810
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020811#if TDLS_MGMT_VERSION2
20812static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20813 u8 *peer, u8 action_code, u8 dialog_token,
20814 u16 status_code, u32 peer_capability,
20815 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020816#else /* TDLS_MGMT_VERSION2 */
20817#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20818static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20819 struct net_device *dev,
20820 const u8 *peer, u8 action_code,
20821 u8 dialog_token, u16 status_code,
20822 u32 peer_capability, bool initiator,
20823 const u8 *buf, size_t len)
20824#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20825static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20826 struct net_device *dev,
20827 const u8 *peer, u8 action_code,
20828 u8 dialog_token, u16 status_code,
20829 u32 peer_capability, const u8 *buf,
20830 size_t len)
20831#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20832static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20833 struct net_device *dev,
20834 u8 *peer, u8 action_code,
20835 u8 dialog_token,
20836 u16 status_code, u32 peer_capability,
20837 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020838#else
20839static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20840 u8 *peer, u8 action_code, u8 dialog_token,
20841 u16 status_code, const u8 *buf, size_t len)
20842#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020843#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020844{
20845 int ret;
20846
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020847 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020848#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020849 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20850 dialog_token, status_code,
20851 peer_capability, buf, len);
20852#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020853#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20854 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020855 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20856 dialog_token, status_code,
20857 peer_capability, initiator,
20858 buf, len);
20859#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20860 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20861 dialog_token, status_code,
20862 peer_capability, buf, len);
20863#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20864 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20865 dialog_token, status_code,
20866 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020867#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020868 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20869 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020870#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020871#endif
20872 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020873
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020874 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020875}
Atul Mittal115287b2014-07-08 13:26:33 +053020876
20877int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020878#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20879 const u8 *peer,
20880#else
Atul Mittal115287b2014-07-08 13:26:33 +053020881 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020882#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020883 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020884 cfg80211_exttdls_callback callback)
20885{
20886
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020887 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020888 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020889 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020890 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20891 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20892 __func__, MAC_ADDR_ARRAY(peer));
20893
20894 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20895 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20896
20897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020898 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20899 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20900 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020901 return -ENOTSUPP;
20902 }
20903
20904 /* To cater the requirement of establishing the TDLS link
20905 * irrespective of the data traffic , get an entry of TDLS peer.
20906 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020907 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020908 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20909 if (pTdlsPeer == NULL) {
20910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20911 "%s: peer " MAC_ADDRESS_STR " not existing",
20912 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020913 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020914 return -EINVAL;
20915 }
20916
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020917 /* check FW TDLS Off Channel capability */
20918 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020919 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020920 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020921 {
20922 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20923 pTdlsPeer->peerParams.global_operating_class =
20924 tdls_peer_params->global_operating_class;
20925 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20926 pTdlsPeer->peerParams.min_bandwidth_kbps =
20927 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020928 /* check configured channel is valid, non dfs and
20929 * not current operating channel */
20930 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20931 tdls_peer_params->channel)) &&
20932 (pHddStaCtx) &&
20933 (tdls_peer_params->channel !=
20934 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020935 {
20936 pTdlsPeer->isOffChannelConfigured = TRUE;
20937 }
20938 else
20939 {
20940 pTdlsPeer->isOffChannelConfigured = FALSE;
20941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20942 "%s: Configured Tdls Off Channel is not valid", __func__);
20943
20944 }
20945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020946 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20947 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020948 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020949 pTdlsPeer->isOffChannelConfigured,
20950 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020951 }
20952 else
20953 {
20954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020955 "%s: TDLS off channel FW capability %d, "
20956 "host capab %d or Invalid TDLS Peer Params", __func__,
20957 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20958 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020959 }
20960
Atul Mittal115287b2014-07-08 13:26:33 +053020961 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20962
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020963 mutex_unlock(&pHddCtx->tdls_lock);
20964
Atul Mittal115287b2014-07-08 13:26:33 +053020965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20966 " %s TDLS Add Force Peer Failed",
20967 __func__);
20968 return -EINVAL;
20969 }
20970 /*EXT TDLS*/
20971
20972 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020973 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20975 " %s TDLS set callback Failed",
20976 __func__);
20977 return -EINVAL;
20978 }
20979
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020980 mutex_unlock(&pHddCtx->tdls_lock);
20981
Atul Mittal115287b2014-07-08 13:26:33 +053020982 return(0);
20983
20984}
20985
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020986int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20987#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20988 const u8 *peer
20989#else
20990 u8 *peer
20991#endif
20992)
Atul Mittal115287b2014-07-08 13:26:33 +053020993{
20994
20995 hddTdlsPeer_t *pTdlsPeer;
20996 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020997
Atul Mittal115287b2014-07-08 13:26:33 +053020998 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20999 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
21000 __func__, MAC_ADDR_ARRAY(peer));
21001
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053021002 if (0 != wlan_hdd_validate_context(pHddCtx)) {
21003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
21004 return -EINVAL;
21005 }
21006
Atul Mittal115287b2014-07-08 13:26:33 +053021007 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
21008 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
21009
21010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021011 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
21012 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
21013 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053021014 return -ENOTSUPP;
21015 }
21016
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021017 mutex_lock(&pHddCtx->tdls_lock);
21018 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053021019
21020 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021021 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053021022 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021023 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053021024 __func__, MAC_ADDR_ARRAY(peer));
21025 return -EINVAL;
21026 }
21027 else {
21028 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
21029 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053021030 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
21031 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021032 /* if channel switch is configured, reset
21033 the channel for this peer */
21034 if (TRUE == pTdlsPeer->isOffChannelConfigured)
21035 {
21036 pTdlsPeer->peerParams.channel = 0;
21037 pTdlsPeer->isOffChannelConfigured = FALSE;
21038 }
Atul Mittal115287b2014-07-08 13:26:33 +053021039 }
21040
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021041 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021042 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021043 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053021044 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021045 }
Atul Mittal115287b2014-07-08 13:26:33 +053021046
21047 /*EXT TDLS*/
21048
21049 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021050 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053021051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21052 " %s TDLS set callback Failed",
21053 __func__);
21054 return -EINVAL;
21055 }
Atul Mittal115287b2014-07-08 13:26:33 +053021056
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021057 mutex_unlock(&pHddCtx->tdls_lock);
21058
21059 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053021060}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021061static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21063 const u8 *peer,
21064#else
21065 u8 *peer,
21066#endif
21067 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021068{
21069 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21070 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021071 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021072 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021073
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021074 ENTER();
21075
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053021076 if (!pAdapter) {
21077 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
21078 return -EINVAL;
21079 }
21080
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021081 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21082 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
21083 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021084 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021085 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080021086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070021087 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021088 return -EINVAL;
21089 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080021090
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021091 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021092 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080021093 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021094 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080021095 }
21096
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021097
21098 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080021099 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021100 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080021101 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021102 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
21103 "Cannot process TDLS commands",
21104 pHddCtx->cfg_ini->fEnableTDLSSupport,
21105 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021106 return -ENOTSUPP;
21107 }
21108
21109 switch (oper) {
21110 case NL80211_TDLS_ENABLE_LINK:
21111 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021112 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021113 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053021114 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
21115 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053021116 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021117 tANI_U16 numCurrTdlsPeers = 0;
21118 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021119 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021120 tSirMacAddr peerMac;
21121 int channel;
21122 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021123
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21125 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
21126 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021127
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021128 mutex_lock(&pHddCtx->tdls_lock);
21129 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053021130 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053021131 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021132 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021133 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21134 " (oper %d) not exsting. ignored",
21135 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21136 return -EINVAL;
21137 }
21138
21139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21140 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21141 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21142 "NL80211_TDLS_ENABLE_LINK");
21143
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070021144 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
21145 {
21146 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
21147 MAC_ADDRESS_STR " failed",
21148 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021149 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070021150 return -EINVAL;
21151 }
21152
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021153 /* before starting tdls connection, set tdls
21154 * off channel established status to default value */
21155 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021156
21157 mutex_unlock(&pHddCtx->tdls_lock);
21158
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053021159 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021160 /* TDLS Off Channel, Disable tdls channel switch,
21161 when there are more than one tdls link */
21162 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053021163 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021164 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021165 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021166 /* get connected peer and send disable tdls off chan */
21167 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021168 if ((connPeer) &&
21169 (connPeer->isOffChannelSupported == TRUE) &&
21170 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021171 {
21172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21173 "%s: More then one peer connected, Disable "
21174 "TDLS channel switch", __func__);
21175
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021176 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021177 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
21178 channel = connPeer->peerParams.channel;
21179
21180 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021181
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021182 ret = sme_SendTdlsChanSwitchReq(
21183 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021184 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021185 peerMac,
21186 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021187 TDLS_OFF_CHANNEL_BW_OFFSET,
21188 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021189 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021190 hddLog(VOS_TRACE_LEVEL_ERROR,
21191 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021192 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021193 }
21194 else
21195 {
21196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21197 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021198 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021199 "isOffChannelConfigured %d",
21200 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021201 (connPeer ? (connPeer->isOffChannelSupported)
21202 : -1),
21203 (connPeer ? (connPeer->isOffChannelConfigured)
21204 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021205 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021206 }
21207 }
21208
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021209 mutex_lock(&pHddCtx->tdls_lock);
21210 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21211 if ( NULL == pTdlsPeer ) {
21212 mutex_unlock(&pHddCtx->tdls_lock);
21213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21214 "%s: " MAC_ADDRESS_STR
21215 " (oper %d) peer got freed in other context. ignored",
21216 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21217 return -EINVAL;
21218 }
21219 peer_status = pTdlsPeer->link_status;
21220 mutex_unlock(&pHddCtx->tdls_lock);
21221
21222 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021223 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021224 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053021225
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021226 if (0 != wlan_hdd_tdls_get_link_establish_params(
21227 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021229 return -EINVAL;
21230 }
21231 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021232
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021233 ret = sme_SendTdlsLinkEstablishParams(
21234 WLAN_HDD_GET_HAL_CTX(pAdapter),
21235 pAdapter->sessionId, peer,
21236 &tdlsLinkEstablishParams);
21237 if (ret != VOS_STATUS_SUCCESS) {
21238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
21239 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021240 /* Send TDLS peer UAPSD capabilities to the firmware and
21241 * register with the TL on after the response for this operation
21242 * is received .
21243 */
21244 ret = wait_for_completion_interruptible_timeout(
21245 &pAdapter->tdls_link_establish_req_comp,
21246 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053021247
21248 mutex_lock(&pHddCtx->tdls_lock);
21249 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21250 if ( NULL == pTdlsPeer ) {
21251 mutex_unlock(&pHddCtx->tdls_lock);
21252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21253 "%s %d: " MAC_ADDRESS_STR
21254 " (oper %d) peer got freed in other context. ignored",
21255 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
21256 (int)oper);
21257 return -EINVAL;
21258 }
21259 peer_status = pTdlsPeer->link_status;
21260 mutex_unlock(&pHddCtx->tdls_lock);
21261
21262 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021263 {
21264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021265 FL("Link Establish Request Failed Status %ld"),
21266 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021267 return -EINVAL;
21268 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021269 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021270
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021271 mutex_lock(&pHddCtx->tdls_lock);
21272 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21273 if ( NULL == pTdlsPeer ) {
21274 mutex_unlock(&pHddCtx->tdls_lock);
21275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21276 "%s: " MAC_ADDRESS_STR
21277 " (oper %d) peer got freed in other context. ignored",
21278 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21279 return -EINVAL;
21280 }
21281
Atul Mittal115287b2014-07-08 13:26:33 +053021282 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21283 eTDLS_LINK_CONNECTED,
21284 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053021285 staDesc.ucSTAId = pTdlsPeer->staId;
21286 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053021287
21288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21289 "%s: tdlsLinkEstablishParams of peer "
21290 MAC_ADDRESS_STR "uapsdQueues: %d"
21291 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
21292 "isResponder: %d peerstaId: %d",
21293 __func__,
21294 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
21295 tdlsLinkEstablishParams.uapsdQueues,
21296 tdlsLinkEstablishParams.qos,
21297 tdlsLinkEstablishParams.maxSp,
21298 tdlsLinkEstablishParams.isBufSta,
21299 tdlsLinkEstablishParams.isOffChannelSupported,
21300 tdlsLinkEstablishParams.isResponder,
21301 pTdlsPeer->staId);
21302
21303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21304 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
21305 __func__,
21306 staDesc.ucSTAId,
21307 staDesc.ucQosEnabled);
21308
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021309 ret = WLANTL_UpdateTdlsSTAClient(
21310 pHddCtx->pvosContext,
21311 &staDesc);
21312 if (ret != VOS_STATUS_SUCCESS) {
21313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
21314 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053021315
Gopichand Nakkala471708b2013-06-04 20:03:01 +053021316 /* Mark TDLS client Authenticated .*/
21317 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
21318 pTdlsPeer->staId,
21319 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070021320 if (VOS_STATUS_SUCCESS == status)
21321 {
Hoonki Lee14621352013-04-16 17:51:19 -070021322 if (pTdlsPeer->is_responder == 0)
21323 {
21324 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053021325 tdlsConnInfo_t *tdlsInfo;
21326
21327 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
21328
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053021329 if (!vos_timer_is_initialized(
21330 &pTdlsPeer->initiatorWaitTimeoutTimer))
21331 {
21332 /* Initialize initiator wait callback */
21333 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053021334 &pTdlsPeer->initiatorWaitTimeoutTimer,
21335 VOS_TIMER_TYPE_SW,
21336 wlan_hdd_tdls_initiator_wait_cb,
21337 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053021338 }
Hoonki Lee14621352013-04-16 17:51:19 -070021339 wlan_hdd_tdls_timer_restart(pAdapter,
21340 &pTdlsPeer->initiatorWaitTimeoutTimer,
21341 WAIT_TIME_TDLS_INITIATOR);
21342 /* suspend initiator TX until it receives direct packet from the
21343 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021344 ret = WLANTL_SuspendDataTx(
21345 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21346 &staId, NULL);
21347 if (ret != VOS_STATUS_SUCCESS) {
21348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
21349 }
Hoonki Lee14621352013-04-16 17:51:19 -070021350 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021351
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021352 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021353 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021354 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021355 suppChannelLen =
21356 tdlsLinkEstablishParams.supportedChannelsLen;
21357
21358 if ((suppChannelLen > 0) &&
21359 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
21360 {
21361 tANI_U8 suppPeerChannel = 0;
21362 int i = 0;
21363 for (i = 0U; i < suppChannelLen; i++)
21364 {
21365 suppPeerChannel =
21366 tdlsLinkEstablishParams.supportedChannels[i];
21367
21368 pTdlsPeer->isOffChannelSupported = FALSE;
21369 if (suppPeerChannel ==
21370 pTdlsPeer->peerParams.channel)
21371 {
21372 pTdlsPeer->isOffChannelSupported = TRUE;
21373 break;
21374 }
21375 }
21376 }
21377 else
21378 {
21379 pTdlsPeer->isOffChannelSupported = FALSE;
21380 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021381 }
21382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21383 "%s: TDLS channel switch request for channel "
21384 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021385 "%d isOffChannelSupported %d", __func__,
21386 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021387 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021388 suppChannelLen,
21389 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021390
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021391 /* TDLS Off Channel, Enable tdls channel switch,
21392 when their is only one tdls link and it supports */
21393 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21394 if ((numCurrTdlsPeers == 1) &&
21395 (TRUE == pTdlsPeer->isOffChannelSupported) &&
21396 (TRUE == pTdlsPeer->isOffChannelConfigured))
21397 {
21398 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21399 "%s: Send TDLS channel switch request for channel %d",
21400 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021401
21402 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021403 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
21404 channel = pTdlsPeer->peerParams.channel;
21405
21406 mutex_unlock(&pHddCtx->tdls_lock);
21407
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021408 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
21409 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021410 peerMac,
21411 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021412 TDLS_OFF_CHANNEL_BW_OFFSET,
21413 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021414 if (ret != VOS_STATUS_SUCCESS) {
21415 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
21416 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021417 }
21418 else
21419 {
21420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21421 "%s: TDLS channel switch request not sent"
21422 " numCurrTdlsPeers %d "
21423 "isOffChannelSupported %d "
21424 "isOffChannelConfigured %d",
21425 __func__, numCurrTdlsPeers,
21426 pTdlsPeer->isOffChannelSupported,
21427 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021428 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021429 }
21430
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070021431 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021432 else
21433 mutex_unlock(&pHddCtx->tdls_lock);
21434
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021435 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021436
21437 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021438 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
21439 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021440 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021441 int ac;
21442 uint8 ucAc[4] = { WLANTL_AC_VO,
21443 WLANTL_AC_VI,
21444 WLANTL_AC_BK,
21445 WLANTL_AC_BE };
21446 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
21447 for(ac=0; ac < 4; ac++)
21448 {
21449 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21450 pTdlsPeer->staId, ucAc[ac],
21451 tlTid[ac], tlTid[ac], 0, 0,
21452 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021453 if (status != VOS_STATUS_SUCCESS) {
21454 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
21455 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021456 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021457 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021458 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021459
Bhargav Shah66896792015-10-01 18:17:37 +053021460 /* stop TCP delack timer if TDLS is enable */
21461 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21462 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053021463 hdd_wlan_tdls_enable_link_event(peer,
21464 pTdlsPeer->isOffChannelSupported,
21465 pTdlsPeer->isOffChannelConfigured,
21466 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021467 }
21468 break;
21469 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080021470 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021471 tANI_U16 numCurrTdlsPeers = 0;
21472 hddTdlsPeer_t *connPeer = NULL;
21473
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21475 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
21476 __func__, MAC_ADDR_ARRAY(peer));
21477
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021478 mutex_lock(&pHddCtx->tdls_lock);
21479 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021480
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021481
Sunil Dutt41de4e22013-11-14 18:09:02 +053021482 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021483 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021484 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21485 " (oper %d) not exsting. ignored",
21486 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21487 return -EINVAL;
21488 }
21489
21490 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21491 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21492 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21493 "NL80211_TDLS_DISABLE_LINK");
21494
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021495 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080021496 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021497 long status;
21498
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021499 /* set tdls off channel status to false for this peer */
21500 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053021501 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21502 eTDLS_LINK_TEARING,
21503 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
21504 eTDLS_LINK_UNSPECIFIED:
21505 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021506 mutex_unlock(&pHddCtx->tdls_lock);
21507
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021508 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21509
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021510 status = sme_DeleteTdlsPeerSta(
21511 WLAN_HDD_GET_HAL_CTX(pAdapter),
21512 pAdapter->sessionId, peer );
21513 if (status != VOS_STATUS_SUCCESS) {
21514 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21515 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021516
21517 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21518 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021519
21520 mutex_lock(&pHddCtx->tdls_lock);
21521 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21522 if ( NULL == pTdlsPeer ) {
21523 mutex_unlock(&pHddCtx->tdls_lock);
21524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21525 " peer was freed in other context",
21526 __func__, MAC_ADDR_ARRAY(peer));
21527 return -EINVAL;
21528 }
21529
Atul Mittal271a7652014-09-12 13:18:22 +053021530 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021531 eTDLS_LINK_IDLE,
21532 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021533 mutex_unlock(&pHddCtx->tdls_lock);
21534
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021535 if (status <= 0)
21536 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21538 "%s: Del station failed status %ld",
21539 __func__, status);
21540 return -EPERM;
21541 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021542
21543 /* TDLS Off Channel, Enable tdls channel switch,
21544 when their is only one tdls link and it supports */
21545 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21546 if (numCurrTdlsPeers == 1)
21547 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021548 tSirMacAddr peerMac;
21549 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021550
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021551 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021552 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021553
21554 if (connPeer == NULL) {
21555 mutex_unlock(&pHddCtx->tdls_lock);
21556 hddLog(VOS_TRACE_LEVEL_ERROR,
21557 "%s connPeer is NULL", __func__);
21558 return -EINVAL;
21559 }
21560
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021561 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21562 channel = connPeer->peerParams.channel;
21563
21564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21565 "%s: TDLS channel switch "
21566 "isOffChannelSupported %d "
21567 "isOffChannelConfigured %d "
21568 "isOffChannelEstablished %d",
21569 __func__,
21570 (connPeer ? connPeer->isOffChannelSupported : -1),
21571 (connPeer ? connPeer->isOffChannelConfigured : -1),
21572 (connPeer ? connPeer->isOffChannelEstablished : -1));
21573
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021574 if ((connPeer) &&
21575 (connPeer->isOffChannelSupported == TRUE) &&
21576 (connPeer->isOffChannelConfigured == TRUE))
21577 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021578 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021579 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021580 status = sme_SendTdlsChanSwitchReq(
21581 WLAN_HDD_GET_HAL_CTX(pAdapter),
21582 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021583 peerMac,
21584 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021585 TDLS_OFF_CHANNEL_BW_OFFSET,
21586 TDLS_CHANNEL_SWITCH_ENABLE);
21587 if (status != VOS_STATUS_SUCCESS) {
21588 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21589 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021590 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021591 else
21592 mutex_unlock(&pHddCtx->tdls_lock);
21593 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021594 else
21595 {
21596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21597 "%s: TDLS channel switch request not sent "
21598 "numCurrTdlsPeers %d ",
21599 __func__, numCurrTdlsPeers);
21600 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021601 }
21602 else
21603 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021604 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21606 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021607 }
Bhargav Shah66896792015-10-01 18:17:37 +053021608 if (numCurrTdlsPeers == 0) {
21609 /* start TCP delack timer if TDLS is disable */
21610 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21611 hdd_manage_delack_timer(pHddCtx);
21612 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021613 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021614 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021615 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021616 {
Atul Mittal115287b2014-07-08 13:26:33 +053021617 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021618
Atul Mittal115287b2014-07-08 13:26:33 +053021619 if (0 != status)
21620 {
21621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021622 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021623 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021624 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021625 break;
21626 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021627 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021628 {
Atul Mittal115287b2014-07-08 13:26:33 +053021629 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21630 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021631 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021632 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021633
Atul Mittal115287b2014-07-08 13:26:33 +053021634 if (0 != status)
21635 {
21636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021637 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021638 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021639 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021640 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021641 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021642 case NL80211_TDLS_DISCOVERY_REQ:
21643 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021644 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021645 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021646 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021647 return -ENOTSUPP;
21648 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21650 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021651 return -ENOTSUPP;
21652 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021653
21654 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021655 return 0;
21656}
Chilam NG571c65a2013-01-19 12:27:36 +053021657
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021658static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021659#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21660 const u8 *peer,
21661#else
21662 u8 *peer,
21663#endif
21664 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021665{
21666 int ret;
21667
21668 vos_ssr_protect(__func__);
21669 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21670 vos_ssr_unprotect(__func__);
21671
21672 return ret;
21673}
21674
Chilam NG571c65a2013-01-19 12:27:36 +053021675int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21676 struct net_device *dev, u8 *peer)
21677{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021678 hddLog(VOS_TRACE_LEVEL_INFO,
21679 "tdls send discover req: "MAC_ADDRESS_STR,
21680 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021681#if TDLS_MGMT_VERSION2
21682 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21683 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21684#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021685#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21686 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21687 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21688#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21689 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21690 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21691#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21692 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21693 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21694#else
Chilam NG571c65a2013-01-19 12:27:36 +053021695 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21696 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021697#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021698#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021699}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021700#endif
21701
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021702#ifdef WLAN_FEATURE_GTK_OFFLOAD
21703/*
21704 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21705 * Callback rountine called upon receiving response for
21706 * get offload info
21707 */
21708void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21709 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21710{
21711
21712 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021713 tANI_U8 tempReplayCounter[8];
21714 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021715
21716 ENTER();
21717
21718 if (NULL == pAdapter)
21719 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021720 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021721 "%s: HDD adapter is Null", __func__);
21722 return ;
21723 }
21724
21725 if (NULL == pGtkOffloadGetInfoRsp)
21726 {
21727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21728 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21729 return ;
21730 }
21731
21732 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21733 {
21734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21735 "%s: wlan Failed to get replay counter value",
21736 __func__);
21737 return ;
21738 }
21739
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021740 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21741 /* Update replay counter */
21742 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21743 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21744
21745 {
21746 /* changing from little to big endian since supplicant
21747 * works on big endian format
21748 */
21749 int i;
21750 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21751
21752 for (i = 0; i < 8; i++)
21753 {
21754 tempReplayCounter[7-i] = (tANI_U8)p[i];
21755 }
21756 }
21757
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021758 /* Update replay counter to NL */
21759 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021760 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021761}
21762
21763/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021764 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021765 * This function is used to offload GTK rekeying job to the firmware.
21766 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021767int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021768 struct cfg80211_gtk_rekey_data *data)
21769{
21770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21771 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21772 hdd_station_ctx_t *pHddStaCtx;
21773 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021774 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021775 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021776 eHalStatus status = eHAL_STATUS_FAILURE;
21777
21778 ENTER();
21779
21780 if (NULL == pAdapter)
21781 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021782 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021783 "%s: HDD adapter is Null", __func__);
21784 return -ENODEV;
21785 }
21786
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021787 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21788 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21789 pAdapter->sessionId, pAdapter->device_mode));
21790
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021791 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021792 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021793 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021794 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021795 }
21796
21797 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21798 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21799 if (NULL == hHal)
21800 {
21801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21802 "%s: HAL context is Null!!!", __func__);
21803 return -EAGAIN;
21804 }
21805
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021806 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21807 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21808 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21809 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021810 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021811 {
21812 /* changing from big to little endian since driver
21813 * works on little endian format
21814 */
21815 tANI_U8 *p =
21816 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21817 int i;
21818
21819 for (i = 0; i < 8; i++)
21820 {
21821 p[7-i] = data->replay_ctr[i];
21822 }
21823 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021824
21825 if (TRUE == pHddCtx->hdd_wlan_suspended)
21826 {
21827 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021828 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21829 sizeof (tSirGtkOffloadParams));
21830 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021831 pAdapter->sessionId);
21832
21833 if (eHAL_STATUS_SUCCESS != status)
21834 {
21835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21836 "%s: sme_SetGTKOffload failed, returned %d",
21837 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021838
21839 /* Need to clear any trace of key value in the memory.
21840 * Thus zero out the memory even though it is local
21841 * variable.
21842 */
21843 vos_mem_zero(&hddGtkOffloadReqParams,
21844 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021845 return status;
21846 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21848 "%s: sme_SetGTKOffload successfull", __func__);
21849 }
21850 else
21851 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21853 "%s: wlan not suspended GTKOffload request is stored",
21854 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021855 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021856
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021857 /* Need to clear any trace of key value in the memory.
21858 * Thus zero out the memory even though it is local
21859 * variable.
21860 */
21861 vos_mem_zero(&hddGtkOffloadReqParams,
21862 sizeof(hddGtkOffloadReqParams));
21863
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021864 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021865 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021866}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021867
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021868int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21869 struct cfg80211_gtk_rekey_data *data)
21870{
21871 int ret;
21872
21873 vos_ssr_protect(__func__);
21874 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21875 vos_ssr_unprotect(__func__);
21876
21877 return ret;
21878}
21879#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021880/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021881 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021882 * This function is used to set access control policy
21883 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021884static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21885 struct net_device *dev,
21886 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021887{
21888 int i;
21889 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21890 hdd_hostapd_state_t *pHostapdState;
21891 tsap_Config_t *pConfig;
21892 v_CONTEXT_t pVosContext = NULL;
21893 hdd_context_t *pHddCtx;
21894 int status;
21895
21896 ENTER();
21897
21898 if (NULL == pAdapter)
21899 {
21900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21901 "%s: HDD adapter is Null", __func__);
21902 return -ENODEV;
21903 }
21904
21905 if (NULL == params)
21906 {
21907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21908 "%s: params is Null", __func__);
21909 return -EINVAL;
21910 }
21911
21912 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21913 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021914 if (0 != status)
21915 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021916 return status;
21917 }
21918
21919 pVosContext = pHddCtx->pvosContext;
21920 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21921
21922 if (NULL == pHostapdState)
21923 {
21924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21925 "%s: pHostapdState is Null", __func__);
21926 return -EINVAL;
21927 }
21928
21929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21930 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021931 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21932 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21933 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021934
21935 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21936 {
21937 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21938
21939 /* default value */
21940 pConfig->num_accept_mac = 0;
21941 pConfig->num_deny_mac = 0;
21942
21943 /**
21944 * access control policy
21945 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21946 * listed in hostapd.deny file.
21947 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21948 * listed in hostapd.accept file.
21949 */
21950 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21951 {
21952 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21953 }
21954 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21955 {
21956 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21957 }
21958 else
21959 {
21960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21961 "%s:Acl Policy : %d is not supported",
21962 __func__, params->acl_policy);
21963 return -ENOTSUPP;
21964 }
21965
21966 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21967 {
21968 pConfig->num_accept_mac = params->n_acl_entries;
21969 for (i = 0; i < params->n_acl_entries; i++)
21970 {
21971 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21972 "** Add ACL MAC entry %i in WhiletList :"
21973 MAC_ADDRESS_STR, i,
21974 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21975
21976 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21977 sizeof(qcmacaddr));
21978 }
21979 }
21980 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21981 {
21982 pConfig->num_deny_mac = params->n_acl_entries;
21983 for (i = 0; i < params->n_acl_entries; i++)
21984 {
21985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21986 "** Add ACL MAC entry %i in BlackList :"
21987 MAC_ADDRESS_STR, i,
21988 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21989
21990 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21991 sizeof(qcmacaddr));
21992 }
21993 }
21994
21995 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21996 {
21997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21998 "%s: SAP Set Mac Acl fail", __func__);
21999 return -EINVAL;
22000 }
22001 }
22002 else
22003 {
22004 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053022005 "%s: Invalid device_mode = %s (%d)",
22006 __func__, hdd_device_modetoString(pAdapter->device_mode),
22007 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022008 return -EINVAL;
22009 }
22010
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022011 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022012 return 0;
22013}
22014
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053022015static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
22016 struct net_device *dev,
22017 const struct cfg80211_acl_data *params)
22018{
22019 int ret;
22020 vos_ssr_protect(__func__);
22021 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
22022 vos_ssr_unprotect(__func__);
22023
22024 return ret;
22025}
22026
Leo Chang9056f462013-08-01 19:21:11 -070022027#ifdef WLAN_NL80211_TESTMODE
22028#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070022029void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070022030(
22031 void *pAdapter,
22032 void *indCont
22033)
22034{
Leo Changd9df8aa2013-09-26 13:32:26 -070022035 tSirLPHBInd *lphbInd;
22036 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053022037 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070022038
22039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070022040 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070022041
c_hpothu73f35e62014-04-18 13:40:08 +053022042 if (pAdapter == NULL)
22043 {
22044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22045 "%s: pAdapter is NULL\n",__func__);
22046 return;
22047 }
22048
Leo Chang9056f462013-08-01 19:21:11 -070022049 if (NULL == indCont)
22050 {
22051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070022052 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070022053 return;
22054 }
22055
c_hpothu73f35e62014-04-18 13:40:08 +053022056 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070022057 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070022058 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053022059 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070022060 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070022061 GFP_ATOMIC);
22062 if (!skb)
22063 {
22064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22065 "LPHB timeout, NL buffer alloc fail");
22066 return;
22067 }
22068
Leo Changac3ba772013-10-07 09:47:04 -070022069 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070022070 {
22071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22072 "WLAN_HDD_TM_ATTR_CMD put fail");
22073 goto nla_put_failure;
22074 }
Leo Changac3ba772013-10-07 09:47:04 -070022075 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070022076 {
22077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22078 "WLAN_HDD_TM_ATTR_TYPE put fail");
22079 goto nla_put_failure;
22080 }
Leo Changac3ba772013-10-07 09:47:04 -070022081 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070022082 sizeof(tSirLPHBInd), lphbInd))
22083 {
22084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22085 "WLAN_HDD_TM_ATTR_DATA put fail");
22086 goto nla_put_failure;
22087 }
Leo Chang9056f462013-08-01 19:21:11 -070022088 cfg80211_testmode_event(skb, GFP_ATOMIC);
22089 return;
22090
22091nla_put_failure:
22092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22093 "NLA Put fail");
22094 kfree_skb(skb);
22095
22096 return;
22097}
22098#endif /* FEATURE_WLAN_LPHB */
22099
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022100static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070022101{
22102 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
22103 int err = 0;
22104#ifdef FEATURE_WLAN_LPHB
22105 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070022106 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022107
22108 ENTER();
22109
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022110 err = wlan_hdd_validate_context(pHddCtx);
22111 if (0 != err)
22112 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022113 return err;
22114 }
Leo Chang9056f462013-08-01 19:21:11 -070022115#endif /* FEATURE_WLAN_LPHB */
22116
22117 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
22118 if (err)
22119 {
22120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22121 "%s Testmode INV ATTR", __func__);
22122 return err;
22123 }
22124
22125 if (!tb[WLAN_HDD_TM_ATTR_CMD])
22126 {
22127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22128 "%s Testmode INV CMD", __func__);
22129 return -EINVAL;
22130 }
22131
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022132 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22133 TRACE_CODE_HDD_CFG80211_TESTMODE,
22134 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070022135 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
22136 {
22137#ifdef FEATURE_WLAN_LPHB
22138 /* Low Power Heartbeat configuration request */
22139 case WLAN_HDD_TM_CMD_WLAN_HB:
22140 {
22141 int buf_len;
22142 void *buf;
22143 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080022144 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070022145
22146 if (!tb[WLAN_HDD_TM_ATTR_DATA])
22147 {
22148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22149 "%s Testmode INV DATA", __func__);
22150 return -EINVAL;
22151 }
22152
22153 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
22154 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080022155
Manjeet Singh3c577442017-02-10 19:03:38 +053022156 if (buf_len > sizeof(*hb_params)) {
22157 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
22158 buf_len);
22159 return -ERANGE;
22160 }
22161
Amar Singhal05852702014-02-04 14:40:00 -080022162 hb_params_temp =(tSirLPHBReq *)buf;
22163 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
22164 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
22165 return -EINVAL;
22166
Leo Chang9056f462013-08-01 19:21:11 -070022167 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
22168 if (NULL == hb_params)
22169 {
22170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22171 "%s Request Buffer Alloc Fail", __func__);
22172 return -EINVAL;
22173 }
22174
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053022175 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070022176 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070022177 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
22178 hb_params,
22179 wlan_hdd_cfg80211_lphb_ind_handler);
22180 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070022181 {
Leo Changd9df8aa2013-09-26 13:32:26 -070022182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22183 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070022184 vos_mem_free(hb_params);
22185 }
Leo Chang9056f462013-08-01 19:21:11 -070022186 return 0;
22187 }
22188#endif /* FEATURE_WLAN_LPHB */
22189 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053022190 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22191 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070022192 return -EOPNOTSUPP;
22193 }
22194
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022195 EXIT();
22196 return err;
Leo Chang9056f462013-08-01 19:21:11 -070022197}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022198
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053022199static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
22200#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
22201 struct wireless_dev *wdev,
22202#endif
22203 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022204{
22205 int ret;
22206
22207 vos_ssr_protect(__func__);
22208 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
22209 vos_ssr_unprotect(__func__);
22210
22211 return ret;
22212}
Leo Chang9056f462013-08-01 19:21:11 -070022213#endif /* CONFIG_NL80211_TESTMODE */
22214
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022215extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022216static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022217 struct net_device *dev,
22218 int idx, struct survey_info *survey)
22219{
22220 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
22221 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053022222 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022223 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053022224 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022225 v_S7_t snr,rssi;
22226 int status, i, j, filled = 0;
22227
22228 ENTER();
22229
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022230 if (NULL == pAdapter)
22231 {
22232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
22233 "%s: HDD adapter is Null", __func__);
22234 return -ENODEV;
22235 }
22236
22237 if (NULL == wiphy)
22238 {
22239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
22240 "%s: wiphy is Null", __func__);
22241 return -ENODEV;
22242 }
22243
22244 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
22245 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022246 if (0 != status)
22247 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022248 return status;
22249 }
22250
Mihir Sheted9072e02013-08-21 17:02:29 +053022251 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
22252
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022253 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053022254 0 != pAdapter->survey_idx ||
22255 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022256 {
22257 /* The survey dump ops when implemented completely is expected to
22258 * return a survey of all channels and the ops is called by the
22259 * kernel with incremental values of the argument 'idx' till it
22260 * returns -ENONET. But we can only support the survey for the
22261 * operating channel for now. survey_idx is used to track
22262 * that the ops is called only once and then return -ENONET for
22263 * the next iteration
22264 */
22265 pAdapter->survey_idx = 0;
22266 return -ENONET;
22267 }
22268
Mukul Sharma9d5233b2015-06-11 20:28:20 +053022269 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
22270 {
22271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22272 "%s: Roaming in progress, hence return ", __func__);
22273 return -ENONET;
22274 }
22275
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022276 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
22277
22278 wlan_hdd_get_snr(pAdapter, &snr);
22279 wlan_hdd_get_rssi(pAdapter, &rssi);
22280
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022281 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22282 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
22283 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022284 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
22285 hdd_wlan_get_freq(channel, &freq);
22286
22287
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053022288 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022289 {
22290 if (NULL == wiphy->bands[i])
22291 {
22292 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
22293 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
22294 continue;
22295 }
22296
22297 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
22298 {
22299 struct ieee80211_supported_band *band = wiphy->bands[i];
22300
22301 if (band->channels[j].center_freq == (v_U16_t)freq)
22302 {
22303 survey->channel = &band->channels[j];
22304 /* The Rx BDs contain SNR values in dB for the received frames
22305 * while the supplicant expects noise. So we calculate and
22306 * return the value of noise (dBm)
22307 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
22308 */
22309 survey->noise = rssi - snr;
22310 survey->filled = SURVEY_INFO_NOISE_DBM;
22311 filled = 1;
22312 }
22313 }
22314 }
22315
22316 if (filled)
22317 pAdapter->survey_idx = 1;
22318 else
22319 {
22320 pAdapter->survey_idx = 0;
22321 return -ENONET;
22322 }
22323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022324 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022325 return 0;
22326}
22327
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022328static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
22329 struct net_device *dev,
22330 int idx, struct survey_info *survey)
22331{
22332 int ret;
22333
22334 vos_ssr_protect(__func__);
22335 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
22336 vos_ssr_unprotect(__func__);
22337
22338 return ret;
22339}
22340
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022341/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022342 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022343 * this is called when cfg80211 driver resume
22344 * driver updates latest sched_scan scan result(if any) to cfg80211 database
22345 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022346int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022347{
22348 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
22349 hdd_adapter_t *pAdapter;
22350 hdd_adapter_list_node_t *pAdapterNode, *pNext;
22351 VOS_STATUS status = VOS_STATUS_SUCCESS;
22352
22353 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022354
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053022355 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022356 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022357 return 0;
22358 }
22359
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022360 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
22361 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022362
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022363 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022364 {
22365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22366 "%s: Resume SoftAP", __func__);
22367 hdd_set_wlan_suspend_mode(false);
22368 }
22369
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022370 spin_lock(&pHddCtx->schedScan_lock);
22371 pHddCtx->isWiphySuspended = FALSE;
22372 if (TRUE != pHddCtx->isSchedScanUpdatePending)
22373 {
22374 spin_unlock(&pHddCtx->schedScan_lock);
22375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22376 "%s: Return resume is not due to PNO indication", __func__);
22377 return 0;
22378 }
22379 // Reset flag to avoid updatating cfg80211 data old results again
22380 pHddCtx->isSchedScanUpdatePending = FALSE;
22381 spin_unlock(&pHddCtx->schedScan_lock);
22382
22383 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
22384
22385 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
22386 {
22387 pAdapter = pAdapterNode->pAdapter;
22388 if ( (NULL != pAdapter) &&
22389 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
22390 {
22391 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022392 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
22394 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022395 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022396 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022397 {
22398 /* Acquire wakelock to handle the case where APP's tries to
22399 * suspend immediately after updating the scan results. Whis
22400 * results in app's is in suspended state and not able to
22401 * process the connect request to AP
22402 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053022403 hdd_prevent_suspend_timeout(2000,
22404 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022405 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022406 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022407
22408 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22409 "%s : cfg80211 scan result database updated", __func__);
22410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022411 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022412 return 0;
22413
22414 }
22415 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
22416 pAdapterNode = pNext;
22417 }
22418
22419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22420 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022421 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022422 return 0;
22423}
22424
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022425int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
22426{
22427 int ret;
22428
22429 vos_ssr_protect(__func__);
22430 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
22431 vos_ssr_unprotect(__func__);
22432
22433 return ret;
22434}
22435
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022436/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022437 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022438 * this is called when cfg80211 driver suspends
22439 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022440int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022441 struct cfg80211_wowlan *wow)
22442{
22443 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022444 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022445
22446 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022447
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022448 ret = wlan_hdd_validate_context(pHddCtx);
22449 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022450 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022451 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022452 }
22453
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022454 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22456 "%s: Suspend SoftAP", __func__);
22457 hdd_set_wlan_suspend_mode(true);
22458 }
22459
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022460
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022461 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22462 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
22463 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022464 pHddCtx->isWiphySuspended = TRUE;
22465
22466 EXIT();
22467
22468 return 0;
22469}
22470
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022471int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
22472 struct cfg80211_wowlan *wow)
22473{
22474 int ret;
22475
22476 vos_ssr_protect(__func__);
22477 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
22478 vos_ssr_unprotect(__func__);
22479
22480 return ret;
22481}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022482
22483#ifdef FEATURE_OEM_DATA_SUPPORT
22484static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022485 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022486{
22487 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22488
22489 ENTER();
22490
22491 if (wlan_hdd_validate_context(pHddCtx)) {
22492 return;
22493 }
22494 if (!pMsg)
22495 {
22496 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
22497 return;
22498 }
22499
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022500 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022501
22502 EXIT();
22503 return;
22504
22505}
22506
22507void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022508 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022509{
22510 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22511
22512 ENTER();
22513
22514 if (wlan_hdd_validate_context(pHddCtx)) {
22515 return;
22516 }
22517
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022518 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022519
22520 switch(evType) {
22521 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022522 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022523 break;
22524 default:
22525 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22526 break;
22527 }
22528 EXIT();
22529}
22530#endif
22531
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022532#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22533 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022534/**
22535 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22536 * @wiphy: Pointer to wiphy
22537 * @wdev: Pointer to wireless device structure
22538 *
22539 * This function is used to abort an ongoing scan
22540 *
22541 * Return: None
22542 */
22543static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22544 struct wireless_dev *wdev)
22545{
22546 struct net_device *dev = wdev->netdev;
22547 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22548 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22549 int ret;
22550
22551 ENTER();
22552
22553 if (NULL == adapter) {
22554 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22555 return;
22556 }
22557
22558 ret = wlan_hdd_validate_context(hdd_ctx);
22559 if (0 != ret)
22560 return;
22561
22562 wlan_hdd_scan_abort(adapter);
22563
22564 return;
22565}
22566
22567/**
22568 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22569 * @wiphy: Pointer to wiphy
22570 * @wdev: Pointer to wireless device structure
22571 *
22572 * Return: None
22573 */
22574void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22575 struct wireless_dev *wdev)
22576{
22577 vos_ssr_protect(__func__);
22578 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22579 vos_ssr_unprotect(__func__);
22580
22581 return;
22582}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022583#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022584
Abhishek Singh936c6932017-11-07 17:28:23 +053022585#ifdef CHANNEL_SWITCH_SUPPORTED
22586/**
22587 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22588 * channel in SAP/GO
22589 * @wiphy: wiphy pointer
22590 * @dev: dev pointer.
22591 * @csa_params: Change channel params
22592 *
22593 * This function is called to switch channel in SAP/GO
22594 *
22595 * Return: 0 if success else return non zero
22596 */
22597static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22598 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22599{
22600 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22601 hdd_context_t *hdd_ctx;
22602 uint8_t channel;
22603 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022604 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022605 v_CONTEXT_t vos_ctx;
22606
22607 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22608
22609 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22610 ret = wlan_hdd_validate_context(hdd_ctx);
22611 if (ret)
22612 return ret;
22613
22614 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22615 if (!vos_ctx) {
22616 hddLog(LOGE, FL("Vos ctx is null"));
22617 return -EINVAL;
22618 }
22619
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022620 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022621 return -ENOTSUPP;
22622
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022623 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22624 if (!sap_ctx) {
22625 hddLog(LOGE, FL("sap_ctx is NULL"));
22626 return -EINVAL;
22627 }
22628
22629 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22630 if (ret)
22631 return ret;
22632
22633 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22634
Abhishek Singh936c6932017-11-07 17:28:23 +053022635 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022636 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022637
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022638 if (ret) {
22639 wlansap_reset_chan_change_in_progress(sap_ctx);
22640 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22641 }
22642
Abhishek Singh936c6932017-11-07 17:28:23 +053022643 return ret;
22644}
22645
22646/**
22647 * wlan_hdd_cfg80211_channel_switch()- function to switch
22648 * channel in SAP/GO
22649 * @wiphy: wiphy pointer
22650 * @dev: dev pointer.
22651 * @csa_params: Change channel params
22652 *
22653 * This function is called to switch channel in SAP/GO
22654 *
22655 * Return: 0 if success else return non zero
22656 */
22657static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22658 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22659{
22660 int ret;
22661
22662 vos_ssr_protect(__func__);
22663 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22664 vos_ssr_unprotect(__func__);
22665
22666 return ret;
22667}
22668#endif
22669
Jeff Johnson295189b2012-06-20 16:38:30 -070022670/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022671static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022672{
22673 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22674 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22675 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22676 .change_station = wlan_hdd_change_station,
22677#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22678 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22679 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22680 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022681#else
22682 .start_ap = wlan_hdd_cfg80211_start_ap,
22683 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22684 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022685#endif
22686 .change_bss = wlan_hdd_cfg80211_change_bss,
22687 .add_key = wlan_hdd_cfg80211_add_key,
22688 .get_key = wlan_hdd_cfg80211_get_key,
22689 .del_key = wlan_hdd_cfg80211_del_key,
22690 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022691#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022692 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022693#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022694 .scan = wlan_hdd_cfg80211_scan,
22695 .connect = wlan_hdd_cfg80211_connect,
22696 .disconnect = wlan_hdd_cfg80211_disconnect,
22697 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22698 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22699 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22700 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22701 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022702 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22703 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022704 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022705#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22706 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22707 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22708 .set_txq_params = wlan_hdd_set_txq_params,
22709#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022710 .get_station = wlan_hdd_cfg80211_get_station,
22711 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22712 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022713 .add_station = wlan_hdd_cfg80211_add_station,
22714#ifdef FEATURE_WLAN_LFR
22715 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22716 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22717 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22718#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022719#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22720 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22721#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022722#ifdef FEATURE_WLAN_TDLS
22723 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22724 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22725#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022726#ifdef WLAN_FEATURE_GTK_OFFLOAD
22727 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22728#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022729#ifdef FEATURE_WLAN_SCAN_PNO
22730 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22731 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22732#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022733 .resume = wlan_hdd_cfg80211_resume_wlan,
22734 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022735 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022736#ifdef WLAN_NL80211_TESTMODE
22737 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22738#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022739 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022740#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22741 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022742 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022743#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022744#ifdef CHANNEL_SWITCH_SUPPORTED
22745 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22746#endif
22747
Abhinav Kumar118efd02019-08-07 16:41:07 +053022748#if defined(WLAN_FEATURE_SAE) && \
22749 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
22750 .external_auth = wlan_hdd_cfg80211_external_auth,
22751#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022752};
22753