blob: 33eeebd8ae2d754b3fd625144b08c5ee5bb7d4c7 [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();
4749
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05304750 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304751 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05304752
Dino Mycle6fb96c12014-06-10 11:52:40 +05304753 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4754 data, dataLen,
4755 wlan_hdd_extscan_config_policy)) {
4756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4757 return -EINVAL;
4758 }
4759
4760 /* Parse and fetch request Id */
4761 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4763 return -EINVAL;
4764 }
4765 requestId = nla_get_u32(
4766 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4767 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4768
4769 /* Parse and fetch wifi band */
4770 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4771 {
4772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4773 return -EINVAL;
4774 }
4775 wifiBand = nla_get_u32(
4776 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4777 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4778
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304779 /* Parse and fetch max channels */
4780 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4781 {
4782 hddLog(LOGE, FL("attr max channels failed"));
4783 return -EINVAL;
4784 }
4785 maxChannels = nla_get_u32(
4786 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4787 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4788
Dino Mycle6fb96c12014-06-10 11:52:40 +05304789 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304790 wifiBand, chan_list,
4791 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304792 if (eHAL_STATUS_SUCCESS != status) {
4793 hddLog(VOS_TRACE_LEVEL_ERROR,
4794 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4795 return -EINVAL;
4796 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304797
Agrawal Ashish16abf782016-08-18 22:42:59 +05304798 num_channels = VOS_MIN(num_channels, maxChannels);
4799 num_chan_new = num_channels;
4800 /* remove the indoor only channels if iface is SAP */
4801 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4802 {
4803 num_chan_new = 0;
4804 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304805 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304806 if (wiphy->bands[j] == NULL)
4807 continue;
4808 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4809 if ((chan_list[i] ==
4810 wiphy->bands[j]->channels[k].center_freq) &&
4811 (!(wiphy->bands[j]->channels[k].flags &
4812 IEEE80211_CHAN_INDOOR_ONLY))) {
4813 chan_list[num_chan_new] = chan_list[i];
4814 num_chan_new++;
4815 }
4816 }
4817 }
4818 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304819
Agrawal Ashish16abf782016-08-18 22:42:59 +05304820 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4821 for (i = 0; i < num_chan_new; i++)
4822 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4823 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304824
4825 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304826 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304827 NLMSG_HDRLEN);
4828
4829 if (!replySkb) {
4830 hddLog(VOS_TRACE_LEVEL_ERROR,
4831 FL("valid channels: buffer alloc fail"));
4832 return -EINVAL;
4833 }
4834 if (nla_put_u32(replySkb,
4835 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304836 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304837 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304838 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304839
4840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4841 kfree_skb(replySkb);
4842 return -EINVAL;
4843 }
4844
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304845 ret = cfg80211_vendor_cmd_reply(replySkb);
4846
4847 EXIT();
4848 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304849}
4850
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304851static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4852 struct wireless_dev *wdev,
4853 const void *data, int dataLen)
4854{
4855 int ret = 0;
4856
4857 vos_ssr_protect(__func__);
4858 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4859 dataLen);
4860 vos_ssr_unprotect(__func__);
4861
4862 return ret;
4863}
4864
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304865static int hdd_extscan_start_fill_bucket_channel_spec(
4866 hdd_context_t *pHddCtx,
4867 tpSirEXTScanStartReqParams pReqMsg,
4868 struct nlattr **tb)
4869{
4870 struct nlattr *bucket[
4871 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4872 struct nlattr *channel[
4873 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4874 struct nlattr *buckets;
4875 struct nlattr *channels;
4876 int rem1, rem2;
4877 eHalStatus status;
4878 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304879 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304880 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4881 tANI_U32 passive_max_chn_time, active_max_chn_time;
4882
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304883 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304884 bktIndex = 0;
4885
4886 nla_for_each_nested(buckets,
4887 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304888 if (bktIndex >= expected_buckets) {
4889 hddLog(LOGW, FL("ignoring excess buckets"));
4890 break;
4891 }
4892
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304893 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304894 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4895 nla_data(buckets), nla_len(buckets),
4896 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304897 hddLog(LOGE, FL("nla_parse failed"));
4898 return -EINVAL;
4899 }
4900
4901 /* Parse and fetch bucket spec */
4902 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4903 hddLog(LOGE, FL("attr bucket index failed"));
4904 return -EINVAL;
4905 }
4906 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4907 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4908 hddLog(LOG1, FL("Bucket spec Index %d"),
4909 pReqMsg->buckets[bktIndex].bucket);
4910
4911 /* Parse and fetch wifi band */
4912 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4913 hddLog(LOGE, FL("attr wifi band failed"));
4914 return -EINVAL;
4915 }
4916 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4917 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4918 hddLog(LOG1, FL("Wifi band %d"),
4919 pReqMsg->buckets[bktIndex].band);
4920
4921 /* Parse and fetch period */
4922 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4923 hddLog(LOGE, FL("attr period failed"));
4924 return -EINVAL;
4925 }
4926 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4927 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4928 hddLog(LOG1, FL("period %d"),
4929 pReqMsg->buckets[bktIndex].period);
4930
4931 /* Parse and fetch report events */
4932 if (!bucket[
4933 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4934 hddLog(LOGE, FL("attr report events failed"));
4935 return -EINVAL;
4936 }
4937 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4938 bucket[
4939 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4940 hddLog(LOG1, FL("report events %d"),
4941 pReqMsg->buckets[bktIndex].reportEvents);
4942
4943 /* Parse and fetch max period */
4944 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4945 hddLog(LOGE, FL("attr max period failed"));
4946 return -EINVAL;
4947 }
4948 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4949 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4950 hddLog(LOG1, FL("max period %u"),
4951 pReqMsg->buckets[bktIndex].max_period);
4952
4953 /* Parse and fetch exponent */
4954 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4955 hddLog(LOGE, FL("attr exponent failed"));
4956 return -EINVAL;
4957 }
4958 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4959 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4960 hddLog(LOG1, FL("exponent %u"),
4961 pReqMsg->buckets[bktIndex].exponent);
4962
4963 /* Parse and fetch step count */
4964 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4965 hddLog(LOGE, FL("attr step count failed"));
4966 return -EINVAL;
4967 }
4968 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4969 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4970 hddLog(LOG1, FL("Step count %u"),
4971 pReqMsg->buckets[bktIndex].step_count);
4972
4973 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4974 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4975
4976 /* Framework shall pass the channel list if the input WiFi band is
4977 * WIFI_BAND_UNSPECIFIED.
4978 * If the input WiFi band is specified (any value other than
4979 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4980 */
4981 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4982 numChannels = 0;
4983 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4984 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4985 pReqMsg->buckets[bktIndex].band,
4986 chanList, &numChannels);
4987 if (!HAL_STATUS_SUCCESS(status)) {
4988 hddLog(LOGE,
4989 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4990 status);
4991 return -EINVAL;
4992 }
4993
4994 pReqMsg->buckets[bktIndex].numChannels =
4995 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4996 hddLog(LOG1, FL("Num channels %d"),
4997 pReqMsg->buckets[bktIndex].numChannels);
4998
4999 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
5000 j++) {
5001 pReqMsg->buckets[bktIndex].channels[j].channel =
5002 chanList[j];
5003 pReqMsg->buckets[bktIndex].channels[j].
5004 chnlClass = 0;
5005 if (CSR_IS_CHANNEL_DFS(
5006 vos_freq_to_chan(chanList[j]))) {
5007 pReqMsg->buckets[bktIndex].channels[j].
5008 passive = 1;
5009 pReqMsg->buckets[bktIndex].channels[j].
5010 dwellTimeMs = passive_max_chn_time;
5011 } else {
5012 pReqMsg->buckets[bktIndex].channels[j].
5013 passive = 0;
5014 pReqMsg->buckets[bktIndex].channels[j].
5015 dwellTimeMs = active_max_chn_time;
5016 }
5017
5018 hddLog(LOG1,
5019 "Channel %u Passive %u Dwell time %u ms",
5020 pReqMsg->buckets[bktIndex].channels[j].channel,
5021 pReqMsg->buckets[bktIndex].channels[j].passive,
5022 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5023 }
5024
5025 bktIndex++;
5026 continue;
5027 }
5028
5029 /* Parse and fetch number of channels */
5030 if (!bucket[
5031 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5032 hddLog(LOGE, FL("attr num channels failed"));
5033 return -EINVAL;
5034 }
5035
5036 pReqMsg->buckets[bktIndex].numChannels =
5037 nla_get_u32(bucket[
5038 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5039 hddLog(LOG1, FL("num channels %d"),
5040 pReqMsg->buckets[bktIndex].numChannels);
5041
5042 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5043 hddLog(LOGE, FL("attr channel spec failed"));
5044 return -EINVAL;
5045 }
5046
5047 j = 0;
5048 nla_for_each_nested(channels,
5049 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5050 if (nla_parse(channel,
5051 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5052 nla_data(channels), nla_len(channels),
5053 wlan_hdd_extscan_config_policy)) {
5054 hddLog(LOGE, FL("nla_parse failed"));
5055 return -EINVAL;
5056 }
5057
5058 /* Parse and fetch channel */
5059 if (!channel[
5060 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5061 hddLog(LOGE, FL("attr channel failed"));
5062 return -EINVAL;
5063 }
5064 pReqMsg->buckets[bktIndex].channels[j].channel =
5065 nla_get_u32(channel[
5066 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5067 hddLog(LOG1, FL("channel %u"),
5068 pReqMsg->buckets[bktIndex].channels[j].channel);
5069
5070 /* Parse and fetch dwell time */
5071 if (!channel[
5072 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5073 hddLog(LOGE, FL("attr dwelltime failed"));
5074 return -EINVAL;
5075 }
5076 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5077 nla_get_u32(channel[
5078 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5079
5080 hddLog(LOG1, FL("Dwell time (%u ms)"),
5081 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5082
5083
5084 /* Parse and fetch channel spec passive */
5085 if (!channel[
5086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5087 hddLog(LOGE,
5088 FL("attr channel spec passive failed"));
5089 return -EINVAL;
5090 }
5091 pReqMsg->buckets[bktIndex].channels[j].passive =
5092 nla_get_u8(channel[
5093 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5094 hddLog(LOG1, FL("Chnl spec passive %u"),
5095 pReqMsg->buckets[bktIndex].channels[j].passive);
5096
5097 j++;
5098 }
5099
Dundi Raviteja18d0c062018-11-13 19:56:45 +05305100 if (j != pReqMsg->buckets[bktIndex].numChannels) {
5101 hddLog(LOG1, FL("Input parameters didn't match"));
5102 return -EINVAL;
5103 }
5104
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305105 bktIndex++;
5106 }
5107
5108 return 0;
5109}
5110
5111
5112/*
5113 * define short names for the global vendor params
5114 * used by wlan_hdd_cfg80211_extscan_start()
5115 */
5116#define PARAM_MAX \
5117QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5118#define PARAM_REQUEST_ID \
5119QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5120#define PARAM_BASE_PERIOD \
5121QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5122#define PARAM_MAX_AP_PER_SCAN \
5123QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5124#define PARAM_RPT_THRHLD_PERCENT \
5125QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5126#define PARAM_RPT_THRHLD_NUM_SCANS \
5127QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5128#define PARAM_NUM_BUCKETS \
5129QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5130
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305131static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305132 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305133 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305134{
Dino Myclee8843b32014-07-04 14:21:45 +05305135 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305136 struct net_device *dev = wdev->netdev;
5137 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5138 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5139 struct nlattr *tb[PARAM_MAX + 1];
5140 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305141 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305142 tANI_U32 request_id;
5143 struct hdd_ext_scan_context *context;
5144 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305145
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305146 ENTER();
5147
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305148 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305149 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305150
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305151 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305152 data, dataLen,
5153 wlan_hdd_extscan_config_policy)) {
5154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5155 return -EINVAL;
5156 }
5157
5158 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305159 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5161 return -EINVAL;
5162 }
5163
Dino Myclee8843b32014-07-04 14:21:45 +05305164 pReqMsg = (tpSirEXTScanStartReqParams)
5165 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305166 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5168 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305169 }
5170
5171 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305172 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305173 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5174
5175 pReqMsg->sessionId = pAdapter->sessionId;
5176 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5177
5178 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305179 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5181 goto fail;
5182 }
5183 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305184 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305185 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5186 pReqMsg->basePeriod);
5187
5188 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305189 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305190 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5191 goto fail;
5192 }
5193 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305194 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305195 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5196 pReqMsg->maxAPperScan);
5197
5198 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305199 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305200 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5201 goto fail;
5202 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305203 pReqMsg->reportThresholdPercent = nla_get_u8(
5204 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305205 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305206 pReqMsg->reportThresholdPercent);
5207
5208 /* Parse and fetch report threshold num scans */
5209 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5210 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5211 goto fail;
5212 }
5213 pReqMsg->reportThresholdNumScans = nla_get_u8(
5214 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5215 hddLog(LOG1, FL("Report Threshold num scans %d"),
5216 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305217
5218 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305219 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305220 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5221 goto fail;
5222 }
5223 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305224 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305225 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5226 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5227 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5228 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5229 }
5230 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5231 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305232
Dino Mycle6fb96c12014-06-10 11:52:40 +05305233 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5234 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5235 goto fail;
5236 }
5237
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305238 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305239
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305240 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5241 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305242
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305243 context = &pHddCtx->ext_scan_context;
5244 spin_lock(&hdd_context_lock);
5245 INIT_COMPLETION(context->response_event);
5246 context->request_id = request_id = pReqMsg->requestId;
5247 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305248
Dino Mycle6fb96c12014-06-10 11:52:40 +05305249 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5250 if (!HAL_STATUS_SUCCESS(status)) {
5251 hddLog(VOS_TRACE_LEVEL_ERROR,
5252 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305253 goto fail;
5254 }
5255
Srinivas Dasari91727c12016-03-23 17:59:06 +05305256 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5257
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305258 /* request was sent -- wait for the response */
5259 rc = wait_for_completion_timeout(&context->response_event,
5260 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5261
5262 if (!rc) {
5263 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5264 retval = -ETIMEDOUT;
5265 } else {
5266 spin_lock(&hdd_context_lock);
5267 if (context->request_id == request_id)
5268 retval = context->response_status;
5269 else
5270 retval = -EINVAL;
5271 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305272 }
5273
Dino Myclee8843b32014-07-04 14:21:45 +05305274 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305275 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305276 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305277
5278fail:
5279 vos_mem_free(pReqMsg);
5280 return -EINVAL;
5281}
5282
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305283/*
5284 * done with short names for the global vendor params
5285 * used by wlan_hdd_cfg80211_extscan_start()
5286 */
5287#undef PARAM_MAX
5288#undef PARAM_REQUEST_ID
5289#undef PARAM_BASE_PERIOD
5290#undef PARAMS_MAX_AP_PER_SCAN
5291#undef PARAMS_RPT_THRHLD_PERCENT
5292#undef PARAMS_RPT_THRHLD_NUM_SCANS
5293#undef PARAMS_NUM_BUCKETS
5294
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305295static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5296 struct wireless_dev *wdev,
5297 const void *data, int dataLen)
5298{
5299 int ret = 0;
5300
5301 vos_ssr_protect(__func__);
5302 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5303 vos_ssr_unprotect(__func__);
5304
5305 return ret;
5306}
5307
5308static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305309 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305310 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305311{
Dino Myclee8843b32014-07-04 14:21:45 +05305312 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305313 struct net_device *dev = wdev->netdev;
5314 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5315 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5316 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5317 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305318 int retval;
5319 unsigned long rc;
5320 struct hdd_ext_scan_context *context;
5321 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305322
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305323 ENTER();
5324
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305325 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305326 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305327
Dino Mycle6fb96c12014-06-10 11:52:40 +05305328 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5329 data, dataLen,
5330 wlan_hdd_extscan_config_policy)) {
5331 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5332 return -EINVAL;
5333 }
5334
5335 /* Parse and fetch request Id */
5336 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5337 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5338 return -EINVAL;
5339 }
5340
Dino Myclee8843b32014-07-04 14:21:45 +05305341 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305342 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305343 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305344
Dino Myclee8843b32014-07-04 14:21:45 +05305345 reqMsg.sessionId = pAdapter->sessionId;
5346 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305347
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305348 context = &pHddCtx->ext_scan_context;
5349 spin_lock(&hdd_context_lock);
5350 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305351 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305352 spin_unlock(&hdd_context_lock);
5353
Dino Myclee8843b32014-07-04 14:21:45 +05305354 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305355 if (!HAL_STATUS_SUCCESS(status)) {
5356 hddLog(VOS_TRACE_LEVEL_ERROR,
5357 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305358 return -EINVAL;
5359 }
5360
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305361 /* request was sent -- wait for the response */
5362 rc = wait_for_completion_timeout(&context->response_event,
5363 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5364
5365 if (!rc) {
5366 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5367 retval = -ETIMEDOUT;
5368 } else {
5369 spin_lock(&hdd_context_lock);
5370 if (context->request_id == request_id)
5371 retval = context->response_status;
5372 else
5373 retval = -EINVAL;
5374 spin_unlock(&hdd_context_lock);
5375 }
5376
5377 return retval;
5378
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305379 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305380 return 0;
5381}
5382
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305383static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5384 struct wireless_dev *wdev,
5385 const void *data, int dataLen)
5386{
5387 int ret = 0;
5388
5389 vos_ssr_protect(__func__);
5390 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5391 vos_ssr_unprotect(__func__);
5392
5393 return ret;
5394}
5395
5396static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305397 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305398 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305399{
Dino Myclee8843b32014-07-04 14:21:45 +05305400 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305401 struct net_device *dev = wdev->netdev;
5402 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5403 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5404 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5405 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305406 struct hdd_ext_scan_context *context;
5407 tANI_U32 request_id;
5408 unsigned long rc;
5409 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305411 ENTER();
5412
Ashish Kumar Dhanotiya4830bba2018-11-15 12:26:29 +05305413 if (!wlan_hdd_is_extscan_supported(pAdapter, pHddCtx))
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305414 return -EINVAL;
Dino Myclee8843b32014-07-04 14:21:45 +05305415
Dino Mycle6fb96c12014-06-10 11:52:40 +05305416 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5417 data, dataLen,
5418 wlan_hdd_extscan_config_policy)) {
5419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5420 return -EINVAL;
5421 }
5422
5423 /* Parse and fetch request Id */
5424 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5425 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5426 return -EINVAL;
5427 }
5428
Dino Myclee8843b32014-07-04 14:21:45 +05305429 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305430 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305431 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305432
Dino Myclee8843b32014-07-04 14:21:45 +05305433 reqMsg.sessionId = pAdapter->sessionId;
5434 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305435
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305436 context = &pHddCtx->ext_scan_context;
5437 spin_lock(&hdd_context_lock);
5438 INIT_COMPLETION(context->response_event);
5439 context->request_id = request_id = reqMsg.requestId;
5440 spin_unlock(&hdd_context_lock);
5441
Dino Myclee8843b32014-07-04 14:21:45 +05305442 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305443 if (!HAL_STATUS_SUCCESS(status)) {
5444 hddLog(VOS_TRACE_LEVEL_ERROR,
5445 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305446 return -EINVAL;
5447 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305448
5449 /* request was sent -- wait for the response */
5450 rc = wait_for_completion_timeout(&context->response_event,
5451 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5452 if (!rc) {
5453 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5454 retval = -ETIMEDOUT;
5455 } else {
5456 spin_lock(&hdd_context_lock);
5457 if (context->request_id == request_id)
5458 retval = context->response_status;
5459 else
5460 retval = -EINVAL;
5461 spin_unlock(&hdd_context_lock);
5462 }
5463
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305464 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305465 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305466}
5467
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305468static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5469 struct wireless_dev *wdev,
5470 const void *data, int dataLen)
5471{
5472 int ret = 0;
5473
5474 vos_ssr_protect(__func__);
5475 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5476 vos_ssr_unprotect(__func__);
5477
5478 return ret;
5479}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305480#endif /* WLAN_FEATURE_EXTSCAN */
5481
Atul Mittal115287b2014-07-08 13:26:33 +05305482/*EXT TDLS*/
5483static const struct nla_policy
5484wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5485{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305486 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5487 .type = NLA_UNSPEC,
5488 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305489 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5490 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5491 {.type = NLA_S32 },
5492 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5493 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5494
5495};
5496
5497static const struct nla_policy
5498wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5499{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305500 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5501 .type = NLA_UNSPEC,
5502 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305503
5504};
5505
5506static const struct nla_policy
5507wlan_hdd_tdls_config_state_change_policy[
5508 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5509{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305510 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5511 .type = NLA_UNSPEC,
5512 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305513 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5514 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305515 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5516 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5517 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305518
5519};
5520
5521static const struct nla_policy
5522wlan_hdd_tdls_config_get_status_policy[
5523 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5524{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305525 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5526 .type = NLA_UNSPEC,
5527 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305528 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5529 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305530 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5531 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5532 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305533
5534};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305535
5536static const struct nla_policy
5537wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5538{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305539 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5540 .type = NLA_UNSPEC,
5541 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305542};
5543
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305544static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305545 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305546 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305547 int data_len)
5548{
5549
5550 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Sourav Mohapatraaf2cc672018-10-30 17:43:29 +05305551 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305552 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5553
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305554 ENTER();
5555
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305556 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305557 return -EINVAL;
5558 }
Sourav Mohapatraaf2cc672018-10-30 17:43:29 +05305559
5560 if (!adapter) {
5561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5562 return -EINVAL;
5563 }
5564
5565 if (adapter->device_mode != WLAN_HDD_INFRA_STATION) {
5566 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN allowed only in STA"));
5567 return -ENOTSUPP;
5568 }
5569
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305570 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305571 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305572 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305573 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305574 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305575 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305576 return -ENOTSUPP;
5577 }
5578
5579 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5580 data, data_len, wlan_hdd_mac_config)) {
5581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5582 return -EINVAL;
5583 }
5584
5585 /* Parse and fetch mac address */
5586 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5588 return -EINVAL;
5589 }
5590
5591 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5592 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5593 VOS_MAC_ADDR_LAST_3_BYTES);
5594
Siddharth Bhal76972212014-10-15 16:22:51 +05305595 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5596
5597 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305598 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5599 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305600 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5601 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5602 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5603 {
5604 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5605 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5606 VOS_MAC_ADDRESS_LEN);
5607 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305608 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305609
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305610 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5611 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305612
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305613 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305614 return 0;
5615}
5616
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305617static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5618 struct wireless_dev *wdev,
5619 const void *data,
5620 int data_len)
5621{
5622 int ret = 0;
5623
5624 vos_ssr_protect(__func__);
5625 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5626 vos_ssr_unprotect(__func__);
5627
5628 return ret;
5629}
5630
5631static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305632 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305633 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305634 int data_len)
5635{
5636 u8 peer[6] = {0};
5637 struct net_device *dev = wdev->netdev;
5638 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5639 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5640 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5641 eHalStatus ret;
5642 tANI_S32 state;
5643 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305644 tANI_S32 global_operating_class = 0;
5645 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305646 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305647 int retVal;
5648
5649 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305650
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305651 if (!pAdapter) {
5652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5653 return -EINVAL;
5654 }
5655
Atul Mittal115287b2014-07-08 13:26:33 +05305656 ret = wlan_hdd_validate_context(pHddCtx);
5657 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305658 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305659 return -EINVAL;
5660 }
5661 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305663 return -ENOTSUPP;
5664 }
5665 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5666 data, data_len,
5667 wlan_hdd_tdls_config_get_status_policy)) {
5668 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5669 return -EINVAL;
5670 }
5671
5672 /* Parse and fetch mac address */
5673 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5675 return -EINVAL;
5676 }
5677
5678 memcpy(peer, nla_data(
5679 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5680 sizeof(peer));
5681 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5682
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305683 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305684
Atul Mittal115287b2014-07-08 13:26:33 +05305685 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305686 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305687 NLMSG_HDRLEN);
5688
5689 if (!skb) {
5690 hddLog(VOS_TRACE_LEVEL_ERROR,
5691 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5692 return -EINVAL;
5693 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305694 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 +05305695 reason,
5696 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305697 global_operating_class,
5698 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305699 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305700 if (nla_put_s32(skb,
5701 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5702 state) ||
5703 nla_put_s32(skb,
5704 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5705 reason) ||
5706 nla_put_s32(skb,
5707 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5708 global_operating_class) ||
5709 nla_put_s32(skb,
5710 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5711 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305712
5713 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5714 goto nla_put_failure;
5715 }
5716
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305717 retVal = cfg80211_vendor_cmd_reply(skb);
5718 EXIT();
5719 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305720
5721nla_put_failure:
5722 kfree_skb(skb);
5723 return -EINVAL;
5724}
5725
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305726static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5727 struct wireless_dev *wdev,
5728 const void *data,
5729 int data_len)
5730{
5731 int ret = 0;
5732
5733 vos_ssr_protect(__func__);
5734 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5735 vos_ssr_unprotect(__func__);
5736
5737 return ret;
5738}
5739
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305740static int wlan_hdd_cfg80211_exttdls_callback(
5741#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5742 const tANI_U8* mac,
5743#else
5744 tANI_U8* mac,
5745#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305746 tANI_S32 state,
5747 tANI_S32 reason,
5748 void *ctx)
5749{
5750 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305751 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305752 tANI_S32 global_operating_class = 0;
5753 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305754 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305755
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305756 ENTER();
5757
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305758 if (!pAdapter) {
5759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5760 return -EINVAL;
5761 }
5762
5763 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305764 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305766 return -EINVAL;
5767 }
5768
5769 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305770 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305771 return -ENOTSUPP;
5772 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305773 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5774#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5775 NULL,
5776#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305777 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5778 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5779 GFP_KERNEL);
5780
5781 if (!skb) {
5782 hddLog(VOS_TRACE_LEVEL_ERROR,
5783 FL("cfg80211_vendor_event_alloc failed"));
5784 return -EINVAL;
5785 }
5786 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305787 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5788 reason,
5789 state,
5790 global_operating_class,
5791 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305792 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5793 MAC_ADDR_ARRAY(mac));
5794
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305795 if (nla_put(skb,
5796 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5797 VOS_MAC_ADDR_SIZE, mac) ||
5798 nla_put_s32(skb,
5799 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5800 state) ||
5801 nla_put_s32(skb,
5802 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5803 reason) ||
5804 nla_put_s32(skb,
5805 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5806 channel) ||
5807 nla_put_s32(skb,
5808 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5809 global_operating_class)
5810 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5812 goto nla_put_failure;
5813 }
5814
5815 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305816 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305817 return (0);
5818
5819nla_put_failure:
5820 kfree_skb(skb);
5821 return -EINVAL;
5822}
5823
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305824static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305825 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305826 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305827 int data_len)
5828{
5829 u8 peer[6] = {0};
5830 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305831 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5832 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5833 eHalStatus status;
5834 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305835 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305836 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305837
5838 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305839
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305840 if (!dev) {
5841 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5842 return -EINVAL;
5843 }
5844
5845 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5846 if (!pAdapter) {
5847 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5848 return -EINVAL;
5849 }
5850
Atul Mittal115287b2014-07-08 13:26:33 +05305851 status = wlan_hdd_validate_context(pHddCtx);
5852 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305854 return -EINVAL;
5855 }
5856 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305857 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305858 return -ENOTSUPP;
5859 }
5860 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5861 data, data_len,
5862 wlan_hdd_tdls_config_enable_policy)) {
5863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5864 return -EINVAL;
5865 }
5866
5867 /* Parse and fetch mac address */
5868 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5870 return -EINVAL;
5871 }
5872
5873 memcpy(peer, nla_data(
5874 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5875 sizeof(peer));
5876 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5877
5878 /* Parse and fetch channel */
5879 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5881 return -EINVAL;
5882 }
5883 pReqMsg.channel = nla_get_s32(
5884 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5885 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5886
5887 /* Parse and fetch global operating class */
5888 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5890 return -EINVAL;
5891 }
5892 pReqMsg.global_operating_class = nla_get_s32(
5893 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5894 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5895 pReqMsg.global_operating_class);
5896
5897 /* Parse and fetch latency ms */
5898 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5900 return -EINVAL;
5901 }
5902 pReqMsg.max_latency_ms = nla_get_s32(
5903 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5904 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5905 pReqMsg.max_latency_ms);
5906
5907 /* Parse and fetch required bandwidth kbps */
5908 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5910 return -EINVAL;
5911 }
5912
5913 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5914 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5915 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5916 pReqMsg.min_bandwidth_kbps);
5917
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305918 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305919 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305920 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305921 wlan_hdd_cfg80211_exttdls_callback);
5922
5923 EXIT();
5924 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305925}
5926
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305927static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5928 struct wireless_dev *wdev,
5929 const void *data,
5930 int data_len)
5931{
5932 int ret = 0;
5933
5934 vos_ssr_protect(__func__);
5935 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5936 vos_ssr_unprotect(__func__);
5937
5938 return ret;
5939}
5940
5941static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305942 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305943 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305944 int data_len)
5945{
5946 u8 peer[6] = {0};
5947 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305948 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5949 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5950 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305951 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305952 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305953
5954 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305955
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305956 if (!dev) {
5957 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5958 return -EINVAL;
5959 }
5960
5961 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5962 if (!pAdapter) {
5963 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5964 return -EINVAL;
5965 }
5966
Atul Mittal115287b2014-07-08 13:26:33 +05305967 status = wlan_hdd_validate_context(pHddCtx);
5968 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305970 return -EINVAL;
5971 }
5972 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305974 return -ENOTSUPP;
5975 }
5976 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5977 data, data_len,
5978 wlan_hdd_tdls_config_disable_policy)) {
5979 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5980 return -EINVAL;
5981 }
5982 /* Parse and fetch mac address */
5983 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5984 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5985 return -EINVAL;
5986 }
5987
5988 memcpy(peer, nla_data(
5989 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5990 sizeof(peer));
5991 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5992
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305993 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5994
5995 EXIT();
5996 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305997}
5998
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305999static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6000 struct wireless_dev *wdev,
6001 const void *data,
6002 int data_len)
6003{
6004 int ret = 0;
6005
6006 vos_ssr_protect(__func__);
6007 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6008 vos_ssr_unprotect(__func__);
6009
6010 return ret;
6011}
6012
Dasari Srinivas7875a302014-09-26 17:50:57 +05306013static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306014__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306015 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306016 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306017{
6018 struct net_device *dev = wdev->netdev;
6019 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6020 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6021 struct sk_buff *skb = NULL;
6022 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306023 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306024
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306025 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306026
6027 ret = wlan_hdd_validate_context(pHddCtx);
6028 if (0 != ret)
6029 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306030 return ret;
6031 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306032 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6033 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6034 fset |= WIFI_FEATURE_INFRA;
6035 }
6036
6037 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6038 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6039 fset |= WIFI_FEATURE_INFRA_5G;
6040 }
6041
6042#ifdef WLAN_FEATURE_P2P
6043 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6044 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6045 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6046 fset |= WIFI_FEATURE_P2P;
6047 }
6048#endif
6049
6050 /* Soft-AP is supported currently by default */
6051 fset |= WIFI_FEATURE_SOFT_AP;
6052
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306053 /* HOTSPOT is a supplicant feature, enable it by default */
6054 fset |= WIFI_FEATURE_HOTSPOT;
6055
Dasari Srinivas7875a302014-09-26 17:50:57 +05306056#ifdef WLAN_FEATURE_EXTSCAN
6057 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306058 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6059 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6060 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306061 fset |= WIFI_FEATURE_EXTSCAN;
6062 }
6063#endif
6064
Dasari Srinivas7875a302014-09-26 17:50:57 +05306065 if (sme_IsFeatureSupportedByFW(NAN)) {
6066 hddLog(LOG1, FL("NAN is supported by firmware"));
6067 fset |= WIFI_FEATURE_NAN;
6068 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306069
6070 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306071 if (sme_IsFeatureSupportedByFW(RTT) &&
6072 pHddCtx->cfg_ini->enable_rtt_support) {
6073 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306074 fset |= WIFI_FEATURE_D2AP_RTT;
6075 }
6076
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306077 if (sme_IsFeatureSupportedByFW(RTT3)) {
6078 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6079 fset |= WIFI_FEATURE_RTT3;
6080 }
6081
Dasari Srinivas7875a302014-09-26 17:50:57 +05306082#ifdef FEATURE_WLAN_BATCH_SCAN
6083 if (fset & WIFI_FEATURE_EXTSCAN) {
6084 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6085 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6086 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6087 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6088 fset |= WIFI_FEATURE_BATCH_SCAN;
6089 }
6090#endif
6091
6092#ifdef FEATURE_WLAN_SCAN_PNO
6093 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6094 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6095 hddLog(LOG1, FL("PNO is supported by firmware"));
6096 fset |= WIFI_FEATURE_PNO;
6097 }
6098#endif
6099
6100 /* STA+STA is supported currently by default */
6101 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6102
6103#ifdef FEATURE_WLAN_TDLS
6104 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6105 sme_IsFeatureSupportedByFW(TDLS)) {
6106 hddLog(LOG1, FL("TDLS is supported by firmware"));
6107 fset |= WIFI_FEATURE_TDLS;
6108 }
6109
6110 /* TDLS_OFFCHANNEL is not supported currently by default */
6111#endif
6112
6113#ifdef WLAN_AP_STA_CONCURRENCY
6114 /* AP+STA concurrency is supported currently by default */
6115 fset |= WIFI_FEATURE_AP_STA;
6116#endif
6117
Mukul Sharma5add0532015-08-17 15:57:47 +05306118#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306119 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6120 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306121 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6122 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306123 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306124#endif
6125
Dasari Srinivas7875a302014-09-26 17:50:57 +05306126 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6127 NLMSG_HDRLEN);
6128
6129 if (!skb) {
6130 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6131 return -EINVAL;
6132 }
6133 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6134
6135 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6136 hddLog(LOGE, FL("nla put fail"));
6137 goto nla_put_failure;
6138 }
6139
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306140 ret = cfg80211_vendor_cmd_reply(skb);
6141 EXIT();
6142 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306143
6144nla_put_failure:
6145 kfree_skb(skb);
6146 return -EINVAL;
6147}
6148
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306149static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306150wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6151 struct wireless_dev *wdev,
6152 const void *data, int data_len)
6153{
6154 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306155 vos_ssr_protect(__func__);
6156 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6157 vos_ssr_unprotect(__func__);
6158
6159 return ret;
6160}
6161
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306162
6163static const struct
6164nla_policy
6165qca_wlan_vendor_wifi_logger_get_ring_data_policy
6166[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6167 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6168 = {.type = NLA_U32 },
6169};
6170
6171static int
6172 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6173 struct wireless_dev *wdev,
6174 const void *data,
6175 int data_len)
6176{
6177 int ret;
6178 VOS_STATUS status;
6179 uint32_t ring_id;
6180 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6181 struct nlattr *tb
6182 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6183
6184 ENTER();
6185
6186 ret = wlan_hdd_validate_context(hdd_ctx);
6187 if (0 != ret) {
6188 return ret;
6189 }
6190
6191 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6192 data, data_len,
6193 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6194 hddLog(LOGE, FL("Invalid attribute"));
6195 return -EINVAL;
6196 }
6197
6198 /* Parse and fetch ring id */
6199 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6200 hddLog(LOGE, FL("attr ATTR failed"));
6201 return -EINVAL;
6202 }
6203
6204 ring_id = nla_get_u32(
6205 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6206
6207 hddLog(LOG1, FL("Bug report triggered by framework"));
6208
6209 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6210 WLAN_LOG_INDICATOR_FRAMEWORK,
6211 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306212 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306213 );
6214 if (VOS_STATUS_SUCCESS != status) {
6215 hddLog(LOGE, FL("Failed to trigger bug report"));
6216
6217 return -EINVAL;
6218 }
6219
6220 return 0;
6221
6222
6223}
6224
6225
6226static int
6227 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6228 struct wireless_dev *wdev,
6229 const void *data,
6230 int data_len)
6231{
6232 int ret = 0;
6233
6234 vos_ssr_protect(__func__);
6235 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6236 wdev, data, data_len);
6237 vos_ssr_unprotect(__func__);
6238
6239 return ret;
6240
6241}
6242
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306243#define MAX_CONCURRENT_MATRIX \
6244 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6245#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6246 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6247static const struct nla_policy
6248wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6249 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6250};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306251
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306252static int
6253__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306254 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306255 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306256{
6257 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6258 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306259 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306260 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306261 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6262 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306263
6264 ENTER();
6265
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306266 ret = wlan_hdd_validate_context(pHddCtx);
6267 if (0 != ret)
6268 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306269 return ret;
6270 }
6271
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306272 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6273 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306274 hddLog(LOGE, FL("Invalid ATTR"));
6275 return -EINVAL;
6276 }
6277
6278 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306279 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306280 hddLog(LOGE, FL("Attr max feature set size failed"));
6281 return -EINVAL;
6282 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306283 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306284 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6285
6286 /* Fill feature combination matrix */
6287 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306288 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6289 WIFI_FEATURE_P2P;
6290
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306291 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6292 WIFI_FEATURE_SOFT_AP;
6293
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306294 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6295 WIFI_FEATURE_SOFT_AP;
6296
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306297 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6298 WIFI_FEATURE_SOFT_AP |
6299 WIFI_FEATURE_P2P;
6300
6301 /* Add more feature combinations here */
6302
6303 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6304 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6305 hddLog(LOG1, "Feature set matrix");
6306 for (i = 0; i < feature_sets; i++)
6307 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6308
6309 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6310 sizeof(u32) * feature_sets +
6311 NLMSG_HDRLEN);
6312
6313 if (reply_skb) {
6314 if (nla_put_u32(reply_skb,
6315 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6316 feature_sets) ||
6317 nla_put(reply_skb,
6318 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6319 sizeof(u32) * feature_sets, feature_set_matrix)) {
6320 hddLog(LOGE, FL("nla put fail"));
6321 kfree_skb(reply_skb);
6322 return -EINVAL;
6323 }
6324
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306325 ret = cfg80211_vendor_cmd_reply(reply_skb);
6326 EXIT();
6327 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306328 }
6329 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6330 return -ENOMEM;
6331
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306332}
6333
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306334#undef MAX_CONCURRENT_MATRIX
6335#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6336
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306337static int
6338wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6339 struct wireless_dev *wdev,
6340 const void *data, int data_len)
6341{
6342 int ret = 0;
6343
6344 vos_ssr_protect(__func__);
6345 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6346 data_len);
6347 vos_ssr_unprotect(__func__);
6348
6349 return ret;
6350}
6351
c_manjeecfd1efb2015-09-25 19:32:34 +05306352
6353static int
6354__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6355 struct wireless_dev *wdev,
6356 const void *data, int data_len)
6357{
6358 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6359 int ret;
6360 ENTER();
6361
6362 ret = wlan_hdd_validate_context(pHddCtx);
6363 if (0 != ret)
6364 {
6365 return ret;
6366 }
6367
6368 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6369 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6370 {
6371 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306372 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306373 }
6374 /*call common API for FW mem dump req*/
6375 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6376
Abhishek Singhc783fa72015-12-09 18:07:34 +05306377 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306378 {
6379 /*indicate to userspace the status of fw mem dump */
6380 wlan_indicate_mem_dump_complete(true);
6381 }
6382 else
6383 {
6384 /*else send failure to userspace */
6385 wlan_indicate_mem_dump_complete(false);
6386 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306387 EXIT();
6388 return ret;
6389}
6390
6391/**
6392 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6393 * @wiphy: pointer to wireless wiphy structure.
6394 * @wdev: pointer to wireless_dev structure.
6395 * @data: Pointer to the NL data.
6396 * @data_len:Length of @data
6397 *
6398 * This is called when wlan driver needs to get the firmware memory dump
6399 * via vendor specific command.
6400 *
6401 * Return: 0 on success, error number otherwise.
6402 */
6403
6404static int
6405wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6406 struct wireless_dev *wdev,
6407 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306408{
6409 int ret = 0;
6410 vos_ssr_protect(__func__);
6411 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6412 data_len);
6413 vos_ssr_unprotect(__func__);
6414 return ret;
6415}
c_manjeecfd1efb2015-09-25 19:32:34 +05306416
Sushant Kaushik8e644982015-09-23 12:18:54 +05306417static const struct
6418nla_policy
6419qca_wlan_vendor_wifi_logger_start_policy
6420[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6421 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6422 = {.type = NLA_U32 },
6423 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6424 = {.type = NLA_U32 },
6425 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6426 = {.type = NLA_U32 },
6427};
6428
6429/**
6430 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6431 * or disable the collection of packet statistics from the firmware
6432 * @wiphy: WIPHY structure pointer
6433 * @wdev: Wireless device structure pointer
6434 * @data: Pointer to the data received
6435 * @data_len: Length of the data received
6436 *
6437 * This function is used to enable or disable the collection of packet
6438 * statistics from the firmware
6439 *
6440 * Return: 0 on success and errno on failure
6441 */
6442static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6443 struct wireless_dev *wdev,
6444 const void *data,
6445 int data_len)
6446{
6447 eHalStatus status;
6448 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6449 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6450 tAniWifiStartLog start_log;
6451
6452 status = wlan_hdd_validate_context(hdd_ctx);
6453 if (0 != status) {
6454 return -EINVAL;
6455 }
6456
6457 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6458 data, data_len,
6459 qca_wlan_vendor_wifi_logger_start_policy)) {
6460 hddLog(LOGE, FL("Invalid attribute"));
6461 return -EINVAL;
6462 }
6463
6464 /* Parse and fetch ring id */
6465 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6466 hddLog(LOGE, FL("attr ATTR failed"));
6467 return -EINVAL;
6468 }
6469 start_log.ringId = nla_get_u32(
6470 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6471 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6472
6473 /* Parse and fetch verbose level */
6474 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6475 hddLog(LOGE, FL("attr verbose_level failed"));
6476 return -EINVAL;
6477 }
6478 start_log.verboseLevel = nla_get_u32(
6479 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6480 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6481
6482 /* Parse and fetch flag */
6483 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6484 hddLog(LOGE, FL("attr flag failed"));
6485 return -EINVAL;
6486 }
6487 start_log.flag = nla_get_u32(
6488 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6489 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6490
6491 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306492 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6493 !vos_isPktStatsEnabled()))
6494
Sushant Kaushik8e644982015-09-23 12:18:54 +05306495 {
6496 hddLog(LOGE, FL("per pkt stats not enabled"));
6497 return -EINVAL;
6498 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306499
Sushant Kaushik33200572015-08-05 16:46:20 +05306500 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306501 return 0;
6502}
6503
6504/**
6505 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6506 * or disable the collection of packet statistics from the firmware
6507 * @wiphy: WIPHY structure pointer
6508 * @wdev: Wireless device structure pointer
6509 * @data: Pointer to the data received
6510 * @data_len: Length of the data received
6511 *
6512 * This function is used to enable or disable the collection of packet
6513 * statistics from the firmware
6514 *
6515 * Return: 0 on success and errno on failure
6516 */
6517static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6518 struct wireless_dev *wdev,
6519 const void *data,
6520 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306521{
6522 int ret = 0;
6523
6524 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306525
6526 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6527 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306528 vos_ssr_unprotect(__func__);
6529
6530 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306531}
6532
6533
Agarwal Ashish738843c2014-09-25 12:27:56 +05306534static const struct nla_policy
6535wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6536 +1] =
6537{
6538 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6539};
6540
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306541static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306542 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306543 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306544 int data_len)
6545{
6546 struct net_device *dev = wdev->netdev;
6547 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6548 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6549 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6550 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6551 eHalStatus status;
6552 u32 dfsFlag = 0;
6553
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306554 ENTER();
6555
Agarwal Ashish738843c2014-09-25 12:27:56 +05306556 status = wlan_hdd_validate_context(pHddCtx);
6557 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306558 return -EINVAL;
6559 }
6560 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6561 data, data_len,
6562 wlan_hdd_set_no_dfs_flag_config_policy)) {
6563 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6564 return -EINVAL;
6565 }
6566
6567 /* Parse and fetch required bandwidth kbps */
6568 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6569 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6570 return -EINVAL;
6571 }
6572
6573 dfsFlag = nla_get_u32(
6574 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6575 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6576 dfsFlag);
6577
6578 pHddCtx->disable_dfs_flag = dfsFlag;
6579
6580 sme_disable_dfs_channel(hHal, dfsFlag);
6581 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306582
6583 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306584 return 0;
6585}
Atul Mittal115287b2014-07-08 13:26:33 +05306586
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306587static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6588 struct wireless_dev *wdev,
6589 const void *data,
6590 int data_len)
6591{
6592 int ret = 0;
6593
6594 vos_ssr_protect(__func__);
6595 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6596 vos_ssr_unprotect(__func__);
6597
6598 return ret;
6599
6600}
6601
Mukul Sharma2a271632014-10-13 14:59:01 +05306602const struct
6603nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6604{
6605 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306606 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6607 .type = NLA_UNSPEC,
6608 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306609};
6610
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306611static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306612 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306613{
6614
6615 u8 bssid[6] = {0};
6616 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6617 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6618 eHalStatus status = eHAL_STATUS_SUCCESS;
6619 v_U32_t isFwrRoamEnabled = FALSE;
6620 int ret;
6621
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306622 ENTER();
6623
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306624 ret = wlan_hdd_validate_context(pHddCtx);
6625 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306626 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306627 }
6628
6629 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6630 data, data_len,
6631 qca_wlan_vendor_attr);
6632 if (ret){
6633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6634 return -EINVAL;
6635 }
6636
6637 /* Parse and fetch Enable flag */
6638 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6640 return -EINVAL;
6641 }
6642
6643 isFwrRoamEnabled = nla_get_u32(
6644 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6645
6646 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6647
6648 /* Parse and fetch bssid */
6649 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6651 return -EINVAL;
6652 }
6653
6654 memcpy(bssid, nla_data(
6655 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6656 sizeof(bssid));
6657 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6658
6659 //Update roaming
6660 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306661 if (!HAL_STATUS_SUCCESS(status)) {
6662 hddLog(LOGE,
6663 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6664 return -EINVAL;
6665 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306666 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306667 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306668}
6669
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306670static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6671 struct wireless_dev *wdev, const void *data, int data_len)
6672{
6673 int ret = 0;
6674
6675 vos_ssr_protect(__func__);
6676 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6677 vos_ssr_unprotect(__func__);
6678
6679 return ret;
6680}
6681
Sushant Kaushik847890c2015-09-28 16:05:17 +05306682static const struct
6683nla_policy
6684qca_wlan_vendor_get_wifi_info_policy[
6685 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6686 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6687 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6688};
6689
6690
6691/**
6692 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6693 * @wiphy: pointer to wireless wiphy structure.
6694 * @wdev: pointer to wireless_dev structure.
6695 * @data: Pointer to the data to be passed via vendor interface
6696 * @data_len:Length of the data to be passed
6697 *
6698 * This is called when wlan driver needs to send wifi driver related info
6699 * (driver/fw version) to the user space application upon request.
6700 *
6701 * Return: Return the Success or Failure code.
6702 */
6703static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6704 struct wireless_dev *wdev,
6705 const void *data, int data_len)
6706{
6707 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6708 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6709 tSirVersionString version;
6710 uint32 version_len;
6711 uint8 attr;
6712 int status;
6713 struct sk_buff *reply_skb = NULL;
6714
6715 if (VOS_FTM_MODE == hdd_get_conparam()) {
6716 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6717 return -EINVAL;
6718 }
6719
6720 status = wlan_hdd_validate_context(hdd_ctx);
6721 if (0 != status) {
6722 hddLog(LOGE, FL("HDD context is not valid"));
6723 return -EINVAL;
6724 }
6725
6726 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6727 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6728 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6729 return -EINVAL;
6730 }
6731
6732 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6733 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6734 QWLAN_VERSIONSTR);
6735 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6736 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6737 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6738 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6739 hdd_ctx->fw_Version);
6740 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6741 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6742 } else {
6743 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6744 return -EINVAL;
6745 }
6746
6747 version_len = strlen(version);
6748 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6749 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6750 if (!reply_skb) {
6751 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6752 return -ENOMEM;
6753 }
6754
6755 if (nla_put(reply_skb, attr, version_len, version)) {
6756 hddLog(LOGE, FL("nla put fail"));
6757 kfree_skb(reply_skb);
6758 return -EINVAL;
6759 }
6760
6761 return cfg80211_vendor_cmd_reply(reply_skb);
6762}
6763
6764/**
6765 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6766 * @wiphy: pointer to wireless wiphy structure.
6767 * @wdev: pointer to wireless_dev structure.
6768 * @data: Pointer to the data to be passed via vendor interface
6769 * @data_len:Length of the data to be passed
6770 * @data_len: Length of the data received
6771 *
6772 * This function is used to enable or disable the collection of packet
6773 * statistics from the firmware
6774 *
6775 * Return: 0 on success and errno on failure
6776 */
6777
6778static int
6779wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6780 struct wireless_dev *wdev,
6781 const void *data, int data_len)
6782
6783
6784{
6785 int ret = 0;
6786
6787 vos_ssr_protect(__func__);
6788 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6789 wdev, data, data_len);
6790 vos_ssr_unprotect(__func__);
6791
6792 return ret;
6793}
6794
6795
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306796/*
6797 * define short names for the global vendor params
6798 * used by __wlan_hdd_cfg80211_monitor_rssi()
6799 */
6800#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6801#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6802#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6803#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6804#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6805
6806/**---------------------------------------------------------------------------
6807
6808 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6809 monitor start is completed successfully.
6810
6811 \return - None
6812
6813 --------------------------------------------------------------------------*/
6814void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6815{
6816 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6817
6818 if (NULL == pHddCtx)
6819 {
6820 hddLog(VOS_TRACE_LEVEL_ERROR,
6821 "%s: HDD context is NULL",__func__);
6822 return;
6823 }
6824
6825 if (VOS_STATUS_SUCCESS == status)
6826 {
6827 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6828 }
6829 else
6830 {
6831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6832 }
6833
6834 return;
6835}
6836
6837/**---------------------------------------------------------------------------
6838
6839 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6840 stop is completed successfully.
6841
6842 \return - None
6843
6844 --------------------------------------------------------------------------*/
6845void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6846{
6847 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6848
6849 if (NULL == pHddCtx)
6850 {
6851 hddLog(VOS_TRACE_LEVEL_ERROR,
6852 "%s: HDD context is NULL",__func__);
6853 return;
6854 }
6855
6856 if (VOS_STATUS_SUCCESS == status)
6857 {
6858 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6859 }
6860 else
6861 {
6862 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6863 }
6864
6865 return;
6866}
6867
6868/**
6869 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6870 * @wiphy: Pointer to wireless phy
6871 * @wdev: Pointer to wireless device
6872 * @data: Pointer to data
6873 * @data_len: Data length
6874 *
6875 * Return: 0 on success, negative errno on failure
6876 */
6877
6878static int
6879__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6880 struct wireless_dev *wdev,
6881 const void *data,
6882 int data_len)
6883{
6884 struct net_device *dev = wdev->netdev;
6885 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6886 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6887 hdd_station_ctx_t *pHddStaCtx;
6888 struct nlattr *tb[PARAM_MAX + 1];
6889 tpSirRssiMonitorReq pReq;
6890 eHalStatus status;
6891 int ret;
6892 uint32_t control;
6893 static const struct nla_policy policy[PARAM_MAX + 1] = {
6894 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6895 [PARAM_CONTROL] = { .type = NLA_U32 },
6896 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6897 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6898 };
6899
6900 ENTER();
6901
6902 ret = wlan_hdd_validate_context(hdd_ctx);
6903 if (0 != ret) {
6904 return -EINVAL;
6905 }
6906
6907 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6908 hddLog(LOGE, FL("Not in Connected state!"));
6909 return -ENOTSUPP;
6910 }
6911
6912 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6913 hddLog(LOGE, FL("Invalid ATTR"));
6914 return -EINVAL;
6915 }
6916
6917 if (!tb[PARAM_REQUEST_ID]) {
6918 hddLog(LOGE, FL("attr request id failed"));
6919 return -EINVAL;
6920 }
6921
6922 if (!tb[PARAM_CONTROL]) {
6923 hddLog(LOGE, FL("attr control failed"));
6924 return -EINVAL;
6925 }
6926
6927 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6928
6929 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6930 if(NULL == pReq)
6931 {
6932 hddLog(LOGE,
6933 FL("vos_mem_alloc failed "));
6934 return eHAL_STATUS_FAILED_ALLOC;
6935 }
6936 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6937
6938 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6939 pReq->sessionId = pAdapter->sessionId;
6940 pReq->rssiMonitorCbContext = hdd_ctx;
6941 control = nla_get_u32(tb[PARAM_CONTROL]);
6942 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6943
6944 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6945 pReq->requestId, pReq->sessionId, control);
6946
6947 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6948 if (!tb[PARAM_MIN_RSSI]) {
6949 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306950 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306951 }
6952
6953 if (!tb[PARAM_MAX_RSSI]) {
6954 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306955 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306956 }
6957
6958 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6959 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6960 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6961
6962 if (!(pReq->minRssi < pReq->maxRssi)) {
6963 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6964 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306965 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306966 }
6967 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6968 pReq->minRssi, pReq->maxRssi);
6969 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6970
6971 }
6972 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6973 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6974 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6975 }
6976 else {
6977 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306978 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306979 }
6980
6981 if (!HAL_STATUS_SUCCESS(status)) {
6982 hddLog(LOGE,
6983 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306984 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306985 }
6986
6987 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306988fail:
6989 vos_mem_free(pReq);
6990 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306991}
6992
6993/*
6994 * done with short names for the global vendor params
6995 * used by __wlan_hdd_cfg80211_monitor_rssi()
6996 */
6997#undef PARAM_MAX
6998#undef PARAM_CONTROL
6999#undef PARAM_REQUEST_ID
7000#undef PARAM_MAX_RSSI
7001#undef PARAM_MIN_RSSI
7002
7003/**
7004 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7005 * @wiphy: wiphy structure pointer
7006 * @wdev: Wireless device structure pointer
7007 * @data: Pointer to the data received
7008 * @data_len: Length of @data
7009 *
7010 * Return: 0 on success; errno on failure
7011 */
7012static int
7013wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7014 const void *data, int data_len)
7015{
7016 int ret;
7017
7018 vos_ssr_protect(__func__);
7019 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7020 vos_ssr_unprotect(__func__);
7021
7022 return ret;
7023}
7024
7025/**
7026 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7027 * @hddctx: HDD context
7028 * @data: rssi breached event data
7029 *
7030 * This function reads the rssi breached event %data and fill in the skb with
7031 * NL attributes and send up the NL event.
7032 * This callback execute in atomic context and must not invoke any
7033 * blocking calls.
7034 *
7035 * Return: none
7036 */
7037void hdd_rssi_threshold_breached_cb(void *hddctx,
7038 struct rssi_breach_event *data)
7039{
7040 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7041 int status;
7042 struct sk_buff *skb;
7043
7044 ENTER();
7045 status = wlan_hdd_validate_context(pHddCtx);
7046
7047 if (0 != status) {
7048 return;
7049 }
7050
7051 if (!data) {
7052 hddLog(LOGE, FL("data is null"));
7053 return;
7054 }
7055
7056 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7057#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7058 NULL,
7059#endif
7060 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7061 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7062 GFP_KERNEL);
7063
7064 if (!skb) {
7065 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7066 return;
7067 }
7068
7069 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7070 data->request_id, data->curr_rssi);
7071 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7072 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7073
7074 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7075 data->request_id) ||
7076 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7077 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7078 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7079 data->curr_rssi)) {
7080 hddLog(LOGE, FL("nla put fail"));
7081 goto fail;
7082 }
7083
7084 cfg80211_vendor_event(skb, GFP_KERNEL);
7085 return;
7086
7087fail:
7088 kfree_skb(skb);
7089 return;
7090}
7091
7092
7093
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307094/**
7095 * __wlan_hdd_cfg80211_setband() - set band
7096 * @wiphy: Pointer to wireless phy
7097 * @wdev: Pointer to wireless device
7098 * @data: Pointer to data
7099 * @data_len: Data length
7100 *
7101 * Return: 0 on success, negative errno on failure
7102 */
7103static int
7104__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7105 struct wireless_dev *wdev,
7106 const void *data,
7107 int data_len)
7108{
7109 struct net_device *dev = wdev->netdev;
7110 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7111 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7112 int ret;
7113 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7114 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7115
7116 ENTER();
7117
7118 ret = wlan_hdd_validate_context(hdd_ctx);
7119 if (0 != ret) {
7120 hddLog(LOGE, FL("HDD context is not valid"));
7121 return ret;
7122 }
7123
7124 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7125 policy)) {
7126 hddLog(LOGE, FL("Invalid ATTR"));
7127 return -EINVAL;
7128 }
7129
7130 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7131 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7132 return -EINVAL;
7133 }
7134
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307135 hdd_ctx->isSetBandByNL = TRUE;
7136 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307137 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307138 hdd_ctx->isSetBandByNL = FALSE;
7139
7140 EXIT();
7141 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307142}
7143
7144/**
7145 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7146 * @wiphy: wiphy structure pointer
7147 * @wdev: Wireless device structure pointer
7148 * @data: Pointer to the data received
7149 * @data_len: Length of @data
7150 *
7151 * Return: 0 on success; errno on failure
7152 */
7153static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7154 struct wireless_dev *wdev,
7155 const void *data,
7156 int data_len)
7157{
7158 int ret = 0;
7159
7160 vos_ssr_protect(__func__);
7161 ret = __wlan_hdd_cfg80211_setband(wiphy,
7162 wdev, data, data_len);
7163 vos_ssr_unprotect(__func__);
7164
7165 return ret;
7166}
7167
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307168#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7169/**
7170 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7171 * @hdd_ctx: HDD context
7172 * @request_id: [input] request id
7173 * @pattern_id: [output] pattern id
7174 *
7175 * This function loops through request id to pattern id array
7176 * if the slot is available, store the request id and return pattern id
7177 * if entry exists, return the pattern id
7178 *
7179 * Return: 0 on success and errno on failure
7180 */
7181static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7182 uint32_t request_id,
7183 uint8_t *pattern_id)
7184{
7185 uint32_t i;
7186
7187 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7188 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7189 {
7190 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7191 {
7192 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7193 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7194 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7195 return 0;
7196 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7197 request_id) {
7198 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7199 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7200 return 0;
7201 }
7202 }
7203 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7204 return -EINVAL;
7205}
7206
7207/**
7208 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7209 * @hdd_ctx: HDD context
7210 * @request_id: [input] request id
7211 * @pattern_id: [output] pattern id
7212 *
7213 * This function loops through request id to pattern id array
7214 * reset request id to 0 (slot available again) and
7215 * return pattern id
7216 *
7217 * Return: 0 on success and errno on failure
7218 */
7219static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7220 uint32_t request_id,
7221 uint8_t *pattern_id)
7222{
7223 uint32_t i;
7224
7225 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7226 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7227 {
7228 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7229 {
7230 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7231 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7232 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7233 return 0;
7234 }
7235 }
7236 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7237 return -EINVAL;
7238}
7239
7240
7241/*
7242 * define short names for the global vendor params
7243 * used by __wlan_hdd_cfg80211_offloaded_packets()
7244 */
7245#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7246#define PARAM_REQUEST_ID \
7247 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7248#define PARAM_CONTROL \
7249 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7250#define PARAM_IP_PACKET \
7251 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7252#define PARAM_SRC_MAC_ADDR \
7253 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7254#define PARAM_DST_MAC_ADDR \
7255 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7256#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7257
7258/**
7259 * wlan_hdd_add_tx_ptrn() - add tx pattern
7260 * @adapter: adapter pointer
7261 * @hdd_ctx: hdd context
7262 * @tb: nl attributes
7263 *
7264 * This function reads the NL attributes and forms a AddTxPtrn message
7265 * posts it to SME.
7266 *
7267 */
7268static int
7269wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7270 struct nlattr **tb)
7271{
7272 struct sSirAddPeriodicTxPtrn *add_req;
7273 eHalStatus status;
7274 uint32_t request_id, ret, len;
7275 uint8_t pattern_id = 0;
7276 v_MACADDR_t dst_addr;
7277 uint16_t eth_type = htons(ETH_P_IP);
7278
7279 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7280 {
7281 hddLog(LOGE, FL("Not in Connected state!"));
7282 return -ENOTSUPP;
7283 }
7284
7285 add_req = vos_mem_malloc(sizeof(*add_req));
7286 if (!add_req)
7287 {
7288 hddLog(LOGE, FL("memory allocation failed"));
7289 return -ENOMEM;
7290 }
7291
7292 /* Parse and fetch request Id */
7293 if (!tb[PARAM_REQUEST_ID])
7294 {
7295 hddLog(LOGE, FL("attr request id failed"));
7296 goto fail;
7297 }
7298
7299 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7300 hddLog(LOG1, FL("Request Id: %u"), request_id);
7301 if (request_id == 0)
7302 {
7303 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307304 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307305 }
7306
7307 if (!tb[PARAM_PERIOD])
7308 {
7309 hddLog(LOGE, FL("attr period failed"));
7310 goto fail;
7311 }
7312 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7313 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7314 if (add_req->usPtrnIntervalMs == 0)
7315 {
7316 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7317 goto fail;
7318 }
7319
7320 if (!tb[PARAM_SRC_MAC_ADDR])
7321 {
7322 hddLog(LOGE, FL("attr source mac address failed"));
7323 goto fail;
7324 }
7325 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7326 VOS_MAC_ADDR_SIZE);
7327 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7328 MAC_ADDR_ARRAY(add_req->macAddress));
7329
7330 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7331 VOS_MAC_ADDR_SIZE))
7332 {
7333 hddLog(LOGE,
7334 FL("input src mac address and connected ap bssid are different"));
7335 goto fail;
7336 }
7337
7338 if (!tb[PARAM_DST_MAC_ADDR])
7339 {
7340 hddLog(LOGE, FL("attr dst mac address failed"));
7341 goto fail;
7342 }
7343 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7344 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7345 MAC_ADDR_ARRAY(dst_addr.bytes));
7346
7347 if (!tb[PARAM_IP_PACKET])
7348 {
7349 hddLog(LOGE, FL("attr ip packet failed"));
7350 goto fail;
7351 }
7352 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7353 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7354
7355 if (add_req->ucPtrnSize < 0 ||
7356 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7357 HDD_ETH_HEADER_LEN))
7358 {
7359 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7360 add_req->ucPtrnSize);
7361 goto fail;
7362 }
7363
7364 len = 0;
7365 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7366 len += VOS_MAC_ADDR_SIZE;
7367 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7368 VOS_MAC_ADDR_SIZE);
7369 len += VOS_MAC_ADDR_SIZE;
7370 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7371 len += 2;
7372
7373 /*
7374 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7375 * ------------------------------------------------------------
7376 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7377 * ------------------------------------------------------------
7378 */
7379 vos_mem_copy(&add_req->ucPattern[len],
7380 nla_data(tb[PARAM_IP_PACKET]),
7381 add_req->ucPtrnSize);
7382 add_req->ucPtrnSize += len;
7383
7384 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7385 add_req->ucPattern, add_req->ucPtrnSize);
7386
7387 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7388 if (ret)
7389 {
7390 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7391 goto fail;
7392 }
7393 add_req->ucPtrnId = pattern_id;
7394 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7395
7396 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7397 if (!HAL_STATUS_SUCCESS(status))
7398 {
7399 hddLog(LOGE,
7400 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7401 goto fail;
7402 }
7403
7404 EXIT();
7405 vos_mem_free(add_req);
7406 return 0;
7407
7408fail:
7409 vos_mem_free(add_req);
7410 return -EINVAL;
7411}
7412
7413/**
7414 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7415 * @adapter: adapter pointer
7416 * @hdd_ctx: hdd context
7417 * @tb: nl attributes
7418 *
7419 * This function reads the NL attributes and forms a DelTxPtrn message
7420 * posts it to SME.
7421 *
7422 */
7423static int
7424wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7425 struct nlattr **tb)
7426{
7427 struct sSirDelPeriodicTxPtrn *del_req;
7428 eHalStatus status;
7429 uint32_t request_id, ret;
7430 uint8_t pattern_id = 0;
7431
7432 /* Parse and fetch request Id */
7433 if (!tb[PARAM_REQUEST_ID])
7434 {
7435 hddLog(LOGE, FL("attr request id failed"));
7436 return -EINVAL;
7437 }
7438 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7439 if (request_id == 0)
7440 {
7441 hddLog(LOGE, FL("request_id cannot be zero"));
7442 return -EINVAL;
7443 }
7444
7445 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7446 if (ret)
7447 {
7448 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7449 return -EINVAL;
7450 }
7451
7452 del_req = vos_mem_malloc(sizeof(*del_req));
7453 if (!del_req)
7454 {
7455 hddLog(LOGE, FL("memory allocation failed"));
7456 return -ENOMEM;
7457 }
7458
7459 vos_mem_set(del_req, sizeof(*del_req), 0);
7460 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7461 VOS_MAC_ADDR_SIZE);
7462 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7463 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7464 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7465 request_id, pattern_id, del_req->ucPatternIdBitmap);
7466
7467 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7468 if (!HAL_STATUS_SUCCESS(status))
7469 {
7470 hddLog(LOGE,
7471 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7472 goto fail;
7473 }
7474
7475 EXIT();
7476 vos_mem_free(del_req);
7477 return 0;
7478
7479fail:
7480 vos_mem_free(del_req);
7481 return -EINVAL;
7482}
7483
7484
7485/**
7486 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7487 * @wiphy: Pointer to wireless phy
7488 * @wdev: Pointer to wireless device
7489 * @data: Pointer to data
7490 * @data_len: Data length
7491 *
7492 * Return: 0 on success, negative errno on failure
7493 */
7494static int
7495__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7496 struct wireless_dev *wdev,
7497 const void *data,
7498 int data_len)
7499{
7500 struct net_device *dev = wdev->netdev;
7501 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7502 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7503 struct nlattr *tb[PARAM_MAX + 1];
7504 uint8_t control;
7505 int ret;
7506 static const struct nla_policy policy[PARAM_MAX + 1] =
7507 {
7508 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7509 [PARAM_CONTROL] = { .type = NLA_U32 },
7510 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7511 .len = VOS_MAC_ADDR_SIZE },
7512 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7513 .len = VOS_MAC_ADDR_SIZE },
7514 [PARAM_PERIOD] = { .type = NLA_U32 },
7515 };
7516
7517 ENTER();
7518
7519 ret = wlan_hdd_validate_context(hdd_ctx);
7520 if (0 != ret)
7521 {
7522 hddLog(LOGE, FL("HDD context is not valid"));
7523 return ret;
7524 }
7525
7526 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7527 {
7528 hddLog(LOGE,
7529 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7530 return -ENOTSUPP;
7531 }
7532
7533 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7534 {
7535 hddLog(LOGE, FL("Invalid ATTR"));
7536 return -EINVAL;
7537 }
7538
7539 if (!tb[PARAM_CONTROL])
7540 {
7541 hddLog(LOGE, FL("attr control failed"));
7542 return -EINVAL;
7543 }
7544 control = nla_get_u32(tb[PARAM_CONTROL]);
7545 hddLog(LOG1, FL("Control: %d"), control);
7546
7547 if (control == WLAN_START_OFFLOADED_PACKETS)
7548 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7549 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7550 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7551 else
7552 {
7553 hddLog(LOGE, FL("Invalid control: %d"), control);
7554 return -EINVAL;
7555 }
7556}
7557
7558/*
7559 * done with short names for the global vendor params
7560 * used by __wlan_hdd_cfg80211_offloaded_packets()
7561 */
7562#undef PARAM_MAX
7563#undef PARAM_REQUEST_ID
7564#undef PARAM_CONTROL
7565#undef PARAM_IP_PACKET
7566#undef PARAM_SRC_MAC_ADDR
7567#undef PARAM_DST_MAC_ADDR
7568#undef PARAM_PERIOD
7569
7570/**
7571 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7572 * @wiphy: wiphy structure pointer
7573 * @wdev: Wireless device structure pointer
7574 * @data: Pointer to the data received
7575 * @data_len: Length of @data
7576 *
7577 * Return: 0 on success; errno on failure
7578 */
7579static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7580 struct wireless_dev *wdev,
7581 const void *data,
7582 int data_len)
7583{
7584 int ret = 0;
7585
7586 vos_ssr_protect(__func__);
7587 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7588 wdev, data, data_len);
7589 vos_ssr_unprotect(__func__);
7590
7591 return ret;
7592}
7593#endif
7594
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307595static const struct
7596nla_policy
7597qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307598 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7599 .type = NLA_BINARY,
7600 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307601};
7602
7603/**
7604 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7605 * get link properties like nss, rate flags and operating frequency for
7606 * the connection with the given peer.
7607 * @wiphy: WIPHY structure pointer
7608 * @wdev: Wireless device structure pointer
7609 * @data: Pointer to the data received
7610 * @data_len: Length of the data received
7611 *
7612 * This function return the above link properties on success.
7613 *
7614 * Return: 0 on success and errno on failure
7615 */
7616static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7617 struct wireless_dev *wdev,
7618 const void *data,
7619 int data_len)
7620{
7621 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7622 struct net_device *dev = wdev->netdev;
7623 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7624 hdd_station_ctx_t *hdd_sta_ctx;
7625 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7626 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7627 uint32_t sta_id;
7628 struct sk_buff *reply_skb;
7629 uint32_t rate_flags = 0;
7630 uint8_t nss;
7631 uint8_t final_rate_flags = 0;
7632 uint32_t freq;
7633 v_CONTEXT_t pVosContext = NULL;
7634 ptSapContext pSapCtx = NULL;
7635
7636 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7638 return -EINVAL;
7639 }
7640
7641 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7642 qca_wlan_vendor_attr_policy)) {
7643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7644 return -EINVAL;
7645 }
7646
7647 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7648 hddLog(VOS_TRACE_LEVEL_ERROR,
7649 FL("Attribute peerMac not provided for mode=%d"),
7650 adapter->device_mode);
7651 return -EINVAL;
7652 }
7653
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307654 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7655 hddLog(VOS_TRACE_LEVEL_ERROR,
7656 FL("Attribute peerMac is invalid=%d"),
7657 adapter->device_mode);
7658 return -EINVAL;
7659 }
7660
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307661 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7662 sizeof(peer_mac));
7663 hddLog(VOS_TRACE_LEVEL_INFO,
7664 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7665 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7666
7667 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7668 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7669 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7670 if ((hdd_sta_ctx->conn_info.connState !=
7671 eConnectionState_Associated) ||
7672 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7673 VOS_MAC_ADDRESS_LEN)) {
7674 hddLog(VOS_TRACE_LEVEL_ERROR,
7675 FL("Not Associated to mac "MAC_ADDRESS_STR),
7676 MAC_ADDR_ARRAY(peer_mac));
7677 return -EINVAL;
7678 }
7679
7680 nss = 1; //pronto supports only one spatial stream
7681 freq = vos_chan_to_freq(
7682 hdd_sta_ctx->conn_info.operationChannel);
7683 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7684
7685 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7686 adapter->device_mode == WLAN_HDD_SOFTAP) {
7687
7688 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7689 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7690 if(pSapCtx == NULL){
7691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7692 FL("psapCtx is NULL"));
7693 return -ENOENT;
7694 }
7695
7696
7697 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7698 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7699 !vos_is_macaddr_broadcast(
7700 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7701 vos_mem_compare(
7702 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7703 peer_mac, VOS_MAC_ADDRESS_LEN))
7704 break;
7705 }
7706
7707 if (WLAN_MAX_STA_COUNT == sta_id) {
7708 hddLog(VOS_TRACE_LEVEL_ERROR,
7709 FL("No active peer with mac="MAC_ADDRESS_STR),
7710 MAC_ADDR_ARRAY(peer_mac));
7711 return -EINVAL;
7712 }
7713
7714 nss = 1; //pronto supports only one spatial stream
7715 freq = vos_chan_to_freq(
7716 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7717 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7718 } else {
7719 hddLog(VOS_TRACE_LEVEL_ERROR,
7720 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7721 MAC_ADDR_ARRAY(peer_mac));
7722 return -EINVAL;
7723 }
7724
7725 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7726 if (rate_flags & eHAL_TX_RATE_VHT80) {
7727 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307728#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7729 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307730 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307731#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307732 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7733 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307734#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7735 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307736 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307737#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307738 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7739 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7740 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7741 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307742#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7743 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307744 if (rate_flags & eHAL_TX_RATE_HT40)
7745 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307746#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307747 }
7748
7749 if (rate_flags & eHAL_TX_RATE_SGI) {
7750 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7751 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7752 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7753 }
7754 }
7755
7756 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7757 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7758
7759 if (NULL == reply_skb) {
7760 hddLog(VOS_TRACE_LEVEL_ERROR,
7761 FL("getLinkProperties: skb alloc failed"));
7762 return -EINVAL;
7763 }
7764
7765 if (nla_put_u8(reply_skb,
7766 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7767 nss) ||
7768 nla_put_u8(reply_skb,
7769 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7770 final_rate_flags) ||
7771 nla_put_u32(reply_skb,
7772 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7773 freq)) {
7774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7775 kfree_skb(reply_skb);
7776 return -EINVAL;
7777 }
7778
7779 return cfg80211_vendor_cmd_reply(reply_skb);
7780}
7781
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307782#define BEACON_MISS_THRESH_2_4 \
7783 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7784#define BEACON_MISS_THRESH_5_0 \
7785 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307786#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7787#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7788#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7789#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307790#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7791 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307792#define PARAM_FORCE_RSN_IE \
7793 QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307794/*
7795 * hdd_set_qpower() - Process the qpower command and invoke the SME api
7796 * @hdd_ctx: hdd context
7797 * @enable: Value received in the command, 1 for disable and 2 for enable
7798 *
7799 * Return: void
7800 */
7801static void hdd_set_qpower(hdd_context_t *hdd_ctx, uint8_t enable)
7802{
7803 if (!hdd_ctx) {
7804 hddLog(LOGE, "hdd_ctx NULL");
7805 return;
7806 }
7807
7808 sme_set_qpower(hdd_ctx->hHal, enable);
7809}
7810
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307811/**
7812 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7813 * vendor command
7814 *
7815 * @wiphy: wiphy device pointer
7816 * @wdev: wireless device pointer
7817 * @data: Vendor command data buffer
7818 * @data_len: Buffer length
7819 *
7820 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7821 *
7822 * Return: EOK or other error codes.
7823 */
7824
7825static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7826 struct wireless_dev *wdev,
7827 const void *data,
7828 int data_len)
7829{
7830 struct net_device *dev = wdev->netdev;
7831 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7832 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7833 hdd_station_ctx_t *pHddStaCtx;
7834 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7835 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307836 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307837 eHalStatus status;
7838 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307839 uint8_t hb_thresh_val;
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05307840 uint8_t qpower;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307841
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307842 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7843 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7844 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307845 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7846 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7847 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307848 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7849 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05307850 [PARAM_FORCE_RSN_IE] = {.type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307851 };
7852
7853 ENTER();
7854
7855 if (VOS_FTM_MODE == hdd_get_conparam()) {
7856 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7857 return -EINVAL;
7858 }
7859
7860 ret_val = wlan_hdd_validate_context(pHddCtx);
7861 if (ret_val) {
7862 return ret_val;
7863 }
7864
7865 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7866
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307867 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7868 hddLog(LOGE, FL("Invalid ATTR"));
7869 return -EINVAL;
7870 }
7871
7872 /* check the Wifi Capability */
7873 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7874 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7875 {
7876 hddLog(VOS_TRACE_LEVEL_ERROR,
7877 FL("WIFICONFIG not supported by Firmware"));
7878 return -EINVAL;
7879 }
7880
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307881 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7882 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7883 modifyRoamParamsReq.value =
7884 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7885
7886 if (eHAL_STATUS_SUCCESS !=
7887 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7888 {
7889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7890 ret_val = -EINVAL;
7891 }
7892 return ret_val;
7893 }
7894
7895 /* Moved this down in order to provide provision to set beacon
7896 * miss penalty count irrespective of connection state.
7897 */
7898 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7899 hddLog(LOGE, FL("Not in Connected state!"));
7900 return -ENOTSUPP;
7901 }
7902
7903 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307904
7905 if (!pReq) {
7906 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7907 "%s: Not able to allocate memory for tSetWifiConfigParams",
7908 __func__);
7909 return eHAL_STATUS_E_MALLOC_FAILED;
7910 }
7911
7912 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7913
7914 pReq->sessionId = pAdapter->sessionId;
7915 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7916
7917 if (tb[PARAM_MODULATED_DTIM]) {
7918 pReq->paramValue = nla_get_u32(
7919 tb[PARAM_MODULATED_DTIM]);
7920 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7921 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307922 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307923 hdd_set_pwrparams(pHddCtx);
7924 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7925 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7926
7927 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7928 iw_full_power_cbfn, pAdapter,
7929 eSME_FULL_PWR_NEEDED_BY_HDD);
7930 }
7931 else
7932 {
7933 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7934 }
7935 }
7936
7937 if (tb[PARAM_STATS_AVG_FACTOR]) {
7938 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7939 pReq->paramValue = nla_get_u16(
7940 tb[PARAM_STATS_AVG_FACTOR]);
7941 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7942 pReq->paramType, pReq->paramValue);
7943 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7944
7945 if (eHAL_STATUS_SUCCESS != status)
7946 {
7947 vos_mem_free(pReq);
7948 pReq = NULL;
7949 ret_val = -EPERM;
7950 return ret_val;
7951 }
7952 }
7953
7954
7955 if (tb[PARAM_GUARD_TIME]) {
7956 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7957 pReq->paramValue = nla_get_u32(
7958 tb[PARAM_GUARD_TIME]);
7959 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7960 pReq->paramType, pReq->paramValue);
7961 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7962
7963 if (eHAL_STATUS_SUCCESS != status)
7964 {
7965 vos_mem_free(pReq);
7966 pReq = NULL;
7967 ret_val = -EPERM;
7968 return ret_val;
7969 }
7970
7971 }
7972
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307973 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7974 hb_thresh_val = nla_get_u8(
7975 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7976
7977 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7978 hb_thresh_val);
7979 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7980 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7981 NULL, eANI_BOOLEAN_FALSE);
7982
7983 status = sme_update_hb_threshold(
7984 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7985 WNI_CFG_HEART_BEAT_THRESHOLD,
7986 hb_thresh_val, eCSR_BAND_24);
7987 if (eHAL_STATUS_SUCCESS != status) {
7988 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7989 vos_mem_free(pReq);
7990 pReq = NULL;
7991 return -EPERM;
7992 }
7993 }
7994
7995 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7996 hb_thresh_val = nla_get_u8(
7997 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7998
7999 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8000 hb_thresh_val);
8001 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8002 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8003 NULL, eANI_BOOLEAN_FALSE);
8004
8005 status = sme_update_hb_threshold(
8006 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8007 WNI_CFG_HEART_BEAT_THRESHOLD,
8008 hb_thresh_val, eCSR_BAND_5G);
8009 if (eHAL_STATUS_SUCCESS != status) {
8010 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8011 vos_mem_free(pReq);
8012 pReq = NULL;
8013 return -EPERM;
8014 }
8015 }
8016
Ashish Kumar Dhanotiyaf59c7762018-04-10 17:54:25 +05308017 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]) {
8018 qpower = nla_get_u8(
8019 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER]);
8020
8021 if(qpower > 1) {
8022 hddLog(LOGE, "Invalid QPOWER value %d", qpower);
8023 vos_mem_free(pReq);
8024 pReq = NULL;
8025 return -EINVAL;
8026 }
8027 /* FW is expacting qpower as 1 for Disable and 2 for enable */
8028 qpower++;
8029 hdd_set_qpower(pHddCtx, qpower);
8030 }
8031
Pragaspathi Thilagaraj03e2ab12018-06-22 12:19:48 +05308032 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] &&
8033 pHddCtx->cfg_ini->force_rsne_override) {
8034 uint8_t force_rsne_override;
8035
8036 force_rsne_override =
8037 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE]);
8038 if (force_rsne_override > 1) {
8039 hddLog(LOGE, "Invalid test_mode %d", force_rsne_override);
8040 ret_val = -EINVAL;
8041 }
8042 pHddCtx->force_rsne_override = force_rsne_override;
8043 hddLog(LOG1, "force_rsne_override - %d",
8044 pHddCtx->force_rsne_override);
8045 }
8046
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308047 EXIT();
8048 return ret_val;
8049}
8050
8051/**
8052 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8053 * vendor command
8054 *
8055 * @wiphy: wiphy device pointer
8056 * @wdev: wireless device pointer
8057 * @data: Vendor command data buffer
8058 * @data_len: Buffer length
8059 *
8060 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8061 *
8062 * Return: EOK or other error codes.
8063 */
8064static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8065 struct wireless_dev *wdev,
8066 const void *data,
8067 int data_len)
8068{
8069 int ret;
8070
8071 vos_ssr_protect(__func__);
8072 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8073 data, data_len);
8074 vos_ssr_unprotect(__func__);
8075
8076 return ret;
8077}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308078
8079/*
8080 * define short names for the global vendor params
8081 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8082 */
8083#define STATS_SET_INVALID \
8084 QCA_ATTR_NUD_STATS_SET_INVALID
8085#define STATS_SET_START \
8086 QCA_ATTR_NUD_STATS_SET_START
8087#define STATS_GW_IPV4 \
8088 QCA_ATTR_NUD_STATS_GW_IPV4
8089#define STATS_SET_MAX \
8090 QCA_ATTR_NUD_STATS_SET_MAX
8091
8092const struct nla_policy
8093qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8094{
8095 [STATS_SET_START] = {.type = NLA_FLAG },
8096 [STATS_GW_IPV4] = {.type = NLA_U32 },
8097};
8098
8099/**
8100 * hdd_set_nud_stats_cb() - hdd callback api to get status
8101 * @data: pointer to adapter
8102 * @rsp: status
8103 *
8104 * Return: None
8105 */
8106static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8107{
8108
8109 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8110
8111 if (NULL == adapter)
8112 return;
8113
8114 if (VOS_STATUS_SUCCESS == rsp) {
8115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8116 "%s success received STATS_SET_START", __func__);
8117 } else {
8118 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8119 "%s STATS_SET_START Failed!!", __func__);
8120 }
8121 return;
8122}
8123
8124/**
8125 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8126 * @wiphy: pointer to wireless wiphy structure.
8127 * @wdev: pointer to wireless_dev structure.
8128 * @data: pointer to apfind configuration data.
8129 * @data_len: the length in byte of apfind data.
8130 *
8131 * This is called when wlan driver needs to send arp stats to
8132 * firmware.
8133 *
8134 * Return: An error code or 0 on success.
8135 */
8136static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8137 struct wireless_dev *wdev,
8138 const void *data, int data_len)
8139{
8140 struct nlattr *tb[STATS_SET_MAX + 1];
8141 struct net_device *dev = wdev->netdev;
8142 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8143 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308144 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308145 setArpStatsParams arp_stats_params;
8146 int err = 0;
8147
8148 ENTER();
8149
8150 err = wlan_hdd_validate_context(hdd_ctx);
8151 if (0 != err)
8152 return err;
8153
8154 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8156 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8157 return -EINVAL;
8158 }
8159
8160 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8161 qca_wlan_vendor_set_nud_stats);
8162 if (err)
8163 {
8164 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8165 "%s STATS_SET_START ATTR", __func__);
8166 return err;
8167 }
8168
8169 if (tb[STATS_SET_START])
8170 {
8171 if (!tb[STATS_GW_IPV4]) {
8172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8173 "%s STATS_SET_START CMD", __func__);
8174 return -EINVAL;
8175 }
8176 arp_stats_params.flag = true;
8177 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8178 } else {
8179 arp_stats_params.flag = false;
8180 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308181 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8183 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308184 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8185 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308186
8187 arp_stats_params.pkt_type = 1; // ARP packet type
8188
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308189 if (arp_stats_params.flag) {
8190 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8191 WLANTL_SetARPFWDatapath(pVosContext, true);
8192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8193 "%s Set FW in data path for ARP with tgt IP :%d",
8194 __func__, hdd_ctx->track_arp_ip);
8195 }
8196 else {
8197 WLANTL_SetARPFWDatapath(pVosContext, false);
8198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8199 "%s Remove FW from data path", __func__);
8200 }
8201
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308202 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8203 arp_stats_params.data_ctx = adapter;
8204
8205 if (eHAL_STATUS_SUCCESS !=
8206 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8208 "%s STATS_SET_START CMD Failed!!", __func__);
8209 return -EINVAL;
8210 }
8211
8212 EXIT();
8213
8214 return err;
8215}
8216
8217/**
8218 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8219 * @wiphy: pointer to wireless wiphy structure.
8220 * @wdev: pointer to wireless_dev structure.
8221 * @data: pointer to apfind configuration data.
8222 * @data_len: the length in byte of apfind data.
8223 *
8224 * This is called when wlan driver needs to send arp stats to
8225 * firmware.
8226 *
8227 * Return: An error code or 0 on success.
8228 */
8229static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8230 struct wireless_dev *wdev,
8231 const void *data, int data_len)
8232{
8233 int ret;
8234
8235 vos_ssr_protect(__func__);
8236 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8237 vos_ssr_unprotect(__func__);
8238
8239 return ret;
8240}
8241#undef STATS_SET_INVALID
8242#undef STATS_SET_START
8243#undef STATS_GW_IPV4
8244#undef STATS_SET_MAX
8245
8246/*
8247 * define short names for the global vendor params
8248 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8249 */
8250#define STATS_GET_INVALID \
8251 QCA_ATTR_NUD_STATS_SET_INVALID
8252#define COUNT_FROM_NETDEV \
8253 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8254#define COUNT_TO_LOWER_MAC \
8255 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8256#define RX_COUNT_BY_LOWER_MAC \
8257 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8258#define COUNT_TX_SUCCESS \
8259 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8260#define RSP_RX_COUNT_BY_LOWER_MAC \
8261 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8262#define RSP_RX_COUNT_BY_UPPER_MAC \
8263 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8264#define RSP_COUNT_TO_NETDEV \
8265 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8266#define RSP_COUNT_OUT_OF_ORDER_DROP \
8267 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8268#define AP_LINK_ACTIVE \
8269 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8270#define AP_LINK_DAD \
8271 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8272#define STATS_GET_MAX \
8273 QCA_ATTR_NUD_STATS_GET_MAX
8274
8275const struct nla_policy
8276qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8277{
8278 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8279 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8280 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8281 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8282 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8283 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8284 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8285 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8286 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8287 [AP_LINK_DAD] = {.type = NLA_FLAG },
8288};
8289
8290static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8291{
8292
8293 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308294 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308295 struct hdd_nud_stats_context *context;
8296 int status;
8297
8298 ENTER();
8299
8300 if (NULL == adapter)
8301 return;
8302
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308303 if (!rsp) {
8304 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308305 return;
8306 }
8307
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308308 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8309 status = wlan_hdd_validate_context(hdd_ctx);
8310 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308311 return;
8312 }
8313
8314 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8315 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8316 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8317 adapter->dad |= rsp->dad;
8318
8319 spin_lock(&hdd_context_lock);
8320 context = &hdd_ctx->nud_stats_context;
8321 complete(&context->response_event);
8322 spin_unlock(&hdd_context_lock);
8323
8324 return;
8325}
8326static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8327 struct wireless_dev *wdev,
8328 const void *data, int data_len)
8329{
8330 int err = 0;
8331 unsigned long rc;
8332 struct hdd_nud_stats_context *context;
8333 struct net_device *dev = wdev->netdev;
8334 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8335 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8336 getArpStatsParams arp_stats_params;
8337 struct sk_buff *skb;
8338
8339 ENTER();
8340
8341 err = wlan_hdd_validate_context(hdd_ctx);
8342 if (0 != err)
8343 return err;
8344
8345 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8346 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8347 arp_stats_params.data_ctx = adapter;
8348
8349 spin_lock(&hdd_context_lock);
8350 context = &hdd_ctx->nud_stats_context;
8351 INIT_COMPLETION(context->response_event);
8352 spin_unlock(&hdd_context_lock);
8353
8354 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8356 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8357 return -EINVAL;
8358 }
8359
8360 if (eHAL_STATUS_SUCCESS !=
8361 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8363 "%s STATS_SET_START CMD Failed!!", __func__);
8364 return -EINVAL;
8365 }
8366
8367 rc = wait_for_completion_timeout(&context->response_event,
8368 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8369 if (!rc)
8370 {
8371 hddLog(LOGE,
8372 FL("Target response timed out request "));
8373 return -ETIMEDOUT;
8374 }
8375
8376 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8377 WLAN_NUD_STATS_LEN);
8378 if (!skb)
8379 {
8380 hddLog(VOS_TRACE_LEVEL_ERROR,
8381 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8382 __func__);
8383 return -ENOMEM;
8384 }
8385
8386 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8387 adapter->hdd_stats.hddArpStats.txCount) ||
8388 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8389 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8390 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8391 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8392 nla_put_u16(skb, COUNT_TX_SUCCESS,
8393 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8394 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8395 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8396 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8397 adapter->hdd_stats.hddArpStats.rxCount) ||
8398 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8399 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8400 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8401 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8402 hddLog(LOGE, FL("nla put fail"));
8403 kfree_skb(skb);
8404 return -EINVAL;
8405 }
8406 if (adapter->con_status)
8407 nla_put_flag(skb, AP_LINK_ACTIVE);
8408 if (adapter->dad)
8409 nla_put_flag(skb, AP_LINK_DAD);
8410
8411 cfg80211_vendor_cmd_reply(skb);
8412 return err;
8413}
8414
8415static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8416 struct wireless_dev *wdev,
8417 const void *data, int data_len)
8418{
8419 int ret;
8420
8421 vos_ssr_protect(__func__);
8422 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8423 vos_ssr_unprotect(__func__);
8424
8425 return ret;
8426}
8427
8428#undef QCA_ATTR_NUD_STATS_SET_INVALID
8429#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8430#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8431#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8432#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8433#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8434#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8435#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8436#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8437#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8438#undef QCA_ATTR_NUD_STATS_GET_MAX
8439
8440
8441
Kapil Guptaee33bf12016-12-20 18:27:37 +05308442#ifdef WLAN_FEATURE_APFIND
8443/**
8444 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8445 * @wiphy: pointer to wireless wiphy structure.
8446 * @wdev: pointer to wireless_dev structure.
8447 * @data: pointer to apfind configuration data.
8448 * @data_len: the length in byte of apfind data.
8449 *
8450 * This is called when wlan driver needs to send APFIND configurations to
8451 * firmware.
8452 *
8453 * Return: An error code or 0 on success.
8454 */
8455static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8456 struct wireless_dev *wdev,
8457 const void *data, int data_len)
8458{
8459 struct sme_ap_find_request_req apfind_req;
8460 VOS_STATUS status;
8461 int ret_val;
8462 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8463
8464 ENTER();
8465
8466 ret_val = wlan_hdd_validate_context(hdd_ctx);
8467 if (ret_val)
8468 return ret_val;
8469
8470 if (VOS_FTM_MODE == hdd_get_conparam()) {
8471 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8472 return -EPERM;
8473 }
8474
8475 apfind_req.request_data_len = data_len;
8476 apfind_req.request_data = data;
8477
8478 status = sme_apfind_set_cmd(&apfind_req);
8479 if (VOS_STATUS_SUCCESS != status) {
8480 ret_val = -EIO;
8481 }
8482 return ret_val;
8483}
8484
8485/**
8486 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8487 * @wiphy: pointer to wireless wiphy structure.
8488 * @wdev: pointer to wireless_dev structure.
8489 * @data: pointer to apfind configuration data.
8490 * @data_len: the length in byte of apfind data.
8491 *
8492 * This is called when wlan driver needs to send APFIND configurations to
8493 * firmware.
8494 *
8495 * Return: An error code or 0 on success.
8496 */
8497static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8498 struct wireless_dev *wdev,
8499 const void *data, int data_len)
8500{
8501 int ret;
8502
8503 vos_ssr_protect(__func__);
8504 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8505 vos_ssr_unprotect(__func__);
8506
8507 return ret;
8508}
8509#endif /* WLAN_FEATURE_APFIND */
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308510
8511/**
8512 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8513 * @wiphy: pointer to wireless wiphy structure.
8514 * @wdev: pointer to wireless_dev structure.
8515 * @data: Pointer to the data to be passed via vendor interface
8516 * @data_len:Length of the data to be passed
8517 *
8518 * This is called by userspace to know the supported logger features
8519 *
8520 * Return: Return the Success or Failure code.
8521 */
8522static int
8523__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8524 struct wireless_dev *wdev,
8525 const void *data, int data_len)
8526{
8527 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8528 int status;
8529 uint32_t features;
8530 struct sk_buff *reply_skb = NULL;
8531
8532 if (VOS_FTM_MODE == hdd_get_conparam()) {
8533 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8534 return -EINVAL;
8535 }
8536
8537 status = wlan_hdd_validate_context(hdd_ctx);
8538 if (0 != status)
8539 return -EINVAL;
8540
8541 features = 0;
8542
8543 if (hdd_is_memdump_supported())
8544 features |= WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
8545
8546 if (hdd_ctx->cfg_ini->wlanLoggingEnable &&
8547 hdd_ctx->cfg_ini->enableFatalEvent &&
8548 hdd_ctx->is_fatal_event_log_sup) {
8549 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
8550 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
8551 }
8552
8553 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8554 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
8555 if (!reply_skb) {
8556 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
8557 return -ENOMEM;
8558 }
8559
8560 hddLog(LOG1, FL("Supported logger features: 0x%0x"), features);
8561 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
8562 features)) {
8563 hddLog(LOGE, FL("nla put fail"));
8564 kfree_skb(reply_skb);
8565 return -EINVAL;
8566 }
8567
8568 return cfg80211_vendor_cmd_reply(reply_skb);
8569}
8570
8571/**
8572 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
8573 * @wiphy: pointer to wireless wiphy structure.
8574 * @wdev: pointer to wireless_dev structure.
8575 * @data: Pointer to the data to be passed via vendor interface
8576 * @data_len:Length of the data to be passed
8577 *
8578 * This is called by userspace to know the supported logger features
8579 *
8580 * Return: Return the Success or Failure code.
8581 */
8582static int
8583wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
8584 struct wireless_dev *wdev,
8585 const void *data, int data_len)
8586{
8587 int ret;
8588
8589 vos_ssr_protect(__func__);
8590 ret = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
8591 data, data_len);
8592 vos_ssr_unprotect(__func__);
8593
8594 return ret;
8595}
8596
Sunil Duttc69bccb2014-05-26 21:30:20 +05308597const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8598{
Mukul Sharma2a271632014-10-13 14:59:01 +05308599 {
8600 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8601 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8602 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8603 WIPHY_VENDOR_CMD_NEED_NETDEV |
8604 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308605 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308606 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308607
8608 {
8609 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8610 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8611 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8612 WIPHY_VENDOR_CMD_NEED_NETDEV |
8613 WIPHY_VENDOR_CMD_NEED_RUNNING,
8614 .doit = wlan_hdd_cfg80211_nan_request
8615 },
8616
Sunil Duttc69bccb2014-05-26 21:30:20 +05308617#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8618 {
8619 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8620 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8621 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8622 WIPHY_VENDOR_CMD_NEED_NETDEV |
8623 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308624 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308625 },
8626
8627 {
8628 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8629 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8630 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8631 WIPHY_VENDOR_CMD_NEED_NETDEV |
8632 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308633 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308634 },
8635
8636 {
8637 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8638 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8639 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8640 WIPHY_VENDOR_CMD_NEED_NETDEV |
8641 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308642 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308643 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308644#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308645#ifdef WLAN_FEATURE_EXTSCAN
8646 {
8647 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8648 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8649 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8650 WIPHY_VENDOR_CMD_NEED_NETDEV |
8651 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308652 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308653 },
8654 {
8655 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8656 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8657 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8658 WIPHY_VENDOR_CMD_NEED_NETDEV |
8659 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308660 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308661 },
8662 {
8663 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8664 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8665 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8666 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308667 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308668 },
8669 {
8670 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8671 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8672 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8673 WIPHY_VENDOR_CMD_NEED_NETDEV |
8674 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308675 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308676 },
8677 {
8678 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8679 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8680 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8681 WIPHY_VENDOR_CMD_NEED_NETDEV |
8682 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308683 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
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_SET_BSSID_HOTLIST,
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_set_bssid_hotlist
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_RESET_BSSID_HOTLIST,
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_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308700 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308701#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308702/*EXT TDLS*/
8703 {
8704 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8705 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8706 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8707 WIPHY_VENDOR_CMD_NEED_NETDEV |
8708 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308709 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308710 },
8711 {
8712 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8713 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8714 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8715 WIPHY_VENDOR_CMD_NEED_NETDEV |
8716 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308717 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308718 },
8719 {
8720 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8721 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8722 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8723 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308724 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308725 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308726 {
8727 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8728 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8729 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8730 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308731 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308732 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308733 {
8734 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8735 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8736 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8737 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308738 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308739 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308740 {
8741 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8742 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8743 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8744 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308745 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308746 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308747 {
8748 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8749 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8750 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8751 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308752 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308753 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308754 {
8755 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308756 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8757 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8758 WIPHY_VENDOR_CMD_NEED_NETDEV |
8759 WIPHY_VENDOR_CMD_NEED_RUNNING,
8760 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8761 },
8762 {
8763 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308764 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8765 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8766 WIPHY_VENDOR_CMD_NEED_NETDEV |
8767 WIPHY_VENDOR_CMD_NEED_RUNNING,
8768 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308769 },
8770 {
8771 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8772 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8773 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8774 WIPHY_VENDOR_CMD_NEED_NETDEV,
8775 .doit = wlan_hdd_cfg80211_wifi_logger_start
8776 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308777 {
8778 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8779 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8780 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8781 WIPHY_VENDOR_CMD_NEED_NETDEV|
8782 WIPHY_VENDOR_CMD_NEED_RUNNING,
8783 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308784 },
8785 {
8786 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8787 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8788 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8789 WIPHY_VENDOR_CMD_NEED_NETDEV |
8790 WIPHY_VENDOR_CMD_NEED_RUNNING,
8791 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308792 },
8793 {
8794 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8795 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8796 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8797 WIPHY_VENDOR_CMD_NEED_NETDEV |
8798 WIPHY_VENDOR_CMD_NEED_RUNNING,
8799 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308800 },
8801#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8802 {
8803 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8804 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8805 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8806 WIPHY_VENDOR_CMD_NEED_NETDEV |
8807 WIPHY_VENDOR_CMD_NEED_RUNNING,
8808 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308809 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308810#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308811 {
8812 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8813 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8814 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8815 WIPHY_VENDOR_CMD_NEED_NETDEV |
8816 WIPHY_VENDOR_CMD_NEED_RUNNING,
8817 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308818 },
8819 {
8820 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8821 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8822 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8823 WIPHY_VENDOR_CMD_NEED_NETDEV |
8824 WIPHY_VENDOR_CMD_NEED_RUNNING,
8825 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308826 },
8827#ifdef WLAN_FEATURE_APFIND
8828 {
8829 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8830 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8831 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8832 WIPHY_VENDOR_CMD_NEED_NETDEV,
8833 .doit = wlan_hdd_cfg80211_apfind_cmd
8834 },
8835#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308836 {
8837 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8838 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8839 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8840 WIPHY_VENDOR_CMD_NEED_NETDEV |
8841 WIPHY_VENDOR_CMD_NEED_RUNNING,
8842 .doit = wlan_hdd_cfg80211_set_nud_stats
8843 },
8844 {
8845 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8846 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8847 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8848 WIPHY_VENDOR_CMD_NEED_NETDEV |
8849 WIPHY_VENDOR_CMD_NEED_RUNNING,
8850 .doit = wlan_hdd_cfg80211_get_nud_stats
8851 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308852 {
8853 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8854 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8855 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8856 WIPHY_VENDOR_CMD_NEED_NETDEV |
8857 WIPHY_VENDOR_CMD_NEED_RUNNING,
8858 .doit = hdd_cfg80211_get_station_cmd
8859 },
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308860 {
8861 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8862 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
8863 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Hanumanth Reddy Pothula07c95582018-05-23 12:41:22 +05308864 WIPHY_VENDOR_CMD_NEED_NETDEV,
Hanumanth Reddy Pothula49c3f902018-02-16 16:01:13 +05308865 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
8866 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308867};
8868
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008869/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308870static const
8871struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008872{
8873#ifdef FEATURE_WLAN_CH_AVOID
8874 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308875 .vendor_id = QCA_NL80211_VENDOR_ID,
8876 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008877 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308878#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8879#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8880 {
8881 /* Index = 1*/
8882 .vendor_id = QCA_NL80211_VENDOR_ID,
8883 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8884 },
8885 {
8886 /* Index = 2*/
8887 .vendor_id = QCA_NL80211_VENDOR_ID,
8888 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8889 },
8890 {
8891 /* Index = 3*/
8892 .vendor_id = QCA_NL80211_VENDOR_ID,
8893 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8894 },
8895 {
8896 /* Index = 4*/
8897 .vendor_id = QCA_NL80211_VENDOR_ID,
8898 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8899 },
8900 {
8901 /* Index = 5*/
8902 .vendor_id = QCA_NL80211_VENDOR_ID,
8903 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8904 },
8905 {
8906 /* Index = 6*/
8907 .vendor_id = QCA_NL80211_VENDOR_ID,
8908 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8909 },
8910#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308911#ifdef WLAN_FEATURE_EXTSCAN
8912 {
8913 .vendor_id = QCA_NL80211_VENDOR_ID,
8914 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8915 },
8916 {
8917 .vendor_id = QCA_NL80211_VENDOR_ID,
8918 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8919 },
8920 {
8921 .vendor_id = QCA_NL80211_VENDOR_ID,
8922 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8923 },
8924 {
8925 .vendor_id = QCA_NL80211_VENDOR_ID,
8926 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8927 },
8928 {
8929 .vendor_id = QCA_NL80211_VENDOR_ID,
8930 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8931 },
8932 {
8933 .vendor_id = QCA_NL80211_VENDOR_ID,
8934 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8935 },
8936 {
8937 .vendor_id = QCA_NL80211_VENDOR_ID,
8938 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8939 },
8940 {
8941 .vendor_id = QCA_NL80211_VENDOR_ID,
8942 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8943 },
8944 {
8945 .vendor_id = QCA_NL80211_VENDOR_ID,
8946 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8947 },
8948 {
8949 .vendor_id = QCA_NL80211_VENDOR_ID,
8950 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8951 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308952#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308953/*EXT TDLS*/
8954 {
8955 .vendor_id = QCA_NL80211_VENDOR_ID,
8956 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8957 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308958 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8959 .vendor_id = QCA_NL80211_VENDOR_ID,
8960 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8961 },
8962
Srinivas Dasari030bad32015-02-18 23:23:54 +05308963
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308964 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308965 .vendor_id = QCA_NL80211_VENDOR_ID,
8966 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8967 },
8968
Sushant Kaushik084f6592015-09-10 13:11:56 +05308969 {
8970 .vendor_id = QCA_NL80211_VENDOR_ID,
8971 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308972 },
8973 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8974 .vendor_id = QCA_NL80211_VENDOR_ID,
8975 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8976 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308977 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8978 .vendor_id = QCA_NL80211_VENDOR_ID,
8979 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8980 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308981 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8982 .vendor_id = QCA_NL80211_VENDOR_ID,
8983 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8984 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308985 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8986 .vendor_id = QCA_NL80211_VENDOR_ID,
8987 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
8988 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05308989 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
8990 .vendor_id = QCA_NL80211_VENDOR_ID,
8991 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8992 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008993};
8994
Jeff Johnson295189b2012-06-20 16:38:30 -07008995/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308996 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308997 * This function is called by hdd_wlan_startup()
8998 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308999 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309001struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07009002{
9003 struct wiphy *wiphy;
9004 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309005 /*
9006 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07009007 */
9008 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
9009
9010 if (!wiphy)
9011 {
9012 /* Print error and jump into err label and free the memory */
9013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
9014 return NULL;
9015 }
9016
Sunil Duttc69bccb2014-05-26 21:30:20 +05309017
Jeff Johnson295189b2012-06-20 16:38:30 -07009018 return wiphy;
9019}
9020
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309021#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
9022 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
9023/**
9024 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
9025 * @wiphy: pointer to wiphy
9026 * @config: pointer to config
9027 *
9028 * Return: None
9029 */
9030static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9031 hdd_config_t *config)
9032{
9033 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
9034 if (config->max_sched_scan_plan_interval)
9035 wiphy->max_sched_scan_plan_interval =
9036 config->max_sched_scan_plan_interval;
9037 if (config->max_sched_scan_plan_iterations)
9038 wiphy->max_sched_scan_plan_iterations =
9039 config->max_sched_scan_plan_iterations;
9040}
9041#else
9042static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
9043 hdd_config_t *config)
9044{
9045}
9046#endif
9047
Jeff Johnson295189b2012-06-20 16:38:30 -07009048/*
9049 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309050 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07009051 * private ioctl to change the band value
9052 */
9053int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
9054{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309055 int i, j;
9056 eNVChannelEnabledType channelEnabledState;
9057
Jeff Johnsone7245742012-09-05 17:12:55 -07009058 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309059
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309060 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07009061 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309062
9063 if (NULL == wiphy->bands[i])
9064 {
9065 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
9066 __func__, i);
9067 continue;
9068 }
9069
9070 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9071 {
9072 struct ieee80211_supported_band *band = wiphy->bands[i];
9073
9074 channelEnabledState = vos_nv_getChannelEnabledState(
9075 band->channels[j].hw_value);
9076
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309077 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309078 {
Abhishek Singh678227a2014-11-04 10:52:38 +05309079 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309080 continue;
9081 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309082 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309083 {
9084 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9085 continue;
9086 }
9087
9088 if (NV_CHANNEL_DISABLE == channelEnabledState ||
9089 NV_CHANNEL_INVALID == channelEnabledState)
9090 {
9091 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9092 }
9093 else if (NV_CHANNEL_DFS == channelEnabledState)
9094 {
9095 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9096 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
9097 }
9098 else
9099 {
9100 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
9101 |IEEE80211_CHAN_RADAR);
9102 }
9103 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009104 }
9105 return 0;
9106}
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309107
9108/**
9109 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
9110 * @wiphy: Pointer to the wiphy.
9111 *
9112 * This Function adds Channel Switch support flag, if channel switch is
9113 * supported by kernel.
9114 * Return: void.
9115 */
9116#ifdef CHANNEL_SWITCH_SUPPORTED
9117static inline
9118void hdd_add_channel_switch_support(struct wiphy *wiphy)
9119{
9120 wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
9121 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
9122}
9123#else
9124static inline
9125void hdd_add_channel_switch_support(struct wiphy *wiphy)
9126{
9127}
9128#endif
9129
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +05309130#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
9131 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
9132void wlan_hdd_cfg80211_scan_randomization_init(struct wiphy *wiphy)
9133{
9134 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
9135 hdd_config_t *config = hdd_ctx->cfg_ini;
9136
9137 if (config->enableMacSpoofing != MAC_ADDR_SPOOFING_FW_HOST_ENABLE)
9138 return;
9139
9140 wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
9141}
9142#endif
9143
Abhinav Kumar118efd02019-08-07 16:41:07 +05309144#if defined(WLAN_FEATURE_SAE) && \
9145 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
Abhinav Kumar97821072019-08-02 14:29:48 +05309146/**
9147 * wlan_hdd_cfg80211_set_wiphy_sae_feature() - Indicates support of SAE feature
9148 * @wiphy: Pointer to wiphy
9149 * @config: pointer to config
9150 *
9151 * This function is used to indicate the support of SAE
9152 *
9153 * Return: None
9154 */
9155static
9156void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy,
9157 hdd_config_t *config)
9158{
9159 if (config->is_sae_enabled)
9160 wiphy->features |= NL80211_FEATURE_SAE;
9161}
9162#else
9163static
9164void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy,
9165 hdd_config_t *config)
9166{
9167}
9168#endif
9169
Jeff Johnson295189b2012-06-20 16:38:30 -07009170/*
9171 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309172 * This function is called by hdd_wlan_startup()
9173 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07009174 * This function is used to initialize and register wiphy structure.
9175 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309176int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009177 struct wiphy *wiphy,
9178 hdd_config_t *pCfg
9179 )
9180{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309181 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05309182 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9183
Jeff Johnsone7245742012-09-05 17:12:55 -07009184 ENTER();
9185
Jeff Johnson295189b2012-06-20 16:38:30 -07009186 /* Now bind the underlying wlan device with wiphy */
9187 set_wiphy_dev(wiphy, dev);
9188
9189 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009190
Kiet Lam6c583332013-10-14 05:37:09 +05309191#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009192 /* the flag for the other case would be initialzed in
9193 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309194#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9195 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9196#else
Amar Singhal0a402232013-10-11 20:57:16 -07009197 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309198#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309199#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009200
Amar Singhalfddc28c2013-09-05 13:03:40 -07009201 /* This will disable updating of NL channels from passive to
9202 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309203#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9204 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9205#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009206 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309207#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009208
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309209#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)) || defined(WITH_BACKPORTS)
9210 wiphy->wowlan = &wowlan_support_cfg80211_init;
9211#else
Nachiket Kukade1e1b90e2018-05-10 15:26:13 +05309212 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
9213 WIPHY_WOWLAN_MAGIC_PKT;
Nachiket Kukade5b2e7332018-04-06 14:40:22 +05309214 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
9215 wiphy->wowlan.pattern_min_len = 1;
9216 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
9217#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009218
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009219#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009220 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9221 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9222 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009223 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309224#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309225 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309226#else
9227 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9228#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009229#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009230
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009231#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009232 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009233#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009234 || pCfg->isFastRoamIniFeatureEnabled
9235#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009236#ifdef FEATURE_WLAN_ESE
9237 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009238#endif
9239 )
9240 {
9241 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9242 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009243#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009244#ifdef FEATURE_WLAN_TDLS
9245 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9246 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9247#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309248#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309249 if (pCfg->configPNOScanSupport)
9250 {
9251 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9252 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9253 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9254 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9255 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309256#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009257
Abhishek Singh10d85972015-04-17 10:27:23 +05309258#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9259 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9260#endif
9261
Amar Singhalfddc28c2013-09-05 13:03:40 -07009262#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009263 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9264 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009265 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009266 driver need to determine what to do with both
9267 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009268
9269 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009270#else
9271 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009272#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009273
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309274 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9275
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309276 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009277
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309278 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9279
Jeff Johnson295189b2012-06-20 16:38:30 -07009280 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309281 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9282 | BIT(NL80211_IFTYPE_ADHOC)
9283 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9284 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309285 | BIT(NL80211_IFTYPE_AP)
9286 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009287
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309288 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009289 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309290#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9291 if( pCfg->enableMCC )
9292 {
9293 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309294 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009295
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309296 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309297 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009298
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309299 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309300 wiphy->iface_combinations = wlan_hdd_iface_combination;
9301 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009302#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309303 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009304
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 /* Before registering we need to update the ht capabilitied based
9306 * on ini values*/
9307 if( !pCfg->ShortGI20MhzEnable )
9308 {
9309 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9310 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009311 }
9312
9313 if( !pCfg->ShortGI40MhzEnable )
9314 {
9315 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9316 }
9317
9318 if( !pCfg->nChannelBondingMode5GHz )
9319 {
9320 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9321 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309322 /*
9323 * In case of static linked driver at the time of driver unload,
9324 * module exit doesn't happens. Module cleanup helps in cleaning
9325 * of static memory.
9326 * If driver load happens statically, at the time of driver unload,
9327 * wiphy flags don't get reset because of static memory.
9328 * It's better not to store channel in static memory.
9329 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309330 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9331 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309332 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309333 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309334 {
9335 hddLog(VOS_TRACE_LEVEL_ERROR,
9336 FL("Not enough memory to allocate channels"));
9337 return -ENOMEM;
9338 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309339 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309340 &hdd_channels_2_4_GHZ[0],
9341 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009342
Agrawal Ashish97dec502015-11-26 20:20:58 +05309343 if (true == hdd_is_5g_supported(pHddCtx))
9344 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309345 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9346 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309347 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309348 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309349 {
9350 hddLog(VOS_TRACE_LEVEL_ERROR,
9351 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309352 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9353 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309354 return -ENOMEM;
9355 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309356 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309357 &hdd_channels_5_GHZ[0],
9358 sizeof(hdd_channels_5_GHZ));
9359 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309360
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309361 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309362 {
9363
9364 if (NULL == wiphy->bands[i])
9365 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309366 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309367 __func__, i);
9368 continue;
9369 }
9370
9371 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9372 {
9373 struct ieee80211_supported_band *band = wiphy->bands[i];
9374
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309375 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309376 {
9377 // Enable social channels for P2P
9378 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9379 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9380 else
9381 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9382 continue;
9383 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309384 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309385 {
9386 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9387 continue;
9388 }
9389 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009390 }
9391 /*Initialise the supported cipher suite details*/
9392 wiphy->cipher_suites = hdd_cipher_suites;
9393 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9394
9395 /*signal strength in mBm (100*dBm) */
9396 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9397
9398#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309399 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009400#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009401
Abhishek Singh2f3c4752018-04-11 14:58:53 +05309402 hdd_add_channel_switch_support(wiphy);
Sunil Duttc69bccb2014-05-26 21:30:20 +05309403 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9404 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009405 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9406 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9407
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309408 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
Abhinav Kumar97821072019-08-02 14:29:48 +05309409 wlan_hdd_cfg80211_set_wiphy_sae_feature(wiphy, pCfg);
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309410
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309411 EXIT();
9412 return 0;
9413}
9414
9415/* In this function we are registering wiphy. */
9416int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9417{
9418 ENTER();
9419 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 if (0 > wiphy_register(wiphy))
9421 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309422 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9424 return -EIO;
9425 }
9426
9427 EXIT();
9428 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309429}
Jeff Johnson295189b2012-06-20 16:38:30 -07009430
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309431/* In this function we are updating channel list when,
9432 regulatory domain is FCC and country code is US.
9433 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9434 As per FCC smart phone is not a indoor device.
9435 GO should not opeate on indoor channels */
9436void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9437{
9438 int j;
9439 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9440 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9441 //Default counrtycode from NV at the time of wiphy initialization.
9442 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9443 &defaultCountryCode[0]))
9444 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009445 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309446 }
9447 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9448 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309449 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309450 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309451 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309452 return;
9453 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309454 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309455 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309456 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309457 // Mark UNII -1 band channel as passive
9458 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9459 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9460 }
9461 }
9462}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309463/* This function registers for all frame which supplicant is interested in */
9464void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009465{
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9467 /* Register for all P2P action, public action etc frames */
9468 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009469 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309470 /* Register frame indication call back */
9471 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 /* Right now we are registering these frame when driver is getting
9473 initialized. Once we will move to 2.6.37 kernel, in which we have
9474 frame register ops, we will move this code as a part of that */
9475 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309476 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009477 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9478
9479 /* GAS Initial Response */
9480 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9481 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309482
Jeff Johnson295189b2012-06-20 16:38:30 -07009483 /* GAS Comeback Request */
9484 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9485 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9486
9487 /* GAS Comeback Response */
9488 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9489 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9490
9491 /* P2P Public Action */
9492 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309493 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009494 P2P_PUBLIC_ACTION_FRAME_SIZE );
9495
9496 /* P2P Action */
9497 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9498 (v_U8_t*)P2P_ACTION_FRAME,
9499 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009500
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309501 /* WNM BSS Transition Request frame */
9502 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9503 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9504 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009505
9506 /* WNM-Notification */
9507 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9508 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9509 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009510}
9511
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309512void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009513{
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9515 /* Register for all P2P action, public action etc frames */
9516 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9517
Jeff Johnsone7245742012-09-05 17:12:55 -07009518 ENTER();
9519
Jeff Johnson295189b2012-06-20 16:38:30 -07009520 /* Right now we are registering these frame when driver is getting
9521 initialized. Once we will move to 2.6.37 kernel, in which we have
9522 frame register ops, we will move this code as a part of that */
9523 /* GAS Initial Request */
9524
9525 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9526 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9527
9528 /* GAS Initial Response */
9529 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9530 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309531
Jeff Johnson295189b2012-06-20 16:38:30 -07009532 /* GAS Comeback Request */
9533 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9534 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9535
9536 /* GAS Comeback Response */
9537 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9538 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9539
9540 /* P2P Public Action */
9541 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309542 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009543 P2P_PUBLIC_ACTION_FRAME_SIZE );
9544
9545 /* P2P Action */
9546 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9547 (v_U8_t*)P2P_ACTION_FRAME,
9548 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009549 /* WNM-Notification */
9550 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9551 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9552 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009553}
9554
9555#ifdef FEATURE_WLAN_WAPI
9556void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309557 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009558{
9559 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9560 tCsrRoamSetKey setKey;
9561 v_BOOL_t isConnected = TRUE;
9562 int status = 0;
9563 v_U32_t roamId= 0xFF;
9564 tANI_U8 *pKeyPtr = NULL;
9565 int n = 0;
9566
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309567 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9568 __func__, hdd_device_modetoString(pAdapter->device_mode),
9569 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009570
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309571 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 setKey.keyId = key_index; // Store Key ID
9573 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9574 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9575 setKey.paeRole = 0 ; // the PAE role
9576 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9577 {
9578 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9579 }
9580 else
9581 {
9582 isConnected = hdd_connIsConnected(pHddStaCtx);
9583 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9584 }
9585 setKey.keyLength = key_Len;
9586 pKeyPtr = setKey.Key;
9587 memcpy( pKeyPtr, key, key_Len);
9588
Arif Hussain6d2a3322013-11-17 19:50:10 -08009589 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 __func__, key_Len);
9591 for (n = 0 ; n < key_Len; n++)
9592 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9593 __func__,n,setKey.Key[n]);
9594
9595 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9596 if ( isConnected )
9597 {
9598 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9599 pAdapter->sessionId, &setKey, &roamId );
9600 }
9601 if ( status != 0 )
9602 {
9603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9604 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9605 __LINE__, status );
9606 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9607 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309608 /* Need to clear any trace of key value in the memory.
9609 * Thus zero out the memory even though it is local
9610 * variable.
9611 */
9612 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009613}
9614#endif /* FEATURE_WLAN_WAPI*/
9615
9616#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309617int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009618 beacon_data_t **ppBeacon,
9619 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009620#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309621int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009622 beacon_data_t **ppBeacon,
9623 struct cfg80211_beacon_data *params,
9624 int dtim_period)
9625#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309626{
Jeff Johnson295189b2012-06-20 16:38:30 -07009627 int size;
9628 beacon_data_t *beacon = NULL;
9629 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309630 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9631 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009632
Jeff Johnsone7245742012-09-05 17:12:55 -07009633 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009634 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309635 {
9636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9637 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309639 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009640
9641 old = pAdapter->sessionCtx.ap.beacon;
9642
9643 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309644 {
9645 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9646 FL("session(%d) old and new heads points to NULL"),
9647 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309649 }
9650
9651 if (params->tail && !params->tail_len)
9652 {
9653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9654 FL("tail_len is zero but tail is not NULL"));
9655 return -EINVAL;
9656 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009657
Jeff Johnson295189b2012-06-20 16:38:30 -07009658#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9659 /* Kernel 3.0 is not updating dtim_period for set beacon */
9660 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309661 {
9662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9663 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009664 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309665 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009666#endif
9667
Kapil Gupta137ef892016-12-13 19:38:00 +05309668 if (params->head)
9669 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009670 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309671 head = params->head;
9672 } else
9673 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009674 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309675 head = old->head;
9676 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009677
Kapil Gupta137ef892016-12-13 19:38:00 +05309678 if (params->tail || !old)
9679 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309681 tail = params->tail;
9682 } else
9683 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009684 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309685 tail = old->tail;
9686 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009687
Kapil Gupta137ef892016-12-13 19:38:00 +05309688 if (params->proberesp_ies || !old)
9689 {
9690 proberesp_ies_len = params->proberesp_ies_len;
9691 proberesp_ies = params->proberesp_ies;
9692 } else
9693 {
9694 proberesp_ies_len = old->proberesp_ies_len;
9695 proberesp_ies = old->proberesp_ies;
9696 }
9697
9698 if (params->assocresp_ies || !old)
9699 {
9700 assocresp_ies_len = params->assocresp_ies_len;
9701 assocresp_ies = params->assocresp_ies;
9702 } else
9703 {
9704 assocresp_ies_len = old->assocresp_ies_len;
9705 assocresp_ies = old->assocresp_ies;
9706 }
9707
9708 size = sizeof(beacon_data_t) + head_len + tail_len +
9709 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009710
9711 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009712 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309713 {
9714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9715 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009716 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309717 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009718
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009719#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309720 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009721 beacon->dtim_period = params->dtim_period;
9722 else
9723 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009724#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309725 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009726 beacon->dtim_period = dtim_period;
9727 else
9728 beacon->dtim_period = old->dtim_period;
9729#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309730
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9732 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309733 beacon->proberesp_ies = beacon->tail + tail_len;
9734 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9735
Jeff Johnson295189b2012-06-20 16:38:30 -07009736 beacon->head_len = head_len;
9737 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309738 beacon->proberesp_ies_len = proberesp_ies_len;
9739 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009740
c_manjee527ecac2017-01-25 12:25:27 +05309741 if (head && head_len)
9742 memcpy(beacon->head, head, head_len);
9743 if (tail && tail_len)
9744 memcpy(beacon->tail, tail, tail_len);
9745 if (proberesp_ies && proberesp_ies_len)
9746 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9747 if (assocresp_ies && assocresp_ies_len)
9748 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009749
9750 *ppBeacon = beacon;
9751
9752 kfree(old);
9753
9754 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009755}
Jeff Johnson295189b2012-06-20 16:38:30 -07009756
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309757v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9759 const v_U8_t *pIes,
9760#else
9761 v_U8_t *pIes,
9762#endif
9763 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009764{
9765 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309766 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309768
Jeff Johnson295189b2012-06-20 16:38:30 -07009769 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309770 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009771 elem_id = ptr[0];
9772 elem_len = ptr[1];
9773 left -= 2;
9774 if(elem_len > left)
9775 {
9776 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009777 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009778 eid,elem_len,left);
9779 return NULL;
9780 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309781 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 {
9783 return ptr;
9784 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309785
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 left -= elem_len;
9787 ptr += (elem_len + 2);
9788 }
9789 return NULL;
9790}
9791
Jeff Johnson295189b2012-06-20 16:38:30 -07009792/* Check if rate is 11g rate or not */
9793static int wlan_hdd_rate_is_11g(u8 rate)
9794{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009795 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009796 u8 i;
9797 for (i = 0; i < 8; i++)
9798 {
9799 if(rate == gRateArray[i])
9800 return TRUE;
9801 }
9802 return FALSE;
9803}
9804
9805/* Check for 11g rate and set proper 11g only mode */
9806static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9807 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9808{
9809 u8 i, num_rates = pIe[0];
9810
9811 pIe += 1;
9812 for ( i = 0; i < num_rates; i++)
9813 {
9814 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9815 {
9816 /* If rate set have 11g rate than change the mode to 11G */
9817 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9818 if (pIe[i] & BASIC_RATE_MASK)
9819 {
9820 /* If we have 11g rate as basic rate, it means mode
9821 is 11g only mode.
9822 */
9823 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9824 *pCheckRatesfor11g = FALSE;
9825 }
9826 }
9827 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9828 {
9829 *require_ht = TRUE;
9830 }
9831 }
9832 return;
9833}
9834
9835static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9836{
9837 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9838 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9839 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9840 u8 checkRatesfor11g = TRUE;
9841 u8 require_ht = FALSE;
9842 u8 *pIe=NULL;
9843
9844 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9845
9846 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9847 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9848 if (pIe != NULL)
9849 {
9850 pIe += 1;
9851 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9852 &pConfig->SapHw_mode);
9853 }
9854
9855 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9856 WLAN_EID_EXT_SUPP_RATES);
9857 if (pIe != NULL)
9858 {
9859
9860 pIe += 1;
9861 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9862 &pConfig->SapHw_mode);
9863 }
9864
9865 if( pConfig->channel > 14 )
9866 {
9867 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9868 }
9869
9870 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9871 WLAN_EID_HT_CAPABILITY);
9872
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309873 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009874 {
9875 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9876 if(require_ht)
9877 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9878 }
9879}
9880
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309881static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9882 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9883{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009884 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309885 v_U8_t *pIe = NULL;
9886 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9887
9888 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9889 pBeacon->tail, pBeacon->tail_len);
9890
9891 if (pIe)
9892 {
9893 ielen = pIe[1] + 2;
9894 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9895 {
9896 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9897 }
9898 else
9899 {
9900 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9901 return -EINVAL;
9902 }
9903 *total_ielen += ielen;
9904 }
9905 return 0;
9906}
9907
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009908static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9909 v_U8_t *genie, v_U8_t *total_ielen)
9910{
9911 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9912 int left = pBeacon->tail_len;
9913 v_U8_t *ptr = pBeacon->tail;
9914 v_U8_t elem_id, elem_len;
9915 v_U16_t ielen = 0;
9916
9917 if ( NULL == ptr || 0 == left )
9918 return;
9919
9920 while (left >= 2)
9921 {
9922 elem_id = ptr[0];
9923 elem_len = ptr[1];
9924 left -= 2;
9925 if (elem_len > left)
9926 {
9927 hddLog( VOS_TRACE_LEVEL_ERROR,
9928 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9929 elem_id, elem_len, left);
9930 return;
9931 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309932 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009933 {
9934 /* skipping the VSIE's which we don't want to include or
9935 * it will be included by existing code
9936 */
9937 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9938#ifdef WLAN_FEATURE_WFD
9939 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9940#endif
9941 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9942 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9943 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9944 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9945 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9946 {
9947 ielen = ptr[1] + 2;
9948 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9949 {
9950 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9951 *total_ielen += ielen;
9952 }
9953 else
9954 {
9955 hddLog( VOS_TRACE_LEVEL_ERROR,
9956 "IE Length is too big "
9957 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9958 elem_id, elem_len, *total_ielen);
9959 }
9960 }
9961 }
9962
9963 left -= elem_len;
9964 ptr += (elem_len + 2);
9965 }
9966 return;
9967}
9968
Kapil Gupta137ef892016-12-13 19:38:00 +05309969int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009970{
9971 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309972 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009973 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009974 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309975 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009976
9977 genie = vos_mem_malloc(MAX_GENIE_LEN);
9978
9979 if(genie == NULL) {
9980
9981 return -ENOMEM;
9982 }
9983
Kapil Gupta137ef892016-12-13 19:38:00 +05309984 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309985 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9986 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009987 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309988 hddLog(LOGE,
9989 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309990 ret = -EINVAL;
9991 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009992 }
9993
9994#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309995 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9996 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9997 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309998 hddLog(LOGE,
9999 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010000 ret = -EINVAL;
10001 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 }
10003#endif
10004
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010005 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
10006 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010008 hddLog(LOGE,
10009 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010010 ret = -EINVAL;
10011 goto done;
10012 }
10013
10014 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
10015 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -070010016 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010018
10019 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10020 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
10021 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
10022 {
10023 hddLog(LOGE,
10024 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010025 ret = -EINVAL;
10026 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 }
10028
10029 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10030 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
10031 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10032 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10033 ==eHAL_STATUS_FAILURE)
10034 {
10035 hddLog(LOGE,
10036 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010037 ret = -EINVAL;
10038 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010039 }
10040
10041 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010042 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010043 {
Kapil Gupta137ef892016-12-13 19:38:00 +053010044 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -070010045 u8 probe_rsp_ie_len[3] = {0};
10046 u8 counter = 0;
10047 /* Check Probe Resp Length if it is greater then 255 then Store
10048 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
10049 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
10050 Store More then 255 bytes into One Variable.
10051 */
10052 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
10053 {
10054 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
10055 {
10056 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
10057 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
10058 }
10059 else
10060 {
10061 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
10062 rem_probe_resp_ie_len = 0;
10063 }
10064 }
10065
10066 rem_probe_resp_ie_len = 0;
10067
10068 if (probe_rsp_ie_len[0] > 0)
10069 {
10070 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10071 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +053010072 (tANI_U8*)&pBeacon->
10073 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 probe_rsp_ie_len[0], NULL,
10075 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10076 {
10077 hddLog(LOGE,
10078 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010079 ret = -EINVAL;
10080 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010081 }
10082 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
10083 }
10084
10085 if (probe_rsp_ie_len[1] > 0)
10086 {
10087 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10088 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +053010089 (tANI_U8*)&pBeacon->
10090 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010091 probe_rsp_ie_len[1], NULL,
10092 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10093 {
10094 hddLog(LOGE,
10095 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010096 ret = -EINVAL;
10097 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010098 }
10099 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
10100 }
10101
10102 if (probe_rsp_ie_len[2] > 0)
10103 {
10104 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10105 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +053010106 (tANI_U8*)&pBeacon->
10107 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -070010108 probe_rsp_ie_len[2], NULL,
10109 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10110 {
10111 hddLog(LOGE,
10112 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010113 ret = -EINVAL;
10114 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010115 }
10116 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
10117 }
10118
10119 if (probe_rsp_ie_len[1] == 0 )
10120 {
10121 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10122 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
10123 eANI_BOOLEAN_FALSE) )
10124 {
10125 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010126 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010127 }
10128 }
10129
10130 if (probe_rsp_ie_len[2] == 0 )
10131 {
10132 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10133 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
10134 eANI_BOOLEAN_FALSE) )
10135 {
10136 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010137 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010138 }
10139 }
10140
10141 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10142 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
10143 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10144 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10145 == eHAL_STATUS_FAILURE)
10146 {
10147 hddLog(LOGE,
10148 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010149 ret = -EINVAL;
10150 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010151 }
10152 }
10153 else
10154 {
10155 // Reset WNI_CFG_PROBE_RSP Flags
10156 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
10157
10158 hddLog(VOS_TRACE_LEVEL_INFO,
10159 "%s: No Probe Response IE received in set beacon",
10160 __func__);
10161 }
10162
10163 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +053010164 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010165 {
10166 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +053010167 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
10168 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -070010169 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
10170 {
10171 hddLog(LOGE,
10172 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010173 ret = -EINVAL;
10174 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010175 }
10176
10177 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10178 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
10179 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
10180 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
10181 == eHAL_STATUS_FAILURE)
10182 {
10183 hddLog(LOGE,
10184 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -070010185 ret = -EINVAL;
10186 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -070010187 }
10188 }
10189 else
10190 {
10191 hddLog(VOS_TRACE_LEVEL_INFO,
10192 "%s: No Assoc Response IE received in set beacon",
10193 __func__);
10194
10195 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
10196 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
10197 eANI_BOOLEAN_FALSE) )
10198 {
10199 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010200 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010201 }
10202 }
10203
Jeff Johnsone7245742012-09-05 17:12:55 -070010204done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010205 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010206 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010207}
Jeff Johnson295189b2012-06-20 16:38:30 -070010208
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010209/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010210 * FUNCTION: wlan_hdd_validate_operation_channel
10211 * called by wlan_hdd_cfg80211_start_bss() and
10212 * wlan_hdd_cfg80211_set_channel()
10213 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010214 * channel list.
10215 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010216VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010217{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010218
Jeff Johnson295189b2012-06-20 16:38:30 -070010219 v_U32_t num_ch = 0;
10220 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10221 u32 indx = 0;
10222 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010223 v_U8_t fValidChannel = FALSE, count = 0;
10224 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010225
Jeff Johnson295189b2012-06-20 16:38:30 -070010226 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10227
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010228 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010229 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010230 /* Validate the channel */
10231 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010232 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010233 if ( channel == rfChannels[count].channelNum )
10234 {
10235 fValidChannel = TRUE;
10236 break;
10237 }
10238 }
10239 if (fValidChannel != TRUE)
10240 {
10241 hddLog(VOS_TRACE_LEVEL_ERROR,
10242 "%s: Invalid Channel [%d]", __func__, channel);
10243 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010244 }
10245 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010246 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010247 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010248 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10249 valid_ch, &num_ch))
10250 {
10251 hddLog(VOS_TRACE_LEVEL_ERROR,
10252 "%s: failed to get valid channel list", __func__);
10253 return VOS_STATUS_E_FAILURE;
10254 }
10255 for (indx = 0; indx < num_ch; indx++)
10256 {
10257 if (channel == valid_ch[indx])
10258 {
10259 break;
10260 }
10261 }
10262
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010263 if (indx >= num_ch)
10264 {
10265 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10266 {
10267 eCsrBand band;
10268 unsigned int freq;
10269
10270 sme_GetFreqBand(hHal, &band);
10271
10272 if (eCSR_BAND_5G == band)
10273 {
10274#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10275 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10276 {
10277 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010278 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010279 }
10280 else
10281 {
10282 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010283 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010284 }
10285#else
10286 freq = ieee80211_channel_to_frequency(channel);
10287#endif
10288 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10289 return VOS_STATUS_SUCCESS;
10290 }
10291 }
10292
10293 hddLog(VOS_TRACE_LEVEL_ERROR,
10294 "%s: Invalid Channel [%d]", __func__, channel);
10295 return VOS_STATUS_E_FAILURE;
10296 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010297 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010298
Jeff Johnson295189b2012-06-20 16:38:30 -070010299 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010300
Jeff Johnson295189b2012-06-20 16:38:30 -070010301}
10302
Viral Modi3a32cc52013-02-08 11:14:52 -080010303/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010304 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010305 * This function is used to set the channel number
10306 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010307static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010308 struct ieee80211_channel *chan,
10309 enum nl80211_channel_type channel_type
10310 )
10311{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010312 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010313 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010314 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010315 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010316 hdd_context_t *pHddCtx;
10317 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010318
10319 ENTER();
10320
10321 if( NULL == dev )
10322 {
10323 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010324 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010325 return -ENODEV;
10326 }
10327 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010328
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010329 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10330 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10331 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010332 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010333 "%s: device_mode = %s (%d) freq = %d", __func__,
10334 hdd_device_modetoString(pAdapter->device_mode),
10335 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010336
10337 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10338 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010339 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010340 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010341 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010342 }
10343
10344 /*
10345 * Do freq to chan conversion
10346 * TODO: for 11a
10347 */
10348
10349 channel = ieee80211_frequency_to_channel(freq);
10350
10351 /* Check freq range */
10352 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10353 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10354 {
10355 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010356 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010357 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10358 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10359 return -EINVAL;
10360 }
10361
10362 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10363
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010364 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10365 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010366 {
10367 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10368 {
10369 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010370 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010371 return -EINVAL;
10372 }
10373 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10374 "%s: set channel to [%d] for device mode =%d",
10375 __func__, channel,pAdapter->device_mode);
10376 }
10377 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010378 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010379 )
10380 {
10381 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10382 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10383 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10384
10385 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10386 {
10387 /* Link is up then return cant set channel*/
10388 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010389 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010390 return -EINVAL;
10391 }
10392
10393 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10394 pHddStaCtx->conn_info.operationChannel = channel;
10395 pRoamProfile->ChannelInfo.ChannelList =
10396 &pHddStaCtx->conn_info.operationChannel;
10397 }
10398 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010399 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010400 )
10401 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010402 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10403 {
10404 if(VOS_STATUS_SUCCESS !=
10405 wlan_hdd_validate_operation_channel(pAdapter,channel))
10406 {
10407 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010408 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010409 return -EINVAL;
10410 }
10411 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10412 }
10413 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010414 {
10415 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10416
10417 /* If auto channel selection is configured as enable/ 1 then ignore
10418 channel set by supplicant
10419 */
10420 if ( cfg_param->apAutoChannelSelection )
10421 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010422 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10423 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010424 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010425 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10426 __func__, hdd_device_modetoString(pAdapter->device_mode),
10427 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010428 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010429 else
10430 {
10431 if(VOS_STATUS_SUCCESS !=
10432 wlan_hdd_validate_operation_channel(pAdapter,channel))
10433 {
10434 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010435 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010436 return -EINVAL;
10437 }
10438 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10439 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010440 }
10441 }
10442 else
10443 {
10444 hddLog(VOS_TRACE_LEVEL_FATAL,
10445 "%s: Invalid device mode failed to set valid channel", __func__);
10446 return -EINVAL;
10447 }
10448 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010449 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010450}
10451
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010452static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10453 struct net_device *dev,
10454 struct ieee80211_channel *chan,
10455 enum nl80211_channel_type channel_type
10456 )
10457{
10458 int ret;
10459
10460 vos_ssr_protect(__func__);
10461 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10462 vos_ssr_unprotect(__func__);
10463
10464 return ret;
10465}
10466
Anurag Chouhan83026002016-12-13 22:46:21 +053010467#ifdef DHCP_SERVER_OFFLOAD
10468void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10469 VOS_STATUS status)
10470{
10471 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10472
10473 ENTER();
10474
10475 if (NULL == adapter)
10476 {
10477 hddLog(VOS_TRACE_LEVEL_ERROR,
10478 "%s: adapter is NULL",__func__);
10479 return;
10480 }
10481
10482 adapter->dhcp_status.dhcp_offload_status = status;
10483 vos_event_set(&adapter->dhcp_status.vos_event);
10484 return;
10485}
10486
10487/**
10488 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10489 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010490 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010491 *
10492 * Return: None
10493 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010494VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10495 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010496{
10497 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10498 sir_dhcp_srv_offload_info dhcp_srv_info;
10499 tANI_U8 num_entries = 0;
10500 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10501 tANI_U8 num;
10502 tANI_U32 temp;
10503 VOS_STATUS ret;
10504
10505 ENTER();
10506
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010507 if (!re_init) {
10508 ret = wlan_hdd_validate_context(hdd_ctx);
10509 if (0 != ret)
10510 return VOS_STATUS_E_INVAL;
10511 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010512
10513 /* Prepare the request to send to SME */
10514 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10515 if (NULL == dhcp_srv_info) {
10516 hddLog(VOS_TRACE_LEVEL_ERROR,
10517 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10518 return VOS_STATUS_E_NOMEM;
10519 }
10520
10521 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10522
10523 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10524 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10525 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10526 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10527 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10528 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10529
10530 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10531 srv_ip,
10532 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010533 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010534 if (num_entries != IPADDR_NUM_ENTRIES) {
10535 hddLog(VOS_TRACE_LEVEL_ERROR,
10536 "%s: incorrect IP address (%s) assigned for DHCP server!",
10537 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10538 vos_mem_free(dhcp_srv_info);
10539 return VOS_STATUS_E_FAILURE;
10540 }
10541
10542 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10543 hddLog(VOS_TRACE_LEVEL_ERROR,
10544 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10545 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10546 vos_mem_free(dhcp_srv_info);
10547 return VOS_STATUS_E_FAILURE;
10548 }
10549
10550 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10551 hddLog(VOS_TRACE_LEVEL_ERROR,
10552 "%s: invalid IP address (%s)! The last field must be less than 100!",
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 for (num = 0; num < num_entries; num++) {
10559 temp = srv_ip[num];
10560 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10561 }
10562
10563 if (eHAL_STATUS_SUCCESS !=
10564 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10565 hddLog(VOS_TRACE_LEVEL_ERROR,
10566 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10567 vos_mem_free(dhcp_srv_info);
10568 return VOS_STATUS_E_FAILURE;
10569 }
10570
10571 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10572 "%s: enable DHCP Server offload successfully!", __func__);
10573
10574 vos_mem_free(dhcp_srv_info);
10575 return 0;
10576}
10577#endif /* DHCP_SERVER_OFFLOAD */
10578
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010579/*
10580 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10581 * @wiphy_chan: wiphy channel number
10582 * @rfChannel: channel hw value
10583 * @disable: Disable/enable the flags
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010584 * @hdd_ctx: The HDD context handler
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010585 *
10586 * Modify wiphy flags and cds state if channel is indoor.
10587 *
10588 * Return: void
10589 */
10590void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010591 v_U32_t rfChannel, bool disable, hdd_context_t *hdd_ctx)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010592{
10593 v_U32_t channelLoop;
10594 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10595
10596 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10597
10598 if (rfChannels[channelLoop].channelNum == rfChannel) {
10599 channelEnum = (eRfChannels)channelLoop;
10600 break;
10601 }
10602 }
10603
10604 if (INVALID_RF_CHANNEL == channelEnum)
10605 return;
10606
10607 if (disable) {
10608 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10609 wiphy_chan->flags |=
10610 IEEE80211_CHAN_DISABLED;
10611 regChannels[channelEnum].enabled =
10612 NV_CHANNEL_DISABLE;
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010613 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DISABLE",
10614 channelEnum);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010615 }
10616 } else {
10617 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10618 wiphy_chan->flags &=
10619 ~IEEE80211_CHAN_DISABLED;
10620 /*
10621 * Indoor channels are marked as DFS
10622 * during regulatory processing
10623 */
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010624 if ((wiphy_chan->flags & (IEEE80211_CHAN_RADAR |
10625 IEEE80211_CHAN_PASSIVE_SCAN)) ||
10626 ((hdd_ctx->cfg_ini->indoor_channel_support == false)
10627 && (wiphy_chan->flags &
10628 IEEE80211_CHAN_INDOOR_ONLY))) {
10629 regChannels[channelEnum].enabled = NV_CHANNEL_DFS;
10630 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as DFS",
10631 channelEnum);
10632 } else {
10633 regChannels[channelEnum].enabled =
10634 NV_CHANNEL_ENABLE;
10635 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %d marked as ENABLE",
10636 channelEnum);
10637 }
10638 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010639
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010640 }
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010641}
10642
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010643void hdd_update_indoor_channel(hdd_context_t *hdd_ctx, bool disable)
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010644{
10645 int band_num;
10646 int chan_num;
10647 v_U32_t rfChannel;
10648 struct ieee80211_channel *wiphy_chan;
10649 struct wiphy *wiphy;
10650
10651 ENTER();
10652 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10653
10654 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010655 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010656
10657 if (wiphy->bands[band_num] == NULL)
10658 continue;
10659
10660 for (chan_num = 0;
10661 chan_num < wiphy->bands[band_num]->n_channels;
10662 chan_num++) {
10663
10664 wiphy_chan =
10665 &(wiphy->bands[band_num]->channels[chan_num]);
10666 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10667
10668 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
Sourav Mohapatra077057d2018-02-07 19:19:18 +053010669 disable, hdd_ctx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010670 }
10671 }
10672 EXIT();
10673}
10674
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010675int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10676{
Dundi Raviteja49de66b2018-07-27 12:22:57 +053010677 eHalStatus status;
10678 int result = 0;
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010679 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10680 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10681 long ret;
10682 eConnectionState prev_conn_state;
10683 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10684
10685 ENTER();
10686
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010687 /* Indicate sme of disconnect so that in progress connection or preauth
10688 * can be aborted
10689 */
10690 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10691 pAdapter->sessionId);
10692 pHddCtx->isAmpAllowed = VOS_TRUE;
10693
10694 /* Need to apply spin lock before decreasing active sessions
10695 * as there can be chance for double decrement if context switch
10696 * Calls hdd_DisConnectHandler.
10697 */
10698
10699 prev_conn_state = pHddStaCtx->conn_info.connState;
10700
10701 spin_lock_bh(&pAdapter->lock_for_active_session);
10702 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10703 {
10704 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10705 }
10706 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10707 spin_unlock_bh(&pAdapter->lock_for_active_session);
10708 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10709
10710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10711 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10712
10713 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10714
10715 /*
10716 * stop tx queues before deleting STA/BSS context from the firmware.
10717 * tx has to be disabled because the firmware can get busy dropping
10718 * the tx frames after BSS/STA has been deleted and will not send
10719 * back a response resulting in WDI timeout
10720 */
10721 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10722 netif_tx_disable(pAdapter->dev);
10723 netif_carrier_off(pAdapter->dev);
10724
10725 wlan_hdd_check_and_stop_mon(pAdapter, true);
10726
10727 /*issue disconnect*/
10728 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10729 pAdapter->sessionId, reason);
10730 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10731 prev_conn_state != eConnectionState_Connecting)
10732 {
10733 hddLog(LOG1,
10734 FL("status = %d, already disconnected"), status);
10735 result = 0;
10736 /*
10737 * Wait here instead of returning directly. This will block the
10738 * next connect command and allow processing of the disconnect
10739 * in SME else we might hit some race conditions leading to SME
10740 * and HDD out of sync. As disconnect is already in progress,
10741 * wait here for 1 sec instead of 5 sec.
10742 */
10743 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10744 goto wait_for_disconnect;
10745 }
10746 /*
10747 * Wait here instead of returning directly, this will block the next
10748 * connect command and allow processing of the scan for ssid and
10749 * the previous connect command in CSR. Else we might hit some
10750 * race conditions leading to SME and HDD out of sync.
10751 */
10752 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10753 {
10754 hddLog(LOG1,
10755 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10756 }
10757 else if ( 0 != status )
10758 {
10759 hddLog(LOGE,
10760 FL("csrRoamDisconnect failure, returned %d"),
10761 (int)status);
10762 result = -EINVAL;
10763 goto disconnected;
10764 }
10765wait_for_disconnect:
10766 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10767 msecs_to_jiffies(wait_time));
10768 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10769 {
10770 hddLog(LOGE,
10771 "%s: Failed to disconnect, timed out", __func__);
10772 result = -ETIMEDOUT;
10773 }
10774disconnected:
10775 hddLog(LOG1,
10776 FL("Set HDD connState to eConnectionState_NotConnected"));
10777 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10778#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10779 /* Sending disconnect event to userspace for kernel version < 3.11
10780 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10781 */
10782 hddLog(LOG1, FL("Send disconnected event to userspace"));
10783
10784 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10785 WLAN_REASON_UNSPECIFIED);
10786#endif
10787
10788 EXIT();
10789 return result;
10790}
10791
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010792void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10793{
10794
10795 hdd_adapter_t *sta_adapter;
10796 tANI_U8 sta_chan;
10797
10798 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10799
10800 if (!sta_chan) {
10801 hddLog(LOG1, FL("STA not connected"));
10802 return;
10803 }
10804
10805 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10806
10807 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10808 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10809 sta_chan);
10810 return;
10811 }
10812
10813 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10814
10815 if (!sta_adapter) {
10816 hddLog(LOG1, FL("STA adapter doesn't exist"));
10817 return;
10818 }
10819
10820 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10821 /* Issue Disconnect request */
10822 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10823}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010824
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010825int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10826{
10827 struct hdd_cache_channels *cache_chann;
10828 struct wiphy *wiphy;
10829 int freq, status, rfChannel;
10830 int i, band_num, channel_num;
10831 struct ieee80211_channel *wiphy_channel;
10832
10833 ENTER();
10834
10835 if (!hdd_ctx) {
10836 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10837 return -EINVAL;
10838 }
10839
10840 wiphy = hdd_ctx->wiphy;
10841
10842 mutex_lock(&hdd_ctx->cache_channel_lock);
10843
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010844 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010845
10846 if (!cache_chann || !cache_chann->num_channels) {
10847 hddLog(VOS_TRACE_LEVEL_INFO,
10848 "%s channel list is NULL or num channels are zero",
10849 __func__);
10850 mutex_unlock(&hdd_ctx->cache_channel_lock);
10851 return -EINVAL;
10852 }
10853
10854 for (i = 0; i < cache_chann->num_channels; i++) {
10855 status = hdd_wlan_get_freq(
10856 cache_chann->channel_info[i].channel_num,
10857 &freq);
10858
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010859 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10860 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010861 if (!wiphy->bands[band_num])
10862 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010863 for (channel_num = 0; channel_num <
10864 wiphy->bands[band_num]->n_channels;
10865 channel_num++) {
10866 wiphy_channel = &(wiphy->bands[band_num]->
10867 channels[channel_num]);
10868 if (wiphy_channel->center_freq == freq) {
10869 rfChannel = wiphy_channel->hw_value;
10870 /*
10871 *Restore the orginal states
10872 *of the channels
10873 */
10874 vos_nv_set_channel_state(
10875 rfChannel,
10876 cache_chann->
10877 channel_info[i].reg_status);
10878 wiphy_channel->flags =
10879 cache_chann->
10880 channel_info[i].wiphy_status;
Ashish Kumar Dhanotiya1cf97dd2019-03-11 16:59:25 +053010881 hddLog(VOS_TRACE_LEVEL_DEBUG,
10882 "Restore channel %d reg_stat %d wiphy_stat 0x%x",
10883 cache_chann->
10884 channel_info[i].channel_num,
10885 cache_chann->
10886 channel_info[i].reg_status,
10887 wiphy_channel->flags);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010888 break;
10889 }
10890 }
10891 if (channel_num < wiphy->bands[band_num]->n_channels)
10892 break;
10893 }
10894 }
10895
10896 mutex_unlock(&hdd_ctx->cache_channel_lock);
10897
10898 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10899 if (status)
10900 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10901 EXIT();
10902
10903 return 0;
10904}
10905
Ashish Kumar Dhanotiya1cf97dd2019-03-11 16:59:25 +053010906int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010907{
10908 struct hdd_cache_channels *cache_chann;
10909 struct wiphy *wiphy;
10910 int freq, status, rfChannel;
10911 int i, band_num, band_ch_num;
10912 struct ieee80211_channel *wiphy_channel;
10913
10914 if (!hdd_ctx) {
10915 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10916 return -EINVAL;
10917 }
10918
10919 wiphy = hdd_ctx->wiphy;
10920
10921 mutex_lock(&hdd_ctx->cache_channel_lock);
Ashish Kumar Dhanotiya95e5bc22018-04-19 17:06:33 +053010922 cache_chann = hdd_ctx->original_channels;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010923
10924 if (!cache_chann || !cache_chann->num_channels) {
10925 hddLog(VOS_TRACE_LEVEL_INFO,
10926 "%s channel list is NULL or num channels are zero",
10927 __func__);
10928 mutex_unlock(&hdd_ctx->cache_channel_lock);
10929 return -EINVAL;
10930 }
10931
10932 for (i = 0; i < cache_chann->num_channels; i++) {
10933 status = hdd_wlan_get_freq(
10934 cache_chann->channel_info[i].channel_num,
10935 &freq);
10936
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010937 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010938 band_num++) {
Dundi Raviteja1d019fd2018-09-23 18:18:22 +053010939 if (!wiphy->bands[band_num])
10940 continue;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010941 for (band_ch_num = 0; band_ch_num <
10942 wiphy->bands[band_num]->n_channels;
10943 band_ch_num++) {
10944 wiphy_channel = &(wiphy->bands[band_num]->
10945 channels[band_ch_num]);
10946 if (wiphy_channel->center_freq == freq) {
10947 rfChannel = wiphy_channel->hw_value;
10948 /*
10949 * Cache the current states of
10950 * the channels
10951 */
10952 cache_chann->
10953 channel_info[i].reg_status =
10954 vos_nv_getChannelEnabledState(
10955 rfChannel);
10956
10957 cache_chann->
10958 channel_info[i].wiphy_status =
10959 wiphy_channel->flags;
10960 hddLog(VOS_TRACE_LEVEL_INFO,
10961 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10962 cache_chann->
10963 channel_info[i].channel_num,
10964 cache_chann->
10965 channel_info[i].reg_status,
10966 wiphy_channel->flags);
10967
10968 vos_nv_set_channel_state(
10969 rfChannel,
10970 NV_CHANNEL_DISABLE);
10971 wiphy_channel->flags |=
10972 IEEE80211_CHAN_DISABLED;
10973 break;
10974 }
10975 }
10976 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10977 break;
10978 }
10979 }
10980
10981 mutex_unlock(&hdd_ctx->cache_channel_lock);
10982 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10983 return 0;
10984}
10985
Jeff Johnson295189b2012-06-20 16:38:30 -070010986#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10987static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10988 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010989#else
10990static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10991 struct cfg80211_beacon_data *params,
10992 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010993 enum nl80211_hidden_ssid hidden_ssid,
10994 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010995#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010996{
10997 tsap_Config_t *pConfig;
10998 beacon_data_t *pBeacon = NULL;
10999 struct ieee80211_mgmt *pMgmt_frame;
11000 v_U8_t *pIe=NULL;
11001 v_U16_t capab_info;
11002 eCsrAuthType RSNAuthType;
11003 eCsrEncryptionType RSNEncryptType;
11004 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011005 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011006 tpWLAN_SAPEventCB pSapEventCallback;
11007 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070011008 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011009 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011010 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011011 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070011012 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080011013 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053011014 hdd_adapter_t *sta_adapter;
Peng Xu2446a892014-09-05 17:21:18 +053011015 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070011016 v_BOOL_t MFPCapable = VOS_FALSE;
11017 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011018 v_BOOL_t sapEnable11AC =
11019 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053011020 u_int16_t prev_rsn_length = 0;
11021
Jeff Johnson295189b2012-06-20 16:38:30 -070011022 ENTER();
11023
Nitesh Shah9b066282017-06-06 18:05:52 +053011024 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Vignesh Viswanathan36575f82018-06-14 16:52:21 +053011025
11026 /*
11027 * For STA+SAP concurrency support from GUI, first STA connection gets
11028 * triggered and while it is in progress, SAP start also comes up.
11029 * Once STA association is successful, STA connect event is sent to
11030 * kernel which gets queued in kernel workqueue and supplicant won't
11031 * process M1 received from AP and send M2 until this NL80211_CONNECT
11032 * event is received. Workqueue is not scheduled as RTNL lock is already
11033 * taken by hostapd thread which has issued start_bss command to driver.
11034 * Driver cannot complete start_bss as the pending command at the head
11035 * of the SME command pending list is hw_mode_update for STA session
11036 * which cannot be processed as SME is in WAITforKey state for STA
11037 * interface. The start_bss command for SAP interface is queued behind
11038 * the hw_mode_update command and so it cannot be processed until
11039 * hw_mode_update command is processed. This is causing a deadlock so
11040 * disconnect the STA interface first if connection or key exchange is
11041 * in progress and then start SAP interface.
11042 */
11043 sta_adapter = hdd_get_sta_connection_in_progress(pHddCtx);
11044 if (sta_adapter) {
11045 hddLog(LOG1, FL("Disconnecting STA with session id: %d"),
11046 sta_adapter->sessionId);
11047 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
11048 }
11049
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011050 iniConfig = pHddCtx->cfg_ini;
11051
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011052 /* Mark the indoor channel (passive) to disable */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011053 if (iniConfig->disable_indoor_channel &&
11054 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011055 hdd_update_indoor_channel(pHddCtx, true);
11056
11057 if (!VOS_IS_STATUS_SUCCESS(
11058 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
11059 hdd_update_indoor_channel(pHddCtx, false);
11060 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
11061 FL("Can't start BSS: update channel list failed"));
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011062 ret = eHAL_STATUS_FAILURE;
11063 goto tdls_enable;
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011064 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053011065
11066 /* check if STA is on indoor channel */
11067 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
11068 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011069 }
11070
Jeff Johnson295189b2012-06-20 16:38:30 -070011071 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
11072
11073 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
11074
11075 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
11076
11077 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
11078
11079 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
11080
11081 //channel is already set in the set_channel Call back
11082 //pConfig->channel = pCommitConfig->channel;
11083
11084 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011085 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070011086 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
11087
11088 pConfig->dtim_period = pBeacon->dtim_period;
11089
Arif Hussain6d2a3322013-11-17 19:50:10 -080011090 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070011091 pConfig->dtim_period);
11092
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080011093 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070011094 {
11095 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011096 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053011097 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
11098 {
11099 tANI_BOOLEAN restartNeeded;
11100 pConfig->ieee80211d = 1;
11101 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
11102 sme_setRegInfo(hHal, pConfig->countryCode);
11103 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
11104 }
11105 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070011106 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070011107 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070011108 pConfig->ieee80211d = 1;
11109 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
11110 sme_setRegInfo(hHal, pConfig->countryCode);
11111 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070011112 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011113 else
11114 {
11115 pConfig->ieee80211d = 0;
11116 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011117 /*
11118 * If auto channel is configured i.e. channel is 0,
11119 * so skip channel validation.
11120 */
11121 if( AUTO_CHANNEL_SELECT != pConfig->channel )
11122 {
11123 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
11124 {
11125 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011126 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011127 ret = -EINVAL;
11128 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011129 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011130 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011131 }
11132 else
11133 {
11134 if(1 != pHddCtx->is_dynamic_channel_range_set)
11135 {
11136 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
11137 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
11138 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
11139 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053011140 pHddCtx->is_dynamic_channel_range_set = 0;
11141 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053011142 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011143 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070011144 else
Jeff Johnson295189b2012-06-20 16:38:30 -070011145 {
11146 pConfig->ieee80211d = 0;
11147 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011148
11149#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11150 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11151 pConfig->authType = eSAP_OPEN_SYSTEM;
11152 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11153 pConfig->authType = eSAP_SHARED_KEY;
11154 else
11155 pConfig->authType = eSAP_AUTO_SWITCH;
11156#else
11157 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
11158 pConfig->authType = eSAP_OPEN_SYSTEM;
11159 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
11160 pConfig->authType = eSAP_SHARED_KEY;
11161 else
11162 pConfig->authType = eSAP_AUTO_SWITCH;
11163#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011164
11165 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011166
11167 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070011168 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053011169#ifdef SAP_AUTH_OFFLOAD
11170 /* In case of sap offload, hostapd.conf is configuted with open mode and
11171 * security is configured from ini file. Due to open mode in hostapd.conf
11172 * privacy bit is set to false which will result in not sending,
11173 * data packets as encrypted.
11174 * If enable_sap_auth_offload is enabled in ini and
11175 * sap_auth_offload_sec_type is type of WPA2-PSK,
11176 * driver will set privacy bit to 1.
11177 */
11178 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
11179 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
11180 pConfig->privacy = VOS_TRUE;
11181#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011182
11183 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
11184
11185 /*Set wps station to configured*/
11186 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
11187
11188 if(pIe)
11189 {
11190 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
11191 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011192 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011193 ret = -EINVAL;
11194 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011195 }
11196 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
11197 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070011198 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070011199 /* Check 15 bit of WPS IE as it contain information for wps state
11200 * WPS state
11201 */
11202 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
11203 {
11204 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
11205 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
11206 {
11207 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
11208 }
11209 }
11210 }
11211 else
11212 {
11213 pConfig->wps_state = SAP_WPS_DISABLED;
11214 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011215 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011216
c_hpothufe599e92014-06-16 11:38:55 +053011217 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11218 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11219 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11220 eCSR_ENCRYPT_TYPE_NONE;
11221
Jeff Johnson295189b2012-06-20 16:38:30 -070011222 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011223 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011224 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011225 WLAN_EID_RSN);
11226 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011227 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011228 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011229 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11230 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11231 pConfig->RSNWPAReqIELength);
11232 else
11233 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11234 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011235 /* The actual processing may eventually be more extensive than
11236 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011237 * by the app.
11238 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011239 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011240 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11241 &RSNEncryptType,
11242 &mcRSNEncryptType,
11243 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011244 &MFPCapable,
11245 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011246 pConfig->RSNWPAReqIE[1]+2,
11247 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011248
11249 if( VOS_STATUS_SUCCESS == status )
11250 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011251 /* Now copy over all the security attributes you have
11252 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011253 * */
11254 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11255 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11256 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11257 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011258 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011259 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011260 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11261 }
11262 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011263
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11265 pBeacon->tail, pBeacon->tail_len);
11266
11267 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11268 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011269 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011270 {
11271 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011272 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011273 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011274 if (pConfig->RSNWPAReqIELength <=
11275 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11276 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11277 pIe[1] + 2);
11278 else
11279 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11280 pConfig->RSNWPAReqIELength);
11281
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 }
11283 else
11284 {
11285 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011286 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11287 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11288 pConfig->RSNWPAReqIELength);
11289 else
11290 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11291 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011292 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11294 &RSNEncryptType,
11295 &mcRSNEncryptType,
11296 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011297 &MFPCapable,
11298 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011299 pConfig->RSNWPAReqIE[1]+2,
11300 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011301
11302 if( VOS_STATUS_SUCCESS == status )
11303 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011304 /* Now copy over all the security attributes you have
11305 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011306 * */
11307 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11308 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11309 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11310 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011311 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011312 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011313 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11314 }
11315 }
11316 }
11317
Kapil Gupta137ef892016-12-13 19:38:00 +053011318 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011319 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011320 ret = -EINVAL;
11321 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011322 }
11323
Jeff Johnson295189b2012-06-20 16:38:30 -070011324 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11325
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011326#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011327 if (params->ssid != NULL)
11328 {
11329 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11330 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11331 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11332 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11333 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011334#else
11335 if (ssid != NULL)
11336 {
11337 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11338 pConfig->SSIDinfo.ssid.length = ssid_len;
11339 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11340 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11341 }
11342#endif
11343
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011344 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011345 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011346
Jeff Johnson295189b2012-06-20 16:38:30 -070011347 /* default value */
11348 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11349 pConfig->num_accept_mac = 0;
11350 pConfig->num_deny_mac = 0;
11351
11352 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11353 pBeacon->tail, pBeacon->tail_len);
11354
11355 /* pIe for black list is following form:
11356 type : 1 byte
11357 length : 1 byte
11358 OUI : 4 bytes
11359 acl type : 1 byte
11360 no of mac addr in black list: 1 byte
11361 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011362 */
11363 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011364 {
11365 pConfig->SapMacaddr_acl = pIe[6];
11366 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011367 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011368 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011369 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11370 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011371 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11372 for (i = 0; i < pConfig->num_deny_mac; i++)
11373 {
11374 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11375 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011376 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011377 }
11378 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11379 pBeacon->tail, pBeacon->tail_len);
11380
11381 /* pIe for white list is following form:
11382 type : 1 byte
11383 length : 1 byte
11384 OUI : 4 bytes
11385 acl type : 1 byte
11386 no of mac addr in white list: 1 byte
11387 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011388 */
11389 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011390 {
11391 pConfig->SapMacaddr_acl = pIe[6];
11392 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011393 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011394 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011395 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11396 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011397 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11398 for (i = 0; i < pConfig->num_accept_mac; i++)
11399 {
11400 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11401 acl_entry++;
11402 }
11403 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011404
Jeff Johnson295189b2012-06-20 16:38:30 -070011405 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11406
Jeff Johnsone7245742012-09-05 17:12:55 -070011407#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011408 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011409 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11410 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011411 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11412 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011413 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11414 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011415 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11416 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011417 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011418 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011419 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011420 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011421
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011422 /* If ACS disable and selected channel <= 14
11423 * OR
11424 * ACS enabled and ACS operating band is choosen as 2.4
11425 * AND
11426 * VHT in 2.4G Disabled
11427 * THEN
11428 * Fallback to 11N mode
11429 */
11430 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11431 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011432 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011433 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011434 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011435 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11436 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011437 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11438 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011439 }
11440#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011441
Jeff Johnson295189b2012-06-20 16:38:30 -070011442 // ht_capab is not what the name conveys,this is used for protection bitmap
11443 pConfig->ht_capab =
11444 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11445
Kapil Gupta137ef892016-12-13 19:38:00 +053011446 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011447 {
11448 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011449 ret = -EINVAL;
11450 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011451 }
11452
11453 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011454 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011455 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11456 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011457 pConfig->obssProtEnabled =
11458 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011459
Chet Lanctot8cecea22014-02-11 19:09:36 -080011460#ifdef WLAN_FEATURE_11W
11461 pConfig->mfpCapable = MFPCapable;
11462 pConfig->mfpRequired = MFPRequired;
11463 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11464 pConfig->mfpCapable, pConfig->mfpRequired);
11465#endif
11466
Arif Hussain6d2a3322013-11-17 19:50:10 -080011467 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011469 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11470 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11471 (int)pConfig->channel);
11472 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11473 pConfig->SapHw_mode, pConfig->privacy,
11474 pConfig->authType);
11475 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11476 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11477 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11478 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011479
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011480 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011481 {
11482 //Bss already started. just return.
11483 //TODO Probably it should update some beacon params.
11484 hddLog( LOGE, "Bss Already started...Ignore the request");
11485 EXIT();
11486 return 0;
11487 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011488
Agarwal Ashish51325b52014-06-16 16:50:49 +053011489 if (vos_max_concurrent_connections_reached()) {
11490 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011491 ret = -EINVAL;
11492 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011493 }
11494
Jeff Johnson295189b2012-06-20 16:38:30 -070011495 pConfig->persona = pHostapdAdapter->device_mode;
11496
Peng Xu2446a892014-09-05 17:21:18 +053011497 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11498 if ( NULL != psmeConfig)
11499 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011500 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011501 sme_GetConfigParam(hHal, psmeConfig);
11502 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011503#ifdef WLAN_FEATURE_AP_HT40_24G
11504 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11505 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11506 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11507 {
11508 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11509 sme_UpdateConfig (hHal, psmeConfig);
11510 }
11511#endif
Peng Xu2446a892014-09-05 17:21:18 +053011512 vos_mem_free(psmeConfig);
11513 }
Peng Xuafc34e32014-09-25 13:23:55 +053011514 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011515
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011516 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Jeff Johnson295189b2012-06-20 16:38:30 -070011517 pSapEventCallback = hdd_hostapd_SAPEventCB;
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011518
11519 vos_event_reset(&pHostapdState->vosEvent);
Jeff Johnson295189b2012-06-20 16:38:30 -070011520 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11521 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11522 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011523 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011524 ret = -EINVAL;
11525 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011526 }
11527
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011528 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011529 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11530
11531 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011532
Jeff Johnson295189b2012-06-20 16:38:30 -070011533 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011534 {
11535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011536 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011537 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011538 VOS_ASSERT(0);
11539 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011540
Jeff Johnson295189b2012-06-20 16:38:30 -070011541 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011542 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11543 VOS_STATUS_SUCCESS)
11544 {
11545 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11546 VOS_ASSERT(0);
11547 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011548 /* Initialize WMM configuation */
11549 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011550 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011551
Anurag Chouhan83026002016-12-13 22:46:21 +053011552#ifdef DHCP_SERVER_OFFLOAD
11553 /* set dhcp server offload */
11554 if (iniConfig->enable_dhcp_srv_offload &&
11555 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011556 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011557 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011558 if (!VOS_IS_STATUS_SUCCESS(status))
11559 {
11560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11561 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011562 vos_event_reset(&pHostapdState->vosEvent);
11563 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11564 status = vos_wait_single_event(&pHostapdState->vosEvent,
11565 10000);
11566 if (!VOS_IS_STATUS_SUCCESS(status)) {
11567 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011568 ret = -EINVAL;
11569 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011570 }
11571 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011572 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011573 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11574 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11575 {
11576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11577 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11578 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011579 vos_event_reset(&pHostapdState->vosEvent);
11580 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11581 status = vos_wait_single_event(&pHostapdState->vosEvent,
11582 10000);
11583 if (!VOS_IS_STATUS_SUCCESS(status)) {
11584 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011585 ret = -EINVAL;
11586 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011587 }
11588 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011589 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011590#ifdef MDNS_OFFLOAD
11591 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011592 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011593 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11594 if (VOS_IS_STATUS_SUCCESS(status))
11595 {
11596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11597 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011598 vos_event_reset(&pHostapdState->vosEvent);
11599 if (VOS_STATUS_SUCCESS ==
11600 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11601 status = vos_wait_single_event(&pHostapdState->vosEvent,
11602 10000);
11603 if (!VOS_IS_STATUS_SUCCESS(status)) {
11604 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011605 ret = -EINVAL;
11606 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011607 }
11608 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011609 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011610 status = vos_wait_single_event(&pHostapdAdapter->
11611 mdns_status.vos_event, 2000);
11612 if (!VOS_IS_STATUS_SUCCESS(status) ||
11613 pHostapdAdapter->mdns_status.mdns_enable_status ||
11614 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11615 pHostapdAdapter->mdns_status.mdns_resp_status)
11616 {
11617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11618 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11619 pHostapdAdapter->mdns_status.mdns_enable_status,
11620 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11621 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011622 vos_event_reset(&pHostapdState->vosEvent);
11623 if (VOS_STATUS_SUCCESS ==
11624 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11625 status = vos_wait_single_event(&pHostapdState->vosEvent,
11626 10000);
11627 if (!VOS_IS_STATUS_SUCCESS(status)) {
11628 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011629 ret = -EINVAL;
11630 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011631 }
11632 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011633 }
11634 }
11635#endif /* MDNS_OFFLOAD */
11636 } else {
11637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11638 ("DHCP Disabled ini %d, FW %d"),
11639 iniConfig->enable_dhcp_srv_offload,
11640 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011641 }
11642#endif /* DHCP_SERVER_OFFLOAD */
11643
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011644#ifdef WLAN_FEATURE_P2P_DEBUG
11645 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11646 {
11647 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11648 {
11649 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11650 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011651 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011652 }
11653 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11654 {
11655 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11656 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011657 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011658 }
11659 }
11660#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011661 /* Check and restart SAP if it is on Unsafe channel */
11662 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011663
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 pHostapdState->bCommit = TRUE;
11665 EXIT();
11666
11667 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011668error:
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011669 /* Revert the indoor to passive marking if START BSS fails */
Sourav Mohapatra8b149332018-03-06 14:28:18 +053011670 if (iniConfig->disable_indoor_channel &&
11671 pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011672 hdd_update_indoor_channel(pHddCtx, false);
11673 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11674 }
11675
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011676 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
Bala Venkatesh5c06a252018-07-12 16:08:04 +053011677
11678tdls_enable:
11679 if (ret != eHAL_STATUS_SUCCESS)
11680 wlan_hdd_tdls_reenable(pHddCtx);
11681
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011682 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011683}
11684
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011685#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011686static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011687 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011688 struct beacon_parameters *params)
11689{
11690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011691 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011692 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011693
11694 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011695
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011696 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11697 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11698 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011699 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11700 hdd_device_modetoString(pAdapter->device_mode),
11701 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011702
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011703 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11704 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011705 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011706 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011707 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011708 }
11709
Agarwal Ashish51325b52014-06-16 16:50:49 +053011710 if (vos_max_concurrent_connections_reached()) {
11711 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11712 return -EINVAL;
11713 }
11714
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011715 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 )
11718 {
11719 beacon_data_t *old,*new;
11720
11721 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011722
Jeff Johnson295189b2012-06-20 16:38:30 -070011723 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011724 {
11725 hddLog(VOS_TRACE_LEVEL_WARN,
11726 FL("already beacon info added to session(%d)"),
11727 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011728 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011729 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011730
11731 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11732
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011733 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011734 {
11735 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011736 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 return -EINVAL;
11738 }
11739
11740 pAdapter->sessionCtx.ap.beacon = new;
11741
11742 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11743 }
11744
11745 EXIT();
11746 return status;
11747}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011748
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011749static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11750 struct net_device *dev,
11751 struct beacon_parameters *params)
11752{
11753 int ret;
11754
11755 vos_ssr_protect(__func__);
11756 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11757 vos_ssr_unprotect(__func__);
11758
11759 return ret;
11760}
11761
11762static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011763 struct net_device *dev,
11764 struct beacon_parameters *params)
11765{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011766 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011767 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11768 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011769 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011770
11771 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011772
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011773 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11774 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11775 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11776 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11777 __func__, hdd_device_modetoString(pAdapter->device_mode),
11778 pAdapter->device_mode);
11779
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011780 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11781 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011782 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011783 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011784 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011785 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011786
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011787 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011789 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 {
11791 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011792
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011794
Jeff Johnson295189b2012-06-20 16:38:30 -070011795 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011796 {
11797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11798 FL("session(%d) old and new heads points to NULL"),
11799 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011800 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011801 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011802
11803 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11804
11805 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011806 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011807 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011808 return -EINVAL;
11809 }
11810
11811 pAdapter->sessionCtx.ap.beacon = new;
11812
11813 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11814 }
11815
11816 EXIT();
11817 return status;
11818}
11819
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011820static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11821 struct net_device *dev,
11822 struct beacon_parameters *params)
11823{
11824 int ret;
11825
11826 vos_ssr_protect(__func__);
11827 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11828 vos_ssr_unprotect(__func__);
11829
11830 return ret;
11831}
11832
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011833#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11834
11835#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011836static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011837 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011838#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011839static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011840 struct net_device *dev)
11841#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011842{
11843 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011844 hdd_adapter_t *staAdapter = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011845 hdd_context_t *pHddCtx = NULL;
11846 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011847 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011848 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011849
11850 ENTER();
11851
11852 if (NULL == pAdapter)
11853 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011855 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011856 return -ENODEV;
11857 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011858
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011859 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11860 TRACE_CODE_HDD_CFG80211_STOP_AP,
11861 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011862 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11863 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011864 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011865 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011866 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011867 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011868
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011869 pScanInfo = &pHddCtx->scan_info;
11870
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011871 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11872 __func__, hdd_device_modetoString(pAdapter->device_mode),
11873 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011874
Vignesh Viswanathan5caacc22018-06-14 17:14:20 +053011875 /*
11876 * if a sta connection is in progress in another adapter, disconnect
11877 * the sta and complete the sap operation. sta will reconnect
11878 * after sap stop is done.
11879 */
11880 staAdapter = hdd_get_sta_connection_in_progress(pHddCtx);
11881 if (staAdapter) {
11882 hddLog(LOG1, FL("disconnecting sta with session id: %d"),
11883 staAdapter->sessionId);
11884 wlan_hdd_disconnect(staAdapter, eCSR_DISCONNECT_REASON_DEAUTH);
11885 }
11886
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011887 ret = wlan_hdd_scan_abort(pAdapter);
11888
Girish Gowli4bf7a632014-06-12 13:42:11 +053011889 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011890 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11892 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011893
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011894 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011895 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11897 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011898
Jeff Johnsone7245742012-09-05 17:12:55 -070011899 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011900 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011901 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011902 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011903 }
11904
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011905 /* Delete all associated STAs before stopping AP/P2P GO */
11906 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011907 hdd_hostapd_stop(dev);
11908
Jeff Johnson295189b2012-06-20 16:38:30 -070011909 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011910 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011911 )
11912 {
11913 beacon_data_t *old;
11914
11915 old = pAdapter->sessionCtx.ap.beacon;
11916
11917 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011918 {
11919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11920 FL("session(%d) beacon data points to NULL"),
11921 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011922 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011923 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011924
Jeff Johnson295189b2012-06-20 16:38:30 -070011925 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011926
11927 mutex_lock(&pHddCtx->sap_lock);
11928 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11929 {
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011930 hdd_hostapd_state_t *pHostapdState =
11931 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11932
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011933 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11934 hdd_wait_for_ecsa_complete(pHddCtx);
Hanumanth Reddy Pothula74ba68c2018-06-22 17:52:09 +053011935 vos_event_reset(&pHostapdState->vosEvent);
11936
Jeff Johnson4416a782013-03-25 14:17:50 -070011937 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011938 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011939 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11940
11941 if (!VOS_IS_STATUS_SUCCESS(status))
11942 {
11943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011944 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011945 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011946 }
11947 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011948 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011949 /* BSS stopped, clear the active sessions for this device mode */
11950 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011951 }
11952 mutex_unlock(&pHddCtx->sap_lock);
11953
11954 if(status != VOS_STATUS_SUCCESS)
11955 {
11956 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011957 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011958 return -EINVAL;
11959 }
11960
Jeff Johnson4416a782013-03-25 14:17:50 -070011961 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011962 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11963 ==eHAL_STATUS_FAILURE)
11964 {
11965 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011966 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011967 }
11968
Jeff Johnson4416a782013-03-25 14:17:50 -070011969 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011970 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11971 eANI_BOOLEAN_FALSE) )
11972 {
11973 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011974 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011975 }
11976
11977 // Reset WNI_CFG_PROBE_RSP Flags
11978 wlan_hdd_reset_prob_rspies(pAdapter);
11979
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011980 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11981
Jeff Johnson295189b2012-06-20 16:38:30 -070011982 pAdapter->sessionCtx.ap.beacon = NULL;
11983 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011984#ifdef WLAN_FEATURE_P2P_DEBUG
11985 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11986 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11987 {
11988 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11989 "GO got removed");
11990 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11991 }
11992#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011993 }
11994 EXIT();
11995 return status;
11996}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011997
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011998#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11999static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
12000 struct net_device *dev)
12001{
12002 int ret;
12003
12004 vos_ssr_protect(__func__);
12005 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
12006 vos_ssr_unprotect(__func__);
12007
12008 return ret;
12009}
12010#else
12011static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
12012 struct net_device *dev)
12013{
12014 int ret;
12015
12016 vos_ssr_protect(__func__);
12017 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
12018 vos_ssr_unprotect(__func__);
12019
12020 return ret;
12021}
12022#endif
12023
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012024#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
12025
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012026static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012027 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012028 struct cfg80211_ap_settings *params)
12029{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012030 hdd_adapter_t *pAdapter;
12031 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012032 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012033
12034 ENTER();
12035
Girish Gowlib143d7a2015-02-18 19:39:55 +053012036 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012037 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053012039 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012040 return -ENODEV;
12041 }
12042
12043 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12044 if (NULL == pAdapter)
12045 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012046 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012047 "%s: HDD adapter is Null", __func__);
12048 return -ENODEV;
12049 }
12050
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012051 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12052 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
12053 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012054 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
12055 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012056 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012057 "%s: HDD adapter magic is invalid", __func__);
12058 return -ENODEV;
12059 }
12060
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053012061 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
12062
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012063 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012064 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012065 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012066 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012067 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012068 }
12069
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012070 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
12071 __func__, hdd_device_modetoString(pAdapter->device_mode),
12072 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012073
12074 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012075 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012076 )
12077 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012078 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012079
12080 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012081
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012082 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012083 {
12084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
12085 FL("already beacon info added to session(%d)"),
12086 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012087 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012088 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012089
Girish Gowlib143d7a2015-02-18 19:39:55 +053012090#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
12091 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12092 &new,
12093 &params->beacon);
12094#else
12095 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
12096 &new,
12097 &params->beacon,
12098 params->dtim_period);
12099#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012100
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012101 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012102 {
12103 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053012104 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012105 return -EINVAL;
12106 }
12107 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080012108#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070012109 wlan_hdd_cfg80211_set_channel(wiphy, dev,
12110#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
12111 params->channel, params->channel_type);
12112#else
12113 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
12114#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080012115#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012116 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012117 params->ssid_len, params->hidden_ssid,
12118 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012119 }
12120
12121 EXIT();
12122 return status;
12123}
12124
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012125static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
12126 struct net_device *dev,
12127 struct cfg80211_ap_settings *params)
12128{
12129 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012130
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012131 vos_ssr_protect(__func__);
12132 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
12133 vos_ssr_unprotect(__func__);
12134
12135 return ret;
12136}
12137
12138static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012139 struct net_device *dev,
12140 struct cfg80211_beacon_data *params)
12141{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012142 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012143 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012144 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012145
12146 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012147
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012148 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12149 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
12150 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080012151 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012152 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012153
12154 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12155 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012156 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012157 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012158 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070012159 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012160
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012161 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012162 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012163 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012164 {
12165 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012166
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012167 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012168
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012169 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012170 {
12171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12172 FL("session(%d) beacon data points to NULL"),
12173 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012174 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012175 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012176
12177 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
12178
12179 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012180 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012181 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012182 return -EINVAL;
12183 }
12184
12185 pAdapter->sessionCtx.ap.beacon = new;
12186
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053012187 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
12188 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012189 }
12190
12191 EXIT();
12192 return status;
12193}
12194
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012195static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
12196 struct net_device *dev,
12197 struct cfg80211_beacon_data *params)
12198{
12199 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012200
Mukul Sharmab0e0a982014-12-15 18:58:53 +053012201 vos_ssr_protect(__func__);
12202 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
12203 vos_ssr_unprotect(__func__);
12204
12205 return ret;
12206}
12207
12208#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070012209
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012210static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 struct net_device *dev,
12212 struct bss_parameters *params)
12213{
12214 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012215 hdd_context_t *pHddCtx;
12216 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012217
12218 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012219
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012220 if (NULL == pAdapter)
12221 {
12222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12223 "%s: HDD adapter is Null", __func__);
12224 return -ENODEV;
12225 }
12226 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012227 ret = wlan_hdd_validate_context(pHddCtx);
12228 if (0 != ret)
12229 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012230 return ret;
12231 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012232 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12233 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
12234 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012235 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12236 __func__, hdd_device_modetoString(pAdapter->device_mode),
12237 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012238
12239 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012240 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012241 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 {
12243 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12244 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012245 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012246 {
12247 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012248 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012249 }
12250
12251 EXIT();
12252 return 0;
12253}
12254
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012255static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12256 struct net_device *dev,
12257 struct bss_parameters *params)
12258{
12259 int ret;
12260
12261 vos_ssr_protect(__func__);
12262 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12263 vos_ssr_unprotect(__func__);
12264
12265 return ret;
12266}
Kiet Lam10841362013-11-01 11:36:50 +053012267/* FUNCTION: wlan_hdd_change_country_code_cd
12268* to wait for contry code completion
12269*/
12270void* wlan_hdd_change_country_code_cb(void *pAdapter)
12271{
12272 hdd_adapter_t *call_back_pAdapter = pAdapter;
12273 complete(&call_back_pAdapter->change_country_code);
12274 return NULL;
12275}
12276
Jeff Johnson295189b2012-06-20 16:38:30 -070012277/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012278 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012279 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12280 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012281int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012282 struct net_device *ndev,
12283 enum nl80211_iftype type,
12284 u32 *flags,
12285 struct vif_params *params
12286 )
12287{
12288 struct wireless_dev *wdev;
12289 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012290 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012291 tCsrRoamProfile *pRoamProfile = NULL;
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012292 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012293 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012294 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012295 eMib_dot11DesiredBssType connectedBssType;
12296 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012297 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012298
12299 ENTER();
12300
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012301 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012302 {
12303 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12304 "%s: Adapter context is null", __func__);
12305 return VOS_STATUS_E_FAILURE;
12306 }
12307
12308 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12309 if (!pHddCtx)
12310 {
12311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12312 "%s: HDD context is null", __func__);
12313 return VOS_STATUS_E_FAILURE;
12314 }
12315
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012316 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12317 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12318 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012319 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012320 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012321 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012322 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012323 }
12324
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012325 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12326 __func__, hdd_device_modetoString(pAdapter->device_mode),
12327 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012328
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012329 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12330 hddLog(VOS_TRACE_LEVEL_FATAL,
12331 "%s: STA + MON is in progress, cannot change interface",
12332 __func__);
12333 }
12334
Agarwal Ashish51325b52014-06-16 16:50:49 +053012335 if (vos_max_concurrent_connections_reached()) {
12336 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12337 return -EINVAL;
12338 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012339 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012340 wdev = ndev->ieee80211_ptr;
12341
12342#ifdef WLAN_BTAMP_FEATURE
12343 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12344 (NL80211_IFTYPE_ADHOC == type)||
12345 (NL80211_IFTYPE_AP == type)||
12346 (NL80211_IFTYPE_P2P_GO == type))
12347 {
12348 pHddCtx->isAmpAllowed = VOS_FALSE;
12349 // stop AMP traffic
12350 status = WLANBAP_StopAmp();
12351 if(VOS_STATUS_SUCCESS != status )
12352 {
12353 pHddCtx->isAmpAllowed = VOS_TRUE;
12354 hddLog(VOS_TRACE_LEVEL_FATAL,
12355 "%s: Failed to stop AMP", __func__);
12356 return -EINVAL;
12357 }
12358 }
12359#endif //WLAN_BTAMP_FEATURE
12360 /* Reset the current device mode bit mask*/
12361 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12362
Bala Venkatesh5c06a252018-07-12 16:08:04 +053012363 if (((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12364 (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)) ||
12365 type == NL80211_IFTYPE_AP)
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012366 {
12367 /* Notify Mode change in case of concurrency.
12368 * Below function invokes TDLS teardown Functionality Since TDLS is
12369 * not Supported in case of concurrency i.e Once P2P session
12370 * is detected disable offchannel and teardown TDLS links
12371 */
12372 hddLog(LOG1,
12373 FL("Device mode = %d Interface type = %d"),
12374 pAdapter->device_mode, type);
12375 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12376 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012377
Jeff Johnson295189b2012-06-20 16:38:30 -070012378 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012379 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012380 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 )
12382 {
12383 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012384 if (!pWextState)
12385 {
12386 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12387 "%s: pWextState is null", __func__);
12388 return VOS_STATUS_E_FAILURE;
12389 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 pRoamProfile = &pWextState->roamProfile;
12391 LastBSSType = pRoamProfile->BSSType;
12392
12393 switch (type)
12394 {
12395 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012396 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012397 hddLog(VOS_TRACE_LEVEL_INFO,
12398 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12399 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012400#ifdef WLAN_FEATURE_11AC
12401 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12402 {
12403 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12404 }
12405#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012406 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012407 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012408 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012409 //Check for sub-string p2p to confirm its a p2p interface
12410 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012411 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012412#ifdef FEATURE_WLAN_TDLS
12413 mutex_lock(&pHddCtx->tdls_lock);
12414 wlan_hdd_tdls_exit(pAdapter, TRUE);
12415 mutex_unlock(&pHddCtx->tdls_lock);
12416#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012417 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12418 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12419 }
12420 else
12421 {
12422 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012423 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012424 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012425 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012426
Jeff Johnson295189b2012-06-20 16:38:30 -070012427 case NL80211_IFTYPE_ADHOC:
12428 hddLog(VOS_TRACE_LEVEL_INFO,
12429 "%s: setting interface Type to ADHOC", __func__);
12430 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12431 pRoamProfile->phyMode =
12432 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012433 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012434 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012435 hdd_set_ibss_ops( pAdapter );
12436 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012437
12438 status = hdd_sta_id_hash_attach(pAdapter);
12439 if (VOS_STATUS_SUCCESS != status) {
12440 hddLog(VOS_TRACE_LEVEL_ERROR,
12441 FL("Failed to initialize hash for IBSS"));
12442 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012443 break;
12444
12445 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012446 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012447 {
12448 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12449 "%s: setting interface Type to %s", __func__,
12450 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12451
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012452 //Cancel any remain on channel for GO mode
12453 if (NL80211_IFTYPE_P2P_GO == type)
12454 {
12455 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12456 }
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012457 if (NL80211_IFTYPE_AP == type)
12458 {
12459 /*
12460 * As Loading WLAN Driver one interface being created
12461 * for p2p device address. This will take one HW STA and
12462 * the max number of clients that can connect to softAP
12463 * will be reduced by one. so while changing the interface
12464 * type to NL80211_IFTYPE_AP (SoftAP) remove p2p0 interface
12465 * as it is not required in SoftAP mode.
12466 */
12467
12468 // Get P2P Adapter
12469 pP2pAdapter = hdd_get_adapter(pHddCtx,
12470 WLAN_HDD_P2P_DEVICE);
12471 if (pP2pAdapter)
12472 {
Min Liuf3481952018-12-10 16:01:14 +080012473 wlan_hdd_release_intf_addr(pHddCtx,
12474 pP2pAdapter->macAddressCurrent.bytes);
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012475 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12476 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
12477 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12478 }
12479 }
12480
Swaroop Goltia2e32212014-04-09 23:37:33 +053012481 //Disable IMPS & BMPS for SAP/GO
12482 if(VOS_STATUS_E_FAILURE ==
12483 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12484 {
12485 //Fail to Exit BMPS
12486 VOS_ASSERT(0);
12487 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012488
12489 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12490
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012491#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012492
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012493 /* A Mutex Lock is introduced while changing the mode to
12494 * protect the concurrent access for the Adapters by TDLS
12495 * module.
12496 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012497 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012498#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012499 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012500 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012501 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012502 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12503 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012504#ifdef FEATURE_WLAN_TDLS
12505 mutex_unlock(&pHddCtx->tdls_lock);
12506#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012507 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12508 (pConfig->apRandomBssidEnabled))
12509 {
12510 /* To meet Android requirements create a randomized
12511 MAC address of the form 02:1A:11:Fx:xx:xx */
12512 get_random_bytes(&ndev->dev_addr[3], 3);
12513 ndev->dev_addr[0] = 0x02;
12514 ndev->dev_addr[1] = 0x1A;
12515 ndev->dev_addr[2] = 0x11;
12516 ndev->dev_addr[3] |= 0xF0;
12517 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12518 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012519 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12520 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012521 }
12522
Jeff Johnson295189b2012-06-20 16:38:30 -070012523 hdd_set_ap_ops( pAdapter->dev );
12524
Kiet Lam10841362013-11-01 11:36:50 +053012525 /* This is for only SAP mode where users can
12526 * control country through ini.
12527 * P2P GO follows station country code
12528 * acquired during the STA scanning. */
12529 if((NL80211_IFTYPE_AP == type) &&
12530 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12531 {
12532 int status = 0;
12533 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12534 "%s: setting country code from INI ", __func__);
12535 init_completion(&pAdapter->change_country_code);
12536 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12537 (void *)(tSmeChangeCountryCallback)
12538 wlan_hdd_change_country_code_cb,
12539 pConfig->apCntryCode, pAdapter,
12540 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012541 eSIR_FALSE,
12542 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012543 if (eHAL_STATUS_SUCCESS == status)
12544 {
12545 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012546 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012547 &pAdapter->change_country_code,
12548 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012549 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012550 {
12551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012552 FL("SME Timed out while setting country code %ld"),
12553 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012554
12555 if (pHddCtx->isLogpInProgress)
12556 {
12557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12558 "%s: LOGP in Progress. Ignore!!!", __func__);
12559 return -EAGAIN;
12560 }
Kiet Lam10841362013-11-01 11:36:50 +053012561 }
12562 }
12563 else
12564 {
12565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012566 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012567 return -EINVAL;
12568 }
12569 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012570 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012571 if(status != VOS_STATUS_SUCCESS)
12572 {
12573 hddLog(VOS_TRACE_LEVEL_FATAL,
12574 "%s: Error initializing the ap mode", __func__);
12575 return -EINVAL;
12576 }
12577 hdd_set_conparam(1);
12578
Nirav Shah7e3c8132015-06-22 23:51:42 +053012579 status = hdd_sta_id_hash_attach(pAdapter);
12580 if (VOS_STATUS_SUCCESS != status)
12581 {
12582 hddLog(VOS_TRACE_LEVEL_ERROR,
12583 FL("Failed to initialize hash for AP"));
12584 return -EINVAL;
12585 }
12586
Jeff Johnson295189b2012-06-20 16:38:30 -070012587 /*interface type changed update in wiphy structure*/
12588 if(wdev)
12589 {
12590 wdev->iftype = type;
12591 pHddCtx->change_iface = type;
12592 }
12593 else
12594 {
12595 hddLog(VOS_TRACE_LEVEL_ERROR,
12596 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12597 return -EINVAL;
12598 }
12599 goto done;
12600 }
12601
12602 default:
12603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12604 __func__);
12605 return -EOPNOTSUPP;
12606 }
12607 }
12608 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012609 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012610 )
12611 {
12612 switch(type)
12613 {
12614 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012615 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012616 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012617
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012618 if (pAdapter->device_mode == WLAN_HDD_SOFTAP
12619 && !hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE)) {
12620 /*
12621 * The p2p interface was deleted while SoftAP mode was init,
12622 * create that interface now that the SoftAP is going down.
12623 */
12624 pP2pAdapter = hdd_open_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE,
12625 "p2p%d", wlan_hdd_get_intf_addr(pHddCtx),
12626 VOS_TRUE);
12627 }
12628
Deepthi Gowri500fc472014-08-11 19:53:10 +053012629 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Sourav Mohapatra85ef5062018-11-13 14:02:20 +053012630
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012631#ifdef FEATURE_WLAN_TDLS
12632
12633 /* A Mutex Lock is introduced while changing the mode to
12634 * protect the concurrent access for the Adapters by TDLS
12635 * module.
12636 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012637 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012638#endif
c_hpothu002231a2015-02-05 14:58:51 +053012639 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012640 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012641 //Check for sub-string p2p to confirm its a p2p interface
12642 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012643 {
12644 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12645 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12646 }
12647 else
12648 {
12649 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012651 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012652
12653 /* set con_mode to STA only when no SAP concurrency mode */
12654 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12655 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012656 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012657 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12658 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012659#ifdef FEATURE_WLAN_TDLS
12660 mutex_unlock(&pHddCtx->tdls_lock);
12661#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012662 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012663 if( VOS_STATUS_SUCCESS != status )
12664 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012665 /* In case of JB, for P2P-GO, only change interface will be called,
12666 * This is the right place to enable back bmps_imps()
12667 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012668 if (pHddCtx->hdd_wlan_suspended)
12669 {
12670 hdd_set_pwrparams(pHddCtx);
12671 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012672 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012673 goto done;
12674 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012675 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012676 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012677 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12678 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012679 goto done;
12680 default:
12681 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12682 __func__);
12683 return -EOPNOTSUPP;
12684
12685 }
12686
12687 }
12688 else
12689 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012690 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12691 __func__, hdd_device_modetoString(pAdapter->device_mode),
12692 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012693 return -EOPNOTSUPP;
12694 }
12695
12696
12697 if(pRoamProfile)
12698 {
12699 if ( LastBSSType != pRoamProfile->BSSType )
12700 {
12701 /*interface type changed update in wiphy structure*/
12702 wdev->iftype = type;
12703
12704 /*the BSS mode changed, We need to issue disconnect
12705 if connected or in IBSS disconnect state*/
12706 if ( hdd_connGetConnectedBssType(
12707 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12708 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12709 {
12710 /*need to issue a disconnect to CSR.*/
12711 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12712 if( eHAL_STATUS_SUCCESS ==
12713 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12714 pAdapter->sessionId,
12715 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12716 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012717 ret = wait_for_completion_interruptible_timeout(
12718 &pAdapter->disconnect_comp_var,
12719 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12720 if (ret <= 0)
12721 {
12722 hddLog(VOS_TRACE_LEVEL_ERROR,
12723 FL("wait on disconnect_comp_var failed %ld"), ret);
12724 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012725 }
12726 }
12727 }
12728 }
12729
12730done:
12731 /*set bitmask based on updated value*/
12732 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012733
12734 /* Only STA mode support TM now
12735 * all other mode, TM feature should be disabled */
12736 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12737 (~VOS_STA & pHddCtx->concurrency_mode) )
12738 {
12739 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12740 }
12741
Jeff Johnson295189b2012-06-20 16:38:30 -070012742#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012743 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012744 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012745 {
12746 //we are ok to do AMP
12747 pHddCtx->isAmpAllowed = VOS_TRUE;
12748 }
12749#endif //WLAN_BTAMP_FEATURE
12750 EXIT();
12751 return 0;
12752}
12753
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012754/*
12755 * FUNCTION: wlan_hdd_cfg80211_change_iface
12756 * wrapper function to protect the actual implementation from SSR.
12757 */
12758int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12759 struct net_device *ndev,
12760 enum nl80211_iftype type,
12761 u32 *flags,
12762 struct vif_params *params
12763 )
12764{
12765 int ret;
12766
12767 vos_ssr_protect(__func__);
12768 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12769 vos_ssr_unprotect(__func__);
12770
12771 return ret;
12772}
12773
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012774#ifdef FEATURE_WLAN_TDLS
12775static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012776 struct net_device *dev,
12777#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12778 const u8 *mac,
12779#else
12780 u8 *mac,
12781#endif
12782 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012783{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012784 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012785 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012786 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012787 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012788 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012789 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012790
12791 ENTER();
12792
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012793 if (!dev) {
12794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12795 return -EINVAL;
12796 }
12797
12798 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12799 if (!pAdapter) {
12800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12801 return -EINVAL;
12802 }
12803
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012804 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012805 {
12806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12807 "Invalid arguments");
12808 return -EINVAL;
12809 }
Hoonki Lee27511902013-03-14 18:19:06 -070012810
12811 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12812 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12813 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012815 "%s: TDLS mode is disabled OR not enabled in FW."
12816 MAC_ADDRESS_STR " Request declined.",
12817 __func__, MAC_ADDR_ARRAY(mac));
12818 return -ENOTSUPP;
12819 }
12820
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012821 if (pHddCtx->isLogpInProgress)
12822 {
12823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12824 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012825 wlan_hdd_tdls_set_link_status(pAdapter,
12826 mac,
12827 eTDLS_LINK_IDLE,
12828 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012829 return -EBUSY;
12830 }
12831
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012832 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012833 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012834
12835 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012837 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12838 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012839 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012840 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012841 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012842
12843 /* in add station, we accept existing valid staId if there is */
12844 if ((0 == update) &&
12845 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12846 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012847 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012849 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012850 " link_status %d. staId %d. add station ignored.",
12851 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012852 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012853 return 0;
12854 }
12855 /* in change station, we accept only when staId is valid */
12856 if ((1 == update) &&
12857 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12858 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12859 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012860 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012862 "%s: " MAC_ADDRESS_STR
12863 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012864 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12865 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12866 mutex_unlock(&pHddCtx->tdls_lock);
12867 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012868 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012869 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012870
12871 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012872 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012873 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012874 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12875 "%s: " MAC_ADDRESS_STR
12876 " TDLS setup is ongoing. Request declined.",
12877 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012878 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012879 }
12880
12881 /* first to check if we reached to maximum supported TDLS peer.
12882 TODO: for now, return -EPERM looks working fine,
12883 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012884 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12885 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012886 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12888 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012889 " TDLS Max peer already connected. Request declined."
12890 " Num of peers (%d), Max allowed (%d).",
12891 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12892 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012893 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012894 }
12895 else
12896 {
12897 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012898 mutex_lock(&pHddCtx->tdls_lock);
12899 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012900 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012901 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012902 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12904 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12905 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012906 return -EPERM;
12907 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012908 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012909 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012910 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012911 wlan_hdd_tdls_set_link_status(pAdapter,
12912 mac,
12913 eTDLS_LINK_CONNECTING,
12914 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012915
Jeff Johnsond75fe012013-04-06 10:53:06 -070012916 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012917 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012918 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012920 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012921 if(StaParams->htcap_present)
12922 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012924 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012926 "ht_capa->extended_capabilities: %0x",
12927 StaParams->HTCap.extendedHtCapInfo);
12928 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012930 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012931 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012932 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012933 if(StaParams->vhtcap_present)
12934 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012936 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12937 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12938 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12939 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012940 {
12941 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012943 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012945 "[%d]: %x ", i, StaParams->supported_rates[i]);
12946 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012947 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012948 else if ((1 == update) && (NULL == StaParams))
12949 {
12950 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12951 "%s : update is true, but staParams is NULL. Error!", __func__);
12952 return -EPERM;
12953 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012954
12955 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12956
12957 if (!update)
12958 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012959 /*Before adding sta make sure that device exited from BMPS*/
12960 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12961 {
12962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12963 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12964 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12965 if (status != VOS_STATUS_SUCCESS) {
12966 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12967 }
12968 }
12969
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012970 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012971 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012972 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012973 hddLog(VOS_TRACE_LEVEL_ERROR,
12974 FL("Failed to add TDLS peer STA. Enable Bmps"));
12975 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012976 return -EPERM;
12977 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012978 }
12979 else
12980 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012981 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012982 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012983 if (ret != eHAL_STATUS_SUCCESS) {
12984 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12985 return -EPERM;
12986 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012987 }
12988
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012989 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012990 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12991
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012992 mutex_lock(&pHddCtx->tdls_lock);
12993 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12994
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012995 if ((pTdlsPeer != NULL) &&
12996 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012997 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012998 hddLog(VOS_TRACE_LEVEL_ERROR,
12999 FL("peer link status %u"), pTdlsPeer->link_status);
13000 mutex_unlock(&pHddCtx->tdls_lock);
13001 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013002 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053013003 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013004
Masti, Narayanraddi07262462016-01-19 12:40:06 +053013005 if (ret <= 0)
13006 {
13007 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13008 "%s: timeout waiting for tdls add station indication %ld",
13009 __func__, ret);
13010 goto error;
13011 }
13012
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013013 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
13014 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013015 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013016 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070013017 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013018 }
13019
13020 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070013021
13022error:
Atul Mittal115287b2014-07-08 13:26:33 +053013023 wlan_hdd_tdls_set_link_status(pAdapter,
13024 mac,
13025 eTDLS_LINK_IDLE,
13026 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070013027 return -EPERM;
13028
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013029}
13030#endif
13031
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013032VOS_STATUS wlan_hdd_send_sta_authorized_event(
13033 hdd_adapter_t *adapter,
13034 hdd_context_t *hdd_ctx,
13035 const v_MACADDR_t *mac_addr)
13036{
13037 struct sk_buff *vendor_event;
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013038 VOS_STATUS status;
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053013039 struct nl80211_sta_flag_update sta_flags;
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013040
13041 ENTER();
13042
13043 if (!hdd_ctx) {
13044 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
13045 return -EINVAL;
13046 }
13047
13048 vendor_event =
13049 cfg80211_vendor_event_alloc(
Ashish Kumar Dhanotiyac99fbef2018-04-11 12:23:32 +053013050 hdd_ctx->wiphy,
13051#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
13052 &adapter->wdev,
13053#endif
13054 sizeof(sta_flags) +
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013055 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
13056 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
13057 GFP_KERNEL);
13058 if (!vendor_event) {
13059 hddLog(VOS_TRACE_LEVEL_ERROR,
13060 FL("cfg80211_vendor_event_alloc failed"));
13061 return -EINVAL;
13062 }
13063
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053013064 sta_flags.mask |= BIT(NL80211_STA_FLAG_AUTHORIZED);
13065 sta_flags.set = true;
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013066
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053013067 status = nla_put(vendor_event,
13068 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
13069 sizeof(struct nl80211_sta_flag_update),
13070 &sta_flags);
13071
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013072 if (status) {
13073 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
13074 kfree_skb(vendor_event);
13075 return VOS_STATUS_E_FAILURE;
13076 }
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053013077
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013078 status = nla_put(vendor_event,
Sourav Mohapatra55dfabe2019-04-03 15:09:21 +053013079 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR,
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013080 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
13081 if (status) {
13082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
13083 kfree_skb(vendor_event);
13084 return VOS_STATUS_E_FAILURE;
13085 }
13086
13087 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
13088
13089 EXIT();
13090 return 0;
13091}
13092
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013093static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013094 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013095#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13096 const u8 *mac,
13097#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013098 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013099#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013100 struct station_parameters *params)
13101{
13102 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013103 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013104 hdd_context_t *pHddCtx;
13105 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013106 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013107 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013108#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013109 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013110 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013111 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013112 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013113#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013114
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013115 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013116
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053013117 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013118 if ((NULL == pAdapter))
13119 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013121 "invalid adapter ");
13122 return -EINVAL;
13123 }
13124
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013125 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13126 TRACE_CODE_HDD_CHANGE_STATION,
13127 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053013128 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053013129
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013130 ret = wlan_hdd_validate_context(pHddCtx);
13131 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053013132 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013133 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013134 }
13135
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013136 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13137
13138 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013139 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13141 "invalid HDD station context");
13142 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013143 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013144 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
13145
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013146 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
13147 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070013148 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013149 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070013150 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013151 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070013152 WLANTL_STA_AUTHENTICATED);
13153
Gopichand Nakkala29149562013-05-10 21:43:41 +053013154 if (status != VOS_STATUS_SUCCESS)
13155 {
13156 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13157 "%s: Not able to change TL state to AUTHENTICATED", __func__);
13158 return -EINVAL;
13159 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053013160 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
13161 &STAMacAddress);
13162 if (status != VOS_STATUS_SUCCESS)
13163 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013164 }
13165 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070013166 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
13167 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013168#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013169 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
13170 StaParams.capability = params->capability;
13171 StaParams.uapsd_queues = params->uapsd_queues;
13172 StaParams.max_sp = params->max_sp;
13173
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013174 /* Convert (first channel , number of channels) tuple to
13175 * the total list of channels. This goes with the assumption
13176 * that if the first channel is < 14, then the next channels
13177 * are an incremental of 1 else an incremental of 4 till the number
13178 * of channels.
13179 */
13180 if (0 != params->supported_channels_len) {
13181 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013182 for ( i = 0 ; i < params->supported_channels_len
13183 && j < SIR_MAC_MAX_SUPP_CHANNELS; i+=2)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013184 {
13185 int wifi_chan_index;
13186 StaParams.supported_channels[j] = params->supported_channels[i];
13187 wifi_chan_index =
13188 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
13189 no_of_channels = params->supported_channels[i+1];
Ashish Kumar Dhanotiyaf01ec752018-04-25 15:50:15 +053013190 for(k=1; k <= no_of_channels
13191 && j < SIR_MAC_MAX_SUPP_CHANNELS - 1; k++)
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013192 {
13193 StaParams.supported_channels[j+1] =
13194 StaParams.supported_channels[j] + wifi_chan_index;
13195 j+=1;
13196 }
13197 }
13198 StaParams.supported_channels_len = j;
13199 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053013200 if (params->supported_oper_classes_len >
13201 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
13202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13203 "received oper classes:%d, resetting it to max supported %d",
13204 params->supported_oper_classes_len,
13205 SIR_MAC_MAX_SUPP_OPER_CLASSES);
13206 params->supported_oper_classes_len =
13207 SIR_MAC_MAX_SUPP_OPER_CLASSES;
13208 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013209 vos_mem_copy(StaParams.supported_oper_classes,
13210 params->supported_oper_classes,
13211 params->supported_oper_classes_len);
13212 StaParams.supported_oper_classes_len =
13213 params->supported_oper_classes_len;
13214
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013215 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
13216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13217 "received extn capabilities:%d, resetting it to max supported",
13218 params->ext_capab_len);
13219 params->ext_capab_len = sizeof(StaParams.extn_capability);
13220 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013221 if (0 != params->ext_capab_len)
13222 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053013223 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013224
13225 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013226 {
13227 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013228 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013229 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013230
13231 StaParams.supported_rates_len = params->supported_rates_len;
13232
13233 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
13234 * The supported_rates array , for all the structures propogating till Add Sta
13235 * to the firmware has to be modified , if the supplicant (ieee80211) is
13236 * modified to send more rates.
13237 */
13238
13239 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
13240 */
13241 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
13242 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
13243
13244 if (0 != StaParams.supported_rates_len) {
13245 int i = 0;
13246 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
13247 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013249 "Supported Rates with Length %d", StaParams.supported_rates_len);
13250 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070013251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013252 "[%d]: %0x", i, StaParams.supported_rates[i]);
13253 }
13254
13255 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070013256 {
13257 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013258 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070013259 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070013260
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013261 if (0 != params->ext_capab_len ) {
13262 /*Define A Macro : TODO Sunil*/
13263 if ((1<<4) & StaParams.extn_capability[3]) {
13264 isBufSta = 1;
13265 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013266 /* TDLS Channel Switching Support */
13267 if ((1<<6) & StaParams.extn_capability[3]) {
13268 isOffChannelSupported = 1;
13269 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013270 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013271
13272 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013273 (params->ht_capa || params->vht_capa ||
13274 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013275 /* TDLS Peer is WME/QoS capable */
13276 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013277
13278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13279 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13280 __func__, isQosWmmSta, StaParams.htcap_present);
13281
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013282 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13283 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013284 isOffChannelSupported,
13285 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013286
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013287 if (VOS_STATUS_SUCCESS != status) {
13288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13289 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13290 return -EINVAL;
13291 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013292 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13293
13294 if (VOS_STATUS_SUCCESS != status) {
13295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13296 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13297 return -EINVAL;
13298 }
13299 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013300#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013301 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013302 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013303 return status;
13304}
13305
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13307static int wlan_hdd_change_station(struct wiphy *wiphy,
13308 struct net_device *dev,
13309 const u8 *mac,
13310 struct station_parameters *params)
13311#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013312static int wlan_hdd_change_station(struct wiphy *wiphy,
13313 struct net_device *dev,
13314 u8 *mac,
13315 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013316#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013317{
13318 int ret;
13319
13320 vos_ssr_protect(__func__);
13321 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13322 vos_ssr_unprotect(__func__);
13323
13324 return ret;
13325}
13326
Jeff Johnson295189b2012-06-20 16:38:30 -070013327/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013328 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013329 * This function is used to initialize the key information
13330 */
13331#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013332static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013333 struct net_device *ndev,
13334 u8 key_index, bool pairwise,
13335 const u8 *mac_addr,
13336 struct key_params *params
13337 )
13338#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013339static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013340 struct net_device *ndev,
13341 u8 key_index, const u8 *mac_addr,
13342 struct key_params *params
13343 )
13344#endif
13345{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013346 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013347 tCsrRoamSetKey setKey;
13348 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013349 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013350 v_U32_t roamId= 0xFF;
13351 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013352 hdd_hostapd_state_t *pHostapdState;
13353 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013354 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013355 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013356 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013357 v_MACADDR_t *peerMacAddr;
13358 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013359 uint8_t staid = HDD_MAX_STA_COUNT;
13360 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013361
13362 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013363
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013364 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13365 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13366 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013367 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13368 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013369 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013370 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013371 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013372 }
13373
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013374 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13375 __func__, hdd_device_modetoString(pAdapter->device_mode),
13376 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013377
13378 if (CSR_MAX_NUM_KEY <= key_index)
13379 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013380 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013381 key_index);
13382
13383 return -EINVAL;
13384 }
13385
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013386 if (CSR_MAX_KEY_LEN < params->key_len)
13387 {
13388 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13389 params->key_len);
13390
13391 return -EINVAL;
13392 }
13393
Jingxiang Gec438aea2017-10-26 16:44:00 +080013394 if (CSR_MAX_RSC_LEN < params->seq_len)
13395 {
13396 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13397 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013398
13399 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013400 }
13401
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013402 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013403 "%s: called with key index = %d & key length %d & seq length %d",
13404 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013405
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013406 peerMacAddr = (v_MACADDR_t *)mac_addr;
13407
Jeff Johnson295189b2012-06-20 16:38:30 -070013408 /*extract key idx, key len and key*/
13409 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13410 setKey.keyId = key_index;
13411 setKey.keyLength = params->key_len;
13412 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013413 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013414
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013415 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013416 {
13417 case WLAN_CIPHER_SUITE_WEP40:
13418 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13419 break;
13420
13421 case WLAN_CIPHER_SUITE_WEP104:
13422 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13423 break;
13424
13425 case WLAN_CIPHER_SUITE_TKIP:
13426 {
13427 u8 *pKey = &setKey.Key[0];
13428 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13429
13430 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13431
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013432 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013433
13434 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013435 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013436 |--------------|----------|----------|
13437 <---16bytes---><--8bytes--><--8bytes-->
13438
13439 */
13440 /*Sme expects the 32 bytes key to be in the below order
13441
13442 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013443 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013444 |--------------|----------|----------|
13445 <---16bytes---><--8bytes--><--8bytes-->
13446 */
13447 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013448 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013449
13450 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013451 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013452
13453 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013454 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013455
13456
13457 break;
13458 }
13459
13460 case WLAN_CIPHER_SUITE_CCMP:
13461 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13462 break;
13463
13464#ifdef FEATURE_WLAN_WAPI
13465 case WLAN_CIPHER_SUITE_SMS4:
13466 {
13467 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13468 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13469 params->key, params->key_len);
13470 return 0;
13471 }
13472#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013473
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013474#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013475 case WLAN_CIPHER_SUITE_KRK:
13476 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13477 break;
13478#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013479
13480#ifdef WLAN_FEATURE_11W
13481 case WLAN_CIPHER_SUITE_AES_CMAC:
13482 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013483 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013484#endif
13485
Jeff Johnson295189b2012-06-20 16:38:30 -070013486 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013487 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013488 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013489 status = -EOPNOTSUPP;
13490 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013491 }
13492
13493 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13494 __func__, setKey.encType);
13495
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013496 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013497#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13498 (!pairwise)
13499#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013500 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013501#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013502 )
13503 {
13504 /* set group key*/
13505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13506 "%s- %d: setting Broadcast key",
13507 __func__, __LINE__);
13508 setKey.keyDirection = eSIR_RX_ONLY;
13509 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13510 }
13511 else
13512 {
13513 /* set pairwise key*/
13514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13515 "%s- %d: setting pairwise key",
13516 __func__, __LINE__);
13517 setKey.keyDirection = eSIR_TX_RX;
13518 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013519 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013520 }
13521 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13522 {
13523 setKey.keyDirection = eSIR_TX_RX;
13524 /*Set the group key*/
13525 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13526 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013527
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013528 if ( 0 != status )
13529 {
13530 hddLog(VOS_TRACE_LEVEL_ERROR,
13531 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013532 status = -EINVAL;
13533 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013534 }
13535 /*Save the keys here and call sme_RoamSetKey for setting
13536 the PTK after peer joins the IBSS network*/
13537 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13538 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013539 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013540 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013541 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13542 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13543 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013544 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013545 if( pHostapdState->bssState == BSS_START )
13546 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013547 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13548 vos_status = wlan_hdd_check_ula_done(pAdapter);
13549
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013550 if (peerMacAddr && (pairwise_set_key == true))
13551 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013552
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013553 if ( vos_status != VOS_STATUS_SUCCESS )
13554 {
13555 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13556 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13557 __LINE__, vos_status );
13558
13559 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13560
13561 status = -EINVAL;
13562 goto end;
13563 }
13564
Jeff Johnson295189b2012-06-20 16:38:30 -070013565 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13566
13567 if ( status != eHAL_STATUS_SUCCESS )
13568 {
13569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13570 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13571 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013572 status = -EINVAL;
13573 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013574 }
13575 }
13576
13577 /* Saving WEP keys */
13578 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13579 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13580 {
13581 //Save the wep key in ap context. Issue setkey after the BSS is started.
13582 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13583 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13584 }
13585 else
13586 {
13587 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013588 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013589 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13590 }
13591 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013592 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13593 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013594 {
13595 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13596 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13597
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013598#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13599 if (!pairwise)
13600#else
13601 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13602#endif
13603 {
13604 /* set group key*/
13605 if (pHddStaCtx->roam_info.deferKeyComplete)
13606 {
13607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13608 "%s- %d: Perform Set key Complete",
13609 __func__, __LINE__);
13610 hdd_PerformRoamSetKeyComplete(pAdapter);
13611 }
13612 }
13613
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013614 if (pairwise_set_key == true)
13615 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013616
Jeff Johnson295189b2012-06-20 16:38:30 -070013617 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13618
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013619 pWextState->roamProfile.Keys.defaultIndex = key_index;
13620
13621
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013622 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013623 params->key, params->key_len);
13624
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013625
Jeff Johnson295189b2012-06-20 16:38:30 -070013626 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13627
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013628 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013630 __func__, setKey.peerMac[0], setKey.peerMac[1],
13631 setKey.peerMac[2], setKey.peerMac[3],
13632 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013633 setKey.keyDirection);
13634
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013635 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013636
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013637 if ( vos_status != VOS_STATUS_SUCCESS )
13638 {
13639 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013640 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13641 __LINE__, vos_status );
13642
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013643 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013644
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013645 status = -EINVAL;
13646 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013647
13648 }
13649
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013650#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013651 /* The supplicant may attempt to set the PTK once pre-authentication
13652 is done. Save the key in the UMAC and include it in the ADD BSS
13653 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013654 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013655 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013656 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013657 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13658 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013659 status = 0;
13660 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013661 }
13662 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13663 {
13664 hddLog(VOS_TRACE_LEVEL_ERROR,
13665 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013666 status = -EINVAL;
13667 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013668 }
13669#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013670
13671 /* issue set key request to SME*/
13672 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13673 pAdapter->sessionId, &setKey, &roamId );
13674
13675 if ( 0 != status )
13676 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013677 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013678 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13679 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013680 status = -EINVAL;
13681 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013682 }
13683
13684
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013685 /* in case of IBSS as there was no information available about WEP keys during
13686 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013687 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013688 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13689 !( ( IW_AUTH_KEY_MGMT_802_1X
13690 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013691 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13692 )
13693 &&
13694 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13695 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13696 )
13697 )
13698 {
13699 setKey.keyDirection = eSIR_RX_ONLY;
13700 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13701
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013702 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013703 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013704 __func__, setKey.peerMac[0], setKey.peerMac[1],
13705 setKey.peerMac[2], setKey.peerMac[3],
13706 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013707 setKey.keyDirection);
13708
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013709 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013710 pAdapter->sessionId, &setKey, &roamId );
13711
13712 if ( 0 != status )
13713 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013714 hddLog(VOS_TRACE_LEVEL_ERROR,
13715 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013716 __func__, status);
13717 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013718 status = -EINVAL;
13719 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013720 }
13721 }
13722 }
13723
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013724 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013725 for (i = 0; i < params->seq_len; i++) {
13726 rsc_counter |= (params->seq[i] << i*8);
13727 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013728 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13729 }
13730
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013731end:
13732 /* Need to clear any trace of key value in the memory.
13733 * Thus zero out the memory even though it is local
13734 * variable.
13735 */
13736 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013737 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013738 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013739}
13740
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013741#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13742static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13743 struct net_device *ndev,
13744 u8 key_index, bool pairwise,
13745 const u8 *mac_addr,
13746 struct key_params *params
13747 )
13748#else
13749static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13750 struct net_device *ndev,
13751 u8 key_index, const u8 *mac_addr,
13752 struct key_params *params
13753 )
13754#endif
13755{
13756 int ret;
13757 vos_ssr_protect(__func__);
13758#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13759 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13760 mac_addr, params);
13761#else
13762 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13763 params);
13764#endif
13765 vos_ssr_unprotect(__func__);
13766
13767 return ret;
13768}
13769
Jeff Johnson295189b2012-06-20 16:38:30 -070013770/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013771 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013772 * This function is used to get the key information
13773 */
13774#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013775static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013776 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013777 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013778 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013779 const u8 *mac_addr, void *cookie,
13780 void (*callback)(void *cookie, struct key_params*)
13781 )
13782#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013783static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013784 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013785 struct net_device *ndev,
13786 u8 key_index, const u8 *mac_addr, void *cookie,
13787 void (*callback)(void *cookie, struct key_params*)
13788 )
13789#endif
13790{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013791 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013792 hdd_wext_state_t *pWextState = NULL;
13793 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013794 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013795 hdd_context_t *pHddCtx;
13796 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013797
13798 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013799
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013800 if (NULL == pAdapter)
13801 {
13802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13803 "%s: HDD adapter is Null", __func__);
13804 return -ENODEV;
13805 }
13806
13807 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13808 ret = wlan_hdd_validate_context(pHddCtx);
13809 if (0 != ret)
13810 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013811 return ret;
13812 }
13813
13814 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13815 pRoamProfile = &(pWextState->roamProfile);
13816
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013817 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13818 __func__, hdd_device_modetoString(pAdapter->device_mode),
13819 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013820
Jeff Johnson295189b2012-06-20 16:38:30 -070013821 memset(&params, 0, sizeof(params));
13822
13823 if (CSR_MAX_NUM_KEY <= key_index)
13824 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013826 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013827 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013828
13829 switch(pRoamProfile->EncryptionType.encryptionType[0])
13830 {
13831 case eCSR_ENCRYPT_TYPE_NONE:
13832 params.cipher = IW_AUTH_CIPHER_NONE;
13833 break;
13834
13835 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13836 case eCSR_ENCRYPT_TYPE_WEP40:
13837 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13838 break;
13839
13840 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13841 case eCSR_ENCRYPT_TYPE_WEP104:
13842 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13843 break;
13844
13845 case eCSR_ENCRYPT_TYPE_TKIP:
13846 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13847 break;
13848
13849 case eCSR_ENCRYPT_TYPE_AES:
13850 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13851 break;
13852
13853 default:
13854 params.cipher = IW_AUTH_CIPHER_NONE;
13855 break;
13856 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013857
c_hpothuaaf19692014-05-17 17:01:48 +053013858 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13859 TRACE_CODE_HDD_CFG80211_GET_KEY,
13860 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013861
Jeff Johnson295189b2012-06-20 16:38:30 -070013862 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13863 params.seq_len = 0;
13864 params.seq = NULL;
13865 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13866 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013867 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013868 return 0;
13869}
13870
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013871#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13872static int wlan_hdd_cfg80211_get_key(
13873 struct wiphy *wiphy,
13874 struct net_device *ndev,
13875 u8 key_index, bool pairwise,
13876 const u8 *mac_addr, void *cookie,
13877 void (*callback)(void *cookie, struct key_params*)
13878 )
13879#else
13880static int wlan_hdd_cfg80211_get_key(
13881 struct wiphy *wiphy,
13882 struct net_device *ndev,
13883 u8 key_index, const u8 *mac_addr, void *cookie,
13884 void (*callback)(void *cookie, struct key_params*)
13885 )
13886#endif
13887{
13888 int ret;
13889
13890 vos_ssr_protect(__func__);
13891#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13892 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13893 mac_addr, cookie, callback);
13894#else
13895 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13896 callback);
13897#endif
13898 vos_ssr_unprotect(__func__);
13899
13900 return ret;
13901}
13902
Jeff Johnson295189b2012-06-20 16:38:30 -070013903/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013904 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013905 * This function is used to delete the key information
13906 */
13907#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013908static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013909 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013910 u8 key_index,
13911 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 const u8 *mac_addr
13913 )
13914#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013915static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013916 struct net_device *ndev,
13917 u8 key_index,
13918 const u8 *mac_addr
13919 )
13920#endif
13921{
13922 int status = 0;
13923
13924 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013925 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013926 //it is observed that this is invalidating peer
13927 //key index whenever re-key is done. This is affecting data link.
13928 //It should be ok to ignore del_key.
13929#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013930 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13931 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013932 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13933 tCsrRoamSetKey setKey;
13934 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013935
Jeff Johnson295189b2012-06-20 16:38:30 -070013936 ENTER();
13937
13938 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13939 __func__,pAdapter->device_mode);
13940
13941 if (CSR_MAX_NUM_KEY <= key_index)
13942 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013943 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013944 key_index);
13945
13946 return -EINVAL;
13947 }
13948
13949 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13950 setKey.keyId = key_index;
13951
13952 if (mac_addr)
13953 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13954 else
13955 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13956
13957 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13958
13959 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013960 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013961 )
13962 {
13963
13964 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013965 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13966 if( pHostapdState->bssState == BSS_START)
13967 {
13968 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013969
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 if ( status != eHAL_STATUS_SUCCESS )
13971 {
13972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13973 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13974 __LINE__, status );
13975 }
13976 }
13977 }
13978 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013979 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013980 )
13981 {
13982 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13983
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013984 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13985
13986 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013987 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013988 __func__, setKey.peerMac[0], setKey.peerMac[1],
13989 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013990 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013991 if(pAdapter->sessionCtx.station.conn_info.connState ==
13992 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013993 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013994 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013995 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013996
Jeff Johnson295189b2012-06-20 16:38:30 -070013997 if ( 0 != status )
13998 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013999 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014000 "%s: sme_RoamSetKey failure, returned %d",
14001 __func__, status);
14002 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
14003 return -EINVAL;
14004 }
14005 }
14006 }
14007#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070014008 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014009 return status;
14010}
14011
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014012#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14013static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
14014 struct net_device *ndev,
14015 u8 key_index,
14016 bool pairwise,
14017 const u8 *mac_addr
14018 )
14019#else
14020static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
14021 struct net_device *ndev,
14022 u8 key_index,
14023 const u8 *mac_addr
14024 )
14025#endif
14026{
14027 int ret;
14028
14029 vos_ssr_protect(__func__);
14030#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14031 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
14032 mac_addr);
14033#else
14034 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
14035#endif
14036 vos_ssr_unprotect(__func__);
14037
14038 return ret;
14039}
14040
Jeff Johnson295189b2012-06-20 16:38:30 -070014041/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014042 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070014043 * This function is used to set the default tx key index
14044 */
14045#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014046static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014047 struct net_device *ndev,
14048 u8 key_index,
14049 bool unicast, bool multicast)
14050#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014051static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014052 struct net_device *ndev,
14053 u8 key_index)
14054#endif
14055{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014056 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014057 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053014058 hdd_wext_state_t *pWextState;
14059 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014060 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014061
14062 ENTER();
14063
Gopichand Nakkala29149562013-05-10 21:43:41 +053014064 if ((NULL == pAdapter))
14065 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053014067 "invalid adapter");
14068 return -EINVAL;
14069 }
14070
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014071 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14072 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
14073 pAdapter->sessionId, key_index));
14074
Gopichand Nakkala29149562013-05-10 21:43:41 +053014075 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14076 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14077
14078 if ((NULL == pWextState) || (NULL == pHddStaCtx))
14079 {
14080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
14081 "invalid Wext state or HDD context");
14082 return -EINVAL;
14083 }
14084
Arif Hussain6d2a3322013-11-17 19:50:10 -080014085 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014086 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014087
Jeff Johnson295189b2012-06-20 16:38:30 -070014088 if (CSR_MAX_NUM_KEY <= key_index)
14089 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014090 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014091 key_index);
14092
14093 return -EINVAL;
14094 }
14095
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014096 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14097 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014098 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014099 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014100 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014101 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014102
Jeff Johnson295189b2012-06-20 16:38:30 -070014103 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070014104 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014105 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014106 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053014107 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080014108 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080014109#ifdef FEATURE_WLAN_WAPI
14110 (eCSR_ENCRYPT_TYPE_WPI !=
14111 pHddStaCtx->conn_info.ucEncryptionType) &&
14112#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014113 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080014114 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070014115 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014116 {
14117 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070014118 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014119
Jeff Johnson295189b2012-06-20 16:38:30 -070014120 tCsrRoamSetKey setKey;
14121 v_U32_t roamId= 0xFF;
14122 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014123
14124 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014125 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014126
Jeff Johnson295189b2012-06-20 16:38:30 -070014127 Keys->defaultIndex = (u8)key_index;
14128 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
14129 setKey.keyId = key_index;
14130 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014131
14132 vos_mem_copy(&setKey.Key[0],
14133 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014134 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014135
Gopichand Nakkala29149562013-05-10 21:43:41 +053014136 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014137
14138 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070014139 &pHddStaCtx->conn_info.bssId[0],
14140 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014141
Gopichand Nakkala29149562013-05-10 21:43:41 +053014142 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
14143 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
14144 eCSR_ENCRYPT_TYPE_WEP104)
14145 {
14146 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
14147 even though ap is configured for WEP-40 encryption. In this canse the key length
14148 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
14149 type(104) and switching encryption type to 40*/
14150 pWextState->roamProfile.EncryptionType.encryptionType[0] =
14151 eCSR_ENCRYPT_TYPE_WEP40;
14152 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
14153 eCSR_ENCRYPT_TYPE_WEP40;
14154 }
14155
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014156 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014157 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014158
Jeff Johnson295189b2012-06-20 16:38:30 -070014159 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014160 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070014161 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014162
Jeff Johnson295189b2012-06-20 16:38:30 -070014163 if ( 0 != status )
14164 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014165 hddLog(VOS_TRACE_LEVEL_ERROR,
14166 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014167 status);
14168 return -EINVAL;
14169 }
14170 }
14171 }
14172
14173 /* In SoftAp mode setting key direction for default mode */
14174 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
14175 {
14176 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
14177 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
14178 (eCSR_ENCRYPT_TYPE_AES !=
14179 pWextState->roamProfile.EncryptionType.encryptionType[0])
14180 )
14181 {
14182 /* Saving key direction for default key index to TX default */
14183 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
14184 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
14185 }
14186 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014187 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014188 return status;
14189}
14190
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053014191#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14192static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14193 struct net_device *ndev,
14194 u8 key_index,
14195 bool unicast, bool multicast)
14196#else
14197static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
14198 struct net_device *ndev,
14199 u8 key_index)
14200#endif
14201{
14202 int ret;
14203 vos_ssr_protect(__func__);
14204#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14205 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
14206 multicast);
14207#else
14208 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
14209#endif
14210 vos_ssr_unprotect(__func__);
14211
14212 return ret;
14213}
14214
Jeff Johnson295189b2012-06-20 16:38:30 -070014215/*
14216 * FUNCTION: wlan_hdd_cfg80211_inform_bss
14217 * This function is used to inform the BSS details to nl80211 interface.
14218 */
14219static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
14220 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
14221{
14222 struct net_device *dev = pAdapter->dev;
14223 struct wireless_dev *wdev = dev->ieee80211_ptr;
14224 struct wiphy *wiphy = wdev->wiphy;
14225 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
14226 int chan_no;
14227 int ie_length;
14228 const char *ie;
14229 unsigned int freq;
14230 struct ieee80211_channel *chan;
14231 int rssi = 0;
14232 struct cfg80211_bss *bss = NULL;
14233
Jeff Johnson295189b2012-06-20 16:38:30 -070014234 if( NULL == pBssDesc )
14235 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014236 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014237 return bss;
14238 }
14239
14240 chan_no = pBssDesc->channelId;
14241 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
14242 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
14243
14244 if( NULL == ie )
14245 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014246 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014247 return bss;
14248 }
14249
14250#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
14251 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
14252 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014253 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014254 }
14255 else
14256 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014257 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014258 }
14259#else
14260 freq = ieee80211_channel_to_frequency(chan_no);
14261#endif
14262
14263 chan = __ieee80211_get_channel(wiphy, freq);
14264
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014265 if (!chan) {
14266 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14267 return NULL;
14268 }
14269
Abhishek Singhaee43942014-06-16 18:55:47 +053014270 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014271
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014272 return cfg80211_inform_bss(wiphy, chan,
14273#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14274 CFG80211_BSS_FTYPE_UNKNOWN,
14275#endif
14276 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014277 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014278 pBssDesc->capabilityInfo,
14279 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014280 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014281}
14282
Abhishek Singhe6137b82019-03-22 20:06:09 +053014283void wlan_hdd_cfg80211_unlink_bss(hdd_adapter_t *pAdapter, tSirMacAddr bssid)
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014284{
14285 struct net_device *dev = pAdapter->dev;
14286 struct wireless_dev *wdev = dev->ieee80211_ptr;
14287 struct wiphy *wiphy = wdev->wiphy;
14288 struct cfg80211_bss *bss = NULL;
14289
Abhishek Singh5a597e62016-12-05 15:16:30 +053014290 bss = hdd_get_bss_entry(wiphy,
14291 NULL, bssid,
14292 NULL, 0);
Abhishek Singhe6137b82019-03-22 20:06:09 +053014293 if (!bss) {
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014294 hddLog(LOGE, FL("BSS not present"));
14295 } else {
14296 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14297 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14298 cfg80211_unlink_bss(wiphy, bss);
Abhishek Singhe6137b82019-03-22 20:06:09 +053014299 /* cfg80211_get_bss get bss with ref count so release it */
14300 cfg80211_put_bss(wiphy, bss);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014301 }
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014302}
Jeff Johnson295189b2012-06-20 16:38:30 -070014303
14304
14305/*
14306 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14307 * This function is used to inform the BSS details to nl80211 interface.
14308 */
14309struct cfg80211_bss*
14310wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14311 tSirBssDescription *bss_desc
14312 )
14313{
14314 /*
14315 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14316 already exists in bss data base of cfg80211 for that particular BSS ID.
14317 Using cfg80211_inform_bss_frame to update the bss entry instead of
14318 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14319 now there is no possibility to get the mgmt(probe response) frame from PE,
14320 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14321 cfg80211_inform_bss_frame.
14322 */
14323 struct net_device *dev = pAdapter->dev;
14324 struct wireless_dev *wdev = dev->ieee80211_ptr;
14325 struct wiphy *wiphy = wdev->wiphy;
14326 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014327#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14328 qcom_ie_age *qie_age = NULL;
14329 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14330#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014331 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014332#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014333 const char *ie =
14334 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14335 unsigned int freq;
14336 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014337 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014338 struct cfg80211_bss *bss_status = NULL;
Hanumanth Reddy Pothulae04e06c2018-05-31 14:41:36 +053014339 size_t frame_len = ie_length + offsetof(struct ieee80211_mgmt,
14340 u.probe_resp.variable);
Jeff Johnson295189b2012-06-20 16:38:30 -070014341 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014342 hdd_context_t *pHddCtx;
14343 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014344#ifdef WLAN_OPEN_SOURCE
14345 struct timespec ts;
14346#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014347
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014348
Wilson Yangf80a0542013-10-07 13:02:37 -070014349 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14350 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014351 if (0 != status)
14352 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014353 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014354 }
14355
Hanumanth Reddy Pothula33548e22018-05-31 13:28:51 +053014356 mgmt = kzalloc(frame_len, GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014357 if (!mgmt)
14358 {
14359 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14360 "%s: memory allocation failed ", __func__);
14361 return NULL;
14362 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014363
Jeff Johnson295189b2012-06-20 16:38:30 -070014364 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014365
14366#ifdef WLAN_OPEN_SOURCE
14367 /* Android does not want the timestamp from the frame.
14368 Instead it wants a monotonic increasing value */
14369 get_monotonic_boottime(&ts);
14370 mgmt->u.probe_resp.timestamp =
14371 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14372#else
14373 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014374 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14375 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014376
14377#endif
14378
Jeff Johnson295189b2012-06-20 16:38:30 -070014379 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14380 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014381
14382#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14383 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14384 /* Assuming this is the last IE, copy at the end */
14385 ie_length -=sizeof(qcom_ie_age);
14386 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14387 qie_age->element_id = QCOM_VENDOR_IE_ID;
14388 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14389 qie_age->oui_1 = QCOM_OUI1;
14390 qie_age->oui_2 = QCOM_OUI2;
14391 qie_age->oui_3 = QCOM_OUI3;
14392 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014393 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14394 * bss related timestamp is in units of ms. Due to this when scan results
14395 * are sent to lowi the scan age is high.To address this, send age in units
14396 * of 1/10 ms.
14397 */
14398 qie_age->age = (vos_timer_get_system_time() -
14399 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014400#endif
14401
Jeff Johnson295189b2012-06-20 16:38:30 -070014402 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014403 if (bss_desc->fProbeRsp)
14404 {
14405 mgmt->frame_control |=
14406 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14407 }
14408 else
14409 {
14410 mgmt->frame_control |=
14411 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14412 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014413
14414#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014415 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014416 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014417 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014418 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014419 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014420 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014421 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014422
14423 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014424 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014425 }
14426 else
14427 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014428 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14429 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014430 kfree(mgmt);
14431 return NULL;
14432 }
14433#else
14434 freq = ieee80211_channel_to_frequency(chan_no);
14435#endif
14436 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014437 /*when the band is changed on the fly using the GUI, three things are done
14438 * 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)
14439 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14440 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14441 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14442 * and discards the channels correponding to previous band and calls back with zero bss results.
14443 * 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
14444 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14445 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14446 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14447 * So drop the bss and continue to next bss.
14448 */
14449 if(chan == NULL)
14450 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014451 hddLog(VOS_TRACE_LEVEL_ERROR,
14452 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14453 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014454 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014455 return NULL;
14456 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014457 /*To keep the rssi icon of the connected AP in the scan window
14458 *and the rssi icon of the wireless networks in sync
14459 * */
14460 if (( eConnectionState_Associated ==
14461 pAdapter->sessionCtx.station.conn_info.connState ) &&
14462 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14463 pAdapter->sessionCtx.station.conn_info.bssId,
14464 WNI_CFG_BSSID_LEN)) &&
14465 (pHddCtx->hdd_wlan_suspended == FALSE))
14466 {
14467 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14468 rssi = (pAdapter->rssi * 100);
14469 }
14470 else
14471 {
14472 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14473 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014474
Nirav Shah20ac06f2013-12-12 18:14:06 +053014475 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014476 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14477 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014478
Jeff Johnson295189b2012-06-20 16:38:30 -070014479 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14480 frame_len, rssi, GFP_KERNEL);
14481 kfree(mgmt);
14482 return bss_status;
14483}
14484
14485/*
14486 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14487 * This function is used to update the BSS data base of CFG8011
14488 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014489struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014490 tCsrRoamInfo *pRoamInfo
14491 )
14492{
14493 tCsrRoamConnectedProfile roamProfile;
14494 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14495 struct cfg80211_bss *bss = NULL;
14496
14497 ENTER();
14498
14499 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14500 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14501
14502 if (NULL != roamProfile.pBssDesc)
14503 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014504 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14505 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014506
14507 if (NULL == bss)
14508 {
14509 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14510 __func__);
14511 }
14512
14513 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14514 }
14515 else
14516 {
14517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14518 __func__);
14519 }
14520 return bss;
14521}
14522
14523/*
14524 * FUNCTION: wlan_hdd_cfg80211_update_bss
14525 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014526static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14527 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014528 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014529{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014530 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014531 tCsrScanResultInfo *pScanResult;
14532 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014533 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014534 tScanResultHandle pResult;
14535 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014536 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014537 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014538 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014539
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014540 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14541 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14542 NO_SESSION, pAdapter->sessionId));
14543
Wilson Yangf80a0542013-10-07 13:02:37 -070014544 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014545 ret = wlan_hdd_validate_context(pHddCtx);
14546 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014547 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014548 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014549 }
14550
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014551 if (pAdapter->request != NULL)
14552 {
14553 if ((pAdapter->request->n_ssids == 1)
14554 && (pAdapter->request->ssids != NULL)
14555 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14556 is_p2p_scan = true;
14557 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014558 /*
14559 * start getting scan results and populate cgf80211 BSS database
14560 */
14561 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14562
14563 /* no scan results */
14564 if (NULL == pResult)
14565 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014566 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14567 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014568 wlan_hdd_get_frame_logs(pAdapter,
14569 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014570 return status;
14571 }
14572
14573 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14574
14575 while (pScanResult)
14576 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014577 /*
14578 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14579 * entry already exists in bss data base of cfg80211 for that
14580 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14581 * bss entry instead of cfg80211_inform_bss, But this call expects
14582 * mgmt packet as input. As of now there is no possibility to get
14583 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014584 * ieee80211_mgmt(probe response) and passing to c
14585 * fg80211_inform_bss_frame.
14586 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014587 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14588 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14589 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014590 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14591 continue; //Skip the non p2p bss entries
14592 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014593 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14594 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014595
Jeff Johnson295189b2012-06-20 16:38:30 -070014596
14597 if (NULL == bss_status)
14598 {
14599 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014600 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014601 }
14602 else
14603 {
Yue Maf49ba872013-08-19 12:04:25 -070014604 cfg80211_put_bss(
14605#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14606 wiphy,
14607#endif
14608 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014609 }
14610
14611 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14612 }
14613
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014614 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014615 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014616 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014617}
14618
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014619void
14620hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14621{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014622 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014623 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014624} /****** end hddPrintMacAddr() ******/
14625
14626void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014627hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014628{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014629 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014630 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014631 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14632 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14633 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014634} /****** end hddPrintPmkId() ******/
14635
14636//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14637//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14638
14639//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14640//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14641
14642#define dump_bssid(bssid) \
14643 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014644 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14645 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014646 }
14647
14648#define dump_pmkid(pMac, pmkid) \
14649 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014650 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14651 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014652 }
14653
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014654#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014655/*
14656 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14657 * This function is used to notify the supplicant of a new PMKSA candidate.
14658 */
14659int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014660 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014661 int index, bool preauth )
14662{
Jeff Johnsone7245742012-09-05 17:12:55 -070014663#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014664 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014665 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014666
14667 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014668 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014669
14670 if( NULL == pRoamInfo )
14671 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014672 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014673 return -EINVAL;
14674 }
14675
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014676 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14677 {
14678 dump_bssid(pRoamInfo->bssid);
14679 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014680 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014681 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014682#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014683 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014684}
14685#endif //FEATURE_WLAN_LFR
14686
Yue Maef608272013-04-08 23:09:17 -070014687#ifdef FEATURE_WLAN_LFR_METRICS
14688/*
14689 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14690 * 802.11r/LFR metrics reporting function to report preauth initiation
14691 *
14692 */
14693#define MAX_LFR_METRICS_EVENT_LENGTH 100
14694VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14695 tCsrRoamInfo *pRoamInfo)
14696{
14697 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14698 union iwreq_data wrqu;
14699
14700 ENTER();
14701
14702 if (NULL == pAdapter)
14703 {
14704 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14705 return VOS_STATUS_E_FAILURE;
14706 }
14707
14708 /* create the event */
14709 memset(&wrqu, 0, sizeof(wrqu));
14710 memset(metrics_notification, 0, sizeof(metrics_notification));
14711
14712 wrqu.data.pointer = metrics_notification;
14713 wrqu.data.length = scnprintf(metrics_notification,
14714 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14715 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14716
14717 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14718
14719 EXIT();
14720
14721 return VOS_STATUS_SUCCESS;
14722}
14723
14724/*
14725 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14726 * 802.11r/LFR metrics reporting function to report preauth completion
14727 * or failure
14728 */
14729VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14730 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14731{
14732 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14733 union iwreq_data wrqu;
14734
14735 ENTER();
14736
14737 if (NULL == pAdapter)
14738 {
14739 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14740 return VOS_STATUS_E_FAILURE;
14741 }
14742
14743 /* create the event */
14744 memset(&wrqu, 0, sizeof(wrqu));
14745 memset(metrics_notification, 0, sizeof(metrics_notification));
14746
14747 scnprintf(metrics_notification, sizeof(metrics_notification),
14748 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14749 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14750
14751 if (1 == preauth_status)
14752 strncat(metrics_notification, " TRUE", 5);
14753 else
14754 strncat(metrics_notification, " FALSE", 6);
14755
14756 wrqu.data.pointer = metrics_notification;
14757 wrqu.data.length = strlen(metrics_notification);
14758
14759 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14760
14761 EXIT();
14762
14763 return VOS_STATUS_SUCCESS;
14764}
14765
14766/*
14767 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14768 * 802.11r/LFR metrics reporting function to report handover initiation
14769 *
14770 */
14771VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14772 tCsrRoamInfo *pRoamInfo)
14773{
14774 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14775 union iwreq_data wrqu;
14776
14777 ENTER();
14778
14779 if (NULL == pAdapter)
14780 {
14781 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14782 return VOS_STATUS_E_FAILURE;
14783 }
14784
14785 /* create the event */
14786 memset(&wrqu, 0, sizeof(wrqu));
14787 memset(metrics_notification, 0, sizeof(metrics_notification));
14788
14789 wrqu.data.pointer = metrics_notification;
14790 wrqu.data.length = scnprintf(metrics_notification,
14791 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14792 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14793
14794 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14795
14796 EXIT();
14797
14798 return VOS_STATUS_SUCCESS;
14799}
14800#endif
14801
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014802
14803/**
14804 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14805 * @scan_req: scan request to be checked
14806 *
14807 * Return: true or false
14808 */
14809#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14810static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14811 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014812 *scan_req, hdd_context_t
14813 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014814{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014815 if (!scan_req || !scan_req->wiphy ||
14816 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014817 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14818 return false;
14819 }
14820 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14821 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14822 return false;
14823 }
14824 return true;
14825}
14826#else
14827static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14828 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014829 *scan_req, hdd_context_t
14830 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014831{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014832 if (!scan_req || !scan_req->wiphy ||
14833 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014834 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14835 return false;
14836 }
14837 return true;
14838}
14839#endif
14840
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014841#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14842/**
14843 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14844 * @adapter: Pointer to the adapter
14845 * @req : Scan request
14846 * @aborted : true scan aborted false scan success
14847 *
14848 * This function notifies scan done to cfg80211
14849 *
14850 * Return: none
14851 */
14852static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14853 struct cfg80211_scan_request *req,
14854 bool aborted)
14855{
14856 struct cfg80211_scan_info info = {
14857 .aborted = aborted
14858 };
14859
14860 if (adapter->dev->flags & IFF_UP)
14861 cfg80211_scan_done(req, &info);
14862 else
14863 hddLog(LOGW,
14864 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14865}
14866#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14867/**
14868 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14869 * @adapter: Pointer to the adapter
14870 * @req : Scan request
14871 * @aborted : true scan aborted false scan success
14872 *
14873 * This function notifies scan done to cfg80211
14874 *
14875 * Return: none
14876 */
14877static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14878 struct cfg80211_scan_request *req,
14879 bool aborted)
14880{
14881 if (adapter->dev->flags & IFF_UP)
14882 cfg80211_scan_done(req, aborted);
14883 else
14884 hddLog(LOGW,
14885 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14886}
14887#else
14888/**
14889 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14890 * @adapter: Pointer to the adapter
14891 * @req : Scan request
14892 * @aborted : true scan aborted false scan success
14893 *
14894 * This function notifies scan done to cfg80211
14895 *
14896 * Return: none
14897 */
14898static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14899 struct cfg80211_scan_request *req,
14900 bool aborted)
14901{
14902 cfg80211_scan_done(req, aborted);
14903}
14904#endif
14905
Mukul Sharmab392b642017-08-17 17:45:29 +053014906#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014907/*
14908 * FUNCTION: hdd_cfg80211_scan_done_callback
14909 * scanning callback function, called after finishing scan
14910 *
14911 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014912static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014913 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14914{
14915 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014916 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014917 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014918 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014919 struct cfg80211_scan_request *req = NULL;
14920 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014921 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014922 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014923 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014924
14925 ENTER();
14926
c_manjee1b4ab9a2016-10-26 11:36:55 +053014927 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14928 !pAdapter->dev) {
14929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14930 return 0;
14931 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014932 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014933 if (NULL == pHddCtx) {
14934 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014935 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014936 }
14937
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014938#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014939 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014940 {
14941 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014942 }
14943#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014944 pScanInfo = &pHddCtx->scan_info;
14945
Jeff Johnson295189b2012-06-20 16:38:30 -070014946 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014947 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014948 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014949 __func__, halHandle, pContext, (int) scanId, (int) status);
14950
Kiet Lamac06e2c2013-10-23 16:25:07 +053014951 pScanInfo->mScanPendingCounter = 0;
14952
Jeff Johnson295189b2012-06-20 16:38:30 -070014953 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014954 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014955 &pScanInfo->scan_req_completion_event,
14956 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014957 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014958 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014959 hddLog(VOS_TRACE_LEVEL_ERROR,
14960 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014961 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014962 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014963 }
14964
Yue Maef608272013-04-08 23:09:17 -070014965 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014966 {
14967 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014968 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014969 }
14970
14971 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014972 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014973 {
14974 hddLog(VOS_TRACE_LEVEL_INFO,
14975 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014976 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014977 (int) scanId);
14978 }
14979
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014980#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014981 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014982#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014983 {
14984 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14985 pAdapter);
14986 if (0 > ret)
14987 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014988 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014989
Jeff Johnson295189b2012-06-20 16:38:30 -070014990 /* If any client wait scan result through WEXT
14991 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014992 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014993 {
14994 /* The other scan request waiting for current scan finish
14995 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014996 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014997 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014998 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014999 }
15000 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015001 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070015002 {
15003 struct net_device *dev = pAdapter->dev;
15004 union iwreq_data wrqu;
15005 int we_event;
15006 char *msg;
15007
15008 memset(&wrqu, '\0', sizeof(wrqu));
15009 we_event = SIOCGIWSCAN;
15010 msg = NULL;
15011 wireless_send_event(dev, we_event, &wrqu, msg);
15012 }
15013 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070015014 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015015
15016 /* Get the Scan Req */
15017 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053015018 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015019
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015020 /* Scan is no longer pending */
15021 pScanInfo->mScanPending = VOS_FALSE;
15022
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053015023 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070015024 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015025#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
15026 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053015027 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053015028#endif
15029
15030 if (pAdapter->dev) {
15031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
15032 pAdapter->dev->name);
15033 }
mukul sharmae7041822015-12-03 15:09:21 +053015034 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070015035 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070015036 }
15037
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015038 /* last_scan_timestamp is used to decide if new scan
15039 * is needed or not on station interface. If last station
15040 * scan time and new station scan time is less then
15041 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015042 * Also only last_scan_timestamp is updated here last_scan_channellist
15043 * is updated on receiving scan request itself to make sure kernel
15044 * allocated scan request(scan_req) object is not dereferenced here,
15045 * because interface down, where kernel frees scan_req, may happen any
15046 * time while driver is processing scan_done_callback. So it's better
15047 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015048 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015049 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
15050 if (status == eCSR_SCAN_SUCCESS)
15051 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
15052 else {
15053 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
15054 sizeof(pHddCtx->scan_info.last_scan_channelList));
15055 pHddCtx->scan_info.last_scan_numChannels = 0;
15056 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015057 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015058 }
15059
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070015060 /*
15061 * cfg80211_scan_done informing NL80211 about completion
15062 * of scanning
15063 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053015064 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
15065 {
15066 aborted = true;
15067 }
mukul sharmae7041822015-12-03 15:09:21 +053015068
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015069#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015070 if (NET_DEV_IS_IFF_UP(pAdapter) &&
15071 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015072#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015073 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053015074
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080015075 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070015076
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015077allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015078 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
15079 ) && (pHddCtx->spoofMacAddr.isEnabled
15080 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053015081 /* Generate new random mac addr for next scan */
15082 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053015083
15084 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
15085 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053015086 }
15087
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015088 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015089 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015090
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015091 /* Acquire wakelock to handle the case where APP's tries to suspend
15092 * immediatly after the driver gets connect request(i.e after scan)
15093 * from supplicant, this result in app's is suspending and not able
15094 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015095 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070015096
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015097#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053015098 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015099#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015100#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053015101 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070015102#endif
15103
Jeff Johnson295189b2012-06-20 16:38:30 -070015104 EXIT();
15105 return 0;
15106}
15107
15108/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053015109 * FUNCTION: hdd_isConnectionInProgress
15110 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015111 *
15112 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015113v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
15114 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015115{
15116 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15117 hdd_station_ctx_t *pHddStaCtx = NULL;
15118 hdd_adapter_t *pAdapter = NULL;
15119 VOS_STATUS status = 0;
15120 v_U8_t staId = 0;
15121 v_U8_t *staMac = NULL;
15122
15123 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
15124
15125 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
15126 {
15127 pAdapter = pAdapterNode->pAdapter;
15128
15129 if( pAdapter )
15130 {
15131 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015132 "%s: Adapter with device mode %s (%d) exists",
15133 __func__, hdd_device_modetoString(pAdapter->device_mode),
15134 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015135 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053015136 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15137 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
15138 (eConnectionState_Connecting ==
15139 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15140 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015141 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015142 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053015143 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015144 if (session_id && reason)
15145 {
15146 *session_id = pAdapter->sessionId;
15147 *reason = eHDD_CONNECTION_IN_PROGRESS;
15148 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015149 return VOS_TRUE;
15150 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015151 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053015152 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015153 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015154 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070015155 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015156 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015157 if (session_id && reason)
15158 {
15159 *session_id = pAdapter->sessionId;
15160 *reason = eHDD_REASSOC_IN_PROGRESS;
15161 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053015162 return VOS_TRUE;
15163 }
15164 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015165 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15166 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015167 {
15168 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15169 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Vignesh Viswanathan0ac8e562018-06-14 17:24:10 +053015170 sme_is_sta_key_exchange_in_progress(pHddCtx->hHal,
15171 pAdapter->sessionId))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015172 {
15173 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015174 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015175 "%s: client " MAC_ADDRESS_STR
15176 " is in the middle of WPS/EAPOL exchange.", __func__,
15177 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015178 if (session_id && reason)
15179 {
15180 *session_id = pAdapter->sessionId;
15181 *reason = eHDD_EAPOL_IN_PROGRESS;
15182 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015183 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015184 }
15185 }
15186 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
15187 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
15188 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015189 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15190 ptSapContext pSapCtx = NULL;
15191 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15192 if(pSapCtx == NULL){
15193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15194 FL("psapCtx is NULL"));
15195 return VOS_FALSE;
15196 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015197 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
15198 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015199 if ((pSapCtx->aStaInfo[staId].isUsed) &&
15200 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015201 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015202 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015203
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015204 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080015205 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
15206 "middle of WPS/EAPOL exchange.", __func__,
15207 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015208 if (session_id && reason)
15209 {
15210 *session_id = pAdapter->sessionId;
15211 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
15212 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015213 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015214 }
15215 }
15216 }
15217 }
15218 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15219 pAdapterNode = pNext;
15220 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053015221 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015222}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015223
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015224/**
15225 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
15226 * to the Scan request
15227 * @scanRequest: Pointer to the csr scan request
15228 * @request: Pointer to the scan request from supplicant
15229 *
15230 * Return: None
15231 */
15232#ifdef CFG80211_SCAN_BSSID
15233static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15234 struct cfg80211_scan_request *request)
15235{
15236 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
15237}
15238#else
15239static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
15240 struct cfg80211_scan_request *request)
15241{
15242}
15243#endif
15244
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015245#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
15246 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
15247/**
15248 * hdd_is_wiphy_scan_random_support() - Check NL80211 scan randomization support
15249 * @wiphy: Pointer to wiphy structure
15250 *
15251 * This function is used to check whether @wiphy supports
15252 * NL80211 scan randomization feature.
15253 *
15254 * Return: If randomization is supported then return true else false.
15255 */
15256static bool
15257hdd_is_wiphy_scan_random_support(struct wiphy *wiphy)
15258{
15259 if (wiphy->features & NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)
15260 return true;
15261
15262 return false;
15263}
15264
15265/**
15266 * hdd_is_nl_scan_random() - Check for randomization flag in cfg80211 scan
15267 * @nl_scan: cfg80211 scan request
15268 *
15269 * This function is used to check whether scan randomization flag is set for
15270 * current cfg80211 scan request identified by @nl_scan.
15271 *
15272 * Return: If randomization flag is set then return true else false.
15273 */
15274static bool
15275hdd_is_nl_scan_random(struct cfg80211_scan_request *nl_scan)
15276{
15277 if (nl_scan->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
15278 return true;
15279
15280 return false;
15281}
15282#else
15283static bool
15284hdd_is_wiphy_scan_random_support(struct wiphy *wiphy)
15285{
15286 return false;
15287}
15288
15289static bool
15290hdd_is_nl_scan_random(struct cfg80211_scan_request *nl_scan)
15291{
15292 return false;
15293}
15294#endif
15295
15296/**
15297 * hdd_generate_scan_random_mac() - Generate Random mac addr for cfg80211 scan
15298 * @mac_addr: Input mac-addr from which random-mac address is to be generated
15299 * @mac_mask: Bits of mac_addr which should not be randomized
15300 * @random_mac: Output pointer to hold generated random mac address
15301 *
15302 * This function is used generate random mac address using @mac_addr and
15303 * @mac_mask with following logic:
15304 * Bit value 0 in the mask means that we should randomize that bit.
15305 * Bit value 1 in the mask means that we should take specific bit value
15306 * from mac address provided.
15307 *
15308 * Return: None
15309 */
15310static void
15311hdd_generate_scan_random_mac(uint8_t *mac_addr, uint8_t *mac_mask,
15312 uint8_t *random_mac)
15313{
15314 uint32_t i;
15315 uint8_t random_byte;
15316
15317 for (i = 0; i < VOS_MAC_ADDRESS_LEN; i++) {
15318 random_byte = 0;
15319 get_random_bytes(&random_byte, 1);
15320 random_mac[i] = (mac_addr[i] & mac_mask[i]) |
15321 (random_byte & (~(mac_mask[i])));
15322 }
15323
15324 /*
15325 * Make sure locally administered bit is set if that
15326 * particular bit in the mask is 0
15327 */
15328 if (!(mac_mask[0] & 0x2))
15329 random_mac[0] |= 0x2;
15330
15331 /*
15332 * Make sure multicast/group address bit is NOT set if that
15333 * particular bit in the mask is 0
15334 */
15335 if (!(mac_mask[0] & 0x1))
15336 random_mac[0] &= ~0x1;
15337}
15338
15339/**
15340 * hdd_spoof_scan() - Spoof cfg80211 scan
15341 * @wiphy: Pointer to wiphy
15342 * @adapter: Pointer to adapter for which scan is requested
15343 * @nl_scan: Cfg80211 scan request
15344 * @is_p2p_scan: Check for p2p scan
15345 * @csr_scan: Pointer to internal (csr) scan request
15346 *
15347 * This function is used for following purposes:
15348 * (a) If cfg80211 supports scan randomization then this function invokes helper
15349 * functions to generate random-mac address.
15350 * (b) If the cfg80211 doesn't support scan randomization then randomize scans
15351 * using spoof mac received with VENDOR_SUBCMD_MAC_OUI.
15352 * (c) Configure the random-mac in transport layer.
15353 *
15354 * Return: For success return 0 else return negative value.
15355 */
15356static int
15357hdd_spoof_scan(struct wiphy *wiphy, hdd_adapter_t *adapter,
15358 struct cfg80211_scan_request *nl_scan,
15359 bool is_p2p_scan, tCsrScanRequest *csr_scan)
15360{
15361 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
15362 hdd_config_t *config = hdd_ctx->cfg_ini;
15363 uint8_t random_mac[VOS_MAC_ADDRESS_LEN];
15364 VOS_STATUS vos_status;
15365 eHalStatus hal_status;
15366
15367 csr_scan->nl_scan = true;
15368 csr_scan->scan_randomize = false;
15369
15370 if (config->enableMacSpoofing != MAC_ADDR_SPOOFING_FW_HOST_ENABLE ||
15371 !sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN))
15372 return 0;
15373
15374 vos_flush_delayed_work(&hdd_ctx->spoof_mac_addr_work);
15375
15376 if (hdd_is_wiphy_scan_random_support(wiphy)) {
15377 if (!hdd_is_nl_scan_random(nl_scan) || is_p2p_scan)
15378 return 0;
15379
15380 hdd_generate_scan_random_mac(nl_scan->mac_addr,
15381 nl_scan->mac_addr_mask,
15382 random_mac);
15383
15384 hddLog(VOS_TRACE_LEVEL_INFO,
15385 FL("cfg80211 scan random attributes:"));
15386 hddLog(VOS_TRACE_LEVEL_INFO, "mac-addr: "MAC_ADDRESS_STR
15387 " mac-mask: "MAC_ADDRESS_STR
15388 " random-mac: "MAC_ADDRESS_STR,
15389 MAC_ADDR_ARRAY(nl_scan->mac_addr),
15390 MAC_ADDR_ARRAY(nl_scan->mac_addr_mask),
15391 MAC_ADDR_ARRAY(random_mac));
15392
15393 hal_status = sme_SpoofMacAddrReq(hdd_ctx->hHal,
15394 (v_MACADDR_t *)random_mac,
15395 false);
15396 if (hal_status != eHAL_STATUS_SUCCESS) {
15397 hddLog(LOGE,
15398 FL("Send of Spoof request failed"));
15399 hddLog(LOGE,
15400 FL("Disable spoofing and use self-mac"));
15401 return 0;
15402 }
15403
15404 vos_status = WLANTL_updateSpoofMacAddr(hdd_ctx->pvosContext,
15405 (v_MACADDR_t*)random_mac,
15406 &adapter->macAddressCurrent);
15407 if(vos_status != VOS_STATUS_SUCCESS) {
15408 hddLog(VOS_TRACE_LEVEL_ERROR,
15409 FL("Failed to update spoof mac in TL"));
15410 return -EINVAL;
15411 }
15412
15413 csr_scan->scan_randomize = true;
15414
15415 return 0;
15416 }
15417
15418 /*
15419 * If wiphy does not support cfg80211 scan randomization then scan
15420 * will be randomized using the vendor MAC OUI.
15421 */
15422 if (!hdd_ctx->spoofMacAddr.isEnabled)
15423 return 0;
15424
15425 hddLog(VOS_TRACE_LEVEL_INFO,
15426 FL("MAC Spoofing enabled for current scan and spoof addr is:"
15427 MAC_ADDRESS_STR),
15428 MAC_ADDR_ARRAY(hdd_ctx->spoofMacAddr.randomMacAddr.bytes));
15429
15430 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15431 * to fill TxBds for probe request during current scan
15432 */
15433 vos_status = WLANTL_updateSpoofMacAddr(hdd_ctx->pvosContext,
15434 &hdd_ctx->spoofMacAddr.randomMacAddr, &adapter->macAddressCurrent);
15435 if(vos_status != VOS_STATUS_SUCCESS) {
15436 hddLog(VOS_TRACE_LEVEL_ERROR,
15437 FL("Failed to update spoof mac in TL"));
15438 return -EINVAL;
15439 }
15440
15441 csr_scan->scan_randomize = true;
15442
15443 return 0;
15444}
15445
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015446/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015447 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070015448 * this scan respond to scan trigger and update cfg80211 scan database
15449 * later, scan dump command can be used to recieve scan results
15450 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015451int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080015452#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15453 struct net_device *dev,
15454#endif
15455 struct cfg80211_scan_request *request)
15456{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015457 hdd_adapter_t *pAdapter = NULL;
15458 hdd_context_t *pHddCtx = NULL;
15459 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015460 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015461 tCsrScanRequest scanRequest;
15462 tANI_U8 *channelList = NULL, i;
15463 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015464 int status;
15465 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015466 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015467 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015468 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015469 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015470 v_U8_t curr_session_id;
15471 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015472
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015473#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15474 struct net_device *dev = NULL;
15475 if (NULL == request)
15476 {
15477 hddLog(VOS_TRACE_LEVEL_ERROR,
15478 "%s: scan req param null", __func__);
15479 return -EINVAL;
15480 }
15481 dev = request->wdev->netdev;
15482#endif
15483
15484 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15485 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15486 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15487
Jeff Johnson295189b2012-06-20 16:38:30 -070015488 ENTER();
15489
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015490 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15491 __func__, hdd_device_modetoString(pAdapter->device_mode),
15492 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015493
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015494 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015495 if (0 != status)
15496 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015497 return status;
15498 }
15499
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015500 if (NULL == pwextBuf)
15501 {
15502 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15503 __func__);
15504 return -EIO;
15505 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015506 cfg_param = pHddCtx->cfg_ini;
15507 pScanInfo = &pHddCtx->scan_info;
15508
Jeff Johnson295189b2012-06-20 16:38:30 -070015509#ifdef WLAN_BTAMP_FEATURE
15510 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015511 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015512 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015513 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015514 "%s: No scanning when AMP is on", __func__);
15515 return -EOPNOTSUPP;
15516 }
15517#endif
15518 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015519 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015520 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015521 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015522 "%s: Not scanning on device_mode = %s (%d)",
15523 __func__, hdd_device_modetoString(pAdapter->device_mode),
15524 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015525 return -EOPNOTSUPP;
15526 }
15527
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015528 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15529 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15530 return -EOPNOTSUPP;
15531 }
15532
Jeff Johnson295189b2012-06-20 16:38:30 -070015533 if (TRUE == pScanInfo->mScanPending)
15534 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015535 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15536 {
15537 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15538 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015539 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015540 }
15541
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015542 // Don't allow scan if PNO scan is going on.
15543 if (pHddCtx->isPnoEnable)
15544 {
15545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15546 FL("pno scan in progress"));
15547 return -EBUSY;
15548 }
15549
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015550 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015551 //Channel and action frame is pending
15552 //Otherwise Cancel Remain On Channel and allow Scan
15553 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015554 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015555 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015557 return -EBUSY;
15558 }
15559
Jeff Johnson295189b2012-06-20 16:38:30 -070015560 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15561 {
15562 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015563 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015564 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015565 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015566 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15567 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015568 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015569 "%s: MAX TM Level Scan not allowed", __func__);
15570 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015571 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015572 }
15573 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15574
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015575 /* Check if scan is allowed at this point of time.
15576 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015577 if (TRUE == pHddCtx->btCoexModeSet)
15578 {
15579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15580 FL("BTCoex Mode operation in progress"));
15581 return -EBUSY;
15582 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015583 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015584 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015585
15586 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15587 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15588 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015589 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15590 pHddCtx->last_scan_reject_reason != curr_reason ||
15591 !pHddCtx->last_scan_reject_timestamp)
15592 {
15593 pHddCtx->last_scan_reject_session_id = curr_session_id;
15594 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015595 pHddCtx->last_scan_reject_timestamp =
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015596 jiffies + msecs_to_jiffies(SCAN_REJECT_THRESHOLD_TIME);
Abhishek Singhe4b12562017-06-20 16:53:39 +053015597 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015598 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015599 else
15600 {
15601 pHddCtx->scan_reject_cnt++;
15602
Abhishek Singhe4b12562017-06-20 16:53:39 +053015603 if ((pHddCtx->scan_reject_cnt >=
15604 SCAN_REJECT_THRESHOLD) &&
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015605 vos_system_time_after(jiffies,
Abhishek Singh3e500772017-07-17 10:13:43 +053015606 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015607 {
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015608 hddLog(LOGE, FL("Session %d reason %d reject cnt %d reject timestamp %lu jiffies %lu"),
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015609 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
Abhinav Kumar61d1bfe2018-07-26 00:30:22 +053015610 pHddCtx->last_scan_reject_timestamp, jiffies);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015611 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015612 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015613 if (pHddCtx->cfg_ini->enableFatalEvent)
15614 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15615 WLAN_LOG_INDICATOR_HOST_DRIVER,
15616 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15617 FALSE, FALSE);
15618 else
15619 {
15620 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015621 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015622 }
15623 }
15624 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015625 return -EBUSY;
15626 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015627 pHddCtx->last_scan_reject_timestamp = 0;
15628 pHddCtx->last_scan_reject_session_id = 0xFF;
15629 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015630 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015631
Jeff Johnson295189b2012-06-20 16:38:30 -070015632 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15633
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015634 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15635 * Becasue of this, driver is assuming that this is not wildcard scan and so
15636 * is not aging out the scan results.
15637 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015638 if ((request->ssids) && (request->n_ssids == 1) &&
15639 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015640 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015641 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015642
15643 if ((request->ssids) && (0 < request->n_ssids))
15644 {
15645 tCsrSSIDInfo *SsidInfo;
15646 int j;
15647 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15648 /* Allocate num_ssid tCsrSSIDInfo structure */
15649 SsidInfo = scanRequest.SSIDs.SSIDList =
15650 ( tCsrSSIDInfo *)vos_mem_malloc(
15651 request->n_ssids*sizeof(tCsrSSIDInfo));
15652
15653 if(NULL == scanRequest.SSIDs.SSIDList)
15654 {
15655 hddLog(VOS_TRACE_LEVEL_ERROR,
15656 "%s: memory alloc failed SSIDInfo buffer", __func__);
15657 return -ENOMEM;
15658 }
15659
15660 /* copy all the ssid's and their length */
15661 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15662 {
15663 /* get the ssid length */
15664 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15665 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15666 SsidInfo->SSID.length);
15667 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15668 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15669 j, SsidInfo->SSID.ssId);
15670 }
15671 /* set the scan type to active */
15672 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15673 }
15674 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015675 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015676 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15677 TRACE_CODE_HDD_CFG80211_SCAN,
15678 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015679 /* set the scan type to active */
15680 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015681 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015682 else
15683 {
15684 /*Set the scan type to default type, in this case it is ACTIVE*/
15685 scanRequest.scanType = pScanInfo->scan_mode;
15686 }
15687 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15688 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015689
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015690 csr_scan_request_assign_bssid(&scanRequest, request);
15691
Jeff Johnson295189b2012-06-20 16:38:30 -070015692 /* set BSSType to default type */
15693 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15694
15695 /*TODO: scan the requested channels only*/
15696
15697 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015698 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015699 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015700 hddLog(VOS_TRACE_LEVEL_WARN,
15701 "No of Scan Channels exceeded limit: %d", request->n_channels);
15702 request->n_channels = MAX_CHANNEL;
15703 }
15704
15705 hddLog(VOS_TRACE_LEVEL_INFO,
15706 "No of Scan Channels: %d", request->n_channels);
15707
15708
15709 if( request->n_channels )
15710 {
15711 char chList [(request->n_channels*5)+1];
15712 int len;
15713 channelList = vos_mem_malloc( request->n_channels );
15714 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015715 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015716 hddLog(VOS_TRACE_LEVEL_ERROR,
15717 "%s: memory alloc failed channelList", __func__);
15718 status = -ENOMEM;
15719 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015720 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015721
15722 for( i = 0, len = 0; i < request->n_channels ; i++ )
15723 {
15724 channelList[i] = request->channels[i]->hw_value;
15725 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15726 }
15727
Nirav Shah20ac06f2013-12-12 18:14:06 +053015728 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015729 "Channel-List: %s ", chList);
15730 }
c_hpothu53512302014-04-15 18:49:53 +053015731
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015732 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15733 scanRequest.ChannelInfo.ChannelList = channelList;
15734
15735 /* set requestType to full scan */
15736 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15737
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015738 /* if there is back to back scan happening in driver with in
15739 * nDeferScanTimeInterval interval driver should defer new scan request
15740 * and should provide last cached scan results instead of new channel list.
15741 * This rule is not applicable if scan is p2p scan.
15742 * This condition will work only in case when last request no of channels
15743 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015744 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015745 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015746 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015747
Sushant Kaushik86592172015-04-27 16:35:03 +053015748 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15749 /* if wps ie is NULL , then only defer scan */
15750 if ( pWpsIe == NULL &&
15751 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015752 {
15753 if ( pScanInfo->last_scan_timestamp !=0 &&
15754 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15755 {
15756 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15757 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15758 vos_mem_compare(pScanInfo->last_scan_channelList,
15759 channelList, pScanInfo->last_scan_numChannels))
15760 {
15761 hddLog(VOS_TRACE_LEVEL_WARN,
15762 " New and old station scan time differ is less then %u",
15763 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15764
15765 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015766 pAdapter);
15767
Agarwal Ashish57e84372014-12-05 18:26:53 +053015768 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015769 "Return old cached scan as all channels and no of channels are same");
15770
Agarwal Ashish57e84372014-12-05 18:26:53 +053015771 if (0 > ret)
15772 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015773
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015774 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015775
15776 status = eHAL_STATUS_SUCCESS;
15777 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015778 }
15779 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015780 }
15781
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015782 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15783 * search (Flush on both full scan and social scan but not on single
15784 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15785 */
15786
15787 /* Supplicant does single channel scan after 8-way handshake
15788 * and in that case driver shoudnt flush scan results. If
15789 * driver flushes the scan results here and unfortunately if
15790 * the AP doesnt respond to our probe req then association
15791 * fails which is not desired
15792 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015793 if ((request->n_ssids == 1)
15794 && (request->ssids != NULL)
15795 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15796 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015797
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015798 if( is_p2p_scan ||
15799 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015800 {
15801 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15802 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15803 pAdapter->sessionId );
15804 }
15805
15806 if( request->ie_len )
15807 {
15808 /* save this for future association (join requires this) */
15809 /*TODO: Array needs to be converted to dynamic allocation,
15810 * as multiple ie.s can be sent in cfg80211_scan_request structure
15811 * CR 597966
15812 */
15813 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15814 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15815 pScanInfo->scanAddIE.length = request->ie_len;
15816
15817 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15818 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15819 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015820 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015821 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015822 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015823 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15824 memcpy( pwextBuf->roamProfile.addIEScan,
15825 request->ie, request->ie_len);
15826 }
15827 else
15828 {
15829 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15830 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015831 }
15832
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015833 }
15834 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15835 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15836
15837 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15838 request->ie_len);
15839 if (pP2pIe != NULL)
15840 {
15841#ifdef WLAN_FEATURE_P2P_DEBUG
15842 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15843 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15844 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015845 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015846 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15847 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15848 "Go nego completed to Connection is started");
15849 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15850 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015851 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015852 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15853 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015854 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015855 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15856 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15857 "Disconnected state to Connection is started");
15858 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15859 "for 4way Handshake");
15860 }
15861#endif
15862
15863 /* no_cck will be set during p2p find to disable 11b rates */
15864 if(TRUE == request->no_cck)
15865 {
15866 hddLog(VOS_TRACE_LEVEL_INFO,
15867 "%s: This is a P2P Search", __func__);
15868 scanRequest.p2pSearch = 1;
15869
15870 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015871 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015872 /* set requestType to P2P Discovery */
15873 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15874 }
15875
15876 /*
15877 Skip Dfs Channel in case of P2P Search
15878 if it is set in ini file
15879 */
15880 if(cfg_param->skipDfsChnlInP2pSearch)
15881 {
15882 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015883 }
15884 else
15885 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015886 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015887 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015888
Agarwal Ashish4f616132013-12-30 23:32:50 +053015889 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015890 }
15891 }
15892
15893 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15894
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015895#ifdef FEATURE_WLAN_TDLS
15896 /* if tdls disagree scan right now, return immediately.
15897 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15898 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15899 */
15900 status = wlan_hdd_tdls_scan_callback (pAdapter,
15901 wiphy,
15902#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15903 dev,
15904#endif
15905 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015906 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015907 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015908 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015909 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15910 "scan rejected %d", __func__, status);
15911 else
15912 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15913 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015914 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015915 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015916 }
15917#endif
15918
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015919 /* acquire the wakelock to avoid the apps suspend during the scan. To
15920 * address the following issues.
15921 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15922 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15923 * for long time, this result in apps running at full power for long time.
15924 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15925 * be stuck in full power because of resume BMPS
15926 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015927 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015928
Nirav Shah20ac06f2013-12-12 18:14:06 +053015929 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15930 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015931 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15932 scanRequest.requestType, scanRequest.scanType,
15933 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015934 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15935
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015936 ret = hdd_spoof_scan(wiphy, pAdapter, request, is_p2p_scan, &scanRequest);
15937 if(ret) {
15938 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
15939 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015940#ifdef FEATURE_WLAN_TDLS
15941 wlan_hdd_tdls_scan_done_callback(pAdapter);
15942#endif
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015943 goto free_mem;
Siddharth Bhal76972212014-10-15 16:22:51 +053015944 }
Rajeev Kumar Sirasanagandla2bb30b82019-01-07 22:30:16 +053015945
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015946 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015947 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015948 pAdapter->sessionId, &scanRequest, &scanId,
15949 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015950
Jeff Johnson295189b2012-06-20 16:38:30 -070015951 if (eHAL_STATUS_SUCCESS != status)
15952 {
15953 hddLog(VOS_TRACE_LEVEL_ERROR,
15954 "%s: sme_ScanRequest returned error %d", __func__, status);
15955 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015956 if(eHAL_STATUS_RESOURCES == status)
15957 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015958 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15959 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015960 status = -EBUSY;
15961 } else {
15962 status = -EIO;
15963 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015964 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015965
15966#ifdef FEATURE_WLAN_TDLS
15967 wlan_hdd_tdls_scan_done_callback(pAdapter);
15968#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015969 goto free_mem;
15970 }
15971
15972 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015973 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015974 pAdapter->request = request;
15975 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015976 pScanInfo->no_cck = request->no_cck;
15977 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15978 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15979 pHddCtx->scan_info.last_scan_channelList[i] =
15980 request->channels[i]->hw_value;
15981 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015982
15983 complete(&pScanInfo->scan_req_completion_event);
15984
15985free_mem:
15986 if( scanRequest.SSIDs.SSIDList )
15987 {
15988 vos_mem_free(scanRequest.SSIDs.SSIDList);
15989 }
15990
15991 if( channelList )
15992 vos_mem_free( channelList );
15993
15994 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015995 return status;
15996}
15997
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015998int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15999#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
16000 struct net_device *dev,
16001#endif
16002 struct cfg80211_scan_request *request)
16003{
16004 int ret;
16005
16006 vos_ssr_protect(__func__);
16007 ret = __wlan_hdd_cfg80211_scan(wiphy,
16008#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
16009 dev,
16010#endif
16011 request);
16012 vos_ssr_unprotect(__func__);
16013
16014 return ret;
16015}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016016
16017void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
16018{
16019 v_U8_t iniDot11Mode =
16020 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
16021 eHddDot11Mode hddDot11Mode = iniDot11Mode;
16022
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016023 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
16024 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016025 switch ( iniDot11Mode )
16026 {
16027 case eHDD_DOT11_MODE_AUTO:
16028 case eHDD_DOT11_MODE_11ac:
16029 case eHDD_DOT11_MODE_11ac_ONLY:
16030#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053016031 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
16032 sme_IsFeatureSupportedByFW(DOT11AC) )
16033 hddDot11Mode = eHDD_DOT11_MODE_11ac;
16034 else
16035 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016036#else
16037 hddDot11Mode = eHDD_DOT11_MODE_11n;
16038#endif
16039 break;
16040 case eHDD_DOT11_MODE_11n:
16041 case eHDD_DOT11_MODE_11n_ONLY:
16042 hddDot11Mode = eHDD_DOT11_MODE_11n;
16043 break;
16044 default:
16045 hddDot11Mode = iniDot11Mode;
16046 break;
16047 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053016048#ifdef WLAN_FEATURE_AP_HT40_24G
16049 if (operationChannel > SIR_11B_CHANNEL_END)
16050#endif
16051 {
16052 /* This call decides required channel bonding mode */
16053 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016054 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053016055 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053016056 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016057}
16058
Jeff Johnson295189b2012-06-20 16:38:30 -070016059/*
16060 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016061 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016062 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016063int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053016064 const u8 *ssid, size_t ssid_len, const u8 *bssid,
16065 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070016066{
16067 int status = 0;
16068 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080016069 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016070 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070016071 v_U32_t roamId;
16072 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070016073 eCsrAuthType RSNAuthType;
16074
16075 ENTER();
16076
16077 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080016078 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053016079 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080016080
16081 status = wlan_hdd_validate_context(pHddCtx);
16082 if (status)
16083 {
Yue Mae36e3552014-03-05 17:06:20 -080016084 return status;
16085 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016086
Jeff Johnson295189b2012-06-20 16:38:30 -070016087 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
16088 {
16089 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
16090 return -EINVAL;
16091 }
16092
Nitesh Shah9b066282017-06-06 18:05:52 +053016093
Jeff Johnson295189b2012-06-20 16:38:30 -070016094 pRoamProfile = &pWextState->roamProfile;
16095
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016096 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070016097 {
Jeff Johnsone7245742012-09-05 17:12:55 -070016098 hdd_station_ctx_t *pHddStaCtx;
16099 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053016100 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016101
Siddharth Bhalda0d1622015-04-24 15:47:49 +053016102 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
16103
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016104 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070016105 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
16106 {
16107 /*QoS not enabled in cfg file*/
16108 pRoamProfile->uapsd_mask = 0;
16109 }
16110 else
16111 {
16112 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016113 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070016114 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
16115 }
16116
16117 pRoamProfile->SSIDs.numOfSSIDs = 1;
16118 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
16119 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016120 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070016121 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
16122 ssid, ssid_len);
16123
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016124 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
16125 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
16126
Jeff Johnson295189b2012-06-20 16:38:30 -070016127 if (bssid)
16128 {
16129 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016130 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070016131 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016132 /* Save BSSID in seperate variable as well, as RoamProfile
16133 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070016134 case of join failure we should send valid BSSID to supplicant
16135 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016136 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070016137 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016138
Jeff Johnson295189b2012-06-20 16:38:30 -070016139 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016140 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070016141 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016142 /* Store bssid_hint to use in the scan filter. */
16143 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
16144 WNI_CFG_BSSID_LEN);
16145 /*
16146 * Save BSSID in seperate variable as well, as RoamProfile
16147 * BSSID is getting zeroed out in the association process. And in
16148 * case of join failure we should send valid BSSID to supplicant
16149 */
16150 vos_mem_copy(pWextState->req_bssId, bssid_hint,
16151 WNI_CFG_BSSID_LEN);
16152 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
16153 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070016154 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016155
Abhishek Singhb3e376c2017-01-04 15:27:13 +053016156
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016157 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
16158 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016159 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
16160 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016161 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016162 /*set gen ie*/
16163 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
16164 /*set auth*/
16165 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
16166 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016167#ifdef FEATURE_WLAN_WAPI
16168 if (pAdapter->wapi_info.nWapiMode)
16169 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016170 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016171 switch (pAdapter->wapi_info.wapiAuthMode)
16172 {
16173 case WAPI_AUTH_MODE_PSK:
16174 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016175 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016176 pAdapter->wapi_info.wapiAuthMode);
16177 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
16178 break;
16179 }
16180 case WAPI_AUTH_MODE_CERT:
16181 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016182 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016183 pAdapter->wapi_info.wapiAuthMode);
16184 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
16185 break;
16186 }
16187 } // End of switch
16188 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
16189 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
16190 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016191 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016192 pRoamProfile->AuthType.numEntries = 1;
16193 pRoamProfile->EncryptionType.numEntries = 1;
16194 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
16195 pRoamProfile->mcEncryptionType.numEntries = 1;
16196 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
16197 }
16198 }
16199#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016200#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016201 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016202 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
16203 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
16204 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016205 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
16206 sizeof (tSirGtkOffloadParams));
16207 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016208 }
16209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016210 pRoamProfile->csrPersona = pAdapter->device_mode;
16211
Jeff Johnson32d95a32012-09-10 13:15:23 -070016212 if( operatingChannel )
16213 {
16214 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
16215 pRoamProfile->ChannelInfo.numOfChannels = 1;
16216 }
Chet Lanctot186b5732013-03-18 10:26:30 -070016217 else
16218 {
16219 pRoamProfile->ChannelInfo.ChannelList = NULL;
16220 pRoamProfile->ChannelInfo.numOfChannels = 0;
16221 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070016222 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
16223 {
16224 hdd_select_cbmode(pAdapter,operatingChannel);
16225 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053016226
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016227 /*
16228 * Change conn_state to connecting before sme_RoamConnect(),
16229 * because sme_RoamConnect() has a direct path to call
16230 * hdd_smeRoamCallback(), which will change the conn_state
16231 * If direct path, conn_state will be accordingly changed
16232 * to NotConnected or Associated by either
16233 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
16234 * in sme_RoamCallback()
16235 * if sme_RomConnect is to be queued,
16236 * Connecting state will remain until it is completed.
16237 * If connection state is not changed,
16238 * connection state will remain in eConnectionState_NotConnected state.
16239 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
16240 * if conn state is eConnectionState_NotConnected.
16241 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
16242 * informed of connect result indication which is an issue.
16243 */
16244
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016245 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16246 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053016247 {
16248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016249 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016250 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
16251 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016252 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
16253 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053016254 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053016255
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016256 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070016257 pAdapter->sessionId, pRoamProfile, &roamId);
16258
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053016259 if ((eHAL_STATUS_SUCCESS != status) &&
16260 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
16261 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016262
16263 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053016264 hddLog(VOS_TRACE_LEVEL_ERROR,
16265 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
16266 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016267 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016268 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080016269 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053016270 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080016271
16272 pRoamProfile->ChannelInfo.ChannelList = NULL;
16273 pRoamProfile->ChannelInfo.numOfChannels = 0;
16274
Jeff Johnson295189b2012-06-20 16:38:30 -070016275 }
16276 else
16277 {
16278 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
16279 return -EINVAL;
16280 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080016281 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070016282 return status;
16283}
16284
16285/*
16286 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
16287 * This function is used to set the authentication type (OPEN/SHARED).
16288 *
16289 */
16290static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
16291 enum nl80211_auth_type auth_type)
16292{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016293 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016294 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16295
16296 ENTER();
16297
16298 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016299 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070016300 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016301 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016302 hddLog(VOS_TRACE_LEVEL_INFO,
16303 "%s: set authentication type to AUTOSWITCH", __func__);
16304 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
16305 break;
16306
16307 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016308#ifdef WLAN_FEATURE_VOWIFI_11R
16309 case NL80211_AUTHTYPE_FT:
16310#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016311 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016312 "%s: set authentication type to OPEN", __func__);
16313 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
16314 break;
16315
16316 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016317 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016318 "%s: set authentication type to SHARED", __func__);
16319 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
16320 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016321#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016322 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016323 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070016324 "%s: set authentication type to CCKM WPA", __func__);
16325 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
16326 break;
16327#endif
Abhinav Kumar4d44f632019-08-02 13:55:54 +053016328 case NL80211_AUTHTYPE_SAE:
16329 hddLog(LOG1, "set authentication type to SAE");
16330 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SAE;
16331 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016332
16333 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016334 hddLog(VOS_TRACE_LEVEL_ERROR,
16335 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016336 auth_type);
16337 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
16338 return -EINVAL;
16339 }
16340
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016341 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016342 pHddStaCtx->conn_info.authType;
16343 return 0;
16344}
16345
16346/*
16347 * FUNCTION: wlan_hdd_set_akm_suite
16348 * This function is used to set the key mgmt type(PSK/8021x).
16349 *
16350 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016351static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016352 u32 key_mgmt
16353 )
16354{
16355 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
16356 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053016357 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016358#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016359#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016360#endif
16361#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053016362#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053016363#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016364 /*set key mgmt type*/
16365 switch(key_mgmt)
16366 {
16367 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053016368 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016369#ifdef WLAN_FEATURE_VOWIFI_11R
16370 case WLAN_AKM_SUITE_FT_PSK:
16371#endif
16372 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070016373 __func__);
16374 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
16375 break;
16376
16377 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053016378 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016379#ifdef WLAN_FEATURE_VOWIFI_11R
16380 case WLAN_AKM_SUITE_FT_8021X:
16381#endif
16382 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016383 __func__);
16384 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16385 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016386#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016387#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
16388#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
16389 case WLAN_AKM_SUITE_CCKM:
16390 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
16391 __func__);
16392 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
16393 break;
16394#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070016395#ifndef WLAN_AKM_SUITE_OSEN
16396#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
16397 case WLAN_AKM_SUITE_OSEN:
16398 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
16399 __func__);
16400 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16401 break;
16402#endif
Abhinav Kumar4d44f632019-08-02 13:55:54 +053016403 case WLAN_AKM_SUITE_SAE:
16404 hddLog(LOG1, "setting key mgmt type to SAE");
16405 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16406 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016407
Abhinav Kumar487e49e2019-07-22 14:46:18 +053016408 case WLAN_AKM_SUITE_OWE_1:
16409 hddLog(LOG1, "setting key mgmt type to OWE");
16410 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
16411 break;
16412
Jeff Johnson295189b2012-06-20 16:38:30 -070016413 default:
Abhinav Kumar487e49e2019-07-22 14:46:18 +053016414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %x",
Jeff Johnson295189b2012-06-20 16:38:30 -070016415 __func__, key_mgmt);
16416 return -EINVAL;
16417
16418 }
16419 return 0;
16420}
16421
16422/*
16423 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016424 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070016425 * (NONE/WEP40/WEP104/TKIP/CCMP).
16426 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016427static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
16428 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070016429 bool ucast
16430 )
16431{
16432 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016433 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016434 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16435
16436 ENTER();
16437
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016438 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016439 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053016440 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070016441 __func__, cipher);
16442 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16443 }
16444 else
16445 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016446
Jeff Johnson295189b2012-06-20 16:38:30 -070016447 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016448 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070016449 {
16450 case IW_AUTH_CIPHER_NONE:
16451 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
16452 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016453
Jeff Johnson295189b2012-06-20 16:38:30 -070016454 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016455 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070016456 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016457
Jeff Johnson295189b2012-06-20 16:38:30 -070016458 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016459 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016460 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016461
Jeff Johnson295189b2012-06-20 16:38:30 -070016462 case WLAN_CIPHER_SUITE_TKIP:
16463 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16464 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016465
Jeff Johnson295189b2012-06-20 16:38:30 -070016466 case WLAN_CIPHER_SUITE_CCMP:
16467 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16468 break;
16469#ifdef FEATURE_WLAN_WAPI
16470 case WLAN_CIPHER_SUITE_SMS4:
16471 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16472 break;
16473#endif
16474
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016475#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016476 case WLAN_CIPHER_SUITE_KRK:
16477 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16478 break;
16479#endif
16480 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016481 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016482 __func__, cipher);
16483 return -EOPNOTSUPP;
16484 }
16485 }
16486
16487 if (ucast)
16488 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016489 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016490 __func__, encryptionType);
16491 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16492 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016493 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016494 encryptionType;
16495 }
16496 else
16497 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016498 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016499 __func__, encryptionType);
16500 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16501 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16502 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16503 }
16504
16505 return 0;
16506}
16507
16508
16509/*
16510 * FUNCTION: wlan_hdd_cfg80211_set_ie
16511 * This function is used to parse WPA/RSN IE's.
16512 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016513int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016514#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16515 const u8 *ie,
16516#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016517 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016518#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016519 size_t ie_len
16520 )
16521{
16522 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016523#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16524 const u8 *genie = ie;
16525#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016526 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016527#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016528 v_U16_t remLen = ie_len;
16529#ifdef FEATURE_WLAN_WAPI
16530 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16531 u16 *tmp;
16532 v_U16_t akmsuiteCount;
16533 int *akmlist;
16534#endif
16535 ENTER();
16536
16537 /* clear previous assocAddIE */
16538 pWextState->assocAddIE.length = 0;
16539 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016540 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016541
16542 while (remLen >= 2)
16543 {
16544 v_U16_t eLen = 0;
16545 v_U8_t elementId;
16546 elementId = *genie++;
16547 eLen = *genie++;
16548 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016549
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016550 /* Sanity check on eLen */
16551 if (eLen > remLen) {
16552 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16553 __func__, eLen, elementId);
16554 VOS_ASSERT(0);
16555 return -EINVAL;
16556 }
16557
Arif Hussain6d2a3322013-11-17 19:50:10 -080016558 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016559 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016560
16561 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016562 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016563 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016564 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 -070016565 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016566 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016567 "%s: Invalid WPA IE", __func__);
16568 return -EINVAL;
16569 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016570 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016571 {
16572 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016573 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016574 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016575
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016576 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016577 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016578 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16579 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016580 VOS_ASSERT(0);
16581 return -ENOMEM;
16582 }
16583 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16584 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16585 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016586
Jeff Johnson295189b2012-06-20 16:38:30 -070016587 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16588 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16589 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16590 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016591 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16592 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016593 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16594 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16595 __func__, eLen);
16596 VOS_ASSERT(0);
16597 return -EINVAL;
16598 }
16599
Jeff Johnson295189b2012-06-20 16:38:30 -070016600 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16601 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16602 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16603 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16604 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16605 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016606 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016607 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016608 {
16609 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016610 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016611 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016612
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016613 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016614 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016615 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16616 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016617 VOS_ASSERT(0);
16618 return -ENOMEM;
16619 }
16620 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16621 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16622 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016623
Jeff Johnson295189b2012-06-20 16:38:30 -070016624 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16625 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16626 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016627#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016628 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16629 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016630 /*Consider WFD IE, only for P2P Client */
16631 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16632 {
16633 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016634 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016635 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016636
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016637 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016638 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016639 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16640 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016641 VOS_ASSERT(0);
16642 return -ENOMEM;
16643 }
16644 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16645 // WPS IE + P2P IE + WFD IE
16646 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16647 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016648
Jeff Johnson295189b2012-06-20 16:38:30 -070016649 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16650 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16651 }
16652#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016653 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016654 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016655 HS20_OUI_TYPE_SIZE)) )
16656 {
16657 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016658 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016659 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016660
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016661 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016662 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016663 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16664 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016665 VOS_ASSERT(0);
16666 return -ENOMEM;
16667 }
16668 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16669 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016670
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016671 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16672 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16673 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016674 /* Appending OSEN Information Element in Assiciation Request */
16675 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16676 OSEN_OUI_TYPE_SIZE)) )
16677 {
16678 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16679 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16680 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016681
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016682 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016683 {
16684 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16685 "Need bigger buffer space");
16686 VOS_ASSERT(0);
16687 return -ENOMEM;
16688 }
16689 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16690 pWextState->assocAddIE.length += eLen + 2;
16691
16692 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16693 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16694 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16695 }
16696
Abhishek Singh4322e622015-06-10 15:42:54 +053016697 /* Update only for WPA IE */
16698 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16699 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016700
16701 /* populating as ADDIE in beacon frames */
16702 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016703 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016704 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16705 {
16706 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16707 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16708 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16709 {
16710 hddLog(LOGE,
16711 "Coldn't pass "
16712 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16713 }
16714 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16715 else
16716 hddLog(LOGE,
16717 "Could not pass on "
16718 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16719
16720 /* IBSS mode doesn't contain params->proberesp_ies still
16721 beaconIE's need to be populated in probe response frames */
16722 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16723 {
16724 u16 rem_probe_resp_ie_len = eLen + 2;
16725 u8 probe_rsp_ie_len[3] = {0};
16726 u8 counter = 0;
16727
16728 /* Check Probe Resp Length if it is greater then 255 then
16729 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16730 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16731 not able Store More then 255 bytes into One Variable */
16732
16733 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16734 {
16735 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16736 {
16737 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16738 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16739 }
16740 else
16741 {
16742 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16743 rem_probe_resp_ie_len = 0;
16744 }
16745 }
16746
16747 rem_probe_resp_ie_len = 0;
16748
16749 if (probe_rsp_ie_len[0] > 0)
16750 {
16751 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16752 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16753 (tANI_U8*)(genie - 2),
16754 probe_rsp_ie_len[0], NULL,
16755 eANI_BOOLEAN_FALSE)
16756 == eHAL_STATUS_FAILURE)
16757 {
16758 hddLog(LOGE,
16759 "Could not pass"
16760 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16761 }
16762 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16763 }
16764
16765 if (probe_rsp_ie_len[1] > 0)
16766 {
16767 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16768 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16769 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16770 probe_rsp_ie_len[1], NULL,
16771 eANI_BOOLEAN_FALSE)
16772 == eHAL_STATUS_FAILURE)
16773 {
16774 hddLog(LOGE,
16775 "Could not pass"
16776 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16777 }
16778 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16779 }
16780
16781 if (probe_rsp_ie_len[2] > 0)
16782 {
16783 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16784 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16785 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16786 probe_rsp_ie_len[2], NULL,
16787 eANI_BOOLEAN_FALSE)
16788 == eHAL_STATUS_FAILURE)
16789 {
16790 hddLog(LOGE,
16791 "Could not pass"
16792 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16793 }
16794 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16795 }
16796
16797 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16798 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16799 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16800 {
16801 hddLog(LOGE,
16802 "Could not pass"
16803 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16804 }
16805 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016806 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016807 break;
16808 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016809 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16810 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16811 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16812 VOS_ASSERT(0);
16813 return -EINVAL;
16814 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016815 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16816 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16817 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16818 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16819 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16820 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016821
Abhishek Singhb16f3562016-01-20 11:08:32 +053016822 /* Appending extended capabilities with Interworking or
16823 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016824 *
16825 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016826 * interworkingService or bsstransition bit is set to 1.
16827 * Driver is only interested in interworkingService and
16828 * bsstransition capability from supplicant.
16829 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016830 * required from supplicat, it needs to be handled while
16831 * sending Assoc Req in LIM.
16832 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016833 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016834 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016835 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016836 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016837 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016838
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016839 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016840 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016841 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16842 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016843 VOS_ASSERT(0);
16844 return -ENOMEM;
16845 }
16846 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16847 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016848
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016849 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16850 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16851 break;
16852 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016853#ifdef FEATURE_WLAN_WAPI
16854 case WLAN_EID_WAPI:
16855 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016856 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016857 pAdapter->wapi_info.nWapiMode);
16858 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016859 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016860 akmsuiteCount = WPA_GET_LE16(tmp);
16861 tmp = tmp + 1;
16862 akmlist = (int *)(tmp);
16863 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16864 {
16865 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16866 }
16867 else
16868 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016869 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016870 VOS_ASSERT(0);
16871 return -EINVAL;
16872 }
16873
16874 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16875 {
16876 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016877 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016878 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016879 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016880 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016881 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016882 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016883 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016884 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16885 }
16886 break;
16887#endif
Abhinav Kumar487e49e2019-07-22 14:46:18 +053016888 case SIR_MAC_REQUEST_EID_MAX:
16889 if (genie[0] == SIR_DH_PARAMETER_ELEMENT_EXT_EID)
16890 {
16891 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16892 if (SIR_MAC_MAX_ADD_IE_LENGTH <
16893 (pWextState->assocAddIE.length + eLen))
16894 {
16895 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16896 "Need bigger buffer space");
16897 VOS_ASSERT(0);
16898 return -ENOMEM;
16899 }
16900 hddLog(VOS_TRACE_LEVEL_INFO, "Set DH EXT IE(len %d)",
16901 eLen + 2);
16902 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen,
16903 genie - 2, eLen + 2);
16904 pWextState->assocAddIE.length += eLen + 2;
16905 pWextState->roamProfile.pAddIEAssoc =
16906 pWextState->assocAddIE.addIEdata;
16907 pWextState->roamProfile.nAddIEAssocLength =
16908 pWextState->assocAddIE.length;
16909 }else {
16910 hddLog(VOS_TRACE_LEVEL_FATAL, "UNKNOWN EID: %X", genie[0]);
16911 }
16912 break;
16913
Jeff Johnson295189b2012-06-20 16:38:30 -070016914 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016915 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016916 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016917 /* when Unknown IE is received we should break and continue
16918 * to the next IE in the buffer instead we were returning
16919 * so changing this to break */
16920 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016921 }
16922 genie += eLen;
16923 remLen -= eLen;
16924 }
16925 EXIT();
16926 return 0;
16927}
16928
16929/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016930 * FUNCTION: hdd_isWPAIEPresent
16931 * Parse the received IE to find the WPA IE
16932 *
16933 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016934static bool hdd_isWPAIEPresent(
16935#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16936 const u8 *ie,
16937#else
16938 u8 *ie,
16939#endif
16940 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016941{
16942 v_U8_t eLen = 0;
16943 v_U16_t remLen = ie_len;
16944 v_U8_t elementId = 0;
16945
16946 while (remLen >= 2)
16947 {
16948 elementId = *ie++;
16949 eLen = *ie++;
16950 remLen -= 2;
16951 if (eLen > remLen)
16952 {
16953 hddLog(VOS_TRACE_LEVEL_ERROR,
16954 "%s: IE length is wrong %d", __func__, eLen);
16955 return FALSE;
16956 }
16957 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16958 {
16959 /* OUI - 0x00 0X50 0XF2
16960 WPA Information Element - 0x01
16961 WPA version - 0x01*/
16962 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16963 return TRUE;
16964 }
16965 ie += eLen;
16966 remLen -= eLen;
16967 }
16968 return FALSE;
16969}
16970
16971/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016972 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016973 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016974 * parameters during connect operation.
16975 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016976int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016977 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016978 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016979{
16980 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016981 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016982 ENTER();
16983
16984 /*set wpa version*/
16985 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16986
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016987 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016988 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016989 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016990 {
16991 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16992 }
16993 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16994 {
16995 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16996 }
16997 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016998
16999 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017000 pWextState->wpaVersion);
17001
17002 /*set authentication type*/
17003 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
17004
17005 if (0 > status)
17006 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017007 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017008 "%s: failed to set authentication type ", __func__);
17009 return status;
17010 }
17011
17012 /*set key mgmt type*/
17013 if (req->crypto.n_akm_suites)
17014 {
17015 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
17016 if (0 > status)
17017 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017018 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070017019 __func__);
17020 return status;
17021 }
17022 }
17023
17024 /*set pairwise cipher type*/
17025 if (req->crypto.n_ciphers_pairwise)
17026 {
17027 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
17028 req->crypto.ciphers_pairwise[0], true);
17029 if (0 > status)
17030 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017031 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017032 "%s: failed to set unicast cipher type", __func__);
17033 return status;
17034 }
17035 }
17036 else
17037 {
17038 /*Reset previous cipher suite to none*/
17039 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
17040 if (0 > status)
17041 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017042 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017043 "%s: failed to set unicast cipher type", __func__);
17044 return status;
17045 }
17046 }
17047
17048 /*set group cipher type*/
17049 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
17050 false);
17051
17052 if (0 > status)
17053 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017054 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070017055 __func__);
17056 return status;
17057 }
17058
Chet Lanctot186b5732013-03-18 10:26:30 -070017059#ifdef WLAN_FEATURE_11W
17060 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
17061#endif
17062
Jeff Johnson295189b2012-06-20 16:38:30 -070017063 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
17064 if (req->ie_len)
17065 {
17066 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
17067 if ( 0 > status)
17068 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017069 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017070 __func__);
17071 return status;
17072 }
17073 }
17074
17075 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017076 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070017077 {
17078 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
17079 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
17080 )
17081 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017082 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070017083 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
17084 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017085 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017086 __func__);
17087 return -EOPNOTSUPP;
17088 }
17089 else
17090 {
17091 u8 key_len = req->key_len;
17092 u8 key_idx = req->key_idx;
17093
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017094 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070017095 && (CSR_MAX_NUM_KEY > key_idx)
17096 )
17097 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017098 hddLog(VOS_TRACE_LEVEL_INFO,
17099 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017100 __func__, key_idx, key_len);
17101 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017102 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070017103 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017104 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070017105 (u8)key_len;
17106 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
17107 }
17108 }
17109 }
17110 }
17111
17112 return status;
17113}
17114
17115/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017116 * FUNCTION: wlan_hdd_try_disconnect
17117 * This function is used to disconnect from previous
17118 * connection
17119 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053017120int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017121{
17122 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017123 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017124 hdd_station_ctx_t *pHddStaCtx;
17125 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053017126 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017127
Abhishek Singh19a7dd92015-12-30 16:31:51 +053017128 ret = wlan_hdd_validate_context(pHddCtx);
17129 if (0 != ret)
17130 {
17131 return ret;
17132 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017133 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17134
17135 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
17136
17137 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
17138 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053017139 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017140 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
17141 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053017142 /* Indicate disconnect to SME so that in-progress connection or preauth
17143 * can be aborted
17144 */
17145 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
17146 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053017147 spin_lock_bh(&pAdapter->lock_for_active_session);
17148 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
17149 {
17150 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
17151 }
17152 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053017153 hdd_connSetConnectionState(pHddStaCtx,
17154 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017155 /* Issue disconnect to CSR */
17156 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017157 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017158 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017159 eCSR_DISCONNECT_REASON_UNSPECIFIED);
17160 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
17161 hddLog(LOG1,
17162 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
17163 } else if ( 0 != status ) {
17164 hddLog(LOGE,
17165 FL("csrRoamDisconnect failure, returned %d"),
17166 (int)status );
17167 result = -EINVAL;
17168 goto disconnected;
17169 }
17170 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017171 &pAdapter->disconnect_comp_var,
17172 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017173 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
17174 hddLog(LOGE,
17175 "%s: Failed to disconnect, timed out", __func__);
17176 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017177 }
17178 }
17179 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
17180 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017181 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017182 &pAdapter->disconnect_comp_var,
17183 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017184 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017185 {
17186 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017187 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017188 }
17189 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053017190disconnected:
17191 hddLog(LOG1,
17192 FL("Set HDD connState to eConnectionState_NotConnected"));
17193 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
17194 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017195}
17196
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017197/**
17198 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
17199 * @adapter: Pointer to the HDD adapter
17200 * @req: Pointer to the structure cfg_connect_params receieved from user space
17201 *
Abhinav Kumar42c34902018-09-27 19:00:35 +053017202 * This function will start reassociation if prev_bssid is set and bssid/
17203 * bssid_hint, channel/channel_hint parameters are present in connect request.
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017204 *
17205 * Return: success if reassociation is happening
17206 * Error code if reassociation is not permitted or not happening
17207 */
17208#ifdef CFG80211_CONNECT_PREV_BSSID
17209static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
17210 struct cfg80211_connect_params *req)
17211{
17212 int status = -EPERM;
Abhinav Kumar42c34902018-09-27 19:00:35 +053017213 const uint8_t *bssid = NULL;
17214 uint16_t channel = 0;
17215
17216 if (req->bssid)
17217 bssid = req->bssid;
17218 else if (req->bssid_hint)
17219 bssid = req->bssid_hint;
17220
17221 if (req->channel)
17222 channel = req->channel->hw_value;
17223 else if (req->channel_hint)
17224 channel = req->channel_hint->hw_value;
17225
17226 if (bssid && channel && req->prev_bssid) {
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017227 hddLog(VOS_TRACE_LEVEL_INFO,
17228 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
Abhinav Kumar42c34902018-09-27 19:00:35 +053017229 channel, MAC_ADDR_ARRAY(bssid));
17230 status = hdd_reassoc(adapter, bssid, channel,
17231 CONNECT_CMD_USERSPACE);
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017232 }
17233 return status;
17234}
17235#else
17236static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
17237 struct cfg80211_connect_params *req)
17238{
17239 return -EPERM;
17240}
17241#endif
17242
Abhishek Singhe3beee22017-07-31 15:35:40 +053017243/**
17244 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
17245 * connect in HT20 mode
17246 * @hdd_ctx: hdd context
17247 * @adapter: Pointer to the HDD adapter
17248 * @req: Pointer to the structure cfg_connect_params receieved from user space
17249 *
17250 * This function will check if supplicant has indicated to to connect in HT20
17251 * mode. this is currently applicable only for 2.4Ghz mode only.
17252 * if feature is enabled and supplicant indicate HT20 set
17253 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
17254 *
17255 * Return: void
17256 */
17257#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
17258static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17259 hdd_adapter_t *adapter,
17260 struct cfg80211_connect_params *req)
17261{
17262 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17263 tCsrRoamProfile *roam_profile;
17264
17265 roam_profile = &wext_state->roamProfile;
17266 roam_profile->force_24ghz_in_ht20 = false;
17267 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
17268 !(req->ht_capa.cap_info &
17269 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
17270 roam_profile->force_24ghz_in_ht20 = true;
17271
17272 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
17273 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
17274}
17275#else
17276static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
17277 hdd_adapter_t *adapter,
17278 struct cfg80211_connect_params *req)
17279{
17280 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
17281 tCsrRoamProfile *roam_profile;
17282
17283 roam_profile = &wext_state->roamProfile;
17284 roam_profile->force_24ghz_in_ht20 = false;
17285}
17286#endif
17287
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017288/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053017289 * FUNCTION: __wlan_hdd_cfg80211_connect
17290 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070017291 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017292static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017293 struct net_device *ndev,
17294 struct cfg80211_connect_params *req
17295 )
17296{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017297 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017298 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053017299#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
17300 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017301 const u8 *bssid_hint = req->bssid_hint;
17302#else
17303 const u8 *bssid_hint = NULL;
17304#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017305 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017306 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053017307 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017308
17309 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017310
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017311 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17312 TRACE_CODE_HDD_CFG80211_CONNECT,
17313 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017314 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017315 "%s: device_mode = %s (%d)", __func__,
17316 hdd_device_modetoString(pAdapter->device_mode),
17317 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017318
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017319 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017320 if (!pHddCtx)
17321 {
17322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17323 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053017324 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080017325 }
17326
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017327 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017328 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017329 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017330 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017331 }
17332
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053017333 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
17334 return -EINVAL;
17335
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053017336 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
17337 if (0 == status)
17338 return status;
17339
Agarwal Ashish51325b52014-06-16 16:50:49 +053017340
Jeff Johnson295189b2012-06-20 16:38:30 -070017341#ifdef WLAN_BTAMP_FEATURE
17342 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017343 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070017344 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017345 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017346 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080017347 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070017348 }
17349#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017350
17351 //If Device Mode is Station Concurrent Sessions Exit BMps
17352 //P2P Mode will be taken care in Open/close adapter
17353 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053017354 (vos_concurrent_open_sessions_running())) {
17355 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
17356 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017357 }
17358
17359 /*Try disconnecting if already in connected state*/
17360 status = wlan_hdd_try_disconnect(pAdapter);
17361 if ( 0 > status)
17362 {
17363 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17364 " connection"));
17365 return -EALREADY;
17366 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053017367 /* Check for max concurrent connections after doing disconnect if any*/
17368 if (vos_max_concurrent_connections_reached()) {
17369 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17370 return -ECONNREFUSED;
17371 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017372
Jeff Johnson295189b2012-06-20 16:38:30 -070017373 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017374 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070017375
17376 if ( 0 > status)
17377 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017378 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070017379 __func__);
17380 return status;
17381 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053017382
17383 if (pHddCtx->spoofMacAddr.isEnabled)
17384 {
17385 hddLog(VOS_TRACE_LEVEL_INFO,
17386 "%s: MAC Spoofing enabled ", __func__);
17387 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
17388 * to fill TxBds for probe request during SSID scan which may happen
17389 * as part of connect command
17390 */
17391 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
17392 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
17393 if (status != VOS_STATUS_SUCCESS)
17394 return -ECONNREFUSED;
17395 }
17396
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017397 if (req->channel)
17398 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070017399 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017400 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053017401
17402 /* Abort if any scan is going on */
17403 status = wlan_hdd_scan_abort(pAdapter);
17404 if (0 != status)
17405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
17406
Abhishek Singhe3beee22017-07-31 15:35:40 +053017407 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
17408
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053017409 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
17410 req->ssid_len, req->bssid,
17411 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017412
Sushant Kaushikd7083982015-03-18 14:33:24 +053017413 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017414 {
17415 //ReEnable BMPS if disabled
17416 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
17417 (NULL != pHddCtx))
17418 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053017419 if (pHddCtx->hdd_wlan_suspended)
17420 {
17421 hdd_set_pwrparams(pHddCtx);
17422 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017423 //ReEnable Bmps and Imps back
17424 hdd_enable_bmps_imps(pHddCtx);
17425 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053017426 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070017427 return status;
17428 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017429 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070017430 EXIT();
17431 return status;
17432}
17433
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017434static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
17435 struct net_device *ndev,
17436 struct cfg80211_connect_params *req)
17437{
17438 int ret;
17439 vos_ssr_protect(__func__);
17440 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
17441 vos_ssr_unprotect(__func__);
17442
17443 return ret;
17444}
Jeff Johnson295189b2012-06-20 16:38:30 -070017445
17446/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017447 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070017448 * This function is used to issue a disconnect request to SME
17449 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017450static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017451 struct net_device *dev,
17452 u16 reason
17453 )
17454{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017455 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017456 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017457 tCsrRoamProfile *pRoamProfile;
17458 hdd_station_ctx_t *pHddStaCtx;
17459 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017460#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017461 tANI_U8 staIdx;
17462#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017463
Jeff Johnson295189b2012-06-20 16:38:30 -070017464 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017465
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017466 if (!pAdapter) {
17467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17468 return -EINVAL;
17469 }
17470
17471 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17472 if (!pHddStaCtx) {
17473 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
17474 return -EINVAL;
17475 }
17476
17477 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17478 status = wlan_hdd_validate_context(pHddCtx);
17479 if (0 != status)
17480 {
17481 return status;
17482 }
17483
17484 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
17485
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017486 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17487 TRACE_CODE_HDD_CFG80211_DISCONNECT,
17488 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017489 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
17490 __func__, hdd_device_modetoString(pAdapter->device_mode),
17491 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017492
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017493 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
17494 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017495
Jeff Johnson295189b2012-06-20 16:38:30 -070017496 if (NULL != pRoamProfile)
17497 {
17498 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017499 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17500 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017501 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017502 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017503 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017504 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017505 switch(reason)
17506 {
17507 case WLAN_REASON_MIC_FAILURE:
17508 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17509 break;
17510
17511 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17512 case WLAN_REASON_DISASSOC_AP_BUSY:
17513 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17514 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17515 break;
17516
17517 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17518 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017519 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017520 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17521 break;
17522
Jeff Johnson295189b2012-06-20 16:38:30 -070017523 default:
17524 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17525 break;
17526 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017527 pScanInfo = &pHddCtx->scan_info;
17528 if (pScanInfo->mScanPending)
17529 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017530 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017531 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017532 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017533 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017534 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017535 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017536#ifdef FEATURE_WLAN_TDLS
17537 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017538 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017539 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017540 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17541 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017542 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017543 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017544 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017545 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017546 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017547 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017548 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017549 status = sme_DeleteTdlsPeerSta(
17550 WLAN_HDD_GET_HAL_CTX(pAdapter),
17551 pAdapter->sessionId,
17552 mac);
17553 if (status != eHAL_STATUS_SUCCESS) {
17554 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17555 return -EPERM;
17556 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017557 }
17558 }
17559#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017560
17561 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17562 reasonCode,
17563 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017564 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17565 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017566 {
17567 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017568 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017569 __func__, (int)status );
17570 return -EINVAL;
17571 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017572 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017573 else
17574 {
17575 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17576 "called while in %d state", __func__,
17577 pHddStaCtx->conn_info.connState);
17578 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017579 }
17580 else
17581 {
17582 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17583 }
17584
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017585 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017586 return status;
17587}
17588
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017589static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17590 struct net_device *dev,
17591 u16 reason
17592 )
17593{
17594 int ret;
17595 vos_ssr_protect(__func__);
17596 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17597 vos_ssr_unprotect(__func__);
17598
17599 return ret;
17600}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017601
Jeff Johnson295189b2012-06-20 16:38:30 -070017602/*
17603 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017604 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017605 * settings in IBSS mode.
17606 */
17607static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017608 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017609 struct cfg80211_ibss_params *params
17610 )
17611{
17612 int status = 0;
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017613 tANI_U32 ret;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017614 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017615 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17616 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017617
Jeff Johnson295189b2012-06-20 16:38:30 -070017618 ENTER();
17619
17620 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017621 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017622
17623 if (params->ie_len && ( NULL != params->ie) )
17624 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017625 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17626 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017627 {
17628 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17629 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17630 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017631 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017632 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017633 tDot11fIEWPA dot11WPAIE;
17634 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017635 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017636
Wilson Yang00256342013-10-10 23:13:38 -070017637 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017638 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17639 params->ie_len, DOT11F_EID_WPA);
17640 if ( NULL != ie )
17641 {
17642 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
Hanumanth Reddy Pothulad6d2d2c2018-06-27 12:28:12 +053017643
17644 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
17645 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
17646 hddLog(LOGE, FL("invalid ie len:%d"), ie[1]);
17647 return -EINVAL;
17648 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017649 // Unpack the WPA IE
17650 //Skip past the EID byte and length byte - and four byte WiFi OUI
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017651 ret = dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017652 &ie[2+4],
17653 ie[1] - 4,
17654 &dot11WPAIE);
Pragaspathi Thilagarajb2041e82018-03-28 17:14:02 +053017655 if (DOT11F_FAILED(ret))
17656 {
17657 hddLog(LOGE,
17658 FL("unpack failed status:(0x%08x)"),
17659 ret);
17660 return -EINVAL;
17661 }
17662
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017663 /*Extract the multicast cipher, the encType for unicast
17664 cipher for wpa-none is none*/
17665 encryptionType =
17666 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17667 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017668 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017669
Jeff Johnson295189b2012-06-20 16:38:30 -070017670 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17671
17672 if (0 > status)
17673 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017674 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017675 __func__);
17676 return status;
17677 }
17678 }
17679
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017680 pWextState->roamProfile.AuthType.authType[0] =
17681 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017682 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017683 if (params->privacy)
17684 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017685 /* Security enabled IBSS, At this time there is no information available
17686 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017687 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017688 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017689 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017690 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017691 *enable privacy bit in beacons */
17692
17693 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17694 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017695 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17696 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017697 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17698 pWextState->roamProfile.EncryptionType.numEntries = 1;
17699 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017700 return status;
17701}
17702
17703/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017704 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017705 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017706 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017707static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017708 struct net_device *dev,
17709 struct cfg80211_ibss_params *params
17710 )
17711{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017712 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017713 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17714 tCsrRoamProfile *pRoamProfile;
17715 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017716 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17717 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017718 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017719
17720 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017721
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017722 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17723 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17724 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017725 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017726 "%s: device_mode = %s (%d)", __func__,
17727 hdd_device_modetoString(pAdapter->device_mode),
17728 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017729
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017730 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017731 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017732 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017733 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017734 }
17735
17736 if (NULL == pWextState)
17737 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017738 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017739 __func__);
17740 return -EIO;
17741 }
17742
Agarwal Ashish51325b52014-06-16 16:50:49 +053017743 if (vos_max_concurrent_connections_reached()) {
17744 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17745 return -ECONNREFUSED;
17746 }
17747
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017748 /*Try disconnecting if already in connected state*/
17749 status = wlan_hdd_try_disconnect(pAdapter);
17750 if ( 0 > status)
17751 {
17752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17753 " IBSS connection"));
17754 return -EALREADY;
17755 }
17756
Jeff Johnson295189b2012-06-20 16:38:30 -070017757 pRoamProfile = &pWextState->roamProfile;
17758
17759 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17760 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017761 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017762 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017763 return -EINVAL;
17764 }
17765
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017766 /* BSSID is provided by upper layers hence no need to AUTO generate */
17767 if (NULL != params->bssid) {
17768 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17769 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17770 hddLog (VOS_TRACE_LEVEL_ERROR,
17771 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17772 return -EIO;
17773 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017774 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017775 }
krunal sonie9002db2013-11-25 14:24:17 -080017776 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17777 {
17778 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17779 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17780 {
17781 hddLog (VOS_TRACE_LEVEL_ERROR,
17782 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17783 return -EIO;
17784 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017785
17786 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017787 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017788 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017789 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017790
Jeff Johnson295189b2012-06-20 16:38:30 -070017791 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017792 if (NULL !=
17793#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17794 params->chandef.chan)
17795#else
17796 params->channel)
17797#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017798 {
17799 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017800 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17801 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17802 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17803 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017804
17805 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017806 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017807 ieee80211_frequency_to_channel(
17808#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17809 params->chandef.chan->center_freq);
17810#else
17811 params->channel->center_freq);
17812#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017813
17814 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17815 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017816 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017817 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17818 __func__);
17819 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017820 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017821
17822 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017823 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017824 if (channelNum == validChan[indx])
17825 {
17826 break;
17827 }
17828 }
17829 if (indx >= numChans)
17830 {
17831 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017832 __func__, channelNum);
17833 return -EINVAL;
17834 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017835 /* Set the Operational Channel */
17836 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17837 channelNum);
17838 pRoamProfile->ChannelInfo.numOfChannels = 1;
17839 pHddStaCtx->conn_info.operationChannel = channelNum;
17840 pRoamProfile->ChannelInfo.ChannelList =
17841 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017842 }
17843
17844 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017845 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017846 if (status < 0)
17847 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017848 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017849 __func__);
17850 return status;
17851 }
17852
17853 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017854 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017855 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017856 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017857
17858 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017859 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017860
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017861 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017862 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017863}
17864
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017865static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17866 struct net_device *dev,
17867 struct cfg80211_ibss_params *params
17868 )
17869{
17870 int ret = 0;
17871
17872 vos_ssr_protect(__func__);
17873 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17874 vos_ssr_unprotect(__func__);
17875
17876 return ret;
17877}
17878
Jeff Johnson295189b2012-06-20 16:38:30 -070017879/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017880 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017881 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017882 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017883static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017884 struct net_device *dev
17885 )
17886{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017887 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017888 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17889 tCsrRoamProfile *pRoamProfile;
17890 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017891 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017892 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017893#ifdef WLAN_FEATURE_RMC
17894 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17895#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017896
17897 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017898
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017899 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17900 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17901 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017902 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017903 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017904 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017905 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017906 }
17907
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017908 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17909 hdd_device_modetoString(pAdapter->device_mode),
17910 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017911 if (NULL == pWextState)
17912 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017913 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017914 __func__);
17915 return -EIO;
17916 }
17917
17918 pRoamProfile = &pWextState->roamProfile;
17919
17920 /* Issue disconnect only if interface type is set to IBSS */
17921 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17922 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017923 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017924 __func__);
17925 return -EINVAL;
17926 }
17927
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017928#ifdef WLAN_FEATURE_RMC
17929 /* Clearing add IE of beacon */
17930 if (ccmCfgSetStr(pHddCtx->hHal,
17931 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17932 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17933 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17934 {
17935 hddLog (VOS_TRACE_LEVEL_ERROR,
17936 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17937 return -EINVAL;
17938 }
17939 if (ccmCfgSetInt(pHddCtx->hHal,
17940 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17941 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17942 {
17943 hddLog (VOS_TRACE_LEVEL_ERROR,
17944 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17945 __func__);
17946 return -EINVAL;
17947 }
17948
17949 // Reset WNI_CFG_PROBE_RSP Flags
17950 wlan_hdd_reset_prob_rspies(pAdapter);
17951
17952 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17953 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17954 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17955 {
17956 hddLog (VOS_TRACE_LEVEL_ERROR,
17957 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17958 __func__);
17959 return -EINVAL;
17960 }
17961#endif
17962
Jeff Johnson295189b2012-06-20 16:38:30 -070017963 /* Issue Disconnect request */
17964 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017965 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17966 pAdapter->sessionId,
17967 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17968 if (!HAL_STATUS_SUCCESS(hal_status)) {
17969 hddLog(LOGE,
17970 FL("sme_RoamDisconnect failed hal_status(%d)"),
17971 hal_status);
17972 return -EAGAIN;
17973 }
17974 status = wait_for_completion_timeout(
17975 &pAdapter->disconnect_comp_var,
17976 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17977 if (!status) {
17978 hddLog(LOGE,
17979 FL("wait on disconnect_comp_var failed"));
17980 return -ETIMEDOUT;
17981 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017982
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017983 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017984 return 0;
17985}
17986
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017987static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17988 struct net_device *dev
17989 )
17990{
17991 int ret = 0;
17992
17993 vos_ssr_protect(__func__);
17994 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17995 vos_ssr_unprotect(__func__);
17996
17997 return ret;
17998}
17999
Jeff Johnson295189b2012-06-20 16:38:30 -070018000/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018001 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070018002 * This function is used to set the phy parameters
18003 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
18004 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018005static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070018006 u32 changed)
18007{
18008 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18009 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018010 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018011
18012 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018013
18014 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018015 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
18016 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018017
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018018 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018019 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018020 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018021 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018022 }
18023
Jeff Johnson295189b2012-06-20 16:38:30 -070018024 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
18025 {
18026 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
18027 WNI_CFG_RTS_THRESHOLD_STAMAX :
18028 wiphy->rts_threshold;
18029
18030 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018031 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070018032 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018033 hddLog(VOS_TRACE_LEVEL_ERROR,
18034 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018035 __func__, rts_threshold);
18036 return -EINVAL;
18037 }
18038
18039 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
18040 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018041 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018042 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018043 hddLog(VOS_TRACE_LEVEL_ERROR,
18044 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018045 __func__, rts_threshold);
18046 return -EIO;
18047 }
18048
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018049 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070018050 rts_threshold);
18051 }
18052
18053 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
18054 {
18055 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
18056 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
18057 wiphy->frag_threshold;
18058
18059 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018060 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070018061 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018062 hddLog(VOS_TRACE_LEVEL_ERROR,
18063 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070018064 frag_threshold);
18065 return -EINVAL;
18066 }
18067
18068 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
18069 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018070 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018071 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018072 hddLog(VOS_TRACE_LEVEL_ERROR,
18073 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018074 __func__, frag_threshold);
18075 return -EIO;
18076 }
18077
18078 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
18079 frag_threshold);
18080 }
18081
18082 if ((changed & WIPHY_PARAM_RETRY_SHORT)
18083 || (changed & WIPHY_PARAM_RETRY_LONG))
18084 {
18085 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
18086 wiphy->retry_short :
18087 wiphy->retry_long;
18088
18089 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
18090 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
18091 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018092 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018093 __func__, retry_value);
18094 return -EINVAL;
18095 }
18096
18097 if (changed & WIPHY_PARAM_RETRY_SHORT)
18098 {
18099 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
18100 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018101 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018102 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018103 hddLog(VOS_TRACE_LEVEL_ERROR,
18104 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018105 __func__, retry_value);
18106 return -EIO;
18107 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018108 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018109 __func__, retry_value);
18110 }
18111 else if (changed & WIPHY_PARAM_RETRY_SHORT)
18112 {
18113 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
18114 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018115 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018116 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018117 hddLog(VOS_TRACE_LEVEL_ERROR,
18118 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018119 __func__, retry_value);
18120 return -EIO;
18121 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018122 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070018123 __func__, retry_value);
18124 }
18125 }
18126
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018127 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018128 return 0;
18129}
18130
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018131static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
18132 u32 changed)
18133{
18134 int ret;
18135
18136 vos_ssr_protect(__func__);
18137 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
18138 vos_ssr_unprotect(__func__);
18139
18140 return ret;
18141}
18142
Jeff Johnson295189b2012-06-20 16:38:30 -070018143/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018144 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070018145 * This function is used to set the txpower
18146 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018147static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070018148#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18149 struct wireless_dev *wdev,
18150#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018151#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018152 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070018153#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018154 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070018155#endif
18156 int dbm)
18157{
18158 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018159 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070018160 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
18161 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018162 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018163
18164 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018165
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018166 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18167 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
18168 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018169 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018170 if (0 != status)
18171 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018172 return status;
18173 }
18174
18175 hHal = pHddCtx->hHal;
18176
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018177 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
18178 dbm, ccmCfgSetCallback,
18179 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070018180 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018181 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018182 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
18183 return -EIO;
18184 }
18185
18186 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
18187 dbm);
18188
18189 switch(type)
18190 {
18191 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
18192 /* Fall through */
18193 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
18194 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
18195 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018196 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
18197 __func__);
18198 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070018199 }
18200 break;
18201 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018202 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070018203 __func__);
18204 return -EOPNOTSUPP;
18205 break;
18206 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018207 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
18208 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070018209 return -EIO;
18210 }
18211
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018212 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018213 return 0;
18214}
18215
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053018216static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
18217#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18218 struct wireless_dev *wdev,
18219#endif
18220#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
18221 enum tx_power_setting type,
18222#else
18223 enum nl80211_tx_power_setting type,
18224#endif
18225 int dbm)
18226{
18227 int ret;
18228 vos_ssr_protect(__func__);
18229 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
18230#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18231 wdev,
18232#endif
18233#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
18234 type,
18235#else
18236 type,
18237#endif
18238 dbm);
18239 vos_ssr_unprotect(__func__);
18240
18241 return ret;
18242}
18243
Jeff Johnson295189b2012-06-20 16:38:30 -070018244/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018245 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070018246 * This function is used to read the txpower
18247 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018248static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070018249#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18250 struct wireless_dev *wdev,
18251#endif
18252 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070018253{
18254
18255 hdd_adapter_t *pAdapter;
18256 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018257 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018258
Jeff Johnsone7245742012-09-05 17:12:55 -070018259 ENTER();
18260
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018261 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018262 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018263 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018264 *dbm = 0;
18265 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018266 }
18267
Jeff Johnson295189b2012-06-20 16:38:30 -070018268 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
18269 if (NULL == pAdapter)
18270 {
18271 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
18272 return -ENOENT;
18273 }
18274
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018275 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18276 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
18277 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070018278 wlan_hdd_get_classAstats(pAdapter);
18279 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
18280
Jeff Johnsone7245742012-09-05 17:12:55 -070018281 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018282 return 0;
18283}
18284
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018285static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
18286#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18287 struct wireless_dev *wdev,
18288#endif
18289 int *dbm)
18290{
18291 int ret;
18292
18293 vos_ssr_protect(__func__);
18294 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
18295#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
18296 wdev,
18297#endif
18298 dbm);
18299 vos_ssr_unprotect(__func__);
18300
18301 return ret;
18302}
18303
Dustin Brown8c1d4092017-07-28 18:08:01 +053018304/*
18305 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
18306 * @stats: summary stats to use as a source
18307 * @info: kernel station_info struct to use as a destination
18308 *
18309 * Return: None
18310 */
18311static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
18312 struct station_info *info)
18313{
18314 int i;
18315
18316 info->rx_packets = stats->rx_frm_cnt;
18317 info->tx_packets = 0;
18318 info->tx_retries = 0;
18319 info->tx_failed = 0;
18320
18321 for (i = 0; i < 4; ++i) {
18322 info->tx_packets += stats->tx_frm_cnt[i];
18323 info->tx_retries += stats->multiple_retry_cnt[i];
18324 info->tx_failed += stats->fail_cnt[i];
18325 }
18326
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018327#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18328 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018329 info->filled |= STATION_INFO_TX_PACKETS |
18330 STATION_INFO_TX_RETRIES |
18331 STATION_INFO_TX_FAILED |
18332 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018333#else
18334 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
18335 BIT(NL80211_STA_INFO_TX_RETRIES) |
18336 BIT(NL80211_STA_INFO_TX_FAILED) |
18337 BIT(NL80211_STA_INFO_RX_PACKETS);
18338#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053018339}
18340
18341/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018342 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
18343 * @adapter: sap adapter pointer
18344 * @staid: station id of the client
18345 * @rssi: rssi value to fill
18346 *
18347 * Return: None
18348 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053018349void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018350wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
18351{
18352 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
18353
18354 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
18355}
18356
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018357#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18358 !defined(WITH_BACKPORTS)
18359static inline void wlan_hdd_fill_station_info_signal(struct station_info
18360 *sinfo)
18361{
18362 sinfo->filled |= STATION_INFO_SIGNAL;
18363}
18364#else
18365static inline void wlan_hdd_fill_station_info_signal(struct station_info
18366 *sinfo)
18367{
18368 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
18369}
18370#endif
18371
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018372/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053018373 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
18374 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018375 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053018376 * @info: kernel station_info struct to populate
18377 *
18378 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
18379 * support "station dump" and "station get" for SAP vdevs, even though they
18380 * aren't technically stations.
18381 *
18382 * Return: errno
18383 */
18384static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018385wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
18386#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18387 const u8* mac,
18388#else
18389 u8* mac,
18390#endif
18391 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053018392{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018393 v_MACADDR_t *peerMacAddr;
18394 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018395 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018396 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053018397
18398 status = wlan_hdd_get_station_stats(adapter);
18399 if (!VOS_IS_STATUS_SUCCESS(status)) {
18400 hddLog(VOS_TRACE_LEVEL_ERROR,
18401 "Failed to get SAP stats; status:%d", status);
18402 return 0;
18403 }
18404
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018405 peerMacAddr = (v_MACADDR_t *)mac;
18406 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
18407 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
18408 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
18409
18410 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
18411 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018412 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018413 }
18414
Dustin Brown8c1d4092017-07-28 18:08:01 +053018415 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
18416
18417 return 0;
18418}
18419
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018420static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018421#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18422 const u8* mac,
18423#else
18424 u8* mac,
18425#endif
18426 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070018427{
18428 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
18429 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
c_hpothu44ff4e02014-05-08 00:13:57 +053018430 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018431
18432 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
18433 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070018434
18435 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
18436 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
18437 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
18438 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
18439 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
18440 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
18441 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018442 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018443 tANI_U16 myRate;
18444 tANI_U16 currentRate = 0;
18445 tANI_U8 maxSpeedMCS = 0;
18446 tANI_U8 maxMCSIdx = 0;
18447 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053018448 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070018449 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018450 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018451
Leo Chang6f8870f2013-03-26 18:11:36 -070018452#ifdef WLAN_FEATURE_11AC
18453 tANI_U32 vht_mcs_map;
18454 eDataRate11ACMaxMcs vhtMaxMcs;
18455#endif /* WLAN_FEATURE_11AC */
18456
Jeff Johnsone7245742012-09-05 17:12:55 -070018457 ENTER();
18458
Dustin Brown8c1d4092017-07-28 18:08:01 +053018459 status = wlan_hdd_validate_context(pHddCtx);
18460 if (0 != status)
18461 {
18462 return status;
18463 }
18464
18465 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053018466 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053018467
Abhinav Kumarf70293b2019-09-19 12:33:43 +053018468 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState))
Jeff Johnson295189b2012-06-20 16:38:30 -070018469 {
Abhinav Kumarf70293b2019-09-19 12:33:43 +053018470 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018471 /*To keep GUI happy*/
18472 return 0;
18473 }
18474
Mukul Sharma811205f2014-07-09 21:07:30 +053018475 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18476 {
18477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18478 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053018479 /* return a cached value */
18480 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053018481 return 0;
18482 }
18483
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053018484 wlan_hdd_get_station_stats(pAdapter);
18485 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070018486
Kiet Lam3b17fc82013-09-27 05:24:08 +053018487 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018488 wlan_hdd_get_snr(pAdapter, &snr);
18489 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018490 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018491 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018492 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018493 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053018494
c_hpothu09f19542014-05-30 21:53:31 +053018495 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053018496 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
18497 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053018498 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053018499 {
18500 rate_flags = pAdapter->maxRateFlags;
18501 }
c_hpothu44ff4e02014-05-08 00:13:57 +053018502
Jeff Johnson295189b2012-06-20 16:38:30 -070018503 //convert to the UI units of 100kbps
18504 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
18505
18506#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018507 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 -070018508 sinfo->signal,
18509 pCfg->reportMaxLinkSpeed,
18510 myRate,
18511 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018512 (int) pCfg->linkSpeedRssiMid,
18513 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018514 (int) rate_flags,
18515 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018516#endif //LINKSPEED_DEBUG_ENABLED
18517
Hanumanth Reddy Pothula596b8b32018-05-01 20:17:38 +053018518#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
18519 /* assume basic BW. anything else will override this later */
18520 sinfo->txrate.bw = RATE_INFO_BW_20;
18521#endif
18522
Jeff Johnson295189b2012-06-20 16:38:30 -070018523 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18524 {
18525 // we do not want to necessarily report the current speed
18526 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18527 {
18528 // report the max possible speed
18529 rssidx = 0;
18530 }
18531 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18532 {
18533 // report the max possible speed with RSSI scaling
18534 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18535 {
18536 // report the max possible speed
18537 rssidx = 0;
18538 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018539 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018540 {
18541 // report middle speed
18542 rssidx = 1;
18543 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018544 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18545 {
18546 // report middle speed
18547 rssidx = 2;
18548 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018549 else
18550 {
18551 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018552 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018553 }
18554 }
18555 else
18556 {
18557 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18558 hddLog(VOS_TRACE_LEVEL_ERROR,
18559 "%s: Invalid value for reportMaxLinkSpeed: %u",
18560 __func__, pCfg->reportMaxLinkSpeed);
18561 rssidx = 0;
18562 }
18563
18564 maxRate = 0;
18565
18566 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018567 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18568 OperationalRates, &ORLeng))
18569 {
18570 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18571 /*To keep GUI happy*/
18572 return 0;
18573 }
18574
Jeff Johnson295189b2012-06-20 16:38:30 -070018575 for (i = 0; i < ORLeng; i++)
18576 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018577 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018578 {
18579 /* Validate Rate Set */
18580 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18581 {
18582 currentRate = supported_data_rate[j].supported_rate[rssidx];
18583 break;
18584 }
18585 }
18586 /* Update MAX rate */
18587 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18588 }
18589
18590 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018591 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18592 ExtendedRates, &ERLeng))
18593 {
18594 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18595 /*To keep GUI happy*/
18596 return 0;
18597 }
18598
Jeff Johnson295189b2012-06-20 16:38:30 -070018599 for (i = 0; i < ERLeng; i++)
18600 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018601 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018602 {
18603 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18604 {
18605 currentRate = supported_data_rate[j].supported_rate[rssidx];
18606 break;
18607 }
18608 }
18609 /* Update MAX rate */
18610 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18611 }
c_hpothu79aab322014-07-14 21:11:01 +053018612
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018613 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018614 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018615 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018616 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018617 {
c_hpothu79aab322014-07-14 21:11:01 +053018618 if (rate_flags & eHAL_TX_RATE_VHT80)
18619 mode = 2;
18620 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18621 mode = 1;
18622 else
18623 mode = 0;
18624
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018625 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18626 MCSRates, &MCSLeng))
18627 {
18628 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18629 /*To keep GUI happy*/
18630 return 0;
18631 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018632 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018633#ifdef WLAN_FEATURE_11AC
18634 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018635 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018636 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018637 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018638 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018639 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018640 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018641 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018642 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018643 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018644 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018645 maxMCSIdx = 7;
18646 }
18647 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18648 {
18649 maxMCSIdx = 8;
18650 }
18651 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18652 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018653 //VHT20 is supporting 0~8
18654 if (rate_flags & eHAL_TX_RATE_VHT20)
18655 maxMCSIdx = 8;
18656 else
18657 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018658 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018659
c_hpothu79aab322014-07-14 21:11:01 +053018660 if (0 != rssidx)/*check for scaled */
18661 {
18662 //get middle rate MCS index if rssi=1/2
18663 for (i=0; i <= maxMCSIdx; i++)
18664 {
18665 if (sinfo->signal <= rssiMcsTbl[mode][i])
18666 {
18667 maxMCSIdx = i;
18668 break;
18669 }
18670 }
18671 }
18672
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018673 if (rate_flags & eHAL_TX_RATE_VHT80)
18674 {
18675 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18676 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18677 }
18678 else if (rate_flags & eHAL_TX_RATE_VHT40)
18679 {
18680 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18681 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18682 }
18683 else if (rate_flags & eHAL_TX_RATE_VHT20)
18684 {
18685 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18686 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18687 }
18688
Leo Chang6f8870f2013-03-26 18:11:36 -070018689 maxSpeedMCS = 1;
18690 if (currentRate > maxRate)
18691 {
18692 maxRate = currentRate;
18693 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018694
Leo Chang6f8870f2013-03-26 18:11:36 -070018695 }
18696 else
18697#endif /* WLAN_FEATURE_11AC */
18698 {
18699 if (rate_flags & eHAL_TX_RATE_HT40)
18700 {
18701 rateFlag |= 1;
18702 }
18703 if (rate_flags & eHAL_TX_RATE_SGI)
18704 {
18705 rateFlag |= 2;
18706 }
18707
Girish Gowli01abcee2014-07-31 20:18:55 +053018708 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018709 if (rssidx == 1 || rssidx == 2)
18710 {
18711 //get middle rate MCS index if rssi=1/2
18712 for (i=0; i <= 7; i++)
18713 {
18714 if (sinfo->signal <= rssiMcsTbl[mode][i])
18715 {
18716 temp = i+1;
18717 break;
18718 }
18719 }
18720 }
c_hpothu79aab322014-07-14 21:11:01 +053018721
18722 for (i = 0; i < MCSLeng; i++)
18723 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018724 for (j = 0; j < temp; j++)
18725 {
18726 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18727 {
18728 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018729 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018730 break;
18731 }
18732 }
18733 if ((j < temp) && (currentRate > maxRate))
18734 {
18735 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018736 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018737 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018738 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018739 }
18740 }
18741
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018742 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18743 {
18744 maxRate = myRate;
18745 maxSpeedMCS = 1;
18746 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18747 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018748 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018749 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018750 {
18751 maxRate = myRate;
18752 if (rate_flags & eHAL_TX_RATE_LEGACY)
18753 {
18754 maxSpeedMCS = 0;
18755 }
18756 else
18757 {
18758 maxSpeedMCS = 1;
18759 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18760 }
18761 }
18762
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018763 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018764 {
18765 sinfo->txrate.legacy = maxRate;
18766#ifdef LINKSPEED_DEBUG_ENABLED
18767 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18768#endif //LINKSPEED_DEBUG_ENABLED
18769 }
18770 else
18771 {
18772 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018773#ifdef WLAN_FEATURE_11AC
18774 sinfo->txrate.nss = 1;
18775 if (rate_flags & eHAL_TX_RATE_VHT80)
18776 {
18777 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018778#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18779 defined(WITH_BACKPORTS)
18780 sinfo->txrate.bw = RATE_INFO_BW_80;
18781#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018782 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018783#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018784 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018785 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018786 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018787 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018788#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18789 defined(WITH_BACKPORTS)
18790 sinfo->txrate.bw = RATE_INFO_BW_40;
18791#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018792 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018793#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018794 }
18795 else if (rate_flags & eHAL_TX_RATE_VHT20)
18796 {
18797 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18798 }
18799#endif /* WLAN_FEATURE_11AC */
18800 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18801 {
18802 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18803 if (rate_flags & eHAL_TX_RATE_HT40)
18804 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018805#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18806 defined(WITH_BACKPORTS)
18807 sinfo->txrate.bw = RATE_INFO_BW_40;
18808#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018809 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018810#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018811 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018812 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018813 if (rate_flags & eHAL_TX_RATE_SGI)
18814 {
18815 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18816 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018817
Jeff Johnson295189b2012-06-20 16:38:30 -070018818#ifdef LINKSPEED_DEBUG_ENABLED
18819 pr_info("Reporting MCS rate %d flags %x\n",
18820 sinfo->txrate.mcs,
18821 sinfo->txrate.flags );
18822#endif //LINKSPEED_DEBUG_ENABLED
18823 }
18824 }
18825 else
18826 {
18827 // report current rate instead of max rate
18828
18829 if (rate_flags & eHAL_TX_RATE_LEGACY)
18830 {
18831 //provide to the UI in units of 100kbps
18832 sinfo->txrate.legacy = myRate;
18833#ifdef LINKSPEED_DEBUG_ENABLED
18834 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18835#endif //LINKSPEED_DEBUG_ENABLED
18836 }
18837 else
18838 {
18839 //must be MCS
18840 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018841#ifdef WLAN_FEATURE_11AC
18842 sinfo->txrate.nss = 1;
18843 if (rate_flags & eHAL_TX_RATE_VHT80)
18844 {
18845 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18846 }
18847 else
18848#endif /* WLAN_FEATURE_11AC */
18849 {
18850 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18851 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018852 if (rate_flags & eHAL_TX_RATE_SGI)
18853 {
18854 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18855 }
18856 if (rate_flags & eHAL_TX_RATE_HT40)
18857 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018858#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18859 defined(WITH_BACKPORTS)
18860 sinfo->txrate.bw = RATE_INFO_BW_40;
18861#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018862 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018863#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018864 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018865#ifdef WLAN_FEATURE_11AC
18866 else if (rate_flags & eHAL_TX_RATE_VHT80)
18867 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018868#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18869 defined(WITH_BACKPORTS)
18870 sinfo->txrate.bw = RATE_INFO_BW_80;
18871#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018872 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018873#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018874 }
18875#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018876#ifdef LINKSPEED_DEBUG_ENABLED
18877 pr_info("Reporting actual MCS rate %d flags %x\n",
18878 sinfo->txrate.mcs,
18879 sinfo->txrate.flags );
18880#endif //LINKSPEED_DEBUG_ENABLED
18881 }
18882 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018883
18884#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18885 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018886 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018887#else
18888 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18889#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018890
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018891 sinfo->tx_packets =
18892 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18893 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18894 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18895 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18896
18897 sinfo->tx_retries =
18898 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18899 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18900 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18901 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18902
18903 sinfo->tx_failed =
18904 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18905 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18906 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18907 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18908
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018909#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18910 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018911 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018912 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018913 STATION_INFO_TX_PACKETS |
18914 STATION_INFO_TX_RETRIES |
18915 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018916#else
18917 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18918 BIT(NL80211_STA_INFO_TX_PACKETS) |
18919 BIT(NL80211_STA_INFO_TX_RETRIES) |
18920 BIT(NL80211_STA_INFO_TX_FAILED);
18921#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018922
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018923 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018924
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018925 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18926 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018927 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18928 &sinfo->txrate, sizeof(sinfo->txrate));
18929
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018930 if (rate_flags & eHAL_TX_RATE_LEGACY)
18931 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18932 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18933 sinfo->rx_packets);
18934 else
18935 hddLog(LOG1,
18936 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18937 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18938 sinfo->tx_packets, sinfo->rx_packets);
18939
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018940 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18941 TRACE_CODE_HDD_CFG80211_GET_STA,
18942 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018943 EXIT();
18944 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018945}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018946#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18947static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18948 const u8* mac, struct station_info *sinfo)
18949#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018950static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18951 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018952#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018953{
18954 int ret;
18955
18956 vos_ssr_protect(__func__);
18957 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18958 vos_ssr_unprotect(__func__);
18959
18960 return ret;
18961}
18962
18963static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018964 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018965{
18966 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018967 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018968 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018969 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018970
Jeff Johnsone7245742012-09-05 17:12:55 -070018971 ENTER();
18972
Jeff Johnson295189b2012-06-20 16:38:30 -070018973 if (NULL == pAdapter)
18974 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018975 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018976 return -ENODEV;
18977 }
18978
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018979 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18980 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18981 pAdapter->sessionId, timeout));
18982
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018983 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018984 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018985 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018986 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018987 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018988 }
18989
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018990 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18991 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18992 (pHddCtx->cfg_ini->fhostArpOffload) &&
18993 (eConnectionState_Associated ==
18994 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18995 {
Amar Singhald53568e2013-09-26 11:03:45 -070018996
18997 hddLog(VOS_TRACE_LEVEL_INFO,
18998 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018999 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053019000 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19001 {
19002 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080019003 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053019004 __func__, vos_status);
19005 }
19006 }
19007
Jeff Johnson295189b2012-06-20 16:38:30 -070019008 /**The get power cmd from the supplicant gets updated by the nl only
19009 *on successful execution of the function call
19010 *we are oppositely mapped w.r.t mode in the driver
19011 **/
19012 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
19013
19014 if (VOS_STATUS_E_FAILURE == vos_status)
19015 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053019016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19017 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070019018 return -EINVAL;
19019 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019020 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070019021 return 0;
19022}
19023
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019024static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
19025 struct net_device *dev, bool mode, int timeout)
19026{
19027 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070019028
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019029 vos_ssr_protect(__func__);
19030 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
19031 vos_ssr_unprotect(__func__);
19032
19033 return ret;
19034}
Sushant Kaushik084f6592015-09-10 13:11:56 +053019035
Jeff Johnson295189b2012-06-20 16:38:30 -070019036#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019037static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
19038 struct net_device *netdev,
19039 u8 key_index)
19040{
19041 ENTER();
19042 return 0;
19043}
19044
Jeff Johnson295189b2012-06-20 16:38:30 -070019045static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019046 struct net_device *netdev,
19047 u8 key_index)
19048{
19049 int ret;
19050 vos_ssr_protect(__func__);
19051 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
19052 vos_ssr_unprotect(__func__);
19053 return ret;
19054}
19055#endif //LINUX_VERSION_CODE
19056
19057#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
19058static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
19059 struct net_device *dev,
19060 struct ieee80211_txq_params *params)
19061{
19062 ENTER();
19063 return 0;
19064}
19065#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19066static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
19067 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070019068{
Jeff Johnsone7245742012-09-05 17:12:55 -070019069 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070019070 return 0;
19071}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019072#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070019073
19074#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
19075static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019076 struct net_device *dev,
19077 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070019078{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019079 int ret;
19080
19081 vos_ssr_protect(__func__);
19082 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
19083 vos_ssr_unprotect(__func__);
19084 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070019085}
19086#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19087static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
19088 struct ieee80211_txq_params *params)
19089{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019090 int ret;
19091
19092 vos_ssr_protect(__func__);
19093 ret = __wlan_hdd_set_txq_params(wiphy, params);
19094 vos_ssr_unprotect(__func__);
19095 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070019096}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019097#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019098
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019099static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019100 struct net_device *dev,
19101 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070019102{
19103 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019104 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019105 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019106 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019107 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019108 v_CONTEXT_t pVosContext = NULL;
19109 ptSapContext pSapCtx = NULL;
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019110 hdd_hostapd_state_t *hostap_state;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019111
Jeff Johnsone7245742012-09-05 17:12:55 -070019112 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019113
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019114 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070019115 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070019117 return -EINVAL;
19118 }
19119
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019120 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19121 TRACE_CODE_HDD_CFG80211_DEL_STA,
19122 pAdapter->sessionId, pAdapter->device_mode));
19123
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019124 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19125 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019126 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019127 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019128 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019129 }
19130
Jeff Johnson295189b2012-06-20 16:38:30 -070019131 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070019132 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070019133 )
19134 {
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019135 hostap_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019136 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
19137 pSapCtx = VOS_GET_SAP_CB(pVosContext);
19138 if(pSapCtx == NULL){
19139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19140 FL("psapCtx is NULL"));
19141 return -ENOENT;
19142 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053019143 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
19144 {
19145 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
19146 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
19147 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
19148 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019149 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070019150 {
19151 v_U16_t i;
19152 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
19153 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019154 if ((pSapCtx->aStaInfo[i].isUsed) &&
19155 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070019156 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019157 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019158 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019159 ETHER_ADDR_LEN);
19160
Jeff Johnson295189b2012-06-20 16:38:30 -070019161 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080019162 "%s: Delete STA with MAC::"
19163 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019164 __func__,
19165 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019166 vos_event_reset(&hostap_state->sta_discon_event);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019167 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070019168 if (VOS_IS_STATUS_SUCCESS(vos_status))
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019169 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019170 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019171 vos_status =
19172 vos_wait_single_event(
19173 &hostap_state->sta_discon_event,
19174 WLAN_WAIT_TIME_DISCONNECT);
19175 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19176 hddLog(LOGE,"!!%s: ERROR: Deauth wait expired!!",
19177 __func__);
19178 }
Jeff Johnson295189b2012-06-20 16:38:30 -070019179 }
19180 }
19181 }
19182 else
19183 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019184
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019185 vos_status = hdd_softap_GetStaId(pAdapter,
19186 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019187 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19188 {
19189 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080019190 "%s: Skip this DEL STA as this is not used::"
19191 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019192 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019193 return -ENOENT;
19194 }
19195
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019196 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019197 {
19198 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080019199 "%s: Skip this DEL STA as deauth is in progress::"
19200 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019201 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019202 return -ENOENT;
19203 }
19204
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019205 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019206
Jeff Johnson295189b2012-06-20 16:38:30 -070019207 hddLog(VOS_TRACE_LEVEL_INFO,
19208 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080019209 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070019210 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019211 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019212
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019213 vos_event_reset(&hostap_state->sta_discon_event);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019214 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019215 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19216 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053019217 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019218 hddLog(VOS_TRACE_LEVEL_INFO,
19219 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080019220 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019221 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019222 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080019223 return -ENOENT;
19224 }
Abhishek Singh1a9dbcf2019-09-06 12:50:03 +053019225 vos_status =
19226 vos_wait_single_event(&hostap_state->sta_discon_event,
19227 WLAN_WAIT_TIME_DISCONNECT);
19228 if (!VOS_IS_STATUS_SUCCESS(vos_status))
19229 hddLog(LOGE,"!!%s: ERROR: Deauth wait expired!!", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070019230 }
19231 }
19232
19233 EXIT();
19234
19235 return 0;
19236}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019237
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019238#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053019239int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019240 struct net_device *dev,
19241 struct station_del_parameters *param)
19242#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019243#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053019244int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019245 struct net_device *dev, const u8 *mac)
19246#else
Kapil Gupta137ef892016-12-13 19:38:00 +053019247int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019248 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019249#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019250#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019251{
19252 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019253 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070019254
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019255 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019256
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019257#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019258 if (NULL == param) {
19259 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053019260 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019261 return -EINVAL;
19262 }
19263
19264 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
19265 param->subtype, &delStaParams);
19266
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019267#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053019268 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019269 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053019270#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053019271 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
19272
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019273 vos_ssr_unprotect(__func__);
19274
19275 return ret;
19276}
19277
19278static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019279 struct net_device *dev,
19280#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
19281 const u8 *mac,
19282#else
19283 u8 *mac,
19284#endif
19285 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019286{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019287 hdd_adapter_t *pAdapter;
19288 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019289 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019290#ifdef FEATURE_WLAN_TDLS
19291 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019292
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019293 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019294
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019295 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19296 if (NULL == pAdapter)
19297 {
19298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19299 "%s: Adapter is NULL",__func__);
19300 return -EINVAL;
19301 }
19302 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19303 status = wlan_hdd_validate_context(pHddCtx);
19304 if (0 != status)
19305 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019306 return status;
19307 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019308
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019309 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19310 TRACE_CODE_HDD_CFG80211_ADD_STA,
19311 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019312 mask = params->sta_flags_mask;
19313
19314 set = params->sta_flags_set;
19315
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019317 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
19318 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019319
19320 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19321 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080019322 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019323 }
19324 }
19325#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019326 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019327 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070019328}
19329
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
19331static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19332 struct net_device *dev, const u8 *mac,
19333 struct station_parameters *params)
19334#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019335static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19336 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053019337#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019338{
19339 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019340
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019341 vos_ssr_protect(__func__);
19342 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
19343 vos_ssr_unprotect(__func__);
19344
19345 return ret;
19346}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019347#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070019348
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019349static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070019350 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019351{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019352 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19353 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019354 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019355 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019356 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019357 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070019358
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019359 ENTER();
19360
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019361 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019362 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019363 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019364 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019365 return -EINVAL;
19366 }
19367
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019368 if (!pmksa) {
19369 hddLog(LOGE, FL("pmksa is NULL"));
19370 return -EINVAL;
19371 }
19372
19373 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070019374 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019375 pmksa->bssid, pmksa->pmkid);
19376 return -EINVAL;
19377 }
19378
19379 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
19380 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19381
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019382 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19383 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019384 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019385 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053019386 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019387 }
19388
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019389 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019390 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19391
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019392 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
19393 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019394
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019395 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019396 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019397 &pmk_id, 1, FALSE);
19398
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019399 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19400 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
19401 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019403 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019404 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019405}
19406
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019407static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
19408 struct cfg80211_pmksa *pmksa)
19409{
19410 int ret;
19411
19412 vos_ssr_protect(__func__);
19413 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
19414 vos_ssr_unprotect(__func__);
19415
19416 return ret;
19417}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019418
Wilson Yang6507c4e2013-10-01 20:11:19 -070019419
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019420static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070019421 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019422{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019423 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19424 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019425 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019426 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019427
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019428 ENTER();
19429
Wilson Yang6507c4e2013-10-01 20:11:19 -070019430 /* Validate pAdapter */
19431 if (NULL == pAdapter)
19432 {
19433 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
19434 return -EINVAL;
19435 }
19436
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019437 if (!pmksa) {
19438 hddLog(LOGE, FL("pmksa is NULL"));
19439 return -EINVAL;
19440 }
19441
19442 if (!pmksa->bssid) {
19443 hddLog(LOGE, FL("pmksa->bssid is NULL"));
19444 return -EINVAL;
19445 }
19446
Kiet Lam98c46a12014-10-31 15:34:57 -070019447 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
19448 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
19449
Wilson Yang6507c4e2013-10-01 20:11:19 -070019450 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19451 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019452 if (0 != status)
19453 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019454 return status;
19455 }
19456
19457 /*Retrieve halHandle*/
19458 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19459
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019460 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19461 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
19462 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019463 /* Delete the PMKID CSR cache */
19464 if (eHAL_STATUS_SUCCESS !=
19465 sme_RoamDelPMKIDfromCache(halHandle,
19466 pAdapter->sessionId, pmksa->bssid, FALSE)) {
19467 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
19468 MAC_ADDR_ARRAY(pmksa->bssid));
19469 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019470 }
19471
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019472 EXIT();
19473 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019474}
19475
Wilson Yang6507c4e2013-10-01 20:11:19 -070019476
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019477static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
19478 struct cfg80211_pmksa *pmksa)
19479{
19480 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019481
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019482 vos_ssr_protect(__func__);
19483 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
19484 vos_ssr_unprotect(__func__);
19485
19486 return ret;
19487
19488}
19489
19490static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019491{
Wilson Yang6507c4e2013-10-01 20:11:19 -070019492 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19493 tHalHandle halHandle;
19494 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080019495 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019497 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070019498
19499 /* Validate pAdapter */
19500 if (NULL == pAdapter)
19501 {
19502 hddLog(VOS_TRACE_LEVEL_ERROR,
19503 "%s: Invalid Adapter" ,__func__);
19504 return -EINVAL;
19505 }
19506
19507 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19508 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070019509 if (0 != status)
19510 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070019511 return status;
19512 }
19513
19514 /*Retrieve halHandle*/
19515 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
19516
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053019517 /* Flush the PMKID cache in CSR */
19518 if (eHAL_STATUS_SUCCESS !=
19519 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
19520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
19521 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070019522 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019523 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080019524 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019525}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053019526
19527static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
19528{
19529 int ret;
19530
19531 vos_ssr_protect(__func__);
19532 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19533 vos_ssr_unprotect(__func__);
19534
19535 return ret;
19536}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019537#endif
19538
Abhinav Kumar118efd02019-08-07 16:41:07 +053019539#if defined(WLAN_FEATURE_SAE) && \
19540 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
19541/**
19542 * __wlan_hdd_cfg80211_external_auth() - Handle external auth
19543 * @wiphy: Pointer to wireless phy
19544 * @dev: net device
19545 * @params: Pointer to external auth params
19546 *
19547 * Return: 0 on success, negative errno on failure
19548 */
19549static int
19550__wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy, struct net_device *dev,
19551 struct cfg80211_external_auth_params *params)
19552{
19553 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
19554 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
19555 int ret;
19556
19557 if (hdd_get_conparam() == VOS_FTM_MODE) {
19558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Command not allowed in FTM mode"));
19559 return -EPERM;
19560 }
19561
19562 ret = wlan_hdd_validate_context(hdd_ctx);
19563 if (ret)
19564 return ret;
19565
19566 hddLog(VOS_TRACE_LEVEL_DEBUG, FL("external_auth status: %d"),
19567 params->status);
19568
19569 sme_handle_sae_msg(hdd_ctx->hHal, adapter->sessionId, params->status);
19570
19571 return ret;
19572}
19573
19574/**
19575 * wlan_hdd_cfg80211_external_auth() - Handle external auth
19576 * @wiphy: Pointer to wireless phy
19577 * @dev: net device
19578 * @params: Pointer to external auth params
19579 *
19580 * Return: 0 on success, negative errno on failure
19581 */
19582static int
19583wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
19584 struct net_device *dev,
19585 struct cfg80211_external_auth_params *params)
19586{
19587 int ret;
19588
19589 vos_ssr_protect(__func__);
19590 ret = __wlan_hdd_cfg80211_external_auth(wiphy, dev, params);
19591 vos_ssr_unprotect(__func__);
19592
19593 return ret;
19594}
19595#endif
19596
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019597#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019598static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19599 struct net_device *dev,
19600 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019601{
19602 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19603 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019604 hdd_context_t *pHddCtx;
19605 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019606
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019607 ENTER();
19608
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019609 if (NULL == pAdapter)
19610 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019611 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019612 return -ENODEV;
19613 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019614 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19615 ret = wlan_hdd_validate_context(pHddCtx);
19616 if (0 != ret)
19617 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019618 return ret;
19619 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019620 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019621 if (NULL == pHddStaCtx)
19622 {
19623 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19624 return -EINVAL;
19625 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019626
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019627 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19628 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19629 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019630 // Added for debug on reception of Re-assoc Req.
19631 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19632 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019633 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019634 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019635 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019636 }
19637
19638#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Abhinav Kumar36177e12018-10-30 11:55:48 +053019639 hddLog(LOG1, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019640 ftie->ie_len);
19641#endif
19642
19643 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019644 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19645 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019646 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019647
19648 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019649 return 0;
19650}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019651
19652static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19653 struct net_device *dev,
19654 struct cfg80211_update_ft_ies_params *ftie)
19655{
19656 int ret;
19657
19658 vos_ssr_protect(__func__);
19659 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19660 vos_ssr_unprotect(__func__);
19661
19662 return ret;
19663}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019664#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019665
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019666#ifdef FEATURE_WLAN_SCAN_PNO
19667
19668void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19669 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19670{
19671 int ret;
19672 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19673 hdd_context_t *pHddCtx;
19674
Nirav Shah80830bf2013-12-31 16:35:12 +053019675 ENTER();
19676
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019677 if (NULL == pAdapter)
19678 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019679 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019680 "%s: HDD adapter is Null", __func__);
19681 return ;
19682 }
19683
19684 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19685 if (NULL == pHddCtx)
19686 {
19687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19688 "%s: HDD context is Null!!!", __func__);
19689 return ;
19690 }
19691
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019692 spin_lock(&pHddCtx->schedScan_lock);
19693 if (TRUE == pHddCtx->isWiphySuspended)
19694 {
19695 pHddCtx->isSchedScanUpdatePending = TRUE;
19696 spin_unlock(&pHddCtx->schedScan_lock);
19697 hddLog(VOS_TRACE_LEVEL_INFO,
19698 "%s: Update cfg80211 scan database after it resume", __func__);
19699 return ;
19700 }
19701 spin_unlock(&pHddCtx->schedScan_lock);
19702
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019703 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19704
19705 if (0 > ret)
19706 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019707 else
19708 {
19709 /* Acquire wakelock to handle the case where APP's tries to suspend
19710 * immediatly after the driver gets connect request(i.e after pno)
19711 * from supplicant, this result in app's is suspending and not able
19712 * to process the connect request to AP */
19713 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19714 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019715 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19717 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019718}
19719
19720/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019721 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019722 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019723 */
19724static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19725{
19726 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19727 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019728 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019729 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19730 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019731
19732 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19733 {
19734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19735 "%s: PNO is allowed only in STA interface", __func__);
19736 return eHAL_STATUS_FAILURE;
19737 }
19738
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019739 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19740
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019741 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019742 * active sessions. PNO is allowed only in case when sap session
19743 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019744 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019745 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19746 {
19747 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019748 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019749
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019750 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19751 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19752 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19753 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019754 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19755 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019756 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019757 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019758 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019759 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019760 }
19761 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19762 pAdapterNode = pNext;
19763 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019764 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019765}
19766
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019767void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19768{
19769 hdd_adapter_t *pAdapter = callbackContext;
19770 hdd_context_t *pHddCtx;
19771
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019772 ENTER();
19773
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019774 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19775 {
19776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19777 FL("Invalid adapter or adapter has invalid magic"));
19778 return;
19779 }
19780
19781 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19782 if (0 != wlan_hdd_validate_context(pHddCtx))
19783 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019784 return;
19785 }
19786
c_hpothub53c45d2014-08-18 16:53:14 +053019787 if (VOS_STATUS_SUCCESS != status)
19788 {
19789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019790 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019791 pHddCtx->isPnoEnable = FALSE;
19792 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019793
19794 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19795 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019796 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019797}
19798
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019799#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19800 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19801/**
19802 * hdd_config_sched_scan_plan() - configures the sched scan plans
19803 * from the framework.
19804 * @pno_req: pointer to PNO scan request
19805 * @request: pointer to scan request from framework
19806 *
19807 * Return: None
19808 */
19809static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19810 struct cfg80211_sched_scan_request *request,
19811 hdd_context_t *hdd_ctx)
19812{
19813 v_U32_t i = 0;
19814
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019815 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019816 for (i = 0; i < request->n_scan_plans; i++)
19817 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019818 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19819 request->scan_plans[i].iterations;
19820 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19821 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019822 }
19823}
19824#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019825static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019826 struct cfg80211_sched_scan_request *request,
19827 hdd_context_t *hdd_ctx)
19828{
19829 v_U32_t i, temp_int;
19830 /* Driver gets only one time interval which is hardcoded in
19831 * supplicant for 10000ms. Taking power consumption into account 6
19832 * timers will be used, Timervalue is increased exponentially
19833 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19834 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19835 * If it is set to 0 only one timer will be used and PNO scan cycle
19836 * will be repeated after each interval specified by supplicant
19837 * till PNO is disabled.
19838 */
19839 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019840 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019841 HDD_PNO_SCAN_TIMERS_SET_ONE;
19842 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019843 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019844 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19845
19846 temp_int = (request->interval)/1000;
19847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19848 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19849 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019850 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019851 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019852 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019853 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019854 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019855 temp_int *= 2;
19856 }
19857 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019858 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019859}
19860#endif
19861
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019862/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019863 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19864 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019865 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019866static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019867 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19868{
19869 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019870 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019871 hdd_context_t *pHddCtx;
19872 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019873 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019874 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19875 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019876 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19877 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019878 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019879 hdd_config_t *pConfig = NULL;
19880 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019881
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019882 ENTER();
19883
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019884 if (NULL == pAdapter)
19885 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019887 "%s: HDD adapter is Null", __func__);
19888 return -ENODEV;
19889 }
19890
19891 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019892 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019893
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019894 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019895 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019896 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019897 }
19898
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019899 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019900 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19901 if (NULL == hHal)
19902 {
19903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19904 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019905 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019906 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019907 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19908 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19909 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019910 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019911 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019912 {
19913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19914 "%s: aborting the existing scan is unsuccessfull", __func__);
19915 return -EBUSY;
19916 }
19917
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019918 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019919 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019921 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019922 return -EBUSY;
19923 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019924
c_hpothu37f21312014-04-09 21:49:54 +053019925 if (TRUE == pHddCtx->isPnoEnable)
19926 {
19927 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19928 FL("already PNO is enabled"));
19929 return -EBUSY;
19930 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019931
19932 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19933 {
19934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19935 "%s: abort ROC failed ", __func__);
19936 return -EBUSY;
19937 }
19938
c_hpothu37f21312014-04-09 21:49:54 +053019939 pHddCtx->isPnoEnable = TRUE;
19940
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019941 pnoRequest.enable = 1; /*Enable PNO */
19942 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019943
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019944 if (( !pnoRequest.ucNetworksCount ) ||
19945 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019946 {
19947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019948 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019949 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019950 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019951 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019952 goto error;
19953 }
19954
19955 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19956 {
19957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019958 "%s: Incorrect number of channels %d",
19959 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019960 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019961 goto error;
19962 }
19963
19964 /* Framework provides one set of channels(all)
19965 * common for all saved profile */
19966 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19967 channels_allowed, &num_channels_allowed))
19968 {
19969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19970 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019971 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019972 goto error;
19973 }
19974 /* Checking each channel against allowed channel list */
19975 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019976 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019977 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019978 char chList [(request->n_channels*5)+1];
19979 int len;
19980 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019981 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019982 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019983 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019984 if (request->channels[i]->hw_value == channels_allowed[indx])
19985 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019986 if ((!pConfig->enableDFSPnoChnlScan) &&
19987 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19988 {
19989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19990 "%s : Dropping DFS channel : %d",
19991 __func__,channels_allowed[indx]);
19992 num_ignore_dfs_ch++;
19993 break;
19994 }
19995
Nirav Shah80830bf2013-12-31 16:35:12 +053019996 valid_ch[num_ch++] = request->channels[i]->hw_value;
19997 len += snprintf(chList+len, 5, "%d ",
19998 request->channels[i]->hw_value);
19999 break ;
20000 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020001 }
20002 }
Nirav Shah80830bf2013-12-31 16:35:12 +053020003 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020004
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053020005 /*If all channels are DFS and dropped, then ignore the PNO request*/
20006 if (num_ignore_dfs_ch == request->n_channels)
20007 {
20008 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20009 "%s : All requested channels are DFS channels", __func__);
20010 ret = -EINVAL;
20011 goto error;
20012 }
20013 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020014
20015 pnoRequest.aNetworks =
20016 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
20017 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020018 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020019 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
20020 FL("failed to allocate memory aNetworks %u"),
20021 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
20022 goto error;
20023 }
20024 vos_mem_zero(pnoRequest.aNetworks,
20025 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
20026
20027 /* Filling per profile params */
20028 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
20029 {
20030 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020031 request->match_sets[i].ssid.ssid_len;
20032
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020033 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
20034 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020035 {
20036 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053020037 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020038 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020039 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020040 goto error;
20041 }
20042
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020043 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020044 request->match_sets[i].ssid.ssid,
20045 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053020046 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20047 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020048 i, pnoRequest.aNetworks[i].ssId.ssId);
20049 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
20050 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
20051 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020052
20053 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020054 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
20055 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020056
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020057 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020058 }
20059
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020060 for (i = 0; i < request->n_ssids; i++)
20061 {
20062 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020063 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020064 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020065 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020066 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020067 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020068 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020069 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020070 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020071 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053020072 break;
20073 }
20074 j++;
20075 }
20076 }
20077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20078 "Number of hidden networks being Configured = %d",
20079 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053020080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080020081 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020082
20083 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
20084 if (pnoRequest.p24GProbeTemplate == NULL)
20085 {
20086 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
20087 FL("failed to allocate memory p24GProbeTemplate %u"),
20088 SIR_PNO_MAX_PB_REQ_SIZE);
20089 goto error;
20090 }
20091
20092 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
20093 if (pnoRequest.p5GProbeTemplate == NULL)
20094 {
20095 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
20096 FL("failed to allocate memory p5GProbeTemplate %u"),
20097 SIR_PNO_MAX_PB_REQ_SIZE);
20098 goto error;
20099 }
20100
20101 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
20102 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
20103
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053020104 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
20105 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053020106 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020107 pnoRequest.us24GProbeTemplateLen = request->ie_len;
20108 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
20109 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053020110
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020111 pnoRequest.us5GProbeTemplateLen = request->ie_len;
20112 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
20113 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053020114 }
20115
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053020116 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053020117
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020118 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020119
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020120 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020121 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
20122 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020123 pAdapter->pno_req_status = 0;
20124
Nirav Shah80830bf2013-12-31 16:35:12 +053020125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20126 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020127 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
20128 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053020129
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020130 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020131 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020132 hdd_cfg80211_sched_scan_done_callback, pAdapter);
20133 if (eHAL_STATUS_SUCCESS != status)
20134 {
20135 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053020136 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020137 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020138 goto error;
20139 }
20140
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020141 ret = wait_for_completion_timeout(
20142 &pAdapter->pno_comp_var,
20143 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
20144 if (0 >= ret)
20145 {
20146 // Did not receive the response for PNO enable in time.
20147 // Assuming the PNO enable was success.
20148 // Returning error from here, because we timeout, results
20149 // in side effect of Wifi (Wifi Setting) not to work.
20150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20151 FL("Timed out waiting for PNO to be Enabled"));
20152 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020153 }
20154
20155 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053020156 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020157
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020158error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20160 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053020161 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020162 if (pnoRequest.aNetworks)
20163 vos_mem_free(pnoRequest.aNetworks);
20164 if (pnoRequest.p24GProbeTemplate)
20165 vos_mem_free(pnoRequest.p24GProbeTemplate);
20166 if (pnoRequest.p5GProbeTemplate)
20167 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020168
20169 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020170 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020171}
20172
20173/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020174 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
20175 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020176 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020177static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
20178 struct net_device *dev, struct cfg80211_sched_scan_request *request)
20179{
20180 int ret;
20181
20182 vos_ssr_protect(__func__);
20183 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
20184 vos_ssr_unprotect(__func__);
20185
20186 return ret;
20187}
20188
20189/*
20190 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
20191 * Function to disable PNO
20192 */
20193static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020194 struct net_device *dev)
20195{
20196 eHalStatus status = eHAL_STATUS_FAILURE;
20197 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20198 hdd_context_t *pHddCtx;
20199 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020200 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020201 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020202
20203 ENTER();
20204
20205 if (NULL == pAdapter)
20206 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020208 "%s: HDD adapter is Null", __func__);
20209 return -ENODEV;
20210 }
20211
20212 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020213
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020214 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020215 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053020216 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020217 "%s: HDD context is Null", __func__);
20218 return -ENODEV;
20219 }
20220
20221 /* The return 0 is intentional when isLogpInProgress and
20222 * isLoadUnloadInProgress. We did observe a crash due to a return of
20223 * failure in sched_scan_stop , especially for a case where the unload
20224 * of the happens at the same time. The function __cfg80211_stop_sched_scan
20225 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
20226 * success. If it returns a failure , then its next invocation due to the
20227 * clean up of the second interface will have the dev pointer corresponding
20228 * to the first one leading to a crash.
20229 */
20230 if (pHddCtx->isLogpInProgress)
20231 {
20232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20233 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053020234 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020235 return ret;
20236 }
20237
Mihir Shete18156292014-03-11 15:38:30 +053020238 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020239 {
20240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20241 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20242 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020243 }
20244
20245 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
20246 if (NULL == hHal)
20247 {
20248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20249 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020250 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020251 }
20252
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020253 pnoRequest.enable = 0; /* Disable PNO */
20254 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020255
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053020256 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20257 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
20258 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053020259
20260 INIT_COMPLETION(pAdapter->pno_comp_var);
20261 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
20262 pnoRequest.callbackContext = pAdapter;
20263 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053020264 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020265 pAdapter->sessionId,
20266 NULL, pAdapter);
20267 if (eHAL_STATUS_SUCCESS != status)
20268 {
20269 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20270 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020271 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020272 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020273 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053020274 ret = wait_for_completion_timeout(
20275 &pAdapter->pno_comp_var,
20276 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
20277 if (0 >= ret)
20278 {
20279 // Did not receive the response for PNO disable in time.
20280 // Assuming the PNO disable was success.
20281 // Returning error from here, because we timeout, results
20282 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053020283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053020284 FL("Timed out waiting for PNO to be disabled"));
20285 ret = 0;
20286 }
20287
20288 ret = pAdapter->pno_req_status;
20289 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020290
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020291error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053020292 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053020293 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020294
20295 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053020296 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020297}
20298
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053020299/*
20300 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
20301 * NL interface to disable PNO
20302 */
20303static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
20304 struct net_device *dev)
20305{
20306 int ret;
20307
20308 vos_ssr_protect(__func__);
20309 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
20310 vos_ssr_unprotect(__func__);
20311
20312 return ret;
20313}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053020314#endif /*FEATURE_WLAN_SCAN_PNO*/
20315
20316
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020317#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020318#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020319static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20320 struct net_device *dev,
20321 u8 *peer, u8 action_code,
20322 u8 dialog_token,
20323 u16 status_code, u32 peer_capability,
20324 const u8 *buf, size_t len)
20325#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020326#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20327 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020328static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20329 struct net_device *dev,
20330 const u8 *peer, u8 action_code,
20331 u8 dialog_token, u16 status_code,
20332 u32 peer_capability, bool initiator,
20333 const u8 *buf, size_t len)
20334#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20335static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20336 struct net_device *dev,
20337 const u8 *peer, u8 action_code,
20338 u8 dialog_token, u16 status_code,
20339 u32 peer_capability, const u8 *buf,
20340 size_t len)
20341#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20342static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20343 struct net_device *dev,
20344 u8 *peer, u8 action_code,
20345 u8 dialog_token,
20346 u16 status_code, u32 peer_capability,
20347 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020348#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020349static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20350 struct net_device *dev,
20351 u8 *peer, u8 action_code,
20352 u8 dialog_token,
20353 u16 status_code, const u8 *buf,
20354 size_t len)
20355#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020356#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020357{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020358 hdd_adapter_t *pAdapter;
20359 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020360 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070020361 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080020362 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070020363 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020364 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020365 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020366#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020367 u32 peer_capability = 0;
20368#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020369 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020370 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020371 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020372
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020373 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20374 if (NULL == pAdapter)
20375 {
20376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20377 "%s: Adapter is NULL",__func__);
20378 return -EINVAL;
20379 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020380 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20381 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
20382 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020383
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020384 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020385 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020386 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053020387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020388 "Invalid arguments");
20389 return -EINVAL;
20390 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020391
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020392 if (pHddCtx->isLogpInProgress)
20393 {
20394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20395 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053020396 wlan_hdd_tdls_set_link_status(pAdapter,
20397 peer,
20398 eTDLS_LINK_IDLE,
20399 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020400 return -EBUSY;
20401 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020402
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053020403 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
20404 {
20405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20406 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
20407 return -EAGAIN;
20408 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020409
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020410 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
20411 if (!pHddTdlsCtx) {
20412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20413 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053020414 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020415 }
20416
Hoonki Lee27511902013-03-14 18:19:06 -070020417 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020418 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020419 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020420 "%s: TDLS mode is disabled OR not enabled in FW."
20421 MAC_ADDRESS_STR " action %d declined.",
20422 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020423 return -ENOTSUPP;
20424 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020425
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020426 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
20427
20428 if( NULL == pHddStaCtx )
20429 {
20430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20431 "%s: HDD station context NULL ",__func__);
20432 return -EINVAL;
20433 }
20434
20435 /* STA should be connected and authenticated
20436 * before sending any TDLS frames
20437 */
20438 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
20439 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
20440 {
20441 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20442 "STA is not connected or unauthenticated. "
20443 "connState %u, uIsAuthenticated %u",
20444 pHddStaCtx->conn_info.connState,
20445 pHddStaCtx->conn_info.uIsAuthenticated);
20446 return -EAGAIN;
20447 }
20448
Hoonki Lee27511902013-03-14 18:19:06 -070020449 /* other than teardown frame, other mgmt frames are not sent if disabled */
20450 if (SIR_MAC_TDLS_TEARDOWN != action_code)
20451 {
20452 /* if tdls_mode is disabled to respond to peer's request */
20453 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
20454 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070020456 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020457 " TDLS mode is disabled. action %d declined.",
20458 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070020459
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020460 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070020461 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053020462
20463 if (vos_max_concurrent_connections_reached())
20464 {
20465 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
20466 return -EINVAL;
20467 }
Hoonki Lee27511902013-03-14 18:19:06 -070020468 }
20469
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020470 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
20471 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053020472 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020473 {
20474 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020475 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020476 " TDLS setup is ongoing. action %d declined.",
20477 __func__, MAC_ADDR_ARRAY(peer), action_code);
20478 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020479 }
20480 }
20481
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020482 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
20483 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080020484 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020485 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20486 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020487 {
20488 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
20489 we return error code at 'add_station()'. Hence we have this
20490 check again in addtion to add_station().
20491 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020492 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080020493 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20495 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020496 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
20497 __func__, MAC_ADDR_ARRAY(peer), action_code,
20498 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053020499 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080020500 }
20501 else
20502 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020503 /* maximum reached. tweak to send error code to peer and return
20504 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020505 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20507 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053020508 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
20509 __func__, MAC_ADDR_ARRAY(peer), status_code,
20510 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070020511 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020512 /* fall through to send setup resp with failure status
20513 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080020514 }
20515 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020516 else
20517 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020518 mutex_lock(&pHddCtx->tdls_lock);
20519 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020520 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020521 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020522 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020523 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070020524 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
20525 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020526 return -EPERM;
20527 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020528 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020529 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020530 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020531
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020532 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020533 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020534 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
20535 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020536
Hoonki Leea34dd892013-02-05 22:56:02 -080020537 /*Except teardown responder will not be used so just make 0*/
20538 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080020539 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080020540 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020541
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020542 mutex_lock(&pHddCtx->tdls_lock);
20543 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020544
20545 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
20546 responder = pTdlsPeer->is_responder;
20547 else
Hoonki Leea34dd892013-02-05 22:56:02 -080020548 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053020550 "%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 -070020551 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
20552 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020553 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070020554 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080020555 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020556 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020557 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020558
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053020559 /* Discard TDLS setup if peer is removed by user app */
20560 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
20561 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20562 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
20563 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
20564
20565 mutex_lock(&pHddCtx->tdls_lock);
20566 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20567 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
20568 mutex_unlock(&pHddCtx->tdls_lock);
20569 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
20570 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
20571 MAC_ADDR_ARRAY(peer), action_code);
20572 return -EINVAL;
20573 }
20574 mutex_unlock(&pHddCtx->tdls_lock);
20575 }
20576
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020577 /* For explicit trigger of DIS_REQ come out of BMPS for
20578 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070020579 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053020580 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053020581 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
20582 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070020583 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020584 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053020585 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020586 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20587 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020588 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20589 if (status != VOS_STATUS_SUCCESS) {
20590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020591 } else {
20592 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020593 }
Hoonki Lee14621352013-04-16 17:51:19 -070020594 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020595 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020596 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20598 }
20599 }
Hoonki Lee14621352013-04-16 17:51:19 -070020600 }
20601
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020602 /* make sure doesn't call send_mgmt() while it is pending */
20603 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20604 {
20605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020606 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020607 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020608 ret = -EBUSY;
20609 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020610 }
20611
20612 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020613 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20614
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020615 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20616 pAdapter->sessionId, peer, action_code, dialog_token,
20617 status_code, peer_capability, (tANI_U8 *)buf, len,
20618 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020619
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020620 if (VOS_STATUS_SUCCESS != status)
20621 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20623 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020624 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020625 ret = -EINVAL;
20626 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020627 }
20628
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20630 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20631 WAIT_TIME_TDLS_MGMT);
20632
Hoonki Leed37cbb32013-04-20 00:31:14 -070020633 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20634 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20635
20636 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020637 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020639 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020640 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020641 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020642
20643 if (pHddCtx->isLogpInProgress)
20644 {
20645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20646 "%s: LOGP in Progress. Ignore!!!", __func__);
20647 return -EAGAIN;
20648 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020649 if (rc <= 0)
20650 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20651 WLAN_LOG_INDICATOR_HOST_DRIVER,
20652 WLAN_LOG_REASON_HDD_TIME_OUT,
20653 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020654
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020655 ret = -EINVAL;
20656 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020657 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020658 else
20659 {
20660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20661 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20662 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20663 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020664
Gopichand Nakkala05922802013-03-14 12:23:19 -070020665 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020666 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020667 ret = max_sta_failed;
20668 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020669 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020670
Hoonki Leea34dd892013-02-05 22:56:02 -080020671 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20672 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020673 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20675 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020676 }
20677 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20678 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020679 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20681 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020682 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020683
20684 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020685
20686tx_failed:
20687 /* add_station will be called before sending TDLS_SETUP_REQ and
20688 * TDLS_SETUP_RSP and as part of add_station driver will enable
20689 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20690 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20691 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20692 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20693 */
20694
20695 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20696 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20697 wlan_hdd_tdls_check_bmps(pAdapter);
20698 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020699}
20700
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020701#if TDLS_MGMT_VERSION2
20702static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20703 u8 *peer, u8 action_code, u8 dialog_token,
20704 u16 status_code, u32 peer_capability,
20705 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020706#else /* TDLS_MGMT_VERSION2 */
20707#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20708static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20709 struct net_device *dev,
20710 const u8 *peer, u8 action_code,
20711 u8 dialog_token, u16 status_code,
20712 u32 peer_capability, bool initiator,
20713 const u8 *buf, size_t len)
20714#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20715static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20716 struct net_device *dev,
20717 const u8 *peer, u8 action_code,
20718 u8 dialog_token, u16 status_code,
20719 u32 peer_capability, const u8 *buf,
20720 size_t len)
20721#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20722static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20723 struct net_device *dev,
20724 u8 *peer, u8 action_code,
20725 u8 dialog_token,
20726 u16 status_code, u32 peer_capability,
20727 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020728#else
20729static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20730 u8 *peer, u8 action_code, u8 dialog_token,
20731 u16 status_code, const u8 *buf, size_t len)
20732#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020733#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020734{
20735 int ret;
20736
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020737 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020738#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020739 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20740 dialog_token, status_code,
20741 peer_capability, buf, len);
20742#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020743#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20744 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020745 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20746 dialog_token, status_code,
20747 peer_capability, initiator,
20748 buf, len);
20749#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20750 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20751 dialog_token, status_code,
20752 peer_capability, buf, len);
20753#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20754 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20755 dialog_token, status_code,
20756 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020757#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020758 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20759 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020760#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020761#endif
20762 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020763
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020764 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020765}
Atul Mittal115287b2014-07-08 13:26:33 +053020766
20767int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020768#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20769 const u8 *peer,
20770#else
Atul Mittal115287b2014-07-08 13:26:33 +053020771 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020772#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020773 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020774 cfg80211_exttdls_callback callback)
20775{
20776
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020777 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020778 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020779 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20781 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20782 __func__, MAC_ADDR_ARRAY(peer));
20783
20784 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20785 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20786
20787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020788 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20789 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20790 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020791 return -ENOTSUPP;
20792 }
20793
20794 /* To cater the requirement of establishing the TDLS link
20795 * irrespective of the data traffic , get an entry of TDLS peer.
20796 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020797 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020798 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20799 if (pTdlsPeer == NULL) {
20800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20801 "%s: peer " MAC_ADDRESS_STR " not existing",
20802 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020803 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020804 return -EINVAL;
20805 }
20806
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020807 /* check FW TDLS Off Channel capability */
20808 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020809 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020810 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020811 {
20812 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20813 pTdlsPeer->peerParams.global_operating_class =
20814 tdls_peer_params->global_operating_class;
20815 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20816 pTdlsPeer->peerParams.min_bandwidth_kbps =
20817 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020818 /* check configured channel is valid, non dfs and
20819 * not current operating channel */
20820 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20821 tdls_peer_params->channel)) &&
20822 (pHddStaCtx) &&
20823 (tdls_peer_params->channel !=
20824 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020825 {
20826 pTdlsPeer->isOffChannelConfigured = TRUE;
20827 }
20828 else
20829 {
20830 pTdlsPeer->isOffChannelConfigured = FALSE;
20831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20832 "%s: Configured Tdls Off Channel is not valid", __func__);
20833
20834 }
20835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020836 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20837 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020838 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020839 pTdlsPeer->isOffChannelConfigured,
20840 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020841 }
20842 else
20843 {
20844 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020845 "%s: TDLS off channel FW capability %d, "
20846 "host capab %d or Invalid TDLS Peer Params", __func__,
20847 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20848 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020849 }
20850
Atul Mittal115287b2014-07-08 13:26:33 +053020851 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20852
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020853 mutex_unlock(&pHddCtx->tdls_lock);
20854
Atul Mittal115287b2014-07-08 13:26:33 +053020855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20856 " %s TDLS Add Force Peer Failed",
20857 __func__);
20858 return -EINVAL;
20859 }
20860 /*EXT TDLS*/
20861
20862 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020863 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20865 " %s TDLS set callback Failed",
20866 __func__);
20867 return -EINVAL;
20868 }
20869
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020870 mutex_unlock(&pHddCtx->tdls_lock);
20871
Atul Mittal115287b2014-07-08 13:26:33 +053020872 return(0);
20873
20874}
20875
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020876int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20878 const u8 *peer
20879#else
20880 u8 *peer
20881#endif
20882)
Atul Mittal115287b2014-07-08 13:26:33 +053020883{
20884
20885 hddTdlsPeer_t *pTdlsPeer;
20886 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020887
Atul Mittal115287b2014-07-08 13:26:33 +053020888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20889 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20890 __func__, MAC_ADDR_ARRAY(peer));
20891
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020892 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20894 return -EINVAL;
20895 }
20896
Atul Mittal115287b2014-07-08 13:26:33 +053020897 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20898 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20899
20900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020901 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20902 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20903 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020904 return -ENOTSUPP;
20905 }
20906
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020907 mutex_lock(&pHddCtx->tdls_lock);
20908 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020909
20910 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020911 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020912 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020913 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020914 __func__, MAC_ADDR_ARRAY(peer));
20915 return -EINVAL;
20916 }
20917 else {
20918 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20919 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020920 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20921 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020922 /* if channel switch is configured, reset
20923 the channel for this peer */
20924 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20925 {
20926 pTdlsPeer->peerParams.channel = 0;
20927 pTdlsPeer->isOffChannelConfigured = FALSE;
20928 }
Atul Mittal115287b2014-07-08 13:26:33 +053020929 }
20930
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020931 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020932 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020934 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020935 }
Atul Mittal115287b2014-07-08 13:26:33 +053020936
20937 /*EXT TDLS*/
20938
20939 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020940 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20942 " %s TDLS set callback Failed",
20943 __func__);
20944 return -EINVAL;
20945 }
Atul Mittal115287b2014-07-08 13:26:33 +053020946
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020947 mutex_unlock(&pHddCtx->tdls_lock);
20948
20949 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020950}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020951static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020952#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20953 const u8 *peer,
20954#else
20955 u8 *peer,
20956#endif
20957 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020958{
20959 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20960 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020961 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020962 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020963
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020964 ENTER();
20965
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020966 if (!pAdapter) {
20967 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20968 return -EINVAL;
20969 }
20970
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020971 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20972 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20973 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020974 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020975 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020976 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020977 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020978 return -EINVAL;
20979 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020980
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020981 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020982 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020983 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020984 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020985 }
20986
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020987
20988 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020989 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020990 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020992 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20993 "Cannot process TDLS commands",
20994 pHddCtx->cfg_ini->fEnableTDLSSupport,
20995 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020996 return -ENOTSUPP;
20997 }
20998
20999 switch (oper) {
21000 case NL80211_TDLS_ENABLE_LINK:
21001 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021002 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021003 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053021004 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
21005 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053021006 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021007 tANI_U16 numCurrTdlsPeers = 0;
21008 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021009 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021010 tSirMacAddr peerMac;
21011 int channel;
21012 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021013
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21015 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
21016 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021017
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021018 mutex_lock(&pHddCtx->tdls_lock);
21019 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053021020 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053021021 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021022 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21024 " (oper %d) not exsting. ignored",
21025 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21026 return -EINVAL;
21027 }
21028
21029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21030 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21031 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21032 "NL80211_TDLS_ENABLE_LINK");
21033
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070021034 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
21035 {
21036 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
21037 MAC_ADDRESS_STR " failed",
21038 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021039 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070021040 return -EINVAL;
21041 }
21042
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021043 /* before starting tdls connection, set tdls
21044 * off channel established status to default value */
21045 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021046
21047 mutex_unlock(&pHddCtx->tdls_lock);
21048
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053021049 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021050 /* TDLS Off Channel, Disable tdls channel switch,
21051 when there are more than one tdls link */
21052 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053021053 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021054 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021055 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021056 /* get connected peer and send disable tdls off chan */
21057 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021058 if ((connPeer) &&
21059 (connPeer->isOffChannelSupported == TRUE) &&
21060 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021061 {
21062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21063 "%s: More then one peer connected, Disable "
21064 "TDLS channel switch", __func__);
21065
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021066 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021067 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
21068 channel = connPeer->peerParams.channel;
21069
21070 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021071
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021072 ret = sme_SendTdlsChanSwitchReq(
21073 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021074 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021075 peerMac,
21076 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021077 TDLS_OFF_CHANNEL_BW_OFFSET,
21078 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021079 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021080 hddLog(VOS_TRACE_LEVEL_ERROR,
21081 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021082 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021083 }
21084 else
21085 {
21086 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21087 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021088 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021089 "isOffChannelConfigured %d",
21090 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021091 (connPeer ? (connPeer->isOffChannelSupported)
21092 : -1),
21093 (connPeer ? (connPeer->isOffChannelConfigured)
21094 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021095 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021096 }
21097 }
21098
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021099 mutex_lock(&pHddCtx->tdls_lock);
21100 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21101 if ( NULL == pTdlsPeer ) {
21102 mutex_unlock(&pHddCtx->tdls_lock);
21103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21104 "%s: " MAC_ADDRESS_STR
21105 " (oper %d) peer got freed in other context. ignored",
21106 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21107 return -EINVAL;
21108 }
21109 peer_status = pTdlsPeer->link_status;
21110 mutex_unlock(&pHddCtx->tdls_lock);
21111
21112 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021113 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021114 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053021115
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021116 if (0 != wlan_hdd_tdls_get_link_establish_params(
21117 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021119 return -EINVAL;
21120 }
21121 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021122
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021123 ret = sme_SendTdlsLinkEstablishParams(
21124 WLAN_HDD_GET_HAL_CTX(pAdapter),
21125 pAdapter->sessionId, peer,
21126 &tdlsLinkEstablishParams);
21127 if (ret != VOS_STATUS_SUCCESS) {
21128 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
21129 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021130 /* Send TDLS peer UAPSD capabilities to the firmware and
21131 * register with the TL on after the response for this operation
21132 * is received .
21133 */
21134 ret = wait_for_completion_interruptible_timeout(
21135 &pAdapter->tdls_link_establish_req_comp,
21136 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053021137
21138 mutex_lock(&pHddCtx->tdls_lock);
21139 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21140 if ( NULL == pTdlsPeer ) {
21141 mutex_unlock(&pHddCtx->tdls_lock);
21142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21143 "%s %d: " MAC_ADDRESS_STR
21144 " (oper %d) peer got freed in other context. ignored",
21145 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
21146 (int)oper);
21147 return -EINVAL;
21148 }
21149 peer_status = pTdlsPeer->link_status;
21150 mutex_unlock(&pHddCtx->tdls_lock);
21151
21152 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021153 {
21154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021155 FL("Link Establish Request Failed Status %ld"),
21156 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053021157 return -EINVAL;
21158 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021159 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053021160
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021161 mutex_lock(&pHddCtx->tdls_lock);
21162 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21163 if ( NULL == pTdlsPeer ) {
21164 mutex_unlock(&pHddCtx->tdls_lock);
21165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21166 "%s: " MAC_ADDRESS_STR
21167 " (oper %d) peer got freed in other context. ignored",
21168 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21169 return -EINVAL;
21170 }
21171
Atul Mittal115287b2014-07-08 13:26:33 +053021172 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21173 eTDLS_LINK_CONNECTED,
21174 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053021175 staDesc.ucSTAId = pTdlsPeer->staId;
21176 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053021177
21178 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21179 "%s: tdlsLinkEstablishParams of peer "
21180 MAC_ADDRESS_STR "uapsdQueues: %d"
21181 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
21182 "isResponder: %d peerstaId: %d",
21183 __func__,
21184 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
21185 tdlsLinkEstablishParams.uapsdQueues,
21186 tdlsLinkEstablishParams.qos,
21187 tdlsLinkEstablishParams.maxSp,
21188 tdlsLinkEstablishParams.isBufSta,
21189 tdlsLinkEstablishParams.isOffChannelSupported,
21190 tdlsLinkEstablishParams.isResponder,
21191 pTdlsPeer->staId);
21192
21193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21194 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
21195 __func__,
21196 staDesc.ucSTAId,
21197 staDesc.ucQosEnabled);
21198
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021199 ret = WLANTL_UpdateTdlsSTAClient(
21200 pHddCtx->pvosContext,
21201 &staDesc);
21202 if (ret != VOS_STATUS_SUCCESS) {
21203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
21204 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053021205
Gopichand Nakkala471708b2013-06-04 20:03:01 +053021206 /* Mark TDLS client Authenticated .*/
21207 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
21208 pTdlsPeer->staId,
21209 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070021210 if (VOS_STATUS_SUCCESS == status)
21211 {
Hoonki Lee14621352013-04-16 17:51:19 -070021212 if (pTdlsPeer->is_responder == 0)
21213 {
21214 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053021215 tdlsConnInfo_t *tdlsInfo;
21216
21217 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
21218
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053021219 if (!vos_timer_is_initialized(
21220 &pTdlsPeer->initiatorWaitTimeoutTimer))
21221 {
21222 /* Initialize initiator wait callback */
21223 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053021224 &pTdlsPeer->initiatorWaitTimeoutTimer,
21225 VOS_TIMER_TYPE_SW,
21226 wlan_hdd_tdls_initiator_wait_cb,
21227 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053021228 }
Hoonki Lee14621352013-04-16 17:51:19 -070021229 wlan_hdd_tdls_timer_restart(pAdapter,
21230 &pTdlsPeer->initiatorWaitTimeoutTimer,
21231 WAIT_TIME_TDLS_INITIATOR);
21232 /* suspend initiator TX until it receives direct packet from the
21233 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021234 ret = WLANTL_SuspendDataTx(
21235 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21236 &staId, NULL);
21237 if (ret != VOS_STATUS_SUCCESS) {
21238 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
21239 }
Hoonki Lee14621352013-04-16 17:51:19 -070021240 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021241
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021242 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021243 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021244 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021245 suppChannelLen =
21246 tdlsLinkEstablishParams.supportedChannelsLen;
21247
21248 if ((suppChannelLen > 0) &&
21249 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
21250 {
21251 tANI_U8 suppPeerChannel = 0;
21252 int i = 0;
21253 for (i = 0U; i < suppChannelLen; i++)
21254 {
21255 suppPeerChannel =
21256 tdlsLinkEstablishParams.supportedChannels[i];
21257
21258 pTdlsPeer->isOffChannelSupported = FALSE;
21259 if (suppPeerChannel ==
21260 pTdlsPeer->peerParams.channel)
21261 {
21262 pTdlsPeer->isOffChannelSupported = TRUE;
21263 break;
21264 }
21265 }
21266 }
21267 else
21268 {
21269 pTdlsPeer->isOffChannelSupported = FALSE;
21270 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021271 }
21272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21273 "%s: TDLS channel switch request for channel "
21274 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021275 "%d isOffChannelSupported %d", __func__,
21276 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021277 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053021278 suppChannelLen,
21279 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053021280
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021281 /* TDLS Off Channel, Enable tdls channel switch,
21282 when their is only one tdls link and it supports */
21283 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21284 if ((numCurrTdlsPeers == 1) &&
21285 (TRUE == pTdlsPeer->isOffChannelSupported) &&
21286 (TRUE == pTdlsPeer->isOffChannelConfigured))
21287 {
21288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21289 "%s: Send TDLS channel switch request for channel %d",
21290 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021291
21292 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021293 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
21294 channel = pTdlsPeer->peerParams.channel;
21295
21296 mutex_unlock(&pHddCtx->tdls_lock);
21297
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021298 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
21299 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021300 peerMac,
21301 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021302 TDLS_OFF_CHANNEL_BW_OFFSET,
21303 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021304 if (ret != VOS_STATUS_SUCCESS) {
21305 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
21306 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021307 }
21308 else
21309 {
21310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21311 "%s: TDLS channel switch request not sent"
21312 " numCurrTdlsPeers %d "
21313 "isOffChannelSupported %d "
21314 "isOffChannelConfigured %d",
21315 __func__, numCurrTdlsPeers,
21316 pTdlsPeer->isOffChannelSupported,
21317 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021318 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021319 }
21320
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070021321 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021322 else
21323 mutex_unlock(&pHddCtx->tdls_lock);
21324
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021325 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021326
21327 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021328 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
21329 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021330 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021331 int ac;
21332 uint8 ucAc[4] = { WLANTL_AC_VO,
21333 WLANTL_AC_VI,
21334 WLANTL_AC_BK,
21335 WLANTL_AC_BE };
21336 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
21337 for(ac=0; ac < 4; ac++)
21338 {
21339 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
21340 pTdlsPeer->staId, ucAc[ac],
21341 tlTid[ac], tlTid[ac], 0, 0,
21342 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021343 if (status != VOS_STATUS_SUCCESS) {
21344 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
21345 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053021346 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053021347 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021348 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053021349
Bhargav Shah66896792015-10-01 18:17:37 +053021350 /* stop TCP delack timer if TDLS is enable */
21351 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21352 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053021353 hdd_wlan_tdls_enable_link_event(peer,
21354 pTdlsPeer->isOffChannelSupported,
21355 pTdlsPeer->isOffChannelConfigured,
21356 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021357 }
21358 break;
21359 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080021360 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021361 tANI_U16 numCurrTdlsPeers = 0;
21362 hddTdlsPeer_t *connPeer = NULL;
21363
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21365 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
21366 __func__, MAC_ADDR_ARRAY(peer));
21367
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021368 mutex_lock(&pHddCtx->tdls_lock);
21369 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021370
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021371
Sunil Dutt41de4e22013-11-14 18:09:02 +053021372 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021373 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021374 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21375 " (oper %d) not exsting. ignored",
21376 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
21377 return -EINVAL;
21378 }
21379
21380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21381 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
21382 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
21383 "NL80211_TDLS_DISABLE_LINK");
21384
Hoonki Lee5305c3a2013-04-29 23:28:59 -070021385 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080021386 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021387 long status;
21388
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053021389 /* set tdls off channel status to false for this peer */
21390 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053021391 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
21392 eTDLS_LINK_TEARING,
21393 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
21394 eTDLS_LINK_UNSPECIFIED:
21395 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021396 mutex_unlock(&pHddCtx->tdls_lock);
21397
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021398 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
21399
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021400 status = sme_DeleteTdlsPeerSta(
21401 WLAN_HDD_GET_HAL_CTX(pAdapter),
21402 pAdapter->sessionId, peer );
21403 if (status != VOS_STATUS_SUCCESS) {
21404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
21405 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021406
21407 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
21408 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021409
21410 mutex_lock(&pHddCtx->tdls_lock);
21411 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
21412 if ( NULL == pTdlsPeer ) {
21413 mutex_unlock(&pHddCtx->tdls_lock);
21414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
21415 " peer was freed in other context",
21416 __func__, MAC_ADDR_ARRAY(peer));
21417 return -EINVAL;
21418 }
21419
Atul Mittal271a7652014-09-12 13:18:22 +053021420 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053021421 eTDLS_LINK_IDLE,
21422 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021423 mutex_unlock(&pHddCtx->tdls_lock);
21424
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021425 if (status <= 0)
21426 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070021427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21428 "%s: Del station failed status %ld",
21429 __func__, status);
21430 return -EPERM;
21431 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021432
21433 /* TDLS Off Channel, Enable tdls channel switch,
21434 when their is only one tdls link and it supports */
21435 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
21436 if (numCurrTdlsPeers == 1)
21437 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021438 tSirMacAddr peerMac;
21439 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021440
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021441 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021442 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053021443
21444 if (connPeer == NULL) {
21445 mutex_unlock(&pHddCtx->tdls_lock);
21446 hddLog(VOS_TRACE_LEVEL_ERROR,
21447 "%s connPeer is NULL", __func__);
21448 return -EINVAL;
21449 }
21450
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021451 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
21452 channel = connPeer->peerParams.channel;
21453
21454 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21455 "%s: TDLS channel switch "
21456 "isOffChannelSupported %d "
21457 "isOffChannelConfigured %d "
21458 "isOffChannelEstablished %d",
21459 __func__,
21460 (connPeer ? connPeer->isOffChannelSupported : -1),
21461 (connPeer ? connPeer->isOffChannelConfigured : -1),
21462 (connPeer ? connPeer->isOffChannelEstablished : -1));
21463
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021464 if ((connPeer) &&
21465 (connPeer->isOffChannelSupported == TRUE) &&
21466 (connPeer->isOffChannelConfigured == TRUE))
21467 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053021468 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021469 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021470 status = sme_SendTdlsChanSwitchReq(
21471 WLAN_HDD_GET_HAL_CTX(pAdapter),
21472 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021473 peerMac,
21474 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053021475 TDLS_OFF_CHANNEL_BW_OFFSET,
21476 TDLS_CHANNEL_SWITCH_ENABLE);
21477 if (status != VOS_STATUS_SUCCESS) {
21478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
21479 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021480 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021481 else
21482 mutex_unlock(&pHddCtx->tdls_lock);
21483 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021484 else
21485 {
21486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21487 "%s: TDLS channel switch request not sent "
21488 "numCurrTdlsPeers %d ",
21489 __func__, numCurrTdlsPeers);
21490 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021491 }
21492 else
21493 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053021494 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21496 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080021497 }
Bhargav Shah66896792015-10-01 18:17:37 +053021498 if (numCurrTdlsPeers == 0) {
21499 /* start TCP delack timer if TDLS is disable */
21500 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
21501 hdd_manage_delack_timer(pHddCtx);
21502 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080021503 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070021504 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021505 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021506 {
Atul Mittal115287b2014-07-08 13:26:33 +053021507 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021508
Atul Mittal115287b2014-07-08 13:26:33 +053021509 if (0 != status)
21510 {
21511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021512 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053021513 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021514 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053021515 break;
21516 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021517 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053021518 {
Atul Mittal115287b2014-07-08 13:26:33 +053021519 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
21520 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053021521 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053021522 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053021523
Atul Mittal115287b2014-07-08 13:26:33 +053021524 if (0 != status)
21525 {
21526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021527 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053021528 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053021529 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053021530 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053021531 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021532 case NL80211_TDLS_DISCOVERY_REQ:
21533 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053021535 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021536 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021537 return -ENOTSUPP;
21538 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21540 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021541 return -ENOTSUPP;
21542 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021543
21544 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021545 return 0;
21546}
Chilam NG571c65a2013-01-19 12:27:36 +053021547
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021548static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021549#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
21550 const u8 *peer,
21551#else
21552 u8 *peer,
21553#endif
21554 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021555{
21556 int ret;
21557
21558 vos_ssr_protect(__func__);
21559 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
21560 vos_ssr_unprotect(__func__);
21561
21562 return ret;
21563}
21564
Chilam NG571c65a2013-01-19 12:27:36 +053021565int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
21566 struct net_device *dev, u8 *peer)
21567{
Arif Hussaina7c8e412013-11-20 11:06:42 -080021568 hddLog(VOS_TRACE_LEVEL_INFO,
21569 "tdls send discover req: "MAC_ADDRESS_STR,
21570 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021571#if TDLS_MGMT_VERSION2
21572 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21573 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21574#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021575#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
21576 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21577 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
21578#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
21579 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21580 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21581#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
21582 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21583 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
21584#else
Chilam NG571c65a2013-01-19 12:27:36 +053021585 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
21586 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021587#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021588#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021589}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021590#endif
21591
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021592#ifdef WLAN_FEATURE_GTK_OFFLOAD
21593/*
21594 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21595 * Callback rountine called upon receiving response for
21596 * get offload info
21597 */
21598void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21599 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21600{
21601
21602 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021603 tANI_U8 tempReplayCounter[8];
21604 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021605
21606 ENTER();
21607
21608 if (NULL == pAdapter)
21609 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021610 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021611 "%s: HDD adapter is Null", __func__);
21612 return ;
21613 }
21614
21615 if (NULL == pGtkOffloadGetInfoRsp)
21616 {
21617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21618 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21619 return ;
21620 }
21621
21622 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21623 {
21624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21625 "%s: wlan Failed to get replay counter value",
21626 __func__);
21627 return ;
21628 }
21629
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021630 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21631 /* Update replay counter */
21632 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21633 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21634
21635 {
21636 /* changing from little to big endian since supplicant
21637 * works on big endian format
21638 */
21639 int i;
21640 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21641
21642 for (i = 0; i < 8; i++)
21643 {
21644 tempReplayCounter[7-i] = (tANI_U8)p[i];
21645 }
21646 }
21647
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021648 /* Update replay counter to NL */
21649 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021650 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021651}
21652
21653/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021654 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021655 * This function is used to offload GTK rekeying job to the firmware.
21656 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021657int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021658 struct cfg80211_gtk_rekey_data *data)
21659{
21660 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21661 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21662 hdd_station_ctx_t *pHddStaCtx;
21663 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021664 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021665 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021666 eHalStatus status = eHAL_STATUS_FAILURE;
21667
21668 ENTER();
21669
21670 if (NULL == pAdapter)
21671 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021672 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021673 "%s: HDD adapter is Null", __func__);
21674 return -ENODEV;
21675 }
21676
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021677 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21678 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21679 pAdapter->sessionId, pAdapter->device_mode));
21680
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021681 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021682 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021683 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021684 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021685 }
21686
21687 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21688 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21689 if (NULL == hHal)
21690 {
21691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21692 "%s: HAL context is Null!!!", __func__);
21693 return -EAGAIN;
21694 }
21695
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021696 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21697 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21698 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21699 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021700 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021701 {
21702 /* changing from big to little endian since driver
21703 * works on little endian format
21704 */
21705 tANI_U8 *p =
21706 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21707 int i;
21708
21709 for (i = 0; i < 8; i++)
21710 {
21711 p[7-i] = data->replay_ctr[i];
21712 }
21713 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021714
21715 if (TRUE == pHddCtx->hdd_wlan_suspended)
21716 {
21717 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021718 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21719 sizeof (tSirGtkOffloadParams));
21720 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021721 pAdapter->sessionId);
21722
21723 if (eHAL_STATUS_SUCCESS != status)
21724 {
21725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21726 "%s: sme_SetGTKOffload failed, returned %d",
21727 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021728
21729 /* Need to clear any trace of key value in the memory.
21730 * Thus zero out the memory even though it is local
21731 * variable.
21732 */
21733 vos_mem_zero(&hddGtkOffloadReqParams,
21734 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021735 return status;
21736 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21738 "%s: sme_SetGTKOffload successfull", __func__);
21739 }
21740 else
21741 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021742 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21743 "%s: wlan not suspended GTKOffload request is stored",
21744 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021745 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021746
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021747 /* Need to clear any trace of key value in the memory.
21748 * Thus zero out the memory even though it is local
21749 * variable.
21750 */
21751 vos_mem_zero(&hddGtkOffloadReqParams,
21752 sizeof(hddGtkOffloadReqParams));
21753
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021754 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021755 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021756}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021757
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021758int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21759 struct cfg80211_gtk_rekey_data *data)
21760{
21761 int ret;
21762
21763 vos_ssr_protect(__func__);
21764 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21765 vos_ssr_unprotect(__func__);
21766
21767 return ret;
21768}
21769#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021770/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021771 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021772 * This function is used to set access control policy
21773 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021774static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21775 struct net_device *dev,
21776 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021777{
21778 int i;
21779 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21780 hdd_hostapd_state_t *pHostapdState;
21781 tsap_Config_t *pConfig;
21782 v_CONTEXT_t pVosContext = NULL;
21783 hdd_context_t *pHddCtx;
21784 int status;
21785
21786 ENTER();
21787
21788 if (NULL == pAdapter)
21789 {
21790 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21791 "%s: HDD adapter is Null", __func__);
21792 return -ENODEV;
21793 }
21794
21795 if (NULL == params)
21796 {
21797 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21798 "%s: params is Null", __func__);
21799 return -EINVAL;
21800 }
21801
21802 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21803 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021804 if (0 != status)
21805 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021806 return status;
21807 }
21808
21809 pVosContext = pHddCtx->pvosContext;
21810 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21811
21812 if (NULL == pHostapdState)
21813 {
21814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21815 "%s: pHostapdState is Null", __func__);
21816 return -EINVAL;
21817 }
21818
21819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21820 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021821 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21822 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21823 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021824
21825 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21826 {
21827 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21828
21829 /* default value */
21830 pConfig->num_accept_mac = 0;
21831 pConfig->num_deny_mac = 0;
21832
21833 /**
21834 * access control policy
21835 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21836 * listed in hostapd.deny file.
21837 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21838 * listed in hostapd.accept file.
21839 */
21840 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21841 {
21842 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21843 }
21844 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21845 {
21846 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21847 }
21848 else
21849 {
21850 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21851 "%s:Acl Policy : %d is not supported",
21852 __func__, params->acl_policy);
21853 return -ENOTSUPP;
21854 }
21855
21856 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21857 {
21858 pConfig->num_accept_mac = params->n_acl_entries;
21859 for (i = 0; i < params->n_acl_entries; i++)
21860 {
21861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21862 "** Add ACL MAC entry %i in WhiletList :"
21863 MAC_ADDRESS_STR, i,
21864 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21865
21866 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21867 sizeof(qcmacaddr));
21868 }
21869 }
21870 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21871 {
21872 pConfig->num_deny_mac = params->n_acl_entries;
21873 for (i = 0; i < params->n_acl_entries; i++)
21874 {
21875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21876 "** Add ACL MAC entry %i in BlackList :"
21877 MAC_ADDRESS_STR, i,
21878 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21879
21880 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21881 sizeof(qcmacaddr));
21882 }
21883 }
21884
21885 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21886 {
21887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21888 "%s: SAP Set Mac Acl fail", __func__);
21889 return -EINVAL;
21890 }
21891 }
21892 else
21893 {
21894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021895 "%s: Invalid device_mode = %s (%d)",
21896 __func__, hdd_device_modetoString(pAdapter->device_mode),
21897 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021898 return -EINVAL;
21899 }
21900
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021901 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021902 return 0;
21903}
21904
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021905static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21906 struct net_device *dev,
21907 const struct cfg80211_acl_data *params)
21908{
21909 int ret;
21910 vos_ssr_protect(__func__);
21911 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21912 vos_ssr_unprotect(__func__);
21913
21914 return ret;
21915}
21916
Leo Chang9056f462013-08-01 19:21:11 -070021917#ifdef WLAN_NL80211_TESTMODE
21918#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021919void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021920(
21921 void *pAdapter,
21922 void *indCont
21923)
21924{
Leo Changd9df8aa2013-09-26 13:32:26 -070021925 tSirLPHBInd *lphbInd;
21926 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021927 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021928
21929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021930 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021931
c_hpothu73f35e62014-04-18 13:40:08 +053021932 if (pAdapter == NULL)
21933 {
21934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21935 "%s: pAdapter is NULL\n",__func__);
21936 return;
21937 }
21938
Leo Chang9056f462013-08-01 19:21:11 -070021939 if (NULL == indCont)
21940 {
21941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021942 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021943 return;
21944 }
21945
c_hpothu73f35e62014-04-18 13:40:08 +053021946 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021947 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021948 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021949 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021950 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021951 GFP_ATOMIC);
21952 if (!skb)
21953 {
21954 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21955 "LPHB timeout, NL buffer alloc fail");
21956 return;
21957 }
21958
Leo Changac3ba772013-10-07 09:47:04 -070021959 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021960 {
21961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21962 "WLAN_HDD_TM_ATTR_CMD put fail");
21963 goto nla_put_failure;
21964 }
Leo Changac3ba772013-10-07 09:47:04 -070021965 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021966 {
21967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21968 "WLAN_HDD_TM_ATTR_TYPE put fail");
21969 goto nla_put_failure;
21970 }
Leo Changac3ba772013-10-07 09:47:04 -070021971 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021972 sizeof(tSirLPHBInd), lphbInd))
21973 {
21974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21975 "WLAN_HDD_TM_ATTR_DATA put fail");
21976 goto nla_put_failure;
21977 }
Leo Chang9056f462013-08-01 19:21:11 -070021978 cfg80211_testmode_event(skb, GFP_ATOMIC);
21979 return;
21980
21981nla_put_failure:
21982 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21983 "NLA Put fail");
21984 kfree_skb(skb);
21985
21986 return;
21987}
21988#endif /* FEATURE_WLAN_LPHB */
21989
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021990static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021991{
21992 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21993 int err = 0;
21994#ifdef FEATURE_WLAN_LPHB
21995 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021996 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021997
21998 ENTER();
21999
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022000 err = wlan_hdd_validate_context(pHddCtx);
22001 if (0 != err)
22002 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022003 return err;
22004 }
Leo Chang9056f462013-08-01 19:21:11 -070022005#endif /* FEATURE_WLAN_LPHB */
22006
22007 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
22008 if (err)
22009 {
22010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22011 "%s Testmode INV ATTR", __func__);
22012 return err;
22013 }
22014
22015 if (!tb[WLAN_HDD_TM_ATTR_CMD])
22016 {
22017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22018 "%s Testmode INV CMD", __func__);
22019 return -EINVAL;
22020 }
22021
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022022 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22023 TRACE_CODE_HDD_CFG80211_TESTMODE,
22024 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070022025 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
22026 {
22027#ifdef FEATURE_WLAN_LPHB
22028 /* Low Power Heartbeat configuration request */
22029 case WLAN_HDD_TM_CMD_WLAN_HB:
22030 {
22031 int buf_len;
22032 void *buf;
22033 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080022034 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070022035
22036 if (!tb[WLAN_HDD_TM_ATTR_DATA])
22037 {
22038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22039 "%s Testmode INV DATA", __func__);
22040 return -EINVAL;
22041 }
22042
22043 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
22044 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080022045
Manjeet Singh3c577442017-02-10 19:03:38 +053022046 if (buf_len > sizeof(*hb_params)) {
22047 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
22048 buf_len);
22049 return -ERANGE;
22050 }
22051
Amar Singhal05852702014-02-04 14:40:00 -080022052 hb_params_temp =(tSirLPHBReq *)buf;
22053 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
22054 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
22055 return -EINVAL;
22056
Leo Chang9056f462013-08-01 19:21:11 -070022057 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
22058 if (NULL == hb_params)
22059 {
22060 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22061 "%s Request Buffer Alloc Fail", __func__);
22062 return -EINVAL;
22063 }
22064
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053022065 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070022066 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070022067 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
22068 hb_params,
22069 wlan_hdd_cfg80211_lphb_ind_handler);
22070 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070022071 {
Leo Changd9df8aa2013-09-26 13:32:26 -070022072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22073 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070022074 vos_mem_free(hb_params);
22075 }
Leo Chang9056f462013-08-01 19:21:11 -070022076 return 0;
22077 }
22078#endif /* FEATURE_WLAN_LPHB */
22079 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053022080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
22081 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070022082 return -EOPNOTSUPP;
22083 }
22084
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022085 EXIT();
22086 return err;
Leo Chang9056f462013-08-01 19:21:11 -070022087}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022088
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053022089static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
22090#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
22091 struct wireless_dev *wdev,
22092#endif
22093 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022094{
22095 int ret;
22096
22097 vos_ssr_protect(__func__);
22098 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
22099 vos_ssr_unprotect(__func__);
22100
22101 return ret;
22102}
Leo Chang9056f462013-08-01 19:21:11 -070022103#endif /* CONFIG_NL80211_TESTMODE */
22104
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022105extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022106static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022107 struct net_device *dev,
22108 int idx, struct survey_info *survey)
22109{
22110 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
22111 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053022112 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022113 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053022114 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022115 v_S7_t snr,rssi;
22116 int status, i, j, filled = 0;
22117
22118 ENTER();
22119
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022120 if (NULL == pAdapter)
22121 {
22122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
22123 "%s: HDD adapter is Null", __func__);
22124 return -ENODEV;
22125 }
22126
22127 if (NULL == wiphy)
22128 {
22129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
22130 "%s: wiphy is Null", __func__);
22131 return -ENODEV;
22132 }
22133
22134 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
22135 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022136 if (0 != status)
22137 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022138 return status;
22139 }
22140
Mihir Sheted9072e02013-08-21 17:02:29 +053022141 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
22142
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022143 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053022144 0 != pAdapter->survey_idx ||
22145 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022146 {
22147 /* The survey dump ops when implemented completely is expected to
22148 * return a survey of all channels and the ops is called by the
22149 * kernel with incremental values of the argument 'idx' till it
22150 * returns -ENONET. But we can only support the survey for the
22151 * operating channel for now. survey_idx is used to track
22152 * that the ops is called only once and then return -ENONET for
22153 * the next iteration
22154 */
22155 pAdapter->survey_idx = 0;
22156 return -ENONET;
22157 }
22158
Mukul Sharma9d5233b2015-06-11 20:28:20 +053022159 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
22160 {
22161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22162 "%s: Roaming in progress, hence return ", __func__);
22163 return -ENONET;
22164 }
22165
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022166 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
22167
22168 wlan_hdd_get_snr(pAdapter, &snr);
22169 wlan_hdd_get_rssi(pAdapter, &rssi);
22170
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022171 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22172 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
22173 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022174 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
22175 hdd_wlan_get_freq(channel, &freq);
22176
22177
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053022178 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022179 {
22180 if (NULL == wiphy->bands[i])
22181 {
22182 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
22183 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
22184 continue;
22185 }
22186
22187 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
22188 {
22189 struct ieee80211_supported_band *band = wiphy->bands[i];
22190
22191 if (band->channels[j].center_freq == (v_U16_t)freq)
22192 {
22193 survey->channel = &band->channels[j];
22194 /* The Rx BDs contain SNR values in dB for the received frames
22195 * while the supplicant expects noise. So we calculate and
22196 * return the value of noise (dBm)
22197 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
22198 */
22199 survey->noise = rssi - snr;
22200 survey->filled = SURVEY_INFO_NOISE_DBM;
22201 filled = 1;
22202 }
22203 }
22204 }
22205
22206 if (filled)
22207 pAdapter->survey_idx = 1;
22208 else
22209 {
22210 pAdapter->survey_idx = 0;
22211 return -ENONET;
22212 }
22213
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022214 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022215 return 0;
22216}
22217
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053022218static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
22219 struct net_device *dev,
22220 int idx, struct survey_info *survey)
22221{
22222 int ret;
22223
22224 vos_ssr_protect(__func__);
22225 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
22226 vos_ssr_unprotect(__func__);
22227
22228 return ret;
22229}
22230
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022231/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022232 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022233 * this is called when cfg80211 driver resume
22234 * driver updates latest sched_scan scan result(if any) to cfg80211 database
22235 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022236int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022237{
22238 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
22239 hdd_adapter_t *pAdapter;
22240 hdd_adapter_list_node_t *pAdapterNode, *pNext;
22241 VOS_STATUS status = VOS_STATUS_SUCCESS;
22242
22243 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022244
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053022245 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022246 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022247 return 0;
22248 }
22249
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022250 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
22251 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022252
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022253 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022254 {
22255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22256 "%s: Resume SoftAP", __func__);
22257 hdd_set_wlan_suspend_mode(false);
22258 }
22259
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022260 spin_lock(&pHddCtx->schedScan_lock);
22261 pHddCtx->isWiphySuspended = FALSE;
22262 if (TRUE != pHddCtx->isSchedScanUpdatePending)
22263 {
22264 spin_unlock(&pHddCtx->schedScan_lock);
22265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22266 "%s: Return resume is not due to PNO indication", __func__);
22267 return 0;
22268 }
22269 // Reset flag to avoid updatating cfg80211 data old results again
22270 pHddCtx->isSchedScanUpdatePending = FALSE;
22271 spin_unlock(&pHddCtx->schedScan_lock);
22272
22273 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
22274
22275 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
22276 {
22277 pAdapter = pAdapterNode->pAdapter;
22278 if ( (NULL != pAdapter) &&
22279 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
22280 {
22281 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022282 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022283 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
22284 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022285 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022286 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022287 {
22288 /* Acquire wakelock to handle the case where APP's tries to
22289 * suspend immediately after updating the scan results. Whis
22290 * results in app's is in suspended state and not able to
22291 * process the connect request to AP
22292 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053022293 hdd_prevent_suspend_timeout(2000,
22294 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022295 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053022296 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022297
22298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22299 "%s : cfg80211 scan result database updated", __func__);
22300
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022301 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022302 return 0;
22303
22304 }
22305 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
22306 pAdapterNode = pNext;
22307 }
22308
22309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22310 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022311 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022312 return 0;
22313}
22314
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022315int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
22316{
22317 int ret;
22318
22319 vos_ssr_protect(__func__);
22320 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
22321 vos_ssr_unprotect(__func__);
22322
22323 return ret;
22324}
22325
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022326/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022327 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022328 * this is called when cfg80211 driver suspends
22329 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022330int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022331 struct cfg80211_wowlan *wow)
22332{
22333 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022334 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022335
22336 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053022337
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022338 ret = wlan_hdd_validate_context(pHddCtx);
22339 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022340 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022341 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022342 }
22343
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053022344 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053022345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
22346 "%s: Suspend SoftAP", __func__);
22347 hdd_set_wlan_suspend_mode(true);
22348 }
22349
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053022350
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053022351 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
22352 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
22353 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022354 pHddCtx->isWiphySuspended = TRUE;
22355
22356 EXIT();
22357
22358 return 0;
22359}
22360
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053022361int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
22362 struct cfg80211_wowlan *wow)
22363{
22364 int ret;
22365
22366 vos_ssr_protect(__func__);
22367 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
22368 vos_ssr_unprotect(__func__);
22369
22370 return ret;
22371}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022372
22373#ifdef FEATURE_OEM_DATA_SUPPORT
22374static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022375 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022376{
22377 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22378
22379 ENTER();
22380
22381 if (wlan_hdd_validate_context(pHddCtx)) {
22382 return;
22383 }
22384 if (!pMsg)
22385 {
22386 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
22387 return;
22388 }
22389
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022390 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022391
22392 EXIT();
22393 return;
22394
22395}
22396
22397void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022398 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022399{
22400 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
22401
22402 ENTER();
22403
22404 if (wlan_hdd_validate_context(pHddCtx)) {
22405 return;
22406 }
22407
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022408 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022409
22410 switch(evType) {
22411 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053022412 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053022413 break;
22414 default:
22415 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
22416 break;
22417 }
22418 EXIT();
22419}
22420#endif
22421
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022422#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22423 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022424/**
22425 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
22426 * @wiphy: Pointer to wiphy
22427 * @wdev: Pointer to wireless device structure
22428 *
22429 * This function is used to abort an ongoing scan
22430 *
22431 * Return: None
22432 */
22433static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22434 struct wireless_dev *wdev)
22435{
22436 struct net_device *dev = wdev->netdev;
22437 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22438 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
22439 int ret;
22440
22441 ENTER();
22442
22443 if (NULL == adapter) {
22444 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
22445 return;
22446 }
22447
22448 ret = wlan_hdd_validate_context(hdd_ctx);
22449 if (0 != ret)
22450 return;
22451
22452 wlan_hdd_scan_abort(adapter);
22453
22454 return;
22455}
22456
22457/**
22458 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
22459 * @wiphy: Pointer to wiphy
22460 * @wdev: Pointer to wireless device structure
22461 *
22462 * Return: None
22463 */
22464void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
22465 struct wireless_dev *wdev)
22466{
22467 vos_ssr_protect(__func__);
22468 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
22469 vos_ssr_unprotect(__func__);
22470
22471 return;
22472}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022473#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022474
Abhishek Singh936c6932017-11-07 17:28:23 +053022475#ifdef CHANNEL_SWITCH_SUPPORTED
22476/**
22477 * __wlan_hdd_cfg80211_channel_switch()- function to switch
22478 * channel in SAP/GO
22479 * @wiphy: wiphy pointer
22480 * @dev: dev pointer.
22481 * @csa_params: Change channel params
22482 *
22483 * This function is called to switch channel in SAP/GO
22484 *
22485 * Return: 0 if success else return non zero
22486 */
22487static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22488 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22489{
22490 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
22491 hdd_context_t *hdd_ctx;
22492 uint8_t channel;
22493 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022494 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053022495 v_CONTEXT_t vos_ctx;
22496
22497 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
22498
22499 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
22500 ret = wlan_hdd_validate_context(hdd_ctx);
22501 if (ret)
22502 return ret;
22503
22504 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
22505 if (!vos_ctx) {
22506 hddLog(LOGE, FL("Vos ctx is null"));
22507 return -EINVAL;
22508 }
22509
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022510 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053022511 return -ENOTSUPP;
22512
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022513 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
22514 if (!sap_ctx) {
22515 hddLog(LOGE, FL("sap_ctx is NULL"));
22516 return -EINVAL;
22517 }
22518
22519 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
22520 if (ret)
22521 return ret;
22522
22523 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
22524
Abhishek Singh936c6932017-11-07 17:28:23 +053022525 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053022526 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053022527
Abhishek Singh10e17cf2018-03-12 14:34:22 +053022528 if (ret) {
22529 wlansap_reset_chan_change_in_progress(sap_ctx);
22530 complete(&sap_ctx->ecsa_info.chan_switch_comp);
22531 }
22532
Abhishek Singh936c6932017-11-07 17:28:23 +053022533 return ret;
22534}
22535
22536/**
22537 * wlan_hdd_cfg80211_channel_switch()- function to switch
22538 * channel in SAP/GO
22539 * @wiphy: wiphy pointer
22540 * @dev: dev pointer.
22541 * @csa_params: Change channel params
22542 *
22543 * This function is called to switch channel in SAP/GO
22544 *
22545 * Return: 0 if success else return non zero
22546 */
22547static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
22548 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
22549{
22550 int ret;
22551
22552 vos_ssr_protect(__func__);
22553 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
22554 vos_ssr_unprotect(__func__);
22555
22556 return ret;
22557}
22558#endif
22559
Jeff Johnson295189b2012-06-20 16:38:30 -070022560/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053022561static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070022562{
22563 .add_virtual_intf = wlan_hdd_add_virtual_intf,
22564 .del_virtual_intf = wlan_hdd_del_virtual_intf,
22565 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
22566 .change_station = wlan_hdd_change_station,
22567#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
22568 .add_beacon = wlan_hdd_cfg80211_add_beacon,
22569 .del_beacon = wlan_hdd_cfg80211_del_beacon,
22570 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022571#else
22572 .start_ap = wlan_hdd_cfg80211_start_ap,
22573 .change_beacon = wlan_hdd_cfg80211_change_beacon,
22574 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070022575#endif
22576 .change_bss = wlan_hdd_cfg80211_change_bss,
22577 .add_key = wlan_hdd_cfg80211_add_key,
22578 .get_key = wlan_hdd_cfg80211_get_key,
22579 .del_key = wlan_hdd_cfg80211_del_key,
22580 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022581#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070022582 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080022583#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022584 .scan = wlan_hdd_cfg80211_scan,
22585 .connect = wlan_hdd_cfg80211_connect,
22586 .disconnect = wlan_hdd_cfg80211_disconnect,
22587 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22588 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22589 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22590 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22591 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022592 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22593 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022594 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022595#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22596 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22597 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22598 .set_txq_params = wlan_hdd_set_txq_params,
22599#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022600 .get_station = wlan_hdd_cfg80211_get_station,
22601 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22602 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022603 .add_station = wlan_hdd_cfg80211_add_station,
22604#ifdef FEATURE_WLAN_LFR
22605 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22606 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22607 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22608#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022609#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22610 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22611#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022612#ifdef FEATURE_WLAN_TDLS
22613 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22614 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22615#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022616#ifdef WLAN_FEATURE_GTK_OFFLOAD
22617 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22618#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022619#ifdef FEATURE_WLAN_SCAN_PNO
22620 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22621 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22622#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022623 .resume = wlan_hdd_cfg80211_resume_wlan,
22624 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022625 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022626#ifdef WLAN_NL80211_TESTMODE
22627 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22628#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022629 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022630#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22631 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022632 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022633#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022634#ifdef CHANNEL_SWITCH_SUPPORTED
22635 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22636#endif
22637
Abhinav Kumar118efd02019-08-07 16:41:07 +053022638#if defined(WLAN_FEATURE_SAE) && \
22639 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
22640 .external_auth = wlan_hdd_cfg80211_external_auth,
22641#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022642};
22643