blob: 3ac0eac5c4d1ca00f8d87f573cc6d81f18f41405 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Abhishek Singhef6f38c2018-12-20 13:51:29 +05302 * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019/**
20 * DOC: wlan_hdd_cfg80211.c
21 *
22 * WLAN Host Device Driver cfg80211 APIs implementation
23 *
24 */
25
26#include <linux/version.h>
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/etherdevice.h>
31#include <linux/wireless.h>
Dustin Browna09acf42018-11-08 12:32:26 +053032#include "osif_sync.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080033#include <wlan_hdd_includes.h>
34#include <net/arp.h>
35#include <net/cfg80211.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080036#include <wlan_hdd_wowl.h>
37#include <ani_global.h>
38#include "sir_params.h"
39#include "dot11f.h"
40#include "wlan_hdd_assoc.h"
41#include "wlan_hdd_wext.h"
42#include "sme_api.h"
Peng Xu278d0122015-09-24 16:34:17 -070043#include "sme_power_save_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080044#include "wlan_hdd_p2p.h"
45#include "wlan_hdd_cfg80211.h"
46#include "wlan_hdd_hostapd.h"
47#include "wlan_hdd_softap_tx_rx.h"
48#include "wlan_hdd_main.h"
49#include "wlan_hdd_power.h"
50#include "wlan_hdd_trace.h"
Dustin Brownd4241942018-02-26 12:51:37 -080051#include "qdf_str.h"
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053052#include "qdf_trace.h"
Dustin Brownd4241942018-02-26 12:51:37 -080053#include "qdf_types.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080054#include "cds_utils.h"
55#include "cds_sched.h"
56#include "wlan_hdd_scan.h"
57#include <qc_sap_ioctl.h>
58#include "wlan_hdd_tdls.h"
59#include "wlan_hdd_wmm.h"
60#include "wma_types.h"
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053061#include "wma.h"
Arif Hussain1f58cbb2019-03-14 17:06:56 -070062#include "wma_twt.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080063#include "wlan_hdd_misc.h"
64#include "wlan_hdd_nan.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080065#include "wlan_logging_sock_svc.h"
Agrawal Ashish65634612016-08-18 13:24:32 +053066#include "sap_api.h"
Agrawal Ashish21ba2572016-09-03 16:40:10 +053067#include "csr_api.h"
Agrawal Ashish467dde42016-09-08 18:44:22 +053068#include "pld_common.h"
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070069#include "wmi_unified_param.h"
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070070
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -080071#include <cdp_txrx_handle.h>
Sandeep Puligillafdd201e2017-02-02 18:43:46 -080072#include <wlan_cfg80211_scan.h>
Ryan Hsuc8b27a42018-01-02 13:57:56 -080073#include <wlan_cfg80211_ftm.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080074
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080075#include "wlan_hdd_ext_scan.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080076
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080077#include "wlan_hdd_stats.h"
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080078#include "cds_api.h"
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080079#include "wlan_policy_mgr_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080080#include "qwlan_version.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080081
82#include "wlan_hdd_ocb.h"
Manikandan Mohan5356c2b2016-04-03 15:51:35 -070083#include "wlan_hdd_tsf.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080084
Ravi Joshideb5a8d2015-11-09 19:11:43 -080085#include "wlan_hdd_subnet_detect.h"
Abhishek Singh3e6172f2016-05-04 16:56:48 +053086#include <wlan_hdd_regulatory.h>
Jeff Johnson2b0a7b82016-05-18 15:08:02 -070087#include "wlan_hdd_lpass.h"
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -070088#include "wlan_hdd_nan_datapath.h"
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +053089#include "wlan_hdd_disa.h"
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070090#include "wlan_osif_request_manager.h"
Krishna Kumaar Natarajanf5676502017-03-06 10:28:44 -080091#include "wlan_hdd_he.h"
Nachiket Kukade177b5b02018-05-22 20:52:17 +053092#ifdef FEATURE_WLAN_APF
Nachiket Kukaded0dd62e2018-05-21 18:39:22 +053093#include "wlan_hdd_apf.h"
Nachiket Kukade177b5b02018-05-22 20:52:17 +053094#endif
Qun Zhangef655622019-02-25 10:48:10 +080095#include "wlan_hdd_fw_state.h"
stonez2d686482019-03-12 14:54:26 +080096#include "wlan_hdd_mpta_helper.h"
Ravi Joshideb5a8d2015-11-09 19:11:43 -080097
Leo Changfdb45c32016-10-28 11:09:23 -070098#include <cdp_txrx_cmn.h>
99#include <cdp_txrx_misc.h>
Sandeep Puligillafdd201e2017-02-02 18:43:46 -0800100#include <qca_vendor.h>
Mukul Sharma3d36c392017-01-18 18:39:12 +0530101#include "wlan_pmo_ucfg_api.h"
Naveen Rawat5f040ba2017-03-06 12:20:25 -0800102#include "os_if_wifi_pos.h"
Ajit Pal Singh90a45a42017-04-18 18:53:46 +0530103#include "wlan_utility.h"
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -0700104#include "wlan_reg_ucfg_api.h"
Naveen Rawatd2657be2017-10-10 14:31:23 -0700105#include "wifi_pos_api.h"
Sandeep Puligilla063a4342018-01-10 02:50:14 -0800106#include "wlan_hdd_spectralscan.h"
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +0530107#include "wlan_ipa_ucfg_api.h"
Naveen Rawate8b1b822018-01-30 09:46:16 -0800108#include <wlan_cfg80211_mc_cp_stats.h>
Yu Wang157d1472018-03-09 16:05:01 +0800109#include <wlan_cp_stats_mc_ucfg_api.h>
Wu Gaobdb7f272018-07-05 19:33:26 +0800110#include "wlan_tdls_cfg_api.h"
Qiwei Caie689a262018-07-26 15:50:22 +0800111#include <wlan_hdd_bss_transition.h>
112#include <wlan_hdd_concurrency_matrix.h>
113#include <wlan_hdd_p2p_listen_offload.h>
114#include <wlan_hdd_rssi_monitor.h>
115#include <wlan_hdd_sap_cond_chan_switch.h>
116#include <wlan_hdd_station_info.h>
117#include <wlan_hdd_tx_power.h>
118#include <wlan_hdd_active_tos.h>
119#include <wlan_hdd_sar_limits.h>
120#include <wlan_hdd_ota_test.h>
Krunal Soni5e3f9622018-09-26 16:35:50 -0700121#include "wlan_policy_mgr_ucfg.h"
Arunk Khandavalli99716d12018-11-14 15:02:02 +0530122#include "wlan_mlme_ucfg_api.h"
123#include "wlan_mlme_public_struct.h"
Harprit Chhabadae8155d32018-08-22 16:19:34 -0700124#include "wlan_extscan_ucfg_api.h"
Wu Gao93816212018-08-31 16:49:54 +0800125#include "wlan_mlme_ucfg_api.h"
Wu Gao66454f12018-09-26 19:55:41 +0800126#include "wlan_pmo_cfg.h"
127#include "cfg_ucfg_api.h"
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +0530128
Harprit Chhabada6c641ba2018-06-28 14:45:10 -0700129#include "wlan_crypto_global_api.h"
130#include "wlan_nl_to_crypto_params.h"
131#include "wlan_crypto_global_def.h"
jitiphil377bcc12018-10-05 19:46:08 +0530132#include "cdp_txrx_cfg.h"
Min Liu8c5d99e2018-09-10 17:18:44 +0800133#include "wlan_hdd_object_manager.h"
Nachiket Kukade089b9832018-12-12 16:38:17 +0530134#include "nan_ucfg_api.h"
Manikandan Mohand350c192018-11-29 14:01:12 -0800135#include "wlan_fwol_ucfg_api.h"
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -0700136#include "wlan_cfg80211_crypto.h"
Paul Zhang37185672019-05-14 11:20:14 +0800137#include "wlan_cfg80211_interop_issues_ap.h"
gaurank kathpalia97c070b2019-01-07 17:23:06 +0530138#include "wlan_scan_ucfg_api.h"
Jiani Liua5f17222019-03-04 16:22:33 +0800139#include "wlan_hdd_coex_config.h"
Abhinav Kumardbbfd2c2019-05-07 12:22:06 +0530140#include "wlan_hdd_bcn_recv.h"
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +0530141#include "wlan_blm_ucfg_api.h"
guangde4853c402019-05-06 15:54:04 +0800142#include "wlan_hdd_hw_capability.h"
Paul Zhangda2970b2019-06-23 18:16:38 +0800143#include "wlan_hdd_oemdata.h"
Harprit Chhabada6c641ba2018-06-28 14:45:10 -0700144
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800145#define g_mode_rates_size (12)
146#define a_mode_rates_size (8)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800147
148/*
149 * Android CTS verifier needs atleast this much wait time (in msec)
150 */
151#define MAX_REMAIN_ON_CHANNEL_DURATION (5000)
152
153/*
154 * Refer @tCfgProtection structure for definition of the bit map.
155 * below value is obtained by setting the following bit-fields.
156 * enable obss, fromllb, overlapOBSS and overlapFromllb protection.
157 */
158#define IBSS_CFG_PROTECTION_ENABLE_MASK 0x8282
159
160#define HDD2GHZCHAN(freq, chan, flag) { \
Srinivas Girigowda11c28e02017-06-27 20:06:21 -0700161 .band = HDD_NL80211_BAND_2GHZ, \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800162 .center_freq = (freq), \
163 .hw_value = (chan), \
164 .flags = (flag), \
165 .max_antenna_gain = 0, \
Amar Singhal5cccafe2017-02-15 12:42:58 -0800166 .max_power = 0, \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800167}
168
169#define HDD5GHZCHAN(freq, chan, flag) { \
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -0700170 .band = HDD_NL80211_BAND_5GHZ, \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800171 .center_freq = (freq), \
172 .hw_value = (chan), \
173 .flags = (flag), \
174 .max_antenna_gain = 0, \
Amar Singhal5cccafe2017-02-15 12:42:58 -0800175 .max_power = 0, \
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800176}
177
178#define HDD_G_MODE_RATETAB(rate, rate_id, flag) \
179 { \
180 .bitrate = rate, \
181 .hw_value = rate_id, \
182 .flags = flag, \
183 }
184
Agrawal Ashish65634612016-08-18 13:24:32 +0530185#define IS_DFS_MODE_VALID(mode) ((mode >= DFS_MODE_NONE && \
186 mode <= DFS_MODE_DEPRIORITIZE))
Mohit Khannaceb97782017-04-05 16:27:08 -0700187/*
188 * Number of DPTRACE records to dump when a cfg80211 disconnect with reason
189 * WLAN_REASON_DEAUTH_LEAVING DEAUTH is received from user-space.
190 */
191#define WLAN_DEAUTH_DPTRACE_DUMP_COUNT 100
Mukul Sharma05504ac2017-06-08 12:35:53 +0530192#ifndef WLAN_CIPHER_SUITE_GCMP
193#define WLAN_CIPHER_SUITE_GCMP 0x000FAC08
194#endif
195#ifndef WLAN_CIPHER_SUITE_GCMP_256
196#define WLAN_CIPHER_SUITE_GCMP_256 0x000FAC09
197#endif
Mohit Khannaceb97782017-04-05 16:27:08 -0700198
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +0530199static const u32 hdd_gcmp_cipher_suits[] = {
200 WLAN_CIPHER_SUITE_GCMP,
201 WLAN_CIPHER_SUITE_GCMP_256,
202};
203
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800204static const u32 hdd_cipher_suites[] = {
205 WLAN_CIPHER_SUITE_WEP40,
206 WLAN_CIPHER_SUITE_WEP104,
207 WLAN_CIPHER_SUITE_TKIP,
208#ifdef FEATURE_WLAN_ESE
209#define WLAN_CIPHER_SUITE_BTK 0x004096fe /* use for BTK */
210#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
211 WLAN_CIPHER_SUITE_BTK,
212 WLAN_CIPHER_SUITE_KRK,
213 WLAN_CIPHER_SUITE_CCMP,
214#else
215 WLAN_CIPHER_SUITE_CCMP,
216#endif
217#ifdef FEATURE_WLAN_WAPI
218 WLAN_CIPHER_SUITE_SMS4,
219#endif
220#ifdef WLAN_FEATURE_11W
221 WLAN_CIPHER_SUITE_AES_CMAC,
Padma, Santhosh Kumar4117d7a2017-12-20 17:39:33 +0530222#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
223 WLAN_CIPHER_SUITE_BIP_GMAC_128,
224 WLAN_CIPHER_SUITE_BIP_GMAC_256,
225#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800226#endif
227};
228
Abhishek Singhf512bf32016-05-04 16:47:46 +0530229static const struct ieee80211_channel hdd_channels_2_4_ghz[] = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800230 HDD2GHZCHAN(2412, 1, 0),
231 HDD2GHZCHAN(2417, 2, 0),
232 HDD2GHZCHAN(2422, 3, 0),
233 HDD2GHZCHAN(2427, 4, 0),
234 HDD2GHZCHAN(2432, 5, 0),
235 HDD2GHZCHAN(2437, 6, 0),
236 HDD2GHZCHAN(2442, 7, 0),
237 HDD2GHZCHAN(2447, 8, 0),
238 HDD2GHZCHAN(2452, 9, 0),
239 HDD2GHZCHAN(2457, 10, 0),
240 HDD2GHZCHAN(2462, 11, 0),
241 HDD2GHZCHAN(2467, 12, 0),
242 HDD2GHZCHAN(2472, 13, 0),
243 HDD2GHZCHAN(2484, 14, 0),
244};
245
Abhishek Singhf512bf32016-05-04 16:47:46 +0530246static const struct ieee80211_channel hdd_channels_5_ghz[] = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800247 HDD5GHZCHAN(5180, 36, 0),
248 HDD5GHZCHAN(5200, 40, 0),
249 HDD5GHZCHAN(5220, 44, 0),
250 HDD5GHZCHAN(5240, 48, 0),
251 HDD5GHZCHAN(5260, 52, 0),
252 HDD5GHZCHAN(5280, 56, 0),
253 HDD5GHZCHAN(5300, 60, 0),
254 HDD5GHZCHAN(5320, 64, 0),
255 HDD5GHZCHAN(5500, 100, 0),
256 HDD5GHZCHAN(5520, 104, 0),
257 HDD5GHZCHAN(5540, 108, 0),
258 HDD5GHZCHAN(5560, 112, 0),
259 HDD5GHZCHAN(5580, 116, 0),
260 HDD5GHZCHAN(5600, 120, 0),
261 HDD5GHZCHAN(5620, 124, 0),
262 HDD5GHZCHAN(5640, 128, 0),
263 HDD5GHZCHAN(5660, 132, 0),
264 HDD5GHZCHAN(5680, 136, 0),
265 HDD5GHZCHAN(5700, 140, 0),
266 HDD5GHZCHAN(5720, 144, 0),
267 HDD5GHZCHAN(5745, 149, 0),
268 HDD5GHZCHAN(5765, 153, 0),
269 HDD5GHZCHAN(5785, 157, 0),
270 HDD5GHZCHAN(5805, 161, 0),
271 HDD5GHZCHAN(5825, 165, 0),
Ashish Kumar Dhanotiyacc2e0d32017-08-24 20:13:08 +0530272};
273
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -0700274#ifdef WLAN_FEATURE_DSRC
Ashish Kumar Dhanotiyacc2e0d32017-08-24 20:13:08 +0530275static const struct ieee80211_channel hdd_channels_dot11p[] = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800276 HDD5GHZCHAN(5852, 170, 0),
277 HDD5GHZCHAN(5855, 171, 0),
278 HDD5GHZCHAN(5860, 172, 0),
279 HDD5GHZCHAN(5865, 173, 0),
280 HDD5GHZCHAN(5870, 174, 0),
281 HDD5GHZCHAN(5875, 175, 0),
282 HDD5GHZCHAN(5880, 176, 0),
283 HDD5GHZCHAN(5885, 177, 0),
284 HDD5GHZCHAN(5890, 178, 0),
285 HDD5GHZCHAN(5895, 179, 0),
286 HDD5GHZCHAN(5900, 180, 0),
287 HDD5GHZCHAN(5905, 181, 0),
288 HDD5GHZCHAN(5910, 182, 0),
289 HDD5GHZCHAN(5915, 183, 0),
290 HDD5GHZCHAN(5920, 184, 0),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800291};
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -0700292#else
293static const struct ieee80211_channel hdd_etsi13_srd_ch[] = {
294 HDD5GHZCHAN(5845, 169, 0),
295 HDD5GHZCHAN(5865, 173, 0),
296};
297#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800298
Qun Zhang043635a2019-02-27 15:19:29 +0800299#define band_2_ghz_channels_size sizeof(hdd_channels_2_4_ghz)
300
301#ifdef WLAN_FEATURE_DSRC
302#define band_5_ghz_chanenls_size (sizeof(hdd_channels_5_ghz) + \
303 sizeof(hdd_channels_dot11p))
304#else
305#define band_5_ghz_chanenls_size (sizeof(hdd_channels_5_ghz) + \
306 sizeof(hdd_etsi13_srd_ch))
307#endif
308
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800309static struct ieee80211_rate g_mode_rates[] = {
310 HDD_G_MODE_RATETAB(10, 0x1, 0),
311 HDD_G_MODE_RATETAB(20, 0x2, 0),
312 HDD_G_MODE_RATETAB(55, 0x4, 0),
313 HDD_G_MODE_RATETAB(110, 0x8, 0),
314 HDD_G_MODE_RATETAB(60, 0x10, 0),
315 HDD_G_MODE_RATETAB(90, 0x20, 0),
316 HDD_G_MODE_RATETAB(120, 0x40, 0),
317 HDD_G_MODE_RATETAB(180, 0x80, 0),
318 HDD_G_MODE_RATETAB(240, 0x100, 0),
319 HDD_G_MODE_RATETAB(360, 0x200, 0),
320 HDD_G_MODE_RATETAB(480, 0x400, 0),
321 HDD_G_MODE_RATETAB(540, 0x800, 0),
322};
323
324static struct ieee80211_rate a_mode_rates[] = {
325 HDD_G_MODE_RATETAB(60, 0x10, 0),
326 HDD_G_MODE_RATETAB(90, 0x20, 0),
327 HDD_G_MODE_RATETAB(120, 0x40, 0),
328 HDD_G_MODE_RATETAB(180, 0x80, 0),
329 HDD_G_MODE_RATETAB(240, 0x100, 0),
330 HDD_G_MODE_RATETAB(360, 0x200, 0),
331 HDD_G_MODE_RATETAB(480, 0x400, 0),
332 HDD_G_MODE_RATETAB(540, 0x800, 0),
333};
334
335static struct ieee80211_supported_band wlan_hdd_band_2_4_ghz = {
Abhishek Singhf512bf32016-05-04 16:47:46 +0530336 .channels = NULL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800337 .n_channels = ARRAY_SIZE(hdd_channels_2_4_ghz),
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -0700338 .band = HDD_NL80211_BAND_2GHZ,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800339 .bitrates = g_mode_rates,
340 .n_bitrates = g_mode_rates_size,
341 .ht_cap.ht_supported = 1,
342 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
343 | IEEE80211_HT_CAP_GRN_FLD
344 | IEEE80211_HT_CAP_DSSSCCK40
345 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
346 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
347 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
348 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
349 .ht_cap.mcs.rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
350 .ht_cap.mcs.rx_highest = cpu_to_le16(72),
351 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
352};
353
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800354static struct ieee80211_supported_band wlan_hdd_band_5_ghz = {
Abhishek Singhf512bf32016-05-04 16:47:46 +0530355 .channels = NULL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800356 .n_channels = ARRAY_SIZE(hdd_channels_5_ghz),
Srinivas Girigowda11c28e02017-06-27 20:06:21 -0700357 .band = HDD_NL80211_BAND_5GHZ,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800358 .bitrates = a_mode_rates,
359 .n_bitrates = a_mode_rates_size,
360 .ht_cap.ht_supported = 1,
361 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
362 | IEEE80211_HT_CAP_GRN_FLD
363 | IEEE80211_HT_CAP_DSSSCCK40
364 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
365 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
366 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
367 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
368 .ht_cap.mcs.rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
369 .ht_cap.mcs.rx_highest = cpu_to_le16(72),
370 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
371 .vht_cap.vht_supported = 1,
372};
373
374/* This structure contain information what kind of frame are expected in
Jeff Johnsonf3826e12017-01-12 09:49:40 -0800375 * TX/RX direction for each kind of interface
376 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800377static const struct ieee80211_txrx_stypes
378 wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
379 [NL80211_IFTYPE_STATION] = {
380 .tx = 0xffff,
381 .rx = BIT(SIR_MAC_MGMT_ACTION) |
Padma, Santhosh Kumar1ccc1332017-09-13 17:39:01 +0530382 BIT(SIR_MAC_MGMT_PROBE_REQ) |
383 BIT(SIR_MAC_MGMT_AUTH),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800384 },
385 [NL80211_IFTYPE_AP] = {
386 .tx = 0xffff,
387 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
388 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
389 BIT(SIR_MAC_MGMT_PROBE_REQ) |
390 BIT(SIR_MAC_MGMT_DISASSOC) |
391 BIT(SIR_MAC_MGMT_AUTH) |
392 BIT(SIR_MAC_MGMT_DEAUTH) |
393 BIT(SIR_MAC_MGMT_ACTION),
394 },
395 [NL80211_IFTYPE_ADHOC] = {
396 .tx = 0xffff,
397 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
398 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
399 BIT(SIR_MAC_MGMT_PROBE_REQ) |
400 BIT(SIR_MAC_MGMT_DISASSOC) |
401 BIT(SIR_MAC_MGMT_AUTH) |
402 BIT(SIR_MAC_MGMT_DEAUTH) |
403 BIT(SIR_MAC_MGMT_ACTION),
404 },
405 [NL80211_IFTYPE_P2P_CLIENT] = {
406 .tx = 0xffff,
407 .rx = BIT(SIR_MAC_MGMT_ACTION) |
408 BIT(SIR_MAC_MGMT_PROBE_REQ),
409 },
410 [NL80211_IFTYPE_P2P_GO] = {
411 /* This is also same as for SoftAP */
412 .tx = 0xffff,
413 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
414 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
415 BIT(SIR_MAC_MGMT_PROBE_REQ) |
416 BIT(SIR_MAC_MGMT_DISASSOC) |
417 BIT(SIR_MAC_MGMT_AUTH) |
418 BIT(SIR_MAC_MGMT_DEAUTH) |
419 BIT(SIR_MAC_MGMT_ACTION),
420 },
421};
422
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800423/* Interface limits and combinations registered by the driver */
424
425/* STA ( + STA ) combination */
426static const struct ieee80211_iface_limit
427 wlan_hdd_sta_iface_limit[] = {
428 {
429 .max = 3, /* p2p0 is a STA as well */
430 .types = BIT(NL80211_IFTYPE_STATION),
431 },
432};
433
434/* ADHOC (IBSS) limit */
435static const struct ieee80211_iface_limit
436 wlan_hdd_adhoc_iface_limit[] = {
437 {
438 .max = 1,
439 .types = BIT(NL80211_IFTYPE_STATION),
440 },
441 {
442 .max = 1,
443 .types = BIT(NL80211_IFTYPE_ADHOC),
444 },
445};
446
447/* AP ( + AP ) combination */
448static const struct ieee80211_iface_limit
449 wlan_hdd_ap_iface_limit[] = {
450 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530451 .max = (QDF_MAX_NO_OF_SAP_MODE + SAP_MAX_OBSS_STA_CNT),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800452 .types = BIT(NL80211_IFTYPE_AP),
453 },
454};
455
456/* P2P limit */
457static const struct ieee80211_iface_limit
458 wlan_hdd_p2p_iface_limit[] = {
459 {
460 .max = 1,
461 .types = BIT(NL80211_IFTYPE_P2P_CLIENT),
462 },
463 {
464 .max = 1,
465 .types = BIT(NL80211_IFTYPE_P2P_GO),
466 },
467};
468
469static const struct ieee80211_iface_limit
470 wlan_hdd_sta_ap_iface_limit[] = {
471 {
472 /* We need 1 extra STA interface for OBSS scan when SAP starts
473 * with HT40 in STA+SAP concurrency mode
474 */
475 .max = (1 + SAP_MAX_OBSS_STA_CNT),
476 .types = BIT(NL80211_IFTYPE_STATION),
477 },
478 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530479 .max = QDF_MAX_NO_OF_SAP_MODE,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800480 .types = BIT(NL80211_IFTYPE_AP),
481 },
482};
483
484/* STA + P2P combination */
485static const struct ieee80211_iface_limit
486 wlan_hdd_sta_p2p_iface_limit[] = {
487 {
488 /* One reserved for dedicated P2PDEV usage */
489 .max = 2,
490 .types = BIT(NL80211_IFTYPE_STATION)
491 },
492 {
493 /* Support for two identical (GO + GO or CLI + CLI)
494 * or dissimilar (GO + CLI) P2P interfaces
495 */
496 .max = 2,
497 .types = BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT),
498 },
499};
500
501/* STA + AP + P2PGO combination */
502static const struct ieee80211_iface_limit
503wlan_hdd_sta_ap_p2pgo_iface_limit[] = {
504 /* Support for AP+P2PGO interfaces */
505 {
506 .max = 2,
507 .types = BIT(NL80211_IFTYPE_STATION)
508 },
509 {
510 .max = 1,
511 .types = BIT(NL80211_IFTYPE_P2P_GO)
512 },
513 {
514 .max = 1,
515 .types = BIT(NL80211_IFTYPE_AP)
516 }
517};
518
519/* SAP + P2P combination */
520static const struct ieee80211_iface_limit
521wlan_hdd_sap_p2p_iface_limit[] = {
522 {
523 /* 1 dedicated for p2p0 which is a STA type */
524 .max = 1,
525 .types = BIT(NL80211_IFTYPE_STATION)
526 },
527 {
528 /* The p2p interface in SAP+P2P can be GO/CLI.
529 * The p2p connection can be formed on p2p0 or p2p-p2p0-x.
530 */
531 .max = 1,
532 .types = BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT)
533 },
534 {
535 /* SAP+GO to support only one SAP interface */
536 .max = 1,
537 .types = BIT(NL80211_IFTYPE_AP)
538 }
539};
540
541/* P2P + P2P combination */
542static const struct ieee80211_iface_limit
543wlan_hdd_p2p_p2p_iface_limit[] = {
544 {
545 /* 1 dedicated for p2p0 which is a STA type */
546 .max = 1,
547 .types = BIT(NL80211_IFTYPE_STATION)
548 },
549 {
550 /* The p2p interface in P2P+P2P can be GO/CLI.
551 * For P2P+P2P, the new interfaces are formed on p2p-p2p0-x.
552 */
553 .max = 2,
554 .types = BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT)
555 },
556};
557
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -0700558static const struct ieee80211_iface_limit
559 wlan_hdd_mon_iface_limit[] = {
560 {
561 .max = 3, /* Monitor interface */
562 .types = BIT(NL80211_IFTYPE_MONITOR),
563 },
564};
565
566static struct ieee80211_iface_combination
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800567 wlan_hdd_iface_combination[] = {
568 /* STA */
569 {
570 .limits = wlan_hdd_sta_iface_limit,
571 .num_different_channels = 2,
572 .max_interfaces = 3,
573 .n_limits = ARRAY_SIZE(wlan_hdd_sta_iface_limit),
574 },
575 /* ADHOC */
576 {
577 .limits = wlan_hdd_adhoc_iface_limit,
Krunal Soni2c68f232015-10-26 20:52:51 -0700578 .num_different_channels = 2,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800579 .max_interfaces = 2,
580 .n_limits = ARRAY_SIZE(wlan_hdd_adhoc_iface_limit),
581 },
582 /* AP */
583 {
584 .limits = wlan_hdd_ap_iface_limit,
585 .num_different_channels = 2,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530586 .max_interfaces = (SAP_MAX_OBSS_STA_CNT + QDF_MAX_NO_OF_SAP_MODE),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800587 .n_limits = ARRAY_SIZE(wlan_hdd_ap_iface_limit),
hqu3c4ed3d2017-09-19 11:42:35 +0800588#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) || \
589 defined(CFG80211_BEACON_INTERVAL_BACKPORT)
590 .beacon_int_min_gcd = 1,
591#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800592 },
593 /* P2P */
594 {
595 .limits = wlan_hdd_p2p_iface_limit,
596 .num_different_channels = 2,
597 .max_interfaces = 2,
598 .n_limits = ARRAY_SIZE(wlan_hdd_p2p_iface_limit),
599 },
600 /* STA + AP */
601 {
602 .limits = wlan_hdd_sta_ap_iface_limit,
603 .num_different_channels = 2,
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530604 .max_interfaces = (1 + SAP_MAX_OBSS_STA_CNT + QDF_MAX_NO_OF_SAP_MODE),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800605 .n_limits = ARRAY_SIZE(wlan_hdd_sta_ap_iface_limit),
606 .beacon_int_infra_match = true,
hqu3c4ed3d2017-09-19 11:42:35 +0800607#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) || \
608 defined(CFG80211_BEACON_INTERVAL_BACKPORT)
609 .beacon_int_min_gcd = 1,
610#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800611 },
612 /* STA + P2P */
613 {
614 .limits = wlan_hdd_sta_p2p_iface_limit,
615 .num_different_channels = 2,
616 /* one interface reserved for P2PDEV dedicated usage */
617 .max_interfaces = 4,
618 .n_limits = ARRAY_SIZE(wlan_hdd_sta_p2p_iface_limit),
619 .beacon_int_infra_match = true,
620 },
621 /* STA + P2P GO + SAP */
622 {
623 .limits = wlan_hdd_sta_ap_p2pgo_iface_limit,
624 /* we can allow 3 channels for three different persona
625 * but due to firmware limitation, allow max 2 concrnt channels.
626 */
627 .num_different_channels = 2,
628 /* one interface reserved for P2PDEV dedicated usage */
629 .max_interfaces = 4,
630 .n_limits = ARRAY_SIZE(wlan_hdd_sta_ap_p2pgo_iface_limit),
631 .beacon_int_infra_match = true,
632 },
633 /* SAP + P2P */
634 {
635 .limits = wlan_hdd_sap_p2p_iface_limit,
636 .num_different_channels = 2,
637 /* 1-p2p0 + 1-SAP + 1-P2P (on p2p0 or p2p-p2p0-x) */
638 .max_interfaces = 3,
639 .n_limits = ARRAY_SIZE(wlan_hdd_sap_p2p_iface_limit),
640 .beacon_int_infra_match = true,
641 },
642 /* P2P + P2P */
643 {
644 .limits = wlan_hdd_p2p_p2p_iface_limit,
645 .num_different_channels = 2,
646 /* 1-p2p0 + 2-P2P (on p2p-p2p0-x) */
647 .max_interfaces = 3,
648 .n_limits = ARRAY_SIZE(wlan_hdd_p2p_p2p_iface_limit),
649 .beacon_int_infra_match = true,
650 },
Arun Khandavallifae92942016-08-01 13:31:08 +0530651 /* Monitor */
652 {
653 .limits = wlan_hdd_mon_iface_limit,
654 .max_interfaces = 3,
655 .num_different_channels = 2,
656 .n_limits = ARRAY_SIZE(wlan_hdd_mon_iface_limit),
657 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800658};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800659
660static struct cfg80211_ops wlan_hdd_cfg80211_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800661
662#ifdef WLAN_NL80211_TESTMODE
663enum wlan_hdd_tm_attr {
664 WLAN_HDD_TM_ATTR_INVALID = 0,
665 WLAN_HDD_TM_ATTR_CMD = 1,
666 WLAN_HDD_TM_ATTR_DATA = 2,
667 WLAN_HDD_TM_ATTR_STREAM_ID = 3,
668 WLAN_HDD_TM_ATTR_TYPE = 4,
669 /* keep last */
670 WLAN_HDD_TM_ATTR_AFTER_LAST,
671 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
672};
673
674enum wlan_hdd_tm_cmd {
675 WLAN_HDD_TM_CMD_WLAN_FTM = 0,
676 WLAN_HDD_TM_CMD_WLAN_HB = 1,
677};
678
679#define WLAN_HDD_TM_DATA_MAX_LEN 5000
680
681static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] = {
682 [WLAN_HDD_TM_ATTR_CMD] = {.type = NLA_U32},
683 [WLAN_HDD_TM_ATTR_DATA] = {.type = NLA_BINARY,
684 .len = WLAN_HDD_TM_DATA_MAX_LEN},
685};
686#endif /* WLAN_NL80211_TESTMODE */
687
Lin Baia016e9a2017-08-29 19:10:42 +0800688enum wlan_hdd_vendor_ie_access_policy {
689 WLAN_HDD_VENDOR_IE_ACCESS_NONE = 0,
690 WLAN_HDD_VENDOR_IE_ACCESS_ALLOW_IF_LISTED,
691};
692
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
694static const struct wiphy_wowlan_support wowlan_support_cfg80211_init = {
695 .flags = WIPHY_WOWLAN_MAGIC_PKT,
696 .n_patterns = WOWL_MAX_PTRNS_ALLOWED,
697 .pattern_min_len = 1,
698 .pattern_max_len = WOWL_PTRN_MAX_SIZE,
699};
700#endif
701
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800702/**
Abhishek Singh1bdb1572015-10-16 16:24:19 +0530703 * hdd_add_channel_switch_support()- Adds Channel Switch flag if supported
704 * @flags: Pointer to the flags to Add channel switch flag.
705 *
706 * This Function adds Channel Switch support flag, if channel switch is
707 * supported by kernel.
708 * Return: void.
709 */
710#ifdef CHANNEL_SWITCH_SUPPORTED
711static inline void hdd_add_channel_switch_support(uint32_t *flags)
712{
Krishna Kumaar Natarajan8a8df262015-12-04 11:43:46 -0800713 *flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
Abhishek Singh1bdb1572015-10-16 16:24:19 +0530714}
715#else
716static inline void hdd_add_channel_switch_support(uint32_t *flags)
717{
Abhishek Singh1bdb1572015-10-16 16:24:19 +0530718}
719#endif
720
Manikandan Mohan22b83722015-12-15 15:03:23 -0800721#ifdef FEATURE_WLAN_TDLS
722
723/* TDLS capabilities params */
724#define PARAM_MAX_TDLS_SESSION \
725 QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_MAX_CONC_SESSIONS
726#define PARAM_TDLS_FEATURE_SUPPORT \
727 QCA_WLAN_VENDOR_ATTR_TDLS_GET_CAPS_FEATURES_SUPPORTED
728
Abhishek Singh1bdb1572015-10-16 16:24:19 +0530729/**
Jeff Johnson118a4a02018-05-06 00:14:15 -0700730 * __wlan_hdd_cfg80211_get_tdls_capabilities() - Provide TDLS Capabilities.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800731 * @wiphy: WIPHY structure pointer
732 * @wdev: Wireless device structure pointer
733 * @data: Pointer to the data received
734 * @data_len: Length of the data received
735 *
736 * This function provides TDLS capabilities
737 *
738 * Return: 0 on success and errno on failure
739 */
740static int __wlan_hdd_cfg80211_get_tdls_capabilities(struct wiphy *wiphy,
741 struct wireless_dev *wdev,
742 const void *data,
743 int data_len)
744{
745 int status;
Jeff Johnson7aeb95b2017-08-28 12:06:33 -0700746 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800747 struct sk_buff *skb;
748 uint32_t set = 0;
Frank Liu5c63dc82017-09-07 14:49:05 +0800749 uint32_t max_num_tdls_sta = 0;
Wu Gaobdb7f272018-07-05 19:33:26 +0800750 bool tdls_support;
751 bool tdls_external_control;
752 bool tdls_sleep_sta_enable;
753 bool tdls_buffer_sta;
754 bool tdls_off_channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755
Dustin Brownfdf17c12018-03-14 12:55:34 -0700756 hdd_enter_dev(wdev->netdev);
Jeff Johnson1f61b612016-02-12 16:28:33 -0800757
Anurag Chouhan6d760662016-02-20 16:05:43 +0530758 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800759 hdd_err("Command not allowed in FTM mode");
760 return -EPERM;
761 }
762
763 status = wlan_hdd_validate_context(hdd_ctx);
764 if (status)
765 return status;
766
767 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, (2 * sizeof(u32)) +
768 NLMSG_HDRLEN);
769 if (!skb) {
Jeff Johnson020db452016-06-29 14:37:26 -0700770 hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800771 goto fail;
772 }
773
Dustin Brown76cd2932018-09-11 16:03:05 -0700774 if ((cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support) ==
Bala Venkateshdcbad342019-03-18 13:57:24 +0530775 QDF_STATUS_SUCCESS) && !tdls_support) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -0800776 hdd_debug("TDLS feature not Enabled or Not supported in FW");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800777 if (nla_put_u32(skb, PARAM_MAX_TDLS_SESSION, 0) ||
778 nla_put_u32(skb, PARAM_TDLS_FEATURE_SUPPORT, 0)) {
Jeff Johnson020db452016-06-29 14:37:26 -0700779 hdd_err("nla put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800780 goto fail;
781 }
782 } else {
Dustin Brown76cd2932018-09-11 16:03:05 -0700783 cfg_tdls_get_external_control(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +0800784 &tdls_external_control);
Dustin Brown76cd2932018-09-11 16:03:05 -0700785 cfg_tdls_get_sleep_sta_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +0800786 &tdls_sleep_sta_enable);
Dustin Brown76cd2932018-09-11 16:03:05 -0700787 cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +0800788 &tdls_buffer_sta);
Dustin Brown76cd2932018-09-11 16:03:05 -0700789 cfg_tdls_get_off_channel_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +0800790 &tdls_off_channel);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800791 set = set | WIFI_TDLS_SUPPORT;
Wu Gaobdb7f272018-07-05 19:33:26 +0800792 set = set | (tdls_external_control ?
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800793 WIFI_TDLS_EXTERNAL_CONTROL_SUPPORT : 0);
Wu Gaobdb7f272018-07-05 19:33:26 +0800794 set = set | (tdls_off_channel ?
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800795 WIIF_TDLS_OFFCHANNEL_SUPPORT : 0);
Wu Gaobdb7f272018-07-05 19:33:26 +0800796 if (tdls_sleep_sta_enable || tdls_buffer_sta ||
797 tdls_off_channel)
Frank Liu5c63dc82017-09-07 14:49:05 +0800798 max_num_tdls_sta = HDD_MAX_NUM_TDLS_STA_P_UAPSD_OFFCHAN;
799 else
800 max_num_tdls_sta = HDD_MAX_NUM_TDLS_STA;
801
Srinivas Girigowda13d39252017-03-06 16:12:15 -0800802 hdd_debug("TDLS Feature supported value %x", set);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800803 if (nla_put_u32(skb, PARAM_MAX_TDLS_SESSION,
Frank Liu5c63dc82017-09-07 14:49:05 +0800804 max_num_tdls_sta) ||
805 nla_put_u32(skb, PARAM_TDLS_FEATURE_SUPPORT, set)) {
Jeff Johnson020db452016-06-29 14:37:26 -0700806 hdd_err("nla put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800807 goto fail;
808 }
809 }
810 return cfg80211_vendor_cmd_reply(skb);
811fail:
812 if (skb)
813 kfree_skb(skb);
814 return -EINVAL;
815}
816
817/**
Jeff Johnson118a4a02018-05-06 00:14:15 -0700818 * wlan_hdd_cfg80211_get_tdls_capabilities() - Provide TDLS Capabilities.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800819 * @wiphy: WIPHY structure pointer
820 * @wdev: Wireless device structure pointer
821 * @data: Pointer to the data received
822 * @data_len: Length of the data received
823 *
824 * This function provides TDLS capabilities
825 *
826 * Return: 0 on success and errno on failure
827 */
828static int
829wlan_hdd_cfg80211_get_tdls_capabilities(struct wiphy *wiphy,
830 struct wireless_dev *wdev,
831 const void *data,
832 int data_len)
833{
Dustin Brown363b4792019-02-05 16:11:55 -0800834 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -0800835 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +0530836
Dustin Brown363b4792019-02-05 16:11:55 -0800837 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -0800838 if (errno)
839 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800840
Dustin Brownf0f00612019-01-31 16:02:24 -0800841 errno = __wlan_hdd_cfg80211_get_tdls_capabilities(wiphy, wdev,
842 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800843
Dustin Brown363b4792019-02-05 16:11:55 -0800844 osif_psoc_sync_op_stop(psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -0800845
846 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800847}
jiad7b8a5e02018-11-26 16:37:57 +0800848
849static uint8_t hdd_get_bw_offset(uint32_t ch_width)
850{
851 uint8_t bw_offset = 0;
852
853 if (ch_width == CH_WIDTH_40MHZ)
854 bw_offset = 1 << BW_40_OFFSET_BIT;
855 else if (ch_width == CH_WIDTH_20MHZ)
856 bw_offset = 1 << BW_20_OFFSET_BIT;
857
858 return bw_offset;
859}
860
861#else /* !FEATURE_WLAN_TDLS */
862
863static inline uint8_t hdd_get_bw_offset(uint32_t ch_width)
864{
865 return 0;
866}
867
868#endif /* FEATURE_WLAN_TDLS */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800869
870#ifdef QCA_HT_2040_COEX
871static void wlan_hdd_cfg80211_start_pending_acs(struct work_struct *work);
872#endif
873
Kiran Kumar Lokere48795792017-07-07 15:34:29 -0700874int wlan_hdd_merge_avoid_freqs(struct ch_avoid_ind_type *destFreqList,
875 struct ch_avoid_ind_type *srcFreqList)
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +0530876{
877 int i;
Jeff Johnson62f28992019-03-05 14:48:42 -0800878 uint32_t room;
Kiran Kumar Lokere48795792017-07-07 15:34:29 -0700879 struct ch_avoid_freq_type *avoid_range =
880 &destFreqList->avoid_freq_range[destFreqList->ch_avoid_range_cnt];
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +0530881
Jeff Johnson62f28992019-03-05 14:48:42 -0800882 room = CH_AVOID_MAX_RANGE - destFreqList->ch_avoid_range_cnt;
883 if (srcFreqList->ch_avoid_range_cnt > room) {
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +0530884 hdd_err("avoid freq overflow");
885 return -EINVAL;
886 }
Jeff Johnson62f28992019-03-05 14:48:42 -0800887 destFreqList->ch_avoid_range_cnt += srcFreqList->ch_avoid_range_cnt;
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +0530888
Kiran Kumar Lokere48795792017-07-07 15:34:29 -0700889 for (i = 0; i < srcFreqList->ch_avoid_range_cnt; i++) {
890 avoid_range->start_freq =
891 srcFreqList->avoid_freq_range[i].start_freq;
892 avoid_range->end_freq =
893 srcFreqList->avoid_freq_range[i].end_freq;
894 avoid_range++;
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +0530895 }
896 return 0;
897}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800898/*
899 * FUNCTION: wlan_hdd_send_avoid_freq_event
900 * This is called when wlan driver needs to send vendor specific
901 * avoid frequency range event to userspace
902 */
Jeff Johnsonb8944722017-09-03 09:03:19 -0700903int wlan_hdd_send_avoid_freq_event(struct hdd_context *hdd_ctx,
Kiran Kumar Lokere48795792017-07-07 15:34:29 -0700904 struct ch_avoid_ind_type *avoid_freq_list)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800905{
906 struct sk_buff *vendor_event;
907
Dustin Brown491d54b2018-03-14 12:39:11 -0700908 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800909
Jeff Johnsonb8944722017-09-03 09:03:19 -0700910 if (!hdd_ctx) {
Jeff Johnson020db452016-06-29 14:37:26 -0700911 hdd_err("HDD context is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800912 return -EINVAL;
913 }
914
Kiran Kumar Lokere48795792017-07-07 15:34:29 -0700915 if (!avoid_freq_list) {
916 hdd_err("avoid_freq_list is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800917 return -EINVAL;
918 }
919
Jeff Johnsonb8944722017-09-03 09:03:19 -0700920 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
Kiran Kumar Lokere48795792017-07-07 15:34:29 -0700921 NULL, sizeof(struct ch_avoid_ind_type),
922 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
923 GFP_KERNEL);
924
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925 if (!vendor_event) {
Jeff Johnson020db452016-06-29 14:37:26 -0700926 hdd_err("cfg80211_vendor_event_alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800927 return -EINVAL;
928 }
929
Kiran Kumar Lokere48795792017-07-07 15:34:29 -0700930 memcpy(skb_put(vendor_event, sizeof(struct ch_avoid_ind_type)),
931 (void *)avoid_freq_list, sizeof(struct ch_avoid_ind_type));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800932
933 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
934
Dustin Browne74003f2018-03-14 12:51:58 -0700935 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800936 return 0;
937}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800938
Anurag Chouhan4085ff72017-10-05 18:09:56 +0530939/*
940 * define short names for the global vendor params
941 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
942 */
943#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
944
945/**
946 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
947 * hang reason
948 * @reason: cds recovery reason
949 *
950 * Return: Vendor specific reason code
951 */
952static enum qca_wlan_vendor_hang_reason
953hdd_convert_hang_reason(enum qdf_hang_reason reason)
954{
Mahesh Kumar Kalikot Veetil9111a572017-10-10 16:11:11 -0700955 u32 ret_val;
Anurag Chouhan4085ff72017-10-05 18:09:56 +0530956
957 switch (reason) {
958 case QDF_RX_HASH_NO_ENTRY_FOUND:
959 ret_val = QCA_WLAN_HANG_RX_HASH_NO_ENTRY_FOUND;
960 break;
961 case QDF_PEER_DELETION_TIMEDOUT:
962 ret_val = QCA_WLAN_HANG_PEER_DELETION_TIMEDOUT;
963 break;
964 case QDF_PEER_UNMAP_TIMEDOUT:
965 ret_val = QCA_WLAN_HANG_PEER_UNMAP_TIMEDOUT;
966 break;
967 case QDF_SCAN_REQ_EXPIRED:
968 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
969 break;
970 case QDF_SCAN_ATTEMPT_FAILURES:
971 ret_val = QCA_WLAN_HANG_SCAN_ATTEMPT_FAILURES;
972 break;
973 case QDF_GET_MSG_BUFF_FAILURE:
974 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
975 break;
976 case QDF_ACTIVE_LIST_TIMEOUT:
977 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
978 break;
979 case QDF_SUSPEND_TIMEOUT:
980 ret_val = QCA_WLAN_HANG_SUSPEND_TIMEOUT;
981 break;
982 case QDF_RESUME_TIMEOUT:
983 ret_val = QCA_WLAN_HANG_RESUME_TIMEOUT;
984 break;
Jingxiang Ge2a67be52019-04-10 14:47:51 +0800985 case QDF_WMI_EXCEED_MAX_PENDING_CMDS:
986 ret_val = QCA_WLAN_HANG_WMI_EXCEED_MAX_PENDING_CMDS;
987 break;
Anurag Chouhan4085ff72017-10-05 18:09:56 +0530988 case QDF_REASON_UNSPECIFIED:
989 default:
990 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
991 }
992 return ret_val;
993}
994
995/**
996 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
997 * @hdd_ctx: Pointer to hdd context
998 * @reason: cds recovery reason
999 *
1000 * Return: 0 on success or failure reason
1001 */
1002int wlan_hdd_send_hang_reason_event(struct hdd_context *hdd_ctx,
1003 enum qdf_hang_reason reason)
1004{
1005 struct sk_buff *vendor_event;
1006 enum qca_wlan_vendor_hang_reason hang_reason;
1007
Dustin Brown491d54b2018-03-14 12:39:11 -07001008 hdd_enter();
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301009
1010 if (!hdd_ctx) {
1011 hdd_err("HDD context is null");
1012 return -EINVAL;
1013 }
1014
1015 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
1016 NULL,
1017 sizeof(uint32_t),
1018 HANG_REASON_INDEX,
1019 GFP_KERNEL);
1020 if (!vendor_event) {
1021 hdd_err("cfg80211_vendor_event_alloc failed");
1022 return -ENOMEM;
1023 }
1024
1025 hang_reason = hdd_convert_hang_reason(reason);
1026
1027 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
Mahesh Kumar Kalikot Veetil9111a572017-10-10 16:11:11 -07001028 (uint32_t)hang_reason)) {
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301029 hdd_err("QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
1030 kfree_skb(vendor_event);
1031 return -EINVAL;
1032 }
1033
1034 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
1035
Dustin Browne74003f2018-03-14 12:51:58 -07001036 hdd_exit();
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301037 return 0;
1038}
Mahesh Kumar Kalikot Veetil9111a572017-10-10 16:11:11 -07001039
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301040#undef HANG_REASON_INDEX
1041
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301042/**
1043 * wlan_hdd_get_adjacent_chan(): Gets next/previous channel
1044 * with respect to the channel passed.
1045 * @chan: Channel
1046 * @upper: If "true" then next channel is returned or else
1047 * previous channel is returned.
1048 *
1049 * This function returns the next/previous adjacent-channel to
1050 * the channel passed. If "upper = true" then next channel is
1051 * returned else previous is returned.
1052 */
1053int wlan_hdd_get_adjacent_chan(uint8_t chan, bool upper)
1054{
Ashish Kumar Dhanotiyaaa9fdbb2018-12-14 15:29:14 +05301055 enum channel_enum ch_idx = wlan_reg_get_chan_enum(chan);
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301056
1057 if (ch_idx == INVALID_CHANNEL)
1058 return -EINVAL;
1059
1060 if (upper && (ch_idx < (NUM_CHANNELS - 1)))
1061 ch_idx++;
1062 else if (!upper && (ch_idx > CHAN_ENUM_1))
1063 ch_idx--;
1064 else
1065 return -EINVAL;
1066
1067 return WLAN_REG_CH_NUM(ch_idx);
1068}
1069
1070/**
1071 * wlan_hdd_send_avoid_freq_for_dnbs(): Sends list of frequencies to be
1072 * avoided when Do_Not_Break_Stream is active.
Jeff Johnsonb8944722017-09-03 09:03:19 -07001073 * @hdd_ctx: HDD Context
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301074 * @op_chan: AP/P2P-GO operating channel
1075 *
1076 * This function sends list of frequencies to be avoided when
1077 * Do_Not_Break_Stream is active.
1078 * To clear the avoid_frequency_list in the application,
1079 * op_chan = 0 can be passed.
1080 *
1081 * Return: 0 on success and errno on failure
1082 */
Jeff Johnsonb8944722017-09-03 09:03:19 -07001083int wlan_hdd_send_avoid_freq_for_dnbs(struct hdd_context *hdd_ctx, uint8_t op_chan)
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301084{
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001085 struct ch_avoid_ind_type p2p_avoid_freq_list;
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301086 uint8_t min_chan, max_chan;
1087 int ret;
1088 int chan;
1089
Dustin Brown491d54b2018-03-14 12:39:11 -07001090 hdd_enter();
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301091
Jeff Johnsonb8944722017-09-03 09:03:19 -07001092 if (!hdd_ctx) {
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301093 hdd_err("invalid param");
1094 return -EINVAL;
1095 }
1096
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001097 qdf_mem_zero(&p2p_avoid_freq_list, sizeof(struct ch_avoid_ind_type));
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301098 /*
1099 * If channel passed is zero, clear the avoid_freq list in application.
1100 */
1101 if (!op_chan) {
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05301102#ifdef FEATURE_WLAN_CH_AVOID
Jeff Johnsonb8944722017-09-03 09:03:19 -07001103 mutex_lock(&hdd_ctx->avoid_freq_lock);
1104 qdf_mem_zero(&hdd_ctx->dnbs_avoid_freq_list,
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001105 sizeof(struct ch_avoid_ind_type));
Jeff Johnsonb8944722017-09-03 09:03:19 -07001106 if (hdd_ctx->coex_avoid_freq_list.ch_avoid_range_cnt)
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05301107 memcpy(&p2p_avoid_freq_list,
Jeff Johnsonb8944722017-09-03 09:03:19 -07001108 &hdd_ctx->coex_avoid_freq_list,
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001109 sizeof(struct ch_avoid_ind_type));
Jeff Johnsonb8944722017-09-03 09:03:19 -07001110 mutex_unlock(&hdd_ctx->avoid_freq_lock);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05301111#endif
Jeff Johnsonb8944722017-09-03 09:03:19 -07001112 ret = wlan_hdd_send_avoid_freq_event(hdd_ctx,
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301113 &p2p_avoid_freq_list);
1114 if (ret)
1115 hdd_err("wlan_hdd_send_avoid_freq_event error:%d",
1116 ret);
1117
1118 return ret;
1119 }
1120
1121 if (WLAN_REG_IS_24GHZ_CH(op_chan)) {
Ashish Kumar Dhanotiyaaa9fdbb2018-12-14 15:29:14 +05301122 min_chan = WLAN_REG_MIN_24GHZ_CH_NUM;
1123 max_chan = WLAN_REG_MAX_24GHZ_CH_NUM;
1124 } else if (WLAN_REG_IS_5GHZ_CH(op_chan)) {
1125 min_chan = WLAN_REG_MIN_5GHZ_CH_NUM;
1126 max_chan = WLAN_REG_MAX_5GHZ_CH_NUM;
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301127 } else {
1128 hdd_err("invalid channel:%d", op_chan);
1129 return -EINVAL;
1130 }
1131
1132 if ((op_chan > min_chan) && (op_chan < max_chan)) {
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001133 p2p_avoid_freq_list.ch_avoid_range_cnt = 2;
1134 p2p_avoid_freq_list.avoid_freq_range[0].start_freq =
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301135 wlan_chan_to_freq(min_chan);
1136
1137 /* Get channel before the op_chan */
1138 chan = wlan_hdd_get_adjacent_chan(op_chan, false);
1139 if (chan < 0)
1140 return -EINVAL;
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001141 p2p_avoid_freq_list.avoid_freq_range[0].end_freq =
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301142 wlan_chan_to_freq(chan);
1143
1144 /* Get channel next to the op_chan */
1145 chan = wlan_hdd_get_adjacent_chan(op_chan, true);
1146 if (chan < 0)
1147 return -EINVAL;
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001148 p2p_avoid_freq_list.avoid_freq_range[1].start_freq =
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301149 wlan_chan_to_freq(chan);
1150
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001151 p2p_avoid_freq_list.avoid_freq_range[1].end_freq =
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301152 wlan_chan_to_freq(max_chan);
1153 } else if (op_chan == min_chan) {
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001154 p2p_avoid_freq_list.ch_avoid_range_cnt = 1;
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301155
1156 chan = wlan_hdd_get_adjacent_chan(op_chan, true);
1157 if (chan < 0)
1158 return -EINVAL;
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001159 p2p_avoid_freq_list.avoid_freq_range[0].start_freq =
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301160 wlan_chan_to_freq(chan);
1161
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001162 p2p_avoid_freq_list.avoid_freq_range[0].end_freq =
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301163 wlan_chan_to_freq(max_chan);
1164 } else {
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001165 p2p_avoid_freq_list.ch_avoid_range_cnt = 1;
1166 p2p_avoid_freq_list.avoid_freq_range[0].start_freq =
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301167 wlan_chan_to_freq(min_chan);
1168
1169 chan = wlan_hdd_get_adjacent_chan(op_chan, false);
1170 if (chan < 0)
1171 return -EINVAL;
Kiran Kumar Lokere48795792017-07-07 15:34:29 -07001172 p2p_avoid_freq_list.avoid_freq_range[0].end_freq =
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301173 wlan_chan_to_freq(chan);
1174 }
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05301175#ifdef FEATURE_WLAN_CH_AVOID
Jeff Johnsonb8944722017-09-03 09:03:19 -07001176 mutex_lock(&hdd_ctx->avoid_freq_lock);
1177 hdd_ctx->dnbs_avoid_freq_list = p2p_avoid_freq_list;
1178 if (hdd_ctx->coex_avoid_freq_list.ch_avoid_range_cnt) {
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05301179 ret = wlan_hdd_merge_avoid_freqs(&p2p_avoid_freq_list,
Jeff Johnsonb8944722017-09-03 09:03:19 -07001180 &hdd_ctx->coex_avoid_freq_list);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05301181 if (ret) {
Jeff Johnsonb8944722017-09-03 09:03:19 -07001182 mutex_unlock(&hdd_ctx->avoid_freq_lock);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05301183 hdd_err("avoid freq merge failed");
1184 return ret;
1185 }
1186 }
Jeff Johnsonb8944722017-09-03 09:03:19 -07001187 mutex_unlock(&hdd_ctx->avoid_freq_lock);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05301188#endif
Jeff Johnsonb8944722017-09-03 09:03:19 -07001189 ret = wlan_hdd_send_avoid_freq_event(hdd_ctx, &p2p_avoid_freq_list);
Ajit Pal Singh5edd6982017-05-10 11:04:13 +05301190 if (ret)
1191 hdd_err("wlan_hdd_send_avoid_freq_event error:%d", ret);
1192
1193 return ret;
1194}
1195
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001196/* vendor specific events */
1197static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001198 [QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX] = {
1199 .vendor_id =
1200 QCA_NL80211_VENDOR_ID,
1201 .subcmd =
1202 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
1203 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001204
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001205 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
1206 .vendor_id =
1207 QCA_NL80211_VENDOR_ID,
1208 .subcmd =
1209 QCA_NL80211_VENDOR_SUBCMD_NAN
1210 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001211
1212#ifdef WLAN_FEATURE_STATS_EXT
1213 [QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX] = {
1214 .vendor_id =
1215 QCA_NL80211_VENDOR_ID,
1216 .subcmd =
1217 QCA_NL80211_VENDOR_SUBCMD_STATS_EXT
1218 },
1219#endif /* WLAN_FEATURE_STATS_EXT */
1220#ifdef FEATURE_WLAN_EXTSCAN
1221 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX] = {
1222 .vendor_id =
1223 QCA_NL80211_VENDOR_ID,
1224 .subcmd =
1225 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
1226 },
1227 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX] = {
1228 .vendor_id =
1229 QCA_NL80211_VENDOR_ID,
1230 .subcmd =
1231 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
1232 },
1233 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX] = {
1234 .
1235 vendor_id
1236 =
1237 QCA_NL80211_VENDOR_ID,
1238 .subcmd =
1239 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
1240 },
1241 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX] = {
1242 .
1243 vendor_id
1244 =
1245 QCA_NL80211_VENDOR_ID,
1246 .
1247 subcmd =
1248 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
1249 },
1250 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX] = {
1251 .
1252 vendor_id
1253 =
1254 QCA_NL80211_VENDOR_ID,
1255 .
1256 subcmd
1257 =
1258 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
1259 },
1260 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX] = {
1261 .
1262 vendor_id
1263 =
1264 QCA_NL80211_VENDOR_ID,
1265 .subcmd =
1266 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
1267 },
1268 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX] = {
1269 .vendor_id =
1270 QCA_NL80211_VENDOR_ID,
1271 .subcmd =
1272 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
1273 },
1274 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX] = {
1275 .
1276 vendor_id
1277 =
1278 QCA_NL80211_VENDOR_ID,
1279 .subcmd =
1280 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
1281 },
1282 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX] = {
1283 .
1284 vendor_id
1285 =
1286 QCA_NL80211_VENDOR_ID,
1287 .subcmd =
1288 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
1289 },
1290 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX] = {
1291 .
1292 vendor_id
1293 =
1294 QCA_NL80211_VENDOR_ID,
1295 .
1296 subcmd
1297 =
1298 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
1299 },
1300 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX] = {
1301 .
1302 vendor_id
1303 =
1304 QCA_NL80211_VENDOR_ID,
1305 .
1306 subcmd =
1307 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
1308 },
1309 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX] = {
1310 .
1311 vendor_id
1312 =
1313 QCA_NL80211_VENDOR_ID,
1314 .
1315 subcmd
1316 =
1317 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
1318 },
1319 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX] = {
1320 .
1321 vendor_id
1322 =
1323 QCA_NL80211_VENDOR_ID,
1324 .
1325 subcmd
1326 =
1327 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
1328 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329#endif /* FEATURE_WLAN_EXTSCAN */
1330
1331#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1332 [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET_INDEX] = {
1333 .vendor_id =
1334 QCA_NL80211_VENDOR_ID,
1335 .subcmd =
1336 QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
1337 },
1338 [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET_INDEX] = {
1339 .vendor_id =
1340 QCA_NL80211_VENDOR_ID,
1341 .subcmd =
1342 QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
1343 },
1344 [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR_INDEX] = {
1345 .vendor_id =
1346 QCA_NL80211_VENDOR_ID,
1347 .subcmd =
1348 QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
1349 },
1350 [QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX] = {
1351 .vendor_id =
1352 QCA_NL80211_VENDOR_ID,
1353 .subcmd =
1354 QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
1355 },
1356 [QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX] = {
1357 .vendor_id =
1358 QCA_NL80211_VENDOR_ID,
1359 .subcmd =
1360 QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
1361 },
1362 [QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX] = {
1363 .vendor_id =
1364 QCA_NL80211_VENDOR_ID,
1365 .subcmd =
1366 QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
1367 },
Zhang Qianca38fb12016-12-23 11:10:48 +08001368 [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT_INDEX] = {
1369 .vendor_id =
1370 QCA_NL80211_VENDOR_ID,
1371 .subcmd =
1372 QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT
1373 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001374#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
1375 [QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX] = {
1376 .vendor_id =
1377 QCA_NL80211_VENDOR_ID,
1378 .subcmd =
1379 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
1380 },
1381 [QCA_NL80211_VENDOR_SUBCMD_DO_ACS_INDEX] = {
1382 .vendor_id = QCA_NL80211_VENDOR_ID,
1383 .subcmd = QCA_NL80211_VENDOR_SUBCMD_DO_ACS
1384 },
1385#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1386 [QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX] = {
1387 .vendor_id =
1388 QCA_NL80211_VENDOR_ID,
1389 .subcmd =
1390 QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH
1391 },
1392#endif
1393 [QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED_INDEX] = {
1394 .vendor_id =
1395 QCA_NL80211_VENDOR_ID,
1396 .subcmd =
1397 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_STARTED
1398 },
1399 [QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED_INDEX] = {
1400 .vendor_id =
1401 QCA_NL80211_VENDOR_ID,
1402 .subcmd =
1403 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_FINISHED
1404 },
1405 [QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED_INDEX] = {
1406 .vendor_id =
1407 QCA_NL80211_VENDOR_ID,
1408 .subcmd =
1409 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_ABORTED
1410 },
1411 [QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED_INDEX] = {
1412 .vendor_id =
1413 QCA_NL80211_VENDOR_ID,
1414 .subcmd =
1415 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_CAC_NOP_FINISHED
1416 },
1417 [QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED_INDEX] = {
1418 .vendor_id =
1419 QCA_NL80211_VENDOR_ID,
1420 .subcmd =
1421 QCA_NL80211_VENDOR_SUBCMD_DFS_OFFLOAD_RADAR_DETECTED
1422 },
1423#ifdef FEATURE_WLAN_EXTSCAN
1424 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_NETWORK_FOUND_INDEX] = {
1425 .vendor_id = QCA_NL80211_VENDOR_ID,
1426 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_NETWORK_FOUND
1427 },
1428 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_PASSPOINT_NETWORK_FOUND_INDEX] = {
1429 .vendor_id = QCA_NL80211_VENDOR_ID,
1430 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_PASSPOINT_NETWORK_FOUND
1431 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001432 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
1433 .vendor_id = QCA_NL80211_VENDOR_ID,
1434 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
1435 },
1436#endif /* FEATURE_WLAN_EXTSCAN */
Qiwei Caie689a262018-07-26 15:50:22 +08001437
1438 FEATURE_RSSI_MONITOR_VENDOR_EVENTS
1439
Manikandan Mohan5356c2b2016-04-03 15:51:35 -07001440#ifdef WLAN_FEATURE_TSF
1441 [QCA_NL80211_VENDOR_SUBCMD_TSF_INDEX] = {
1442 .vendor_id = QCA_NL80211_VENDOR_ID,
1443 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TSF
1444 },
1445#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446 [QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE_INDEX] = {
1447 .vendor_id = QCA_NL80211_VENDOR_ID,
1448 .subcmd = QCA_NL80211_VENDOR_SUBCMD_SCAN_DONE
1449 },
1450 [QCA_NL80211_VENDOR_SUBCMD_SCAN_INDEX] = {
1451 .vendor_id = QCA_NL80211_VENDOR_ID,
1452 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN
1453 },
1454 /* OCB events */
1455 [QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT_INDEX] = {
1456 .vendor_id = QCA_NL80211_VENDOR_ID,
1457 .subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT
1458 },
Ravi Joshideb5a8d2015-11-09 19:11:43 -08001459#ifdef FEATURE_LFR_SUBNET_DETECTION
1460 [QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG_INDEX] = {
1461 .vendor_id = QCA_NL80211_VENDOR_ID,
1462 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG
1463 },
1464#endif /*FEATURE_LFR_SUBNET_DETECTION */
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001465
Paul Zhang37185672019-05-14 11:20:14 +08001466 FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS_INDEX
1467
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07001468 [QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX] = {
1469 .vendor_id = QCA_NL80211_VENDOR_ID,
1470 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NDP
1471 },
Peng Xu8fdaa492016-06-22 10:20:47 -07001472
1473 [QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX] = {
1474 .vendor_id = QCA_NL80211_VENDOR_ID,
1475 .subcmd = QCA_NL80211_VENDOR_SUBCMD_P2P_LISTEN_OFFLOAD_STOP
1476 },
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05301477 [QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH_INDEX] = {
1478 .vendor_id = QCA_NL80211_VENDOR_ID,
1479 .subcmd = QCA_NL80211_VENDOR_SUBCMD_SAP_CONDITIONAL_CHAN_SWITCH
1480 },
Kapil Gupta8878ad92017-02-13 11:56:04 +05301481 [QCA_NL80211_VENDOR_SUBCMD_UPDATE_EXTERNAL_ACS_CONFIG] = {
1482 .vendor_id = QCA_NL80211_VENDOR_ID,
1483 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS
1484 },
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05301485 [QCA_NL80211_VENDOR_SUBCMD_PWR_SAVE_FAIL_DETECTED_INDEX] = {
1486 .vendor_id = QCA_NL80211_VENDOR_ID,
1487 .subcmd = QCA_NL80211_VENDOR_SUBCMD_CHIP_PWRSAVE_FAILURE
Anurag Chouhan3920c0f2017-09-11 17:10:56 +05301488 },
1489 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
1490 .vendor_id = QCA_NL80211_VENDOR_ID,
1491 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
1492 },
Anurag Chouhan4085ff72017-10-05 18:09:56 +05301493 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
1494 .vendor_id = QCA_NL80211_VENDOR_ID,
1495 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
1496 },
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +05301497 [QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO_INDEX] = {
1498 .vendor_id = QCA_NL80211_VENDOR_ID,
1499 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO,
1500 },
Alok Kumar2fad6442018-11-08 19:19:28 +05301501 [QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT_INDEX] = {
1502 .vendor_id = QCA_NL80211_VENDOR_ID,
1503 .subcmd = QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT,
1504 },
Nachiket Kukadea6a70a92018-10-09 20:07:21 +05301505 [QCA_NL80211_VENDOR_SUBCMD_NAN_EXT_INDEX] = {
1506 .vendor_id = QCA_NL80211_VENDOR_ID,
1507 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN_EXT
1508 },
Ashish Kumar Dhanotiya42b03782018-01-16 10:55:16 +05301509 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
1510 .vendor_id = QCA_NL80211_VENDOR_ID,
1511 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
1512 },
Abhinav Kumar4d1f9f42019-05-07 13:14:49 +05301513
1514 BCN_RECV_FEATURE_VENDOR_EVENTS
1515
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001516};
1517
1518/**
1519 * __is_driver_dfs_capable() - get driver DFS capability
1520 * @wiphy: pointer to wireless wiphy structure.
1521 * @wdev: pointer to wireless_dev structure.
1522 * @data: Pointer to the data to be passed via vendor interface
1523 * @data_len:Length of the data to be passed
1524 *
1525 * This function is called by userspace to indicate whether or not
1526 * the driver supports DFS offload.
1527 *
1528 * Return: 0 on success, negative errno on failure
1529 */
1530static int __is_driver_dfs_capable(struct wiphy *wiphy,
1531 struct wireless_dev *wdev,
1532 const void *data,
1533 int data_len)
1534{
1535 u32 dfs_capability = 0;
1536 struct sk_buff *temp_skbuff;
1537 int ret_val;
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07001538 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001539
Dustin Brownfdf17c12018-03-14 12:55:34 -07001540 hdd_enter_dev(wdev->netdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001541
1542 ret_val = wlan_hdd_validate_context(hdd_ctx);
1543 if (ret_val)
1544 return ret_val;
1545
Anurag Chouhan6d760662016-02-20 16:05:43 +05301546 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001547 hdd_err("Command not allowed in FTM mode");
1548 return -EPERM;
1549 }
1550
Peng Xu8e8b0392018-04-30 11:32:34 -07001551#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) || \
1552 defined(CFG80211_DFS_OFFLOAD_BACKPORT)
1553 dfs_capability =
1554 wiphy_ext_feature_isset(wiphy,
1555 NL80211_EXT_FEATURE_DFS_OFFLOAD);
1556#else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557 dfs_capability = !!(wiphy->flags & WIPHY_FLAG_DFS_OFFLOAD);
Peng Xu8e8b0392018-04-30 11:32:34 -07001558#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559
1560 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
1561 NLMSG_HDRLEN);
1562
Jeff Johnsond36fa332019-03-18 13:42:25 -07001563 if (temp_skbuff) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001564 ret_val = nla_put_u32(temp_skbuff, QCA_WLAN_VENDOR_ATTR_DFS,
1565 dfs_capability);
1566 if (ret_val) {
Jeff Johnson020db452016-06-29 14:37:26 -07001567 hdd_err("QCA_WLAN_VENDOR_ATTR_DFS put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001568 kfree_skb(temp_skbuff);
1569
1570 return ret_val;
1571 }
1572
1573 return cfg80211_vendor_cmd_reply(temp_skbuff);
1574 }
1575
Jeff Johnson020db452016-06-29 14:37:26 -07001576 hdd_err("dfs capability: buffer alloc fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001577 return -ENOMEM;
1578}
1579
1580/**
1581 * is_driver_dfs_capable() - get driver DFS capability
1582 * @wiphy: pointer to wireless wiphy structure.
1583 * @wdev: pointer to wireless_dev structure.
1584 * @data: Pointer to the data to be passed via vendor interface
1585 * @data_len:Length of the data to be passed
1586 *
1587 * This function is called by userspace to indicate whether or not
1588 * the driver supports DFS offload. This is an SSR-protected
1589 * wrapper function.
1590 *
1591 * Return: 0 on success, negative errno on failure
1592 */
1593static int is_driver_dfs_capable(struct wiphy *wiphy,
1594 struct wireless_dev *wdev,
1595 const void *data,
1596 int data_len)
1597{
Dustin Brown363b4792019-02-05 16:11:55 -08001598 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08001599 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05301600
Dustin Brown363b4792019-02-05 16:11:55 -08001601 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08001602 if (errno)
1603 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001604
Dustin Brownf0f00612019-01-31 16:02:24 -08001605 errno = __is_driver_dfs_capable(wiphy, wdev, data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001606
Dustin Brown363b4792019-02-05 16:11:55 -08001607 osif_psoc_sync_op_stop(psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08001608
1609 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001610}
1611
1612/**
1613 * wlan_hdd_sap_cfg_dfs_override() - DFS MCC restriction check
1614 *
1615 * @adapter: SAP adapter pointer
1616 *
1617 * DFS in MCC is not supported for Multi bssid SAP mode due to single physical
1618 * radio. So in case of DFS MCC scenario override current SAP given config
1619 * to follow concurrent SAP DFS config
1620 *
1621 * Return: 0 - No DFS issue, 1 - Override done and negative error codes
1622 */
Jeff Johnsone5006672017-08-29 14:39:02 -07001623int wlan_hdd_sap_cfg_dfs_override(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001624{
Jeff Johnsone5006672017-08-29 14:39:02 -07001625 struct hdd_adapter *con_sap_adapter;
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07001626 struct sap_config *sap_config, *con_sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001627 int con_ch;
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07001628 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001629
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001630 if (!hdd_ctx) {
1631 hdd_err("hdd context is NULL");
1632 return 0;
1633 }
1634
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001635 /*
1636 * Check if AP+AP case, once primary AP chooses a DFS
1637 * channel secondary AP should always follow primary APs channel
1638 */
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -08001639 if (!policy_mgr_concurrent_beaconing_sessions_running(
Dustin Brown76cd2932018-09-11 16:03:05 -07001640 hdd_ctx->psoc))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001641 return 0;
1642
1643 con_sap_adapter = hdd_get_con_sap_adapter(adapter, true);
1644 if (!con_sap_adapter)
1645 return 0;
1646
Jeff Johnsonb9424862017-10-30 08:49:35 -07001647 sap_config = &adapter->session.ap.sap_config;
1648 con_sap_config = &con_sap_adapter->session.ap.sap_config;
1649 con_ch = con_sap_adapter->session.ap.operating_channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001650
Dustin Brown07901ec2018-09-07 11:02:41 -07001651 if (!wlan_reg_is_dfs_ch(hdd_ctx->pdev, con_ch))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652 return 0;
1653
Srinivas Girigowda13d39252017-03-06 16:12:15 -08001654 hdd_debug("Only SCC AP-AP DFS Permitted (ch=%d, con_ch=%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001655 sap_config->channel, con_ch);
Srinivas Girigowda13d39252017-03-06 16:12:15 -08001656 hdd_debug("Overriding guest AP's channel");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001657 sap_config->channel = con_ch;
1658
1659 if (con_sap_config->acs_cfg.acs_mode == true) {
1660 if (con_ch != con_sap_config->acs_cfg.pri_ch &&
1661 con_ch != con_sap_config->acs_cfg.ht_sec_ch) {
Jeff Johnson020db452016-06-29 14:37:26 -07001662 hdd_err("Primary AP channel config error");
1663 hdd_err("Operating ch: %d ACS ch: %d %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001664 con_ch, con_sap_config->acs_cfg.pri_ch,
1665 con_sap_config->acs_cfg.ht_sec_ch);
1666 return -EINVAL;
1667 }
1668 /* Sec AP ACS info is overwritten with Pri AP due to DFS
1669 * MCC restriction. So free ch list allocated in do_acs
1670 * func for Sec AP and realloc for Pri AP ch list size
1671 */
1672 if (sap_config->acs_cfg.ch_list)
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301673 qdf_mem_free(sap_config->acs_cfg.ch_list);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001674
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301675 qdf_mem_copy(&sap_config->acs_cfg,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676 &con_sap_config->acs_cfg,
1677 sizeof(struct sap_acs_cfg));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301678 sap_config->acs_cfg.ch_list = qdf_mem_malloc(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001679 sizeof(uint8_t) *
1680 con_sap_config->acs_cfg.ch_list_count);
gaurank kathpalia6701aef2019-06-27 11:53:08 +05301681 if (!sap_config->acs_cfg.ch_list) {
1682 sap_config->acs_cfg.ch_list_count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001683 return -ENOMEM;
gaurank kathpalia6701aef2019-06-27 11:53:08 +05301684 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301685 qdf_mem_copy(sap_config->acs_cfg.ch_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001686 con_sap_config->acs_cfg.ch_list,
1687 con_sap_config->acs_cfg.ch_list_count);
gaurank kathpalia6701aef2019-06-27 11:53:08 +05301688 sap_config->acs_cfg.ch_list_count =
1689 con_sap_config->acs_cfg.ch_list_count;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001690
1691 } else {
1692 sap_config->acs_cfg.pri_ch = con_ch;
1693 if (sap_config->acs_cfg.ch_width > eHT_CHANNEL_WIDTH_20MHZ)
1694 sap_config->acs_cfg.ht_sec_ch = con_sap_config->sec_ch;
1695 }
1696
1697 return con_ch;
1698}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001699
1700/**
wadesong1795e142018-01-05 11:13:07 +08001701 * wlan_hdd_set_acs_ch_range : Populate ACS hw mode and channel range values
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001702 * @sap_cfg: pointer to SAP config struct
wadesong1795e142018-01-05 11:13:07 +08001703 * @hw_mode: hw mode retrieved from vendor command buffer
1704 * @ht_enabled: whether HT phy mode is enabled
1705 * @vht_enabled: whether VHT phy mode is enabled
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001706 *
wadesong1795e142018-01-05 11:13:07 +08001707 * This function populates the ACS hw mode based on the configuration retrieved
1708 * from the vendor command buffer; and sets ACS start and end channel for the
1709 * given band.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001710 *
wadesong1795e142018-01-05 11:13:07 +08001711 * Return: 0 if success; -EINVAL if ACS channel list is NULL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001712 */
wadesong1795e142018-01-05 11:13:07 +08001713static int wlan_hdd_set_acs_ch_range(
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07001714 struct sap_config *sap_cfg, enum qca_wlan_vendor_acs_hw_mode hw_mode,
wadesong1795e142018-01-05 11:13:07 +08001715 bool ht_enabled, bool vht_enabled)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001716{
1717 int i;
Srinivas Girigowda576b2352017-08-25 14:44:26 -07001718
wadesong1795e142018-01-05 11:13:07 +08001719 if (hw_mode == QCA_ACS_MODE_IEEE80211B) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001720 sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11b;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001721 sap_cfg->acs_cfg.start_ch = WLAN_REG_CH_NUM(CHAN_ENUM_1);
1722 sap_cfg->acs_cfg.end_ch = WLAN_REG_CH_NUM(CHAN_ENUM_14);
wadesong1795e142018-01-05 11:13:07 +08001723 } else if (hw_mode == QCA_ACS_MODE_IEEE80211G) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001724 sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11g;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001725 sap_cfg->acs_cfg.start_ch = WLAN_REG_CH_NUM(CHAN_ENUM_1);
1726 sap_cfg->acs_cfg.end_ch = WLAN_REG_CH_NUM(CHAN_ENUM_13);
wadesong1795e142018-01-05 11:13:07 +08001727 } else if (hw_mode == QCA_ACS_MODE_IEEE80211A) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001728 sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11a;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001729 sap_cfg->acs_cfg.start_ch = WLAN_REG_CH_NUM(CHAN_ENUM_36);
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07001730 sap_cfg->acs_cfg.end_ch = WLAN_REG_CH_NUM(CHAN_ENUM_173);
wadesong1795e142018-01-05 11:13:07 +08001731 } else if (hw_mode == QCA_ACS_MODE_IEEE80211ANY) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001732 sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_abg;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001733 sap_cfg->acs_cfg.start_ch = WLAN_REG_CH_NUM(CHAN_ENUM_1);
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07001734 sap_cfg->acs_cfg.end_ch = WLAN_REG_CH_NUM(CHAN_ENUM_173);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001735 }
1736
1737 if (ht_enabled)
1738 sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11n;
1739
1740 if (vht_enabled)
1741 sap_cfg->acs_cfg.hw_mode = eCSR_DOT11_MODE_11ac;
1742
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001743 /* Parse ACS Chan list from hostapd */
1744 if (!sap_cfg->acs_cfg.ch_list)
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05301745 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001746
1747 sap_cfg->acs_cfg.start_ch = sap_cfg->acs_cfg.ch_list[0];
1748 sap_cfg->acs_cfg.end_ch =
1749 sap_cfg->acs_cfg.ch_list[sap_cfg->acs_cfg.ch_list_count - 1];
1750 for (i = 0; i < sap_cfg->acs_cfg.ch_list_count; i++) {
Manjeet Singh2d3b0c52016-09-02 13:31:48 +05301751 /* avoid channel as start channel */
1752 if (sap_cfg->acs_cfg.start_ch > sap_cfg->acs_cfg.ch_list[i] &&
1753 sap_cfg->acs_cfg.ch_list[i] != 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001754 sap_cfg->acs_cfg.start_ch = sap_cfg->acs_cfg.ch_list[i];
1755 if (sap_cfg->acs_cfg.end_ch < sap_cfg->acs_cfg.ch_list[i])
1756 sap_cfg->acs_cfg.end_ch = sap_cfg->acs_cfg.ch_list[i];
1757 }
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05301758
1759 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001760}
1761
1762
1763static void wlan_hdd_cfg80211_start_pending_acs(struct work_struct *work);
1764
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05301765
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07001766static void hdd_update_acs_channel_list(struct sap_config *sap_config,
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001767 enum band_info band)
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05301768{
1769 int i, temp_count = 0;
1770 int acs_list_count = sap_config->acs_cfg.ch_list_count;
1771
1772 for (i = 0; i < acs_list_count; i++) {
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001773 if (BAND_2G == band) {
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05301774 if (WLAN_REG_IS_24GHZ_CH(
1775 sap_config->acs_cfg.ch_list[i])) {
1776 sap_config->acs_cfg.ch_list[temp_count] =
1777 sap_config->acs_cfg.ch_list[i];
1778 temp_count++;
1779 }
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001780 } else if (BAND_5G == band) {
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05301781 if (WLAN_REG_IS_5GHZ_CH(
1782 sap_config->acs_cfg.ch_list[i])) {
1783 sap_config->acs_cfg.ch_list[temp_count] =
1784 sap_config->acs_cfg.ch_list[i];
1785 temp_count++;
1786 }
1787 }
1788 }
1789 sap_config->acs_cfg.ch_list_count = temp_count;
1790}
1791
1792
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001793/**
1794 * wlan_hdd_cfg80211_start_acs : Start ACS Procedure for SAP
1795 * @adapter: pointer to SAP adapter struct
1796 *
1797 * This function starts the ACS procedure if there are no
1798 * constraints like MBSSID DFS restrictions.
1799 *
1800 * Return: Status of ACS Start procedure
1801 */
Jeff Johnsone5006672017-08-29 14:39:02 -07001802int wlan_hdd_cfg80211_start_acs(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001803{
1804
Kiran Kumar Lokere85cb36b2017-09-14 15:19:14 -07001805 struct hdd_context *hdd_ctx;
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07001806 struct sap_config *sap_config;
Jeff Johnson7dcac7e2019-03-23 15:10:06 -07001807 sap_event_cb acs_event_callback;
Krunal Soni5e3f9622018-09-26 16:35:50 -07001808 uint8_t mcc_to_scc_switch = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001809 int status;
1810
Kiran Kumar Lokere85cb36b2017-09-14 15:19:14 -07001811 if (!adapter) {
Jeff Johnsondd2f1fc2018-05-06 11:22:52 -07001812 hdd_err("adapter is NULL");
Kiran Kumar Lokere85cb36b2017-09-14 15:19:14 -07001813 return -EINVAL;
1814 }
1815 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Ashish Kumar Dhanotiyadc3900f2019-01-11 20:42:04 +05301816 status = wlan_hdd_validate_context(hdd_ctx);
1817 if (0 != status)
1818 return status;
1819
Jeff Johnsonb9424862017-10-30 08:49:35 -07001820 sap_config = &adapter->session.ap.sap_config;
Ashish Kumar Dhanotiyab0629622018-09-21 18:58:59 +05301821 if (!sap_config) {
1822 hdd_err("SAP config is NULL");
1823 return -EINVAL;
1824 }
Agrawal Ashish65634612016-08-18 13:24:32 +05301825 if (hdd_ctx->acs_policy.acs_channel)
1826 sap_config->channel = hdd_ctx->acs_policy.acs_channel;
1827 else
1828 sap_config->channel = AUTO_CHANNEL_SELECT;
Krunal Soni5e3f9622018-09-26 16:35:50 -07001829 ucfg_policy_mgr_get_mcc_scc_switch(hdd_ctx->psoc,
1830 &mcc_to_scc_switch);
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05301831 /*
1832 * No DFS SCC is allowed in Auto use case. Hence not
1833 * calling DFS override
1834 */
1835 if (QDF_MCC_TO_SCC_SWITCH_FORCE_PREFERRED_WITHOUT_DISCONNECTION !=
Jianmin Zhu7f212f72019-06-18 15:41:10 +08001836 mcc_to_scc_switch &&
1837 !(policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) &&
1838 IS_24G_CH(sap_config->acs_cfg.end_ch))) {
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05301839 status = wlan_hdd_sap_cfg_dfs_override(adapter);
1840 if (status < 0)
1841 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001842
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05301843 if (status > 0) {
1844 /*notify hostapd about channel override */
1845 wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
1846 clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);
1847 return 0;
1848 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001849 }
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05301850 /* When first 2 connections are on the same frequency band,
1851 * then PCL would include only channels from the other
1852 * frequency band on which no connections are active
1853 */
Dustin Brown76cd2932018-09-11 16:03:05 -07001854 if ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 2) &&
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05301855 (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211ANY)) {
1856 struct policy_mgr_conc_connection_info *conc_connection_info;
1857 uint32_t i;
Jeff Johnson68755312017-02-10 11:46:55 -08001858
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05301859 conc_connection_info = policy_mgr_get_conn_info(&i);
1860 if (conc_connection_info[0].mac ==
1861 conc_connection_info[1].mac) {
1862 if (WLAN_REG_IS_5GHZ_CH(sap_config->acs_cfg.
1863 pcl_channels[0])) {
1864 sap_config->acs_cfg.band =
1865 QCA_ACS_MODE_IEEE80211A;
1866 hdd_update_acs_channel_list(sap_config,
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001867 BAND_5G);
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05301868 } else {
1869 sap_config->acs_cfg.band =
1870 QCA_ACS_MODE_IEEE80211G;
1871 hdd_update_acs_channel_list(sap_config,
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001872 BAND_2G);
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05301873 }
1874 }
1875 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001876 status = wlan_hdd_config_acs(hdd_ctx, adapter);
1877 if (status) {
Jeff Johnson020db452016-06-29 14:37:26 -07001878 hdd_err("ACS config failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001879 return -EINVAL;
1880 }
1881
1882 acs_event_callback = hdd_hostapd_sap_event_cb;
1883
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301884 qdf_mem_copy(sap_config->self_macaddr.bytes,
Jeff Johnson1e851a12017-10-28 14:36:12 -07001885 adapter->mac_addr.bytes, sizeof(struct qdf_mac_addr));
Dustin Brown5e89ef82018-03-14 11:50:23 -07001886 hdd_info("ACS Started for %s", adapter->dev->name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001887 status = wlansap_acs_chselect(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001888 WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001889 acs_event_callback, sap_config, adapter->dev);
1890
1891
1892 if (status) {
Jeff Johnson020db452016-06-29 14:37:26 -07001893 hdd_err("ACS channel select failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001894 return -EINVAL;
1895 }
bings394afdd2017-01-09 11:22:38 +08001896 if (sap_is_auto_channel_select(WLAN_HDD_GET_SAP_CTX_PTR(adapter)))
1897 sap_config->acs_cfg.acs_mode = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001898 set_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);
1899
1900 return 0;
1901}
1902
1903/**
Kapil Gupta8878ad92017-02-13 11:56:04 +05301904 * hdd_update_vendor_pcl_list() - This API will return unsorted pcl list
1905 * @hdd_ctx: hdd context
1906 * @acs_chan_params: external acs channel params
1907 * @sap_config: SAP config
1908 *
1909 * This API provides unsorted pcl list.
1910 * this list is a subset of the valid channel list given by hostapd.
1911 * if channel is not present in pcl, weightage will be given as zero
1912 *
1913 * Return: Zero on success, non-zero on failure
1914 */
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07001915static void hdd_update_vendor_pcl_list(struct hdd_context *hdd_ctx,
Kapil Gupta8878ad92017-02-13 11:56:04 +05301916 struct hdd_vendor_acs_chan_params *acs_chan_params,
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07001917 struct sap_config *sap_config)
Kapil Gupta8878ad92017-02-13 11:56:04 +05301918{
1919 int i, j;
Adesh Keremane25ce2dc2017-05-29 17:55:39 +05301920 /*
1921 * PCL shall contain only the preferred channels from the
1922 * application. If those channels are not present in the
1923 * driver PCL, then set the weight to zero
1924 */
1925 for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) {
1926 acs_chan_params->vendor_pcl_list[i] =
1927 sap_config->acs_cfg.ch_list[i];
1928 acs_chan_params->vendor_weight_list[i] = 0;
1929 for (j = 0; j < sap_config->acs_cfg.pcl_ch_count; j++) {
1930 if (sap_config->acs_cfg.ch_list[i] ==
1931 sap_config->acs_cfg.pcl_channels[j]) {
1932 acs_chan_params->vendor_weight_list[i] =
1933 sap_config->
1934 acs_cfg.pcl_channels_weight_list[j];
1935 break;
Kapil Gupta8878ad92017-02-13 11:56:04 +05301936 }
1937 }
1938 }
Adesh Keremane25ce2dc2017-05-29 17:55:39 +05301939 acs_chan_params->pcl_count = sap_config->acs_cfg.ch_list_count;
Kapil Gupta8878ad92017-02-13 11:56:04 +05301940}
1941
1942/**
Kapil Gupta086c6202016-12-11 18:17:06 +05301943 * hdd_update_reg_chan_info : This API contructs channel info
1944 * for all the given channel
1945 * @adapter: pointer to SAP adapter struct
1946 * @channel_count: channel count
1947 * @channel_list: channel list
1948 *
1949 * Return: Status of of channel information updation
1950 */
Jeff Johnsone5006672017-08-29 14:39:02 -07001951static int hdd_update_reg_chan_info(struct hdd_adapter *adapter,
Kapil Gupta086c6202016-12-11 18:17:06 +05301952 uint32_t channel_count,
1953 uint8_t *channel_list)
1954{
1955 int i;
1956 struct hdd_channel_info *icv;
Amar Singhal5cccafe2017-02-15 12:42:58 -08001957 struct ch_params ch_params = {0};
Kapil Gupta086c6202016-12-11 18:17:06 +05301958 uint8_t bw_offset = 0, chan = 0;
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07001959 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07001960 struct sap_config *sap_config = &adapter->session.ap.sap_config;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07001961 mac_handle_t mac_handle;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301962 uint8_t sub_20_chan_width = 0;
1963 QDF_STATUS status;
Kapil Gupta086c6202016-12-11 18:17:06 +05301964
Jeff Johnson34fc63a2018-06-14 10:10:02 -07001965 mac_handle = hdd_ctx->mac_handle;
Jayachandran Sreekumaran68c952c2017-04-24 12:42:03 +05301966 sap_config->channel_info_count = channel_count;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301967
1968 status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
1969 &sub_20_chan_width);
1970 if (QDF_IS_STATUS_ERROR(status))
1971 hdd_err("Failed to get sub_20_chan_width config");
1972
Kapil Gupta086c6202016-12-11 18:17:06 +05301973 for (i = 0; i < channel_count; i++) {
1974 icv = &sap_config->channel_info[i];
1975 chan = channel_list[i];
1976
1977 if (chan == 0)
1978 continue;
1979
Dustin Brown07901ec2018-09-07 11:02:41 -07001980 icv->freq = wlan_reg_get_channel_freq(hdd_ctx->pdev, chan);
Kapil Gupta086c6202016-12-11 18:17:06 +05301981 icv->ieee_chan_number = chan;
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001982 icv->max_reg_power = wlan_reg_get_channel_reg_power(
Dustin Brown07901ec2018-09-07 11:02:41 -07001983 hdd_ctx->pdev, chan);
Kapil Gupta086c6202016-12-11 18:17:06 +05301984
1985 /* filling demo values */
1986 icv->max_radio_power = HDD_MAX_TX_POWER;
1987 icv->min_radio_power = HDD_MIN_TX_POWER;
1988 /* not supported in current driver */
1989 icv->max_antenna_gain = 0;
1990
jiad7b8a5e02018-11-26 16:37:57 +08001991 bw_offset = hdd_get_bw_offset(sap_config->acs_cfg.ch_width);
Jeff Johnson34fc63a2018-06-14 10:10:02 -07001992 icv->reg_class_id =
1993 wlan_hdd_find_opclass(mac_handle, chan, bw_offset);
Kapil Gupta086c6202016-12-11 18:17:06 +05301994
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001995 if (WLAN_REG_IS_5GHZ_CH(chan)) {
Kapil Gupta086c6202016-12-11 18:17:06 +05301996 ch_params.ch_width = sap_config->acs_cfg.ch_width;
Dustin Brown07901ec2018-09-07 11:02:41 -07001997 wlan_reg_set_channel_params(hdd_ctx->pdev, chan,
1998 0, &ch_params);
Kapil Gupta086c6202016-12-11 18:17:06 +05301999 icv->vht_center_freq_seg0 = ch_params.center_freq_seg0;
2000 icv->vht_center_freq_seg1 = ch_params.center_freq_seg1;
2001 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002002
Kapil Gupta086c6202016-12-11 18:17:06 +05302003 icv->flags = 0;
Dustin Brown07901ec2018-09-07 11:02:41 -07002004 icv->flags = cds_get_vendor_reg_flags(hdd_ctx->pdev, chan,
Kapil Gupta086c6202016-12-11 18:17:06 +05302005 sap_config->acs_cfg.ch_width,
2006 sap_config->acs_cfg.is_ht_enabled,
2007 sap_config->acs_cfg.is_vht_enabled,
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05302008 sub_20_chan_width);
Kapil Guptac1224bf2017-06-22 21:22:40 +05302009 if (icv->flags & IEEE80211_CHAN_PASSIVE)
2010 icv->flagext |= IEEE80211_CHAN_DFS;
Kapil Gupta086c6202016-12-11 18:17:06 +05302011
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05302012 hdd_debug("freq %d flags %d flagext %d ieee %d maxreg %d maxpw %d minpw %d regClass %d antenna %d seg0 %d seg1 %d",
Kapil Gupta086c6202016-12-11 18:17:06 +05302013 icv->freq, icv->flags,
2014 icv->flagext, icv->ieee_chan_number,
2015 icv->max_reg_power, icv->max_radio_power,
2016 icv->min_radio_power, icv->reg_class_id,
2017 icv->max_antenna_gain, icv->vht_center_freq_seg0,
2018 icv->vht_center_freq_seg1);
2019 }
2020 return 0;
2021}
2022
2023/* Short name for QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_INFO event */
2024#define CHAN_INFO_ATTR_FLAGS \
2025 QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAGS
2026#define CHAN_INFO_ATTR_FLAG_EXT \
2027 QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FLAG_EXT
2028#define CHAN_INFO_ATTR_FREQ \
2029 QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_FREQ
2030#define CHAN_INFO_ATTR_MAX_REG_POWER \
2031 QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_REG_POWER
2032#define CHAN_INFO_ATTR_MAX_POWER \
2033 QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MAX_POWER
2034#define CHAN_INFO_ATTR_MIN_POWER \
2035 QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_MIN_POWER
2036#define CHAN_INFO_ATTR_REG_CLASS_ID \
2037 QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_REG_CLASS_ID
2038#define CHAN_INFO_ATTR_ANTENNA_GAIN \
2039 QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_ANTENNA_GAIN
2040#define CHAN_INFO_ATTR_VHT_SEG_0 \
2041 QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_0
2042#define CHAN_INFO_ATTR_VHT_SEG_1 \
2043 QCA_WLAN_VENDOR_EXTERNAL_ACS_EVENT_CHAN_INFO_ATTR_VHT_SEG_1
2044
2045/**
2046 * hdd_cfg80211_update_channel_info() - add channel info attributes
2047 * @skb: pointer to sk buff
2048 * @hdd_ctx: pointer to hdd station context
2049 * @idx: attribute index
2050 *
2051 * Return: Success(0) or reason code for failure
2052 */
Kapil Gupta8878ad92017-02-13 11:56:04 +05302053static int32_t
Kapil Gupta086c6202016-12-11 18:17:06 +05302054hdd_cfg80211_update_channel_info(struct sk_buff *skb,
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07002055 struct sap_config *sap_config, int idx)
Kapil Gupta086c6202016-12-11 18:17:06 +05302056{
2057 struct nlattr *nla_attr, *channel;
2058 struct hdd_channel_info *icv;
2059 int i;
2060
2061 nla_attr = nla_nest_start(skb, idx);
2062 if (!nla_attr)
2063 goto fail;
2064
Jayachandran Sreekumaran68c952c2017-04-24 12:42:03 +05302065 for (i = 0; i < sap_config->channel_info_count; i++) {
Kapil Gupta086c6202016-12-11 18:17:06 +05302066 channel = nla_nest_start(skb, i);
2067 if (!channel)
2068 goto fail;
2069
2070 icv = &sap_config->channel_info[i];
2071 if (!icv) {
2072 hdd_err("channel info not found");
2073 goto fail;
2074 }
2075 if (nla_put_u16(skb, CHAN_INFO_ATTR_FREQ,
2076 icv->freq) ||
2077 nla_put_u32(skb, CHAN_INFO_ATTR_FLAGS,
2078 icv->flags) ||
Kapil Gupta63e75282017-05-18 20:55:10 +05302079 nla_put_u32(skb, CHAN_INFO_ATTR_FLAG_EXT,
Kapil Gupta086c6202016-12-11 18:17:06 +05302080 icv->flagext) ||
2081 nla_put_u8(skb, CHAN_INFO_ATTR_MAX_REG_POWER,
2082 icv->max_reg_power) ||
2083 nla_put_u8(skb, CHAN_INFO_ATTR_MAX_POWER,
2084 icv->max_radio_power) ||
2085 nla_put_u8(skb, CHAN_INFO_ATTR_MIN_POWER,
2086 icv->min_radio_power) ||
2087 nla_put_u8(skb, CHAN_INFO_ATTR_REG_CLASS_ID,
2088 icv->reg_class_id) ||
2089 nla_put_u8(skb, CHAN_INFO_ATTR_ANTENNA_GAIN,
2090 icv->max_antenna_gain) ||
2091 nla_put_u8(skb, CHAN_INFO_ATTR_VHT_SEG_0,
2092 icv->vht_center_freq_seg0) ||
2093 nla_put_u8(skb, CHAN_INFO_ATTR_VHT_SEG_1,
2094 icv->vht_center_freq_seg1)) {
2095 hdd_err("put fail");
2096 goto fail;
2097 }
2098 nla_nest_end(skb, channel);
2099 }
2100 nla_nest_end(skb, nla_attr);
2101 return 0;
2102fail:
2103 hdd_err("nl channel update failed");
2104 return -EINVAL;
2105}
2106#undef CHAN_INFO_ATTR_FLAGS
2107#undef CHAN_INFO_ATTR_FLAG_EXT
2108#undef CHAN_INFO_ATTR_FREQ
2109#undef CHAN_INFO_ATTR_MAX_REG_POWER
2110#undef CHAN_INFO_ATTR_MAX_POWER
2111#undef CHAN_INFO_ATTR_MIN_POWER
2112#undef CHAN_INFO_ATTR_REG_CLASS_ID
2113#undef CHAN_INFO_ATTR_ANTENNA_GAIN
2114#undef CHAN_INFO_ATTR_VHT_SEG_0
2115#undef CHAN_INFO_ATTR_VHT_SEG_1
2116
2117/**
Kapil Gupta8878ad92017-02-13 11:56:04 +05302118 * hdd_cfg80211_update_pcl() - add pcl info attributes
2119 * @skb: pointer to sk buff
2120 * @hdd_ctx: pointer to hdd station context
2121 * @idx: attribute index
2122 * @vendor_pcl_list: PCL list
2123 * @vendor_weight_list: PCL weights
2124 *
2125 * Return: Success(0) or reason code for failure
2126 */
2127static int32_t
2128hdd_cfg80211_update_pcl(struct sk_buff *skb,
2129 uint8_t ch_list_count, int idx,
2130 uint8_t *vendor_pcl_list, uint8_t *vendor_weight_list)
2131{
2132 struct nlattr *nla_attr, *channel;
2133 int i;
2134
2135 nla_attr = nla_nest_start(skb, idx);
2136
2137 if (!nla_attr)
2138 goto fail;
2139
2140 for (i = 0; i < ch_list_count; i++) {
2141 channel = nla_nest_start(skb, i);
2142 if (!channel)
2143 goto fail;
Kapil Gupta63e75282017-05-18 20:55:10 +05302144 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_PCL_CHANNEL,
Kapil Gupta8878ad92017-02-13 11:56:04 +05302145 vendor_pcl_list[i]) ||
Kapil Gupta63e75282017-05-18 20:55:10 +05302146 nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_PCL_WEIGHT,
Kapil Gupta8878ad92017-02-13 11:56:04 +05302147 vendor_weight_list[i])) {
2148 hdd_err("put fail");
2149 goto fail;
2150 }
2151 nla_nest_end(skb, channel);
2152 }
2153 nla_nest_end(skb, nla_attr);
2154
2155 return 0;
2156fail:
2157 hdd_err("updating pcl list failed");
2158 return -EINVAL;
2159}
2160
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07002161static void hdd_get_scan_band(struct hdd_context *hdd_ctx,
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07002162 struct sap_config *sap_config,
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002163 enum band_info *band)
Kapil Gupta8878ad92017-02-13 11:56:04 +05302164{
2165 /* Get scan band */
Kapil Guptac1224bf2017-06-22 21:22:40 +05302166 if ((sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211B) ||
2167 (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211G)) {
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002168 *band = BAND_2G;
Kapil Guptac1224bf2017-06-22 21:22:40 +05302169 } else if (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211A) {
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002170 *band = BAND_5G;
Kapil Guptac1224bf2017-06-22 21:22:40 +05302171 } else if (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211ANY) {
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002172 *band = BAND_ALL;
Kapil Gupta8878ad92017-02-13 11:56:04 +05302173 }
Kapil Gupta8878ad92017-02-13 11:56:04 +05302174}
2175
Kapil Gupta63e75282017-05-18 20:55:10 +05302176
2177/**
2178 * hdd_get_freq_list: API to get Frequency list based on channel list
2179 * @channel_list: channel list
2180 * @freq_list: frequency list
2181 * @channel_count: channel count
2182 *
2183 * Return: None
2184 */
2185static void hdd_get_freq_list(uint8_t *channel_list, uint32_t *freq_list,
2186 uint32_t channel_count)
2187{
2188 int count;
2189
2190 for (count = 0; count < channel_count ; count++)
2191 freq_list[count] = cds_chan_to_freq(channel_list[count]);
2192}
2193
Qiwei Caie689a262018-07-26 15:50:22 +08002194/**
2195 * wlan_hdd_sap_get_valid_channellist() - Get SAPs valid channel list
2196 * @ap_adapter: adapter
2197 * @channel_count: valid channel count
2198 * @channel_list: valid channel list
2199 * @band: frequency band
2200 *
2201 * This API returns valid channel list for SAP after removing nol and
2202 * channel which lies outside of configuration.
2203 *
2204 * Return: Zero on success, non-zero on failure
2205 */
2206static int wlan_hdd_sap_get_valid_channellist(struct hdd_adapter *adapter,
2207 uint32_t *channel_count,
2208 uint8_t *channel_list,
2209 enum band_info band)
2210{
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07002211 struct sap_config *sap_config;
Qiwei Caie689a262018-07-26 15:50:22 +08002212 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2213 uint8_t tmp_chan_list[QDF_MAX_NUM_CHAN] = {0};
2214 uint32_t chan_count;
2215 uint8_t i;
2216 QDF_STATUS status;
Dustin Brown07901ec2018-09-07 11:02:41 -07002217 struct wlan_objmgr_pdev *pdev = hdd_ctx->pdev;
Qiwei Caie689a262018-07-26 15:50:22 +08002218 uint8_t tmp_chan;
2219
2220 sap_config = &adapter->session.ap.sap_config;
2221
2222 status =
Dustin Brown76cd2932018-09-11 16:03:05 -07002223 policy_mgr_get_valid_chans(hdd_ctx->psoc,
Qiwei Caie689a262018-07-26 15:50:22 +08002224 tmp_chan_list,
2225 &chan_count);
2226 if (QDF_IS_STATUS_ERROR(status)) {
2227 hdd_err("Failed to get channel list");
2228 return -EINVAL;
2229 }
2230
2231 for (i = 0; i < chan_count; i++) {
2232 tmp_chan = tmp_chan_list[i];
2233 if (*channel_count < QDF_MAX_NUM_CHAN) {
2234 if ((band == BAND_2G) &&
2235 (WLAN_REG_IS_24GHZ_CH(tmp_chan)) &&
2236 (!wlan_reg_is_disable_ch(pdev, tmp_chan))) {
2237 channel_list[*channel_count] = tmp_chan;
2238 *channel_count += 1;
2239 } else if ((band == BAND_5G) &&
2240 (WLAN_REG_IS_5GHZ_CH(tmp_chan)) &&
2241 (!wlan_reg_is_disable_ch(pdev, tmp_chan))) {
2242 channel_list[*channel_count] = tmp_chan;
2243 *channel_count += 1;
2244 }
2245 } else {
2246 break;
2247 }
2248 }
2249
2250 if (*channel_count == 0) {
2251 hdd_err("no valid channel found");
2252 return -EINVAL;
2253 }
2254
2255 return 0;
2256}
2257
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302258int hdd_cfg80211_update_acs_config(struct hdd_adapter *adapter,
2259 uint8_t reason)
Kapil Gupta8878ad92017-02-13 11:56:04 +05302260{
2261 struct sk_buff *skb;
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07002262 struct sap_config *sap_config;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302263 uint32_t channel_count = 0, status = -EINVAL;
Kapil Gupta8878ad92017-02-13 11:56:04 +05302264 uint8_t channel_list[QDF_MAX_NUM_CHAN] = {0};
Kapil Gupta63e75282017-05-18 20:55:10 +05302265 uint32_t freq_list[QDF_MAX_NUM_CHAN] = {0};
Kapil Gupta8878ad92017-02-13 11:56:04 +05302266 uint8_t vendor_pcl_list[QDF_MAX_NUM_CHAN] = {0};
2267 uint8_t vendor_weight_list[QDF_MAX_NUM_CHAN] = {0};
2268 struct hdd_vendor_acs_chan_params acs_chan_params;
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07002269 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002270 enum band_info band = BAND_2G;
Kapil Gupta8878ad92017-02-13 11:56:04 +05302271 eCsrPhyMode phy_mode;
Jayachandran Sreekumaran68c952c2017-04-24 12:42:03 +05302272 enum qca_wlan_vendor_attr_external_acs_policy acs_policy;
2273 uint32_t i;
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07002274 QDF_STATUS qdf_status;
2275 bool is_external_acs_policy = cfg_default(CFG_EXTERNAL_ACS_POLICY);
Jayachandran Sreekumaran68c952c2017-04-24 12:42:03 +05302276
Kapil Gupta8878ad92017-02-13 11:56:04 +05302277 if (!hdd_ctx) {
2278 hdd_err("HDD context is NULL");
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302279 return -EINVAL;
Kapil Gupta8878ad92017-02-13 11:56:04 +05302280 }
2281
Dustin Brown491d54b2018-03-14 12:39:11 -07002282 hdd_enter();
Jeff Johnsonb9424862017-10-30 08:49:35 -07002283 sap_config = &adapter->session.ap.sap_config;
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05302284 /* When first 2 connections are on the same frequency band,
2285 * then PCL would include only channels from the other
2286 * frequency band on which no connections are active
2287 */
Dustin Brown76cd2932018-09-11 16:03:05 -07002288 if ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 2) &&
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05302289 (sap_config->acs_cfg.band == QCA_ACS_MODE_IEEE80211ANY)) {
2290 struct policy_mgr_conc_connection_info *conc_connection_info;
2291
2292 conc_connection_info = policy_mgr_get_conn_info(&i);
2293 if (conc_connection_info[0].mac ==
2294 conc_connection_info[1].mac) {
2295
2296 if (WLAN_REG_IS_5GHZ_CH(sap_config->acs_cfg.
2297 pcl_channels[0])) {
2298 sap_config->acs_cfg.band =
2299 QCA_ACS_MODE_IEEE80211A;
2300 hdd_update_acs_channel_list(sap_config,
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002301 BAND_5G);
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05302302 } else {
2303 sap_config->acs_cfg.band =
2304 QCA_ACS_MODE_IEEE80211G;
2305 hdd_update_acs_channel_list(sap_config,
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002306 BAND_2G);
Jayachandran Sreekumaran5c7cd972017-09-27 18:51:41 +05302307 }
2308 }
2309 }
Kapil Gupta8878ad92017-02-13 11:56:04 +05302310
Jeff Johnsonb9424862017-10-30 08:49:35 -07002311 hdd_get_scan_band(hdd_ctx, &adapter->session.ap.sap_config, &band);
Nachiket Kukade3208c162017-08-29 17:40:59 +05302312
2313 if (sap_config->acs_cfg.ch_list) {
2314 /* Copy INI or hostapd provided ACS channel range*/
2315 qdf_mem_copy(channel_list, sap_config->acs_cfg.ch_list,
2316 sap_config->acs_cfg.ch_list_count);
2317 channel_count = sap_config->acs_cfg.ch_list_count;
2318 } else {
2319 /* No channel list provided, copy all valid channels */
2320 wlan_hdd_sap_get_valid_channellist(adapter,
2321 &channel_count,
2322 channel_list,
2323 band);
2324 }
Kapil Gupta8878ad92017-02-13 11:56:04 +05302325
Lin Baifac77972018-07-05 19:51:49 +08002326 sap_config->channel_info = qdf_mem_malloc(
2327 sizeof(struct hdd_channel_info) *
2328 channel_count);
Min Liu74a1a502018-10-10 19:59:07 +08002329 if (!sap_config->channel_info)
Lin Baifac77972018-07-05 19:51:49 +08002330 return -ENOMEM;
Lin Baifac77972018-07-05 19:51:49 +08002331
Kapil Gupta8878ad92017-02-13 11:56:04 +05302332 hdd_update_reg_chan_info(adapter, channel_count, channel_list);
Kapil Gupta63e75282017-05-18 20:55:10 +05302333 hdd_get_freq_list(channel_list, freq_list, channel_count);
Kapil Gupta8878ad92017-02-13 11:56:04 +05302334 /* Get phymode */
Jeff Johnsonb9424862017-10-30 08:49:35 -07002335 phy_mode = adapter->session.ap.sap_config.acs_cfg.hw_mode;
Kapil Gupta8878ad92017-02-13 11:56:04 +05302336
2337 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
2338 &(adapter->wdev),
2339 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2340 QCA_NL80211_VENDOR_SUBCMD_UPDATE_EXTERNAL_ACS_CONFIG,
2341 GFP_KERNEL);
2342
2343 if (!skb) {
2344 hdd_err("cfg80211_vendor_event_alloc failed");
Lin Baifac77972018-07-05 19:51:49 +08002345 qdf_mem_free(sap_config->channel_info);
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302346 return -ENOMEM;
Kapil Gupta8878ad92017-02-13 11:56:04 +05302347 }
2348 /*
2349 * Application expects pcl to be a subset of channel list
2350 * Remove all channels which are not in channel list from pcl
2351 * and add weight as zero
2352 */
2353 acs_chan_params.channel_count = channel_count;
2354 acs_chan_params.channel_list = channel_list;
2355 acs_chan_params.vendor_pcl_list = vendor_pcl_list;
2356 acs_chan_params.vendor_weight_list = vendor_weight_list;
2357
2358 hdd_update_vendor_pcl_list(hdd_ctx, &acs_chan_params,
2359 sap_config);
Jayachandran Sreekumaran68c952c2017-04-24 12:42:03 +05302360
2361 if (acs_chan_params.channel_count) {
2362 hdd_debug("ACS channel list: len: %d",
2363 acs_chan_params.channel_count);
2364 for (i = 0; i < acs_chan_params.channel_count; i++)
2365 hdd_debug("%d ", acs_chan_params.channel_list[i]);
2366 }
2367
2368 if (acs_chan_params.pcl_count) {
2369 hdd_debug("ACS PCL list: len: %d",
2370 acs_chan_params.pcl_count);
2371 for (i = 0; i < acs_chan_params.pcl_count; i++)
2372 hdd_debug("channel:%d, weight:%d ",
2373 acs_chan_params.
2374 vendor_pcl_list[i],
2375 acs_chan_params.
2376 vendor_weight_list[i]);
2377 }
2378
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07002379 qdf_status = ucfg_mlme_get_external_acs_policy(hdd_ctx->psoc,
2380 &is_external_acs_policy);
2381 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
2382 hdd_err("get_external_acs_policy failed, set default");
2383
2384 if (is_external_acs_policy) {
Jayachandran Sreekumaran68c952c2017-04-24 12:42:03 +05302385 acs_policy =
2386 QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_MANDATORY;
2387 } else {
2388 acs_policy =
2389 QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_POLICY_PCL_PREFERRED;
2390 }
Kapil Gupta8878ad92017-02-13 11:56:04 +05302391 /* Update values in NL buffer */
2392 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_REASON,
2393 reason) ||
Kapil Gupta63e75282017-05-18 20:55:10 +05302394 nla_put_flag(skb,
2395 QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_IS_OFFLOAD_ENABLED) ||
2396 nla_put_flag(skb,
2397 QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_ADD_CHAN_STATS_SUPPORT)
2398 ||
Kapil Gupta8878ad92017-02-13 11:56:04 +05302399 nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_WIDTH,
2400 sap_config->acs_cfg.ch_width) ||
Kapil Gupta8878ad92017-02-13 11:56:04 +05302401 nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_BAND,
2402 band) ||
2403 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PHY_MODE,
2404 phy_mode) ||
SaidiReddy Yenugae14cfb82017-05-04 18:50:37 +05302405 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_FREQ_LIST,
Kapil Gupta63e75282017-05-18 20:55:10 +05302406 channel_count * sizeof(uint32_t), freq_list)) {
Kapil Gupta8878ad92017-02-13 11:56:04 +05302407 hdd_err("nla put fail");
2408 goto fail;
2409 }
Jayachandran Sreekumaran68c952c2017-04-24 12:42:03 +05302410 status =
2411 hdd_cfg80211_update_pcl(skb,
2412 acs_chan_params.
2413 pcl_count,
2414 QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_PCL,
2415 vendor_pcl_list,
2416 vendor_weight_list);
Kapil Gupta8878ad92017-02-13 11:56:04 +05302417
2418 if (status != 0)
2419 goto fail;
2420
2421 status = hdd_cfg80211_update_channel_info(skb, sap_config,
2422 QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_CHAN_INFO);
2423
2424 if (status != 0)
2425 goto fail;
2426
Jayachandran Sreekumaran68c952c2017-04-24 12:42:03 +05302427 status = nla_put_u32(skb,
2428 QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_EVENT_POLICY,
2429 acs_policy);
2430
2431 if (status != 0)
2432 goto fail;
2433
Kapil Gupta8878ad92017-02-13 11:56:04 +05302434 cfg80211_vendor_event(skb, GFP_KERNEL);
Lin Baifac77972018-07-05 19:51:49 +08002435 qdf_mem_free(sap_config->channel_info);
2436
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302437 return 0;
Kapil Gupta8878ad92017-02-13 11:56:04 +05302438fail:
Lin Baifac77972018-07-05 19:51:49 +08002439 qdf_mem_free(sap_config->channel_info);
Kapil Gupta8878ad92017-02-13 11:56:04 +05302440 if (skb)
2441 kfree_skb(skb);
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302442 return status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05302443}
2444
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302445/**
2446 * hdd_create_acs_timer(): Initialize vendor ACS timer
2447 * @adapter: pointer to SAP adapter struct
2448 *
2449 * This function initializes the vendor ACS timer.
2450 *
2451 * Return: Status of create vendor ACS timer
2452 */
Jeff Johnsone5006672017-08-29 14:39:02 -07002453static int hdd_create_acs_timer(struct hdd_adapter *adapter)
Kapil Gupta8878ad92017-02-13 11:56:04 +05302454{
2455 struct hdd_external_acs_timer_context *timer_context;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302456 QDF_STATUS status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05302457
Jeff Johnsonb9424862017-10-30 08:49:35 -07002458 if (adapter->session.ap.vendor_acs_timer_initialized)
Kapil Gupta8878ad92017-02-13 11:56:04 +05302459 return 0;
2460
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302461 hdd_debug("Starting vendor app based ACS");
Kapil Gupta8878ad92017-02-13 11:56:04 +05302462 timer_context = qdf_mem_malloc(sizeof(*timer_context));
Min Liu74a1a502018-10-10 19:59:07 +08002463 if (!timer_context)
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302464 return -ENOMEM;
Min Liu74a1a502018-10-10 19:59:07 +08002465
Kapil Gupta8878ad92017-02-13 11:56:04 +05302466 timer_context->adapter = adapter;
2467
2468 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
Jeff Johnsonb9424862017-10-30 08:49:35 -07002469 status = qdf_mc_timer_init(&adapter->session.ap.vendor_acs_timer,
Kapil Gupta8878ad92017-02-13 11:56:04 +05302470 QDF_TIMER_TYPE_SW,
2471 hdd_acs_response_timeout_handler, timer_context);
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302472 if (status != QDF_STATUS_SUCCESS) {
2473 hdd_err("Failed to initialize acs response timeout timer");
2474 return -EFAULT;
2475 }
Jeff Johnsonb9424862017-10-30 08:49:35 -07002476 adapter->session.ap.vendor_acs_timer_initialized = true;
Kapil Gupta8878ad92017-02-13 11:56:04 +05302477 return 0;
2478}
2479
Ashish Kumar Dhanotiyacc770eb2017-06-08 19:31:15 +05302480static const struct nla_policy
2481wlan_hdd_cfg80211_do_acs_policy[QCA_WLAN_VENDOR_ATTR_ACS_MAX+1] = {
2482 [QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE] = { .type = NLA_U8 },
2483 [QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED] = { .type = NLA_FLAG },
2484 [QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED] = { .type = NLA_FLAG },
2485 [QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED] = { .type = NLA_FLAG },
2486 [QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH] = { .type = NLA_U16 },
2487 [QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST] = { .type = NLA_UNSPEC },
2488 [QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST] = { .type = NLA_UNSPEC },
2489};
2490
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302491int hdd_start_vendor_acs(struct hdd_adapter *adapter)
2492{
2493 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2494 int status;
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07002495 QDF_STATUS qdf_status;
2496 bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE);
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302497
2498 status = hdd_create_acs_timer(adapter);
2499 if (status != 0) {
2500 hdd_err("failed to create acs timer");
2501 return status;
2502 }
2503 status = hdd_update_acs_timer_reason(adapter,
2504 QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT);
2505 if (status != 0) {
2506 hdd_err("failed to update acs timer reason");
2507 return status;
2508 }
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07002509 qdf_status = ucfg_mlme_get_acs_support_for_dfs_ltecoex(
2510 hdd_ctx->psoc,
2511 &is_acs_support_for_dfs_ltecoex);
2512 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
2513 hdd_err("get_acs_support_for_dfs_ltecoex failed, set def");
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302514
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07002515 if (is_acs_support_for_dfs_ltecoex)
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302516 status = qdf_status_to_os_return(wlan_sap_set_vendor_acs(
2517 WLAN_HDD_GET_SAP_CTX_PTR(adapter),
2518 true));
2519 else
2520 status = qdf_status_to_os_return(wlan_sap_set_vendor_acs(
2521 WLAN_HDD_GET_SAP_CTX_PTR(adapter),
2522 false));
2523
2524 return status;
2525}
2526
Kapil Gupta8878ad92017-02-13 11:56:04 +05302527/**
Ashish Kumar Dhanotiya2168aad2019-06-12 20:51:36 +05302528 * hdd_avoid_acs_channels() - Avoid acs channels
2529 * @hdd_ctx: Pointer to the hdd context
2530 * @sap_config: Sap config structure pointer
2531 *
2532 * This function avoids channels from the acs corresponding to
2533 * the frequencies configured in the ini sap_avoid_acs_freq_list
2534 *
2535 * Return: None
2536 */
2537
2538#ifdef SAP_AVOID_ACS_FREQ_LIST
2539static void hdd_avoid_acs_channels(struct hdd_context *hdd_ctx,
2540 struct sap_config *sap_config)
2541{
2542 int i, j, ch_cnt = 0;
2543 uint16_t avoid_acs_freq_list[CFG_VALID_CHANNEL_LIST_LEN];
2544 uint8_t avoid_acs_freq_list_num;
2545
2546 hdd_enter();
2547
2548 ucfg_mlme_get_acs_avoid_freq_list(hdd_ctx->psoc,
2549 avoid_acs_freq_list,
2550 &avoid_acs_freq_list_num);
2551
2552 for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) {
2553 for (j = 0; j < avoid_acs_freq_list_num; j++) {
2554 if (sap_config->acs_cfg.ch_list[i] ==
2555 wlan_reg_freq_to_chan(
2556 hdd_ctx->pdev,
2557 avoid_acs_freq_list[j])) {
2558 hdd_debug("skip channel %d",
2559 sap_config->acs_cfg.ch_list[i]);
2560 break;
2561 }
2562 }
2563 if (j == avoid_acs_freq_list_num)
2564 sap_config->acs_cfg.ch_list[ch_cnt++] =
2565 sap_config->acs_cfg.ch_list[i];
2566 }
2567 sap_config->acs_cfg.ch_list_count = ch_cnt;
2568}
2569#else
2570static void hdd_avoid_acs_channels(struct hdd_context *hdd_ctx,
2571 struct sap_config *sap_config)
2572{
2573}
2574#endif
2575
2576/**
Ashish Kumar Dhanotiyacc770eb2017-06-08 19:31:15 +05302577 * __wlan_hdd_cfg80211_do_acs(): CFG80211 handler function for DO_ACS Vendor CMD
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002578 * @wiphy: Linux wiphy struct pointer
2579 * @wdev: Linux wireless device struct pointer
2580 * @data: ACS information from hostapd
2581 * @data_len: ACS information length
2582 *
2583 * This function handle DO_ACS Vendor command from hostapd, parses ACS config
2584 * and starts ACS procedure.
2585 *
2586 * Return: ACS procedure start status
2587 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002588static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
2589 struct wireless_dev *wdev,
2590 const void *data, int data_len)
2591{
2592 struct net_device *ndev = wdev->netdev;
Jeff Johnsone5006672017-08-29 14:39:02 -07002593 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07002594 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07002595 struct sap_config *sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002596 struct sk_buff *temp_skbuff;
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002597 int ret, i, ch_cnt = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002598 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_MAX + 1];
2599 bool ht_enabled, ht40_enabled, vht_enabled;
wadesong1795e142018-01-05 11:13:07 +08002600 uint8_t ch_width;
2601 enum qca_wlan_vendor_acs_hw_mode hw_mode;
Rachit Kankanedef2b172019-03-07 11:34:44 +05302602 enum policy_mgr_con_mode pm_mode;
Nachiket Kukadec3f92f72017-08-07 17:04:50 +05302603 QDF_STATUS qdf_status;
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002604 bool skip_etsi13_srd_chan = false;
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07002605 bool is_vendor_acs_support =
2606 cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
2607 bool is_external_acs_policy =
2608 cfg_default(CFG_EXTERNAL_ACS_POLICY);
Bala Venkatesh3d786eb2018-11-20 12:59:31 +05302609 bool sap_force_11n_for_11ac = 0;
2610 bool go_force_11n_for_11ac = 0;
lifeng0b46ae52018-12-13 09:42:27 +08002611 bool etsi13_srd_chan;
Sandeep Puligilla34618782019-01-04 17:42:42 -08002612 bool go_11ac_override = 0;
2613 bool sap_11ac_override = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002614
2615 /* ***Note*** Donot set SME config related to ACS operation here because
2616 * ACS operation is not synchronouse and ACS for Second AP may come when
2617 * ACS operation for first AP is going on. So only do_acs is split to
Jeff Johnsonfa7d9602018-05-06 11:25:31 -07002618 * separate start_acs routine. Also SME-PMAC struct that is used to
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002619 * pass paremeters from HDD to SAP is global. Thus All ACS related SME
2620 * config shall be set only from start_acs.
2621 */
2622
Dustin Brownfdf17c12018-03-14 12:55:34 -07002623 hdd_enter_dev(ndev);
Jeff Johnson1f61b612016-02-12 16:28:33 -08002624
Anurag Chouhan6d760662016-02-20 16:05:43 +05302625 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002626 hdd_err("Command not allowed in FTM mode");
2627 return -EPERM;
2628 }
2629
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302630 ret = wlan_hdd_validate_context(hdd_ctx);
2631 if (ret)
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05302632 return ret;
2633
Bala Venkatesh3d786eb2018-11-20 12:59:31 +05302634 ucfg_mlme_get_sap_force_11n_for_11ac(hdd_ctx->psoc,
2635 &sap_force_11n_for_11ac);
2636 ucfg_mlme_get_go_force_11n_for_11ac(hdd_ctx->psoc,
2637 &go_force_11n_for_11ac);
2638
Amar Singhalf9898792018-08-20 12:13:34 -07002639 hdd_debug("current country is %s", hdd_ctx->reg.alpha2);
2640
Hanumanth Reddy Pothula89b0dce2018-05-18 12:49:43 +05302641 if (!((adapter->device_mode == QDF_SAP_MODE) ||
2642 (adapter->device_mode == QDF_P2P_GO_MODE))) {
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05302643 hdd_err("Invalid device mode %d", adapter->device_mode);
2644 return -EINVAL;
2645 }
Abhishek Singh23edd1c2016-05-05 11:56:06 +05302646
Naveen Rawat64e477e2016-05-20 10:34:56 -07002647 if (cds_is_sub_20_mhz_enabled()) {
2648 hdd_err("ACS not supported in sub 20 MHz ch wd.");
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05302649 return -EINVAL;
Naveen Rawat64e477e2016-05-20 10:34:56 -07002650 }
2651
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05302652 if (qdf_atomic_read(&adapter->session.ap.acs_in_progress) > 0) {
Abhinav Kumar5eda62d2018-02-13 13:00:39 +05302653 hdd_err("ACS rejected as previous req already in progress");
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05302654 return -EINVAL;
2655 } else {
2656 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 1);
Abhinav Kumar5eda62d2018-02-13 13:00:39 +05302657 }
2658
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302659 ret = wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_MAX, data,
Dustin Brown4ea21db2018-01-05 14:13:17 -08002660 data_len,
2661 wlan_hdd_cfg80211_do_acs_policy);
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302662 if (ret) {
Jeff Johnson020db452016-06-29 14:37:26 -07002663 hdd_err("Invalid ATTR");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002664 goto out;
2665 }
2666
2667 if (!tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
Jeff Johnson020db452016-06-29 14:37:26 -07002668 hdd_err("Attr hw_mode failed");
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302669 ret = -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002670 goto out;
2671 }
Kapil Gupta8878ad92017-02-13 11:56:04 +05302672 hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002673
2674 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED])
2675 ht_enabled =
2676 nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_ACS_HT_ENABLED]);
2677 else
2678 ht_enabled = 0;
2679
2680 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED])
2681 ht40_enabled =
2682 nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_ACS_HT40_ENABLED]);
2683 else
2684 ht40_enabled = 0;
2685
Kapil Guptac1224bf2017-06-22 21:22:40 +05302686 hdd_debug("ht40_enabled %d", ht40_enabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002687 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED])
2688 vht_enabled =
2689 nla_get_flag(tb[QCA_WLAN_VENDOR_ATTR_ACS_VHT_ENABLED]);
2690 else
2691 vht_enabled = 0;
2692
Bala Venkateshb9cf3362017-11-09 15:48:46 +05302693 if (((adapter->device_mode == QDF_SAP_MODE) &&
Bala Venkatesh3d786eb2018-11-20 12:59:31 +05302694 sap_force_11n_for_11ac) ||
2695 ((adapter->device_mode == QDF_P2P_GO_MODE) &&
2696 go_force_11n_for_11ac)) {
Rajeev Kumar Sirasanagandlab79b5462016-09-06 18:33:17 +05302697 vht_enabled = 0;
Dustin Brownbacc48f2018-03-14 14:48:44 -07002698 hdd_info("VHT is Disabled in ACS");
Rajeev Kumar Sirasanagandlab79b5462016-09-06 18:33:17 +05302699 }
2700
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002701 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]) {
2702 ch_width = nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH]);
2703 } else {
2704 if (ht_enabled && ht40_enabled)
2705 ch_width = 40;
2706 else
2707 ch_width = 20;
2708 }
Rajeev Kumar Sirasanagandlab79b5462016-09-06 18:33:17 +05302709
Bala Venkateshb9cf3362017-11-09 15:48:46 +05302710 /* this may be possible, when sap_force_11n_for_11ac or
2711 * go_force_11n_for_11ac is set
2712 */
Rajeev Kumar Sirasanagandlab79b5462016-09-06 18:33:17 +05302713 if ((ch_width == 80 || ch_width == 160) && !vht_enabled) {
2714 if (ht_enabled && ht40_enabled)
2715 ch_width = 40;
2716 else
2717 ch_width = 20;
2718 }
2719
Hanumanth Reddy Pothula560d5712018-03-15 18:11:27 +05302720 sap_config = &adapter->session.ap.sap_config;
2721
2722 /* Check and free if memory is already allocated for acs channel list */
2723 wlan_hdd_undo_acs(adapter);
2724
2725 qdf_mem_zero(&sap_config->acs_cfg, sizeof(struct sap_acs_cfg));
2726
Kapil Guptac1224bf2017-06-22 21:22:40 +05302727 hdd_debug("channel width =%d", ch_width);
Himanshu Agarwal75e74412018-02-01 20:51:47 +05302728 if (ch_width == 160)
2729 sap_config->acs_cfg.ch_width = CH_WIDTH_160MHZ;
2730 else if (ch_width == 80)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002731 sap_config->acs_cfg.ch_width = CH_WIDTH_80MHZ;
2732 else if (ch_width == 40)
2733 sap_config->acs_cfg.ch_width = CH_WIDTH_40MHZ;
2734 else
2735 sap_config->acs_cfg.ch_width = CH_WIDTH_20MHZ;
2736
2737 /* hw_mode = a/b/g: QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST and
2738 * QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST attrs are present, and
2739 * QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST is used for obtaining the
2740 * channel list, QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST is ignored
2741 * since it contains the frequency values of the channels in
2742 * the channel list.
2743 * hw_mode = any: only QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST attr
2744 * is present
2745 */
Himanshu Agarwal1b3be702018-02-20 12:16:57 +05302746
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002747 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]) {
2748 char *tmp = nla_data(tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]);
Srinivas Girigowda576b2352017-08-25 14:44:26 -07002749
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002750 sap_config->acs_cfg.ch_list_count = nla_len(
2751 tb[QCA_WLAN_VENDOR_ATTR_ACS_CH_LIST]);
2752 if (sap_config->acs_cfg.ch_list_count) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302753 sap_config->acs_cfg.ch_list = qdf_mem_malloc(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002754 sizeof(uint8_t) *
2755 sap_config->acs_cfg.ch_list_count);
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302756 if (!sap_config->acs_cfg.ch_list) {
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302757 ret = -ENOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002758 goto out;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302759 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002760
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302761 qdf_mem_copy(sap_config->acs_cfg.ch_list, tmp,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002762 sap_config->acs_cfg.ch_list_count);
2763 }
2764 } else if (tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST]) {
2765 uint32_t *freq =
2766 nla_data(tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST]);
2767 sap_config->acs_cfg.ch_list_count = nla_len(
2768 tb[QCA_WLAN_VENDOR_ATTR_ACS_FREQ_LIST]) /
2769 sizeof(uint32_t);
2770 if (sap_config->acs_cfg.ch_list_count) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302771 sap_config->acs_cfg.ch_list = qdf_mem_malloc(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002772 sap_config->acs_cfg.ch_list_count);
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302773 if (!sap_config->acs_cfg.ch_list) {
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302774 ret = -ENOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002775 goto out;
2776 }
2777
2778 /* convert frequency to channel */
2779 for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++)
2780 sap_config->acs_cfg.ch_list[i] =
2781 ieee80211_frequency_to_channel(freq[i]);
2782 }
2783 }
2784
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302785 if (!sap_config->acs_cfg.ch_list_count) {
Amar Singhal5f783132018-03-29 13:58:50 -07002786 hdd_err("acs config chan count 0");
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302787 ret = -EINVAL;
2788 goto out;
2789 }
2790
lifeng0b46ae52018-12-13 09:42:27 +08002791 ucfg_mlme_get_etsi13_srd_chan_in_master_mode(hdd_ctx->psoc,
2792 &etsi13_srd_chan);
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002793 skip_etsi13_srd_chan =
lifeng0b46ae52018-12-13 09:42:27 +08002794 !etsi13_srd_chan &&
Dustin Brown07901ec2018-09-07 11:02:41 -07002795 wlan_reg_is_etsi13_regdmn(hdd_ctx->pdev);
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002796
2797 if (skip_etsi13_srd_chan) {
2798 for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++) {
Dustin Brown07901ec2018-09-07 11:02:41 -07002799 if (wlan_reg_is_etsi13_srd_chan(hdd_ctx->pdev,
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -07002800 sap_config->acs_cfg.
2801 ch_list[i]))
2802 sap_config->acs_cfg.ch_list[i] = 0;
2803 else
2804 sap_config->acs_cfg.ch_list[ch_cnt++] =
2805 sap_config->acs_cfg.ch_list[i];
2806 }
2807 sap_config->acs_cfg.ch_list_count = ch_cnt;
2808 }
Ashish Kumar Dhanotiya2168aad2019-06-12 20:51:36 +05302809
2810 hdd_avoid_acs_channels(hdd_ctx, sap_config);
2811
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002812 hdd_debug("get pcl for DO_ACS vendor command");
2813
Rachit Kankanedef2b172019-03-07 11:34:44 +05302814 pm_mode =
2815 policy_mgr_convert_device_mode_to_qdf_type(adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002816 /* consult policy manager to get PCL */
Rachit Kankanedef2b172019-03-07 11:34:44 +05302817 qdf_status = policy_mgr_get_pcl(hdd_ctx->psoc, pm_mode,
2818 sap_config->acs_cfg.pcl_channels,
2819 &sap_config->acs_cfg.pcl_ch_count,
2820 sap_config->acs_cfg.
2821 pcl_channels_weight_list,
2822 QDF_MAX_NUM_CHAN);
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302823 if (qdf_status != QDF_STATUS_SUCCESS)
Jeff Johnson020db452016-06-29 14:37:26 -07002824 hdd_err("Get PCL failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002825
Jayachandran Sreekumaran68c952c2017-04-24 12:42:03 +05302826 if (sap_config->acs_cfg.pcl_ch_count) {
2827 hdd_debug("ACS config PCL: len: %d",
2828 sap_config->acs_cfg.pcl_ch_count);
2829 for (i = 0; i < sap_config->acs_cfg.pcl_ch_count; i++)
2830 hdd_debug("channel:%d, weight:%d ",
2831 sap_config->acs_cfg.
2832 pcl_channels[i],
2833 sap_config->acs_cfg.
2834 pcl_channels_weight_list[i]);
Nachiket Kukadec3f92f72017-08-07 17:04:50 +05302835 }
Kapil Guptac1224bf2017-06-22 21:22:40 +05302836 sap_config->acs_cfg.band = hw_mode;
Rachit Kankanedef2b172019-03-07 11:34:44 +05302837
2838 qdf_status = ucfg_mlme_get_external_acs_policy(hdd_ctx->psoc,
2839 &is_external_acs_policy);
2840 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
2841 hdd_err("get_external_acs_policy failed");
2842
gaurank kathpaliaaf483f52019-07-19 09:04:07 +05302843 sap_config->acs_cfg.acs_mode = true;
2844
Rachit Kankanedef2b172019-03-07 11:34:44 +05302845 if (is_external_acs_policy &&
2846 policy_mgr_is_force_scc(hdd_ctx->psoc) &&
2847 policy_mgr_get_connection_count(hdd_ctx->psoc)) {
2848 policy_mgr_trim_acs_channel_list(
2849 sap_config->acs_cfg.pcl_channels,
2850 sap_config->acs_cfg.pcl_ch_count,
2851 sap_config->acs_cfg.ch_list,
2852 &sap_config->acs_cfg.ch_list_count);
2853
2854 /* if it is only one channel, send ACS event to upper layer */
2855 if (sap_config->acs_cfg.ch_list_count == 1) {
2856 sap_config->acs_cfg.pri_ch =
2857 sap_config->acs_cfg.ch_list[0];
2858 wlan_sap_set_sap_ctx_acs_cfg(
2859 WLAN_HDD_GET_SAP_CTX_PTR(adapter), sap_config);
2860 sap_config_acs_result(hdd_ctx->mac_handle,
2861 WLAN_HDD_GET_SAP_CTX_PTR(adapter),
2862 sap_config->acs_cfg.ht_sec_ch);
2863 sap_config->ch_params.ch_width =
2864 sap_config->acs_cfg.ch_width;
2865 sap_config->ch_params.sec_ch_offset =
2866 sap_config->acs_cfg.ht_sec_ch;
2867 sap_config->ch_params.center_freq_seg0 =
2868 sap_config->acs_cfg.vht_seg0_center_ch;
2869 sap_config->ch_params.center_freq_seg1 =
2870 sap_config->acs_cfg.vht_seg1_center_ch;
2871 /*notify hostapd about channel override */
2872 wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
2873 ret = 0;
2874 goto out;
2875 }
2876 }
2877
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302878 ret = wlan_hdd_set_acs_ch_range(sap_config, hw_mode,
Himanshu Agarwal8b3d3e92018-02-08 23:03:54 +05302879 ht_enabled, vht_enabled);
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302880 if (ret) {
Himanshu Agarwal8b3d3e92018-02-08 23:03:54 +05302881 hdd_err("set acs channel range failed");
2882 goto out;
2883 }
2884
Sandeep Puligilla34618782019-01-04 17:42:42 -08002885 ucfg_mlme_is_go_11ac_override(hdd_ctx->psoc, &go_11ac_override);
2886 ucfg_mlme_is_sap_11ac_override(hdd_ctx->psoc, &sap_11ac_override);
Nachiket Kukadec3f92f72017-08-07 17:04:50 +05302887 /* ACS override for android */
Himanshu Agarwal4ecf6ca2018-05-09 16:48:56 +05302888 if (ht_enabled &&
Himanshu Agarwal8b3d3e92018-02-08 23:03:54 +05302889 sap_config->acs_cfg.end_ch >= WLAN_REG_CH_NUM(CHAN_ENUM_36) &&
Himanshu Agarwal4ecf6ca2018-05-09 16:48:56 +05302890 ((adapter->device_mode == QDF_SAP_MODE &&
Bala Venkatesh3d786eb2018-11-20 12:59:31 +05302891 !sap_force_11n_for_11ac &&
Sandeep Puligilla34618782019-01-04 17:42:42 -08002892 sap_11ac_override) ||
Himanshu Agarwal4ecf6ca2018-05-09 16:48:56 +05302893 (adapter->device_mode == QDF_P2P_GO_MODE &&
Bala Venkatesh3d786eb2018-11-20 12:59:31 +05302894 !go_force_11n_for_11ac &&
Sandeep Puligilla34618782019-01-04 17:42:42 -08002895 go_11ac_override))) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002896 vht_enabled = 1;
2897 sap_config->acs_cfg.hw_mode = eCSR_DOT11_MODE_11ac;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302898 qdf_status =
2899 ucfg_mlme_get_vht_channel_width(hdd_ctx->psoc,
2900 &ch_width);
2901 sap_config->acs_cfg.ch_width = ch_width;
Himanshu Agarwal29a9a3e2018-02-21 17:44:37 +05302902 }
2903
2904 /* No VHT80 in 2.4G so perform ACS accordingly */
2905 if (sap_config->acs_cfg.end_ch <= 14 &&
2906 sap_config->acs_cfg.ch_width == eHT_CHANNEL_WIDTH_80MHZ) {
2907 sap_config->acs_cfg.ch_width = eHT_CHANNEL_WIDTH_40MHZ;
2908 hdd_debug("resetting to 40Mhz in 2.4Ghz");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002909 }
2910
Kapil Guptac1224bf2017-06-22 21:22:40 +05302911 hdd_debug("ACS Config for %s: HW_MODE: %d ACS_BW: %d HT: %d VHT: %d START_CH: %d END_CH: %d band %d",
2912 adapter->dev->name, sap_config->acs_cfg.hw_mode,
Himanshu Agarwal1ed8bff2018-02-07 12:50:41 +05302913 sap_config->acs_cfg.ch_width, ht_enabled, vht_enabled,
Kapil Guptac1224bf2017-06-22 21:22:40 +05302914 sap_config->acs_cfg.start_ch, sap_config->acs_cfg.end_ch,
2915 sap_config->acs_cfg.band);
wadesongcb0ded22018-02-02 17:57:20 +08002916 host_log_acs_req_event(adapter->dev->name,
2917 csr_phy_mode_str(sap_config->acs_cfg.hw_mode),
2918 ch_width, ht_enabled, vht_enabled,
2919 sap_config->acs_cfg.start_ch,
2920 sap_config->acs_cfg.end_ch);
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07002921
Kapil Gupta8878ad92017-02-13 11:56:04 +05302922 sap_config->acs_cfg.is_ht_enabled = ht_enabled;
2923 sap_config->acs_cfg.is_vht_enabled = vht_enabled;
2924
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002925 if (sap_config->acs_cfg.ch_list_count) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08002926 hdd_debug("ACS channel list: len: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002927 sap_config->acs_cfg.ch_list_count);
2928 for (i = 0; i < sap_config->acs_cfg.ch_list_count; i++)
Srinivas Girigowda13d39252017-03-06 16:12:15 -08002929 hdd_debug("%d ", sap_config->acs_cfg.ch_list[i]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002930 }
Himanshu Agarwal33163982018-05-17 18:11:10 +05302931
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002932 if (test_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags)) {
Jeff Johnson020db452016-06-29 14:37:26 -07002933 /* ***Note*** Completion variable usage is not allowed
2934 * here since ACS scan operation may take max 2.2 sec
2935 * for 5G band:
2936 * 9 Active channel X 40 ms active scan time +
2937 * 16 Passive channel X 110ms passive scan time
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002938 * Since this CFG80211 call lock rtnl mutex, we cannot hold on
2939 * for this long. So we split up the scanning part.
2940 */
2941 set_bit(ACS_PENDING, &adapter->event_flags);
Srinivas Girigowda13d39252017-03-06 16:12:15 -08002942 hdd_debug("ACS Pending for %s", adapter->dev->name);
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302943 ret = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002944 } else {
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07002945 qdf_status =
2946 ucfg_mlme_get_vendor_acs_support(
2947 hdd_ctx->psoc,
2948 &is_vendor_acs_support);
2949 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
2950 hdd_err("get_vendor_acs_support failed, set default");
2951
Kapil Gupta8878ad92017-02-13 11:56:04 +05302952 /* Check if vendor specific acs is enabled */
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07002953 if (is_vendor_acs_support)
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302954 ret = hdd_start_vendor_acs(adapter);
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05302955 else
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302956 ret = wlan_hdd_cfg80211_start_acs(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002957 }
2958
2959out:
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302960 if (ret == 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002961 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2962 NLMSG_HDRLEN);
Jeff Johnsond36fa332019-03-18 13:42:25 -07002963 if (temp_skbuff)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002964 return cfg80211_vendor_cmd_reply(temp_skbuff);
2965 }
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05302966 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Liangwei Dong8baf7c82016-10-11 01:26:59 -04002967 wlan_hdd_undo_acs(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002968 clear_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags);
2969
Yeshwanth Sriram Guntukad1f8ca72018-03-02 12:31:38 +05302970 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002971}
2972
Jeff Johnsonf3826e12017-01-12 09:49:40 -08002973/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002974 * wlan_hdd_cfg80211_do_acs : CFG80211 handler function for DO_ACS Vendor CMD
2975 * @wiphy: Linux wiphy struct pointer
2976 * @wdev: Linux wireless device struct pointer
2977 * @data: ACS information from hostapd
2978 * @data_len: ACS information len
2979 *
2980 * This function handle DO_ACS Vendor command from hostapd, parses ACS config
2981 * and starts ACS procedure.
2982 *
2983 * Return: ACS procedure start status
2984 */
2985
2986static int wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
2987 struct wireless_dev *wdev,
2988 const void *data, int data_len)
2989{
Dustin Browna09acf42018-11-08 12:32:26 +05302990 int errno;
2991 struct osif_vdev_sync *vdev_sync;
2992
2993 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
2994 if (errno)
2995 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002996
Dustin Browna09acf42018-11-08 12:32:26 +05302997 errno = __wlan_hdd_cfg80211_do_acs(wiphy, wdev, data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002998
Dustin Browna09acf42018-11-08 12:32:26 +05302999 osif_vdev_sync_op_stop(vdev_sync);
3000
3001 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003002}
3003
3004/**
Liangwei Dong8baf7c82016-10-11 01:26:59 -04003005 * wlan_hdd_undo_acs : Do cleanup of DO_ACS
3006 * @adapter: Pointer to adapter struct
3007 *
3008 * This function handle cleanup of what was done in DO_ACS, including free
3009 * memory.
3010 *
3011 * Return: void
3012 */
3013
Jeff Johnsone5006672017-08-29 14:39:02 -07003014void wlan_hdd_undo_acs(struct hdd_adapter *adapter)
Liangwei Dong8baf7c82016-10-11 01:26:59 -04003015{
gaurank kathpaliaaf483f52019-07-19 09:04:07 +05303016 struct sap_config *sap_cfg;
3017
Jeff Johnsond36fa332019-03-18 13:42:25 -07003018 if (!adapter)
Liangwei Dong8baf7c82016-10-11 01:26:59 -04003019 return;
gaurank kathpaliaaf483f52019-07-19 09:04:07 +05303020
3021 sap_cfg = &adapter->session.ap.sap_config;
3022 if (sap_cfg->acs_cfg.ch_list) {
gaurank kathpalia6701aef2019-06-27 11:53:08 +05303023 hdd_debug("Clearing ACS cfg channel list");
gaurank kathpaliaaf483f52019-07-19 09:04:07 +05303024 qdf_mem_free(sap_cfg->acs_cfg.ch_list);
3025 sap_cfg->acs_cfg.ch_list = NULL;
Liangwei Dong8baf7c82016-10-11 01:26:59 -04003026 }
gaurank kathpaliaaf483f52019-07-19 09:04:07 +05303027 sap_cfg->acs_cfg.ch_list_count = 0;
3028 sap_cfg->acs_cfg.acs_mode = false;
Liangwei Dong8baf7c82016-10-11 01:26:59 -04003029}
3030
3031/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003032 * wlan_hdd_cfg80211_start_pending_acs : Start pending ACS procedure for SAP
3033 * @work: Linux workqueue struct pointer for ACS work
3034 *
3035 * This function starts the ACS procedure which was marked pending when an ACS
3036 * procedure was in progress for a concurrent SAP interface.
3037 *
3038 * Return: None
3039 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003040static void wlan_hdd_cfg80211_start_pending_acs(struct work_struct *work)
3041{
Jeff Johnsone5006672017-08-29 14:39:02 -07003042 struct hdd_adapter *adapter = container_of(work, struct hdd_adapter,
Jeff Johnson3aa54d42018-06-26 11:36:50 -07003043 acs_pending_work.work);
Dustin Brown4376fed2019-03-06 11:00:38 -08003044 struct osif_vdev_sync *vdev_sync;
Jeff Johnson3aa54d42018-06-26 11:36:50 -07003045
Dustin Brown4376fed2019-03-06 11:00:38 -08003046 if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync))
3047 return;
3048
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003049 wlan_hdd_cfg80211_start_acs(adapter);
Will Huang7049bae2018-08-13 17:25:02 +08003050 clear_bit(ACS_PENDING, &adapter->event_flags);
Dustin Brown4376fed2019-03-06 11:00:38 -08003051
3052 osif_vdev_sync_op_stop(vdev_sync);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003053}
3054
3055/**
3056 * wlan_hdd_cfg80211_acs_ch_select_evt: Callback function for ACS evt
3057 * @adapter: Pointer to SAP adapter struct
3058 * @pri_channel: SAP ACS procedure selected Primary channel
3059 * @sec_channel: SAP ACS procedure selected secondary channel
3060 *
3061 * This is a callback function from SAP module on ACS procedure is completed.
3062 * This function send the ACS selected channel information to hostapd
3063 *
3064 * Return: None
3065 */
3066
Jeff Johnsone5006672017-08-29 14:39:02 -07003067void wlan_hdd_cfg80211_acs_ch_select_evt(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003068{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07003069 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07003070 struct sap_config *sap_cfg =
3071 &(WLAN_HDD_GET_AP_CTX_PTR(adapter))->sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003072 struct sk_buff *vendor_event;
3073 int ret_val;
Jeff Johnsone5006672017-08-29 14:39:02 -07003074 struct hdd_adapter *con_sap_adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003075 uint16_t ch_width;
3076
3077 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
Ryan Hsu9206a4e2016-01-19 17:23:13 -08003078 &(adapter->wdev),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003079 4 * sizeof(u8) + 1 * sizeof(u16) + 4 + NLMSG_HDRLEN,
3080 QCA_NL80211_VENDOR_SUBCMD_DO_ACS_INDEX,
3081 GFP_KERNEL);
3082
3083 if (!vendor_event) {
Jeff Johnson46b40792016-06-29 14:03:14 -07003084 hdd_err("cfg80211_vendor_event_alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003085 return;
3086 }
3087
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003088 ret_val = nla_put_u8(vendor_event,
3089 QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL,
3090 sap_cfg->acs_cfg.pri_ch);
3091 if (ret_val) {
Jeff Johnson46b40792016-06-29 14:03:14 -07003092 hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_PRIMARY_CHANNEL put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003093 kfree_skb(vendor_event);
3094 return;
3095 }
3096
3097 ret_val = nla_put_u8(vendor_event,
3098 QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL,
3099 sap_cfg->acs_cfg.ht_sec_ch);
3100 if (ret_val) {
Jeff Johnson46b40792016-06-29 14:03:14 -07003101 hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_SECONDARY_CHANNEL put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003102 kfree_skb(vendor_event);
3103 return;
3104 }
3105
3106 ret_val = nla_put_u8(vendor_event,
3107 QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL,
3108 sap_cfg->acs_cfg.vht_seg0_center_ch);
3109 if (ret_val) {
Jeff Johnson46b40792016-06-29 14:03:14 -07003110 hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG0_CENTER_CHANNEL put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003111 kfree_skb(vendor_event);
3112 return;
3113 }
3114
3115 ret_val = nla_put_u8(vendor_event,
3116 QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL,
3117 sap_cfg->acs_cfg.vht_seg1_center_ch);
3118 if (ret_val) {
Jeff Johnson46b40792016-06-29 14:03:14 -07003119 hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_VHT_SEG1_CENTER_CHANNEL put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003120 kfree_skb(vendor_event);
3121 return;
3122 }
3123
Himanshu Agarwal75e74412018-02-01 20:51:47 +05303124 if (sap_cfg->acs_cfg.ch_width == CH_WIDTH_160MHZ)
3125 ch_width = 160;
3126 else if (sap_cfg->acs_cfg.ch_width == CH_WIDTH_80MHZ)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003127 ch_width = 80;
3128 else if (sap_cfg->acs_cfg.ch_width == CH_WIDTH_40MHZ)
3129 ch_width = 40;
3130 else
3131 ch_width = 20;
3132
3133 ret_val = nla_put_u16(vendor_event,
3134 QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH,
3135 ch_width);
3136 if (ret_val) {
Jeff Johnson46b40792016-06-29 14:03:14 -07003137 hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_CHWIDTH put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003138 kfree_skb(vendor_event);
3139 return;
3140 }
3141 if (sap_cfg->acs_cfg.pri_ch > 14)
3142 ret_val = nla_put_u8(vendor_event,
3143 QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE,
3144 QCA_ACS_MODE_IEEE80211A);
3145 else
3146 ret_val = nla_put_u8(vendor_event,
3147 QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE,
3148 QCA_ACS_MODE_IEEE80211G);
3149
3150 if (ret_val) {
Jeff Johnson46b40792016-06-29 14:03:14 -07003151 hdd_err("QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003152 kfree_skb(vendor_event);
3153 return;
3154 }
3155
Mahesh Kumar Kalikot Veetilec1da142017-09-20 10:01:13 -07003156 hdd_debug("ACS result for %s: PRI_CH: %d SEC_CH: %d VHT_SEG0: %d VHT_SEG1: %d ACS_BW: %d",
3157 adapter->dev->name, sap_cfg->acs_cfg.pri_ch,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003158 sap_cfg->acs_cfg.ht_sec_ch, sap_cfg->acs_cfg.vht_seg0_center_ch,
3159 sap_cfg->acs_cfg.vht_seg1_center_ch, ch_width);
3160
3161 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
3162 /* ***Note*** As already mentioned Completion variable usage is not
3163 * allowed here since ACS scan operation may take max 2.2 sec.
3164 * Further in AP-AP mode pending ACS is resumed here to serailize ACS
3165 * operation.
3166 * TODO: Delayed operation is used since SME-PMAC strut is global. Thus
3167 * when Primary AP ACS is complete and secondary AP ACS is started here
3168 * immediately, Primary AP start_bss may come inbetween ACS operation
Jeff Johnson60ed45a2018-05-06 15:28:49 -07003169 * and overwrite Sec AP ACS parameters. Thus Sec AP ACS is executed with
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003170 * delay. This path and below constraint will be removed on sessionizing
3171 * SAP acs parameters and decoupling SAP from PMAC (WIP).
3172 * As per design constraint user space control application must take
3173 * care of serailizing hostapd start for each VIF in AP-AP mode to avoid
3174 * this code path. Sec AP hostapd should be started after Primary AP
3175 * start beaconing which can be confirmed by getchannel iwpriv command
3176 */
3177
3178 con_sap_adapter = hdd_get_con_sap_adapter(adapter, false);
3179 if (con_sap_adapter &&
3180 test_bit(ACS_PENDING, &con_sap_adapter->event_flags)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003181 INIT_DELAYED_WORK(&con_sap_adapter->acs_pending_work,
3182 wlan_hdd_cfg80211_start_pending_acs);
hqu71a1a3b2018-01-23 15:38:13 +08003183 /* Lets give 1500ms for OBSS + START_BSS to complete */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003184 schedule_delayed_work(&con_sap_adapter->acs_pending_work,
hqu71a1a3b2018-01-23 15:38:13 +08003185 msecs_to_jiffies(1500));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003186 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003187}
3188
Sourav Mohapatrac457ae62018-12-06 15:19:41 +05303189/**
3190 * hdd_is_wlm_latency_manager_supported - Checks if WLM Latency manager is
3191 * supported
3192 * @hdd_ctx: The HDD context
3193 *
3194 * Return: True if supported, false otherwise
3195 */
3196static inline
3197bool hdd_is_wlm_latency_manager_supported(struct hdd_context *hdd_ctx)
3198{
3199 bool latency_enable;
3200
3201 if (QDF_IS_STATUS_ERROR(ucfg_mlme_get_latency_enable
3202 (hdd_ctx->psoc, &latency_enable)))
3203 return false;
3204
3205 if (latency_enable &&
3206 sme_is_feature_supported_by_fw(VDEV_LATENCY_CONFIG))
3207 return true;
3208 else
3209 return false;
3210}
3211
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003212static int
3213__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
3214 struct wireless_dev *wdev,
3215 const void *data,
3216 int data_len)
3217{
Jeff Johnsonb8944722017-09-03 09:03:19 -07003218 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003219 struct sk_buff *skb = NULL;
3220 uint32_t fset = 0;
3221 int ret;
Wu Gaobdb7f272018-07-05 19:33:26 +08003222#ifdef FEATURE_WLAN_TDLS
3223 bool bvalue;
3224#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003225
Srinivas Girigowdadbfb2642016-08-28 21:32:38 -07003226 /* ENTER_DEV() intentionally not used in a frequently invoked API */
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303227
Anurag Chouhan6d760662016-02-20 16:05:43 +05303228 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003229 hdd_err("Command not allowed in FTM mode");
3230 return -EPERM;
3231 }
3232
Jeff Johnsonb8944722017-09-03 09:03:19 -07003233 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05303234 if (ret)
3235 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003236
3237 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08003238 hdd_debug("Infra Station mode is supported by driver");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003239 fset |= WIFI_FEATURE_INFRA;
3240 }
Jeff Johnsonb8944722017-09-03 09:03:19 -07003241 if (true == hdd_is_5g_supported(hdd_ctx)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08003242 hdd_debug("INFRA_5G is supported by firmware");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003243 fset |= WIFI_FEATURE_INFRA_5G;
3244 }
3245#ifdef WLAN_FEATURE_P2P
3246 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
3247 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08003248 hdd_debug("WiFi-Direct is supported by driver");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003249 fset |= WIFI_FEATURE_P2P;
3250 }
3251#endif
3252 fset |= WIFI_FEATURE_SOFT_AP;
3253
3254 /* HOTSPOT is a supplicant feature, enable it by default */
3255 fset |= WIFI_FEATURE_HOTSPOT;
3256
Dustin Brown76cd2932018-09-11 16:03:05 -07003257 if (ucfg_extscan_get_enable(hdd_ctx->psoc) &&
Manjeet Singh0f2ce5c2016-09-01 12:08:57 +05303258 sme_is_feature_supported_by_fw(EXTENDED_SCAN)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08003259 hdd_debug("EXTScan is supported by firmware");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003260 fset |= WIFI_FEATURE_EXTSCAN | WIFI_FEATURE_HAL_EPNO;
3261 }
Nachiket Kukade989bb352018-07-31 18:01:17 +05303262 if (wlan_hdd_nan_is_supported(hdd_ctx)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08003263 hdd_debug("NAN is supported by firmware");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003264 fset |= WIFI_FEATURE_NAN;
3265 }
Sourav Mohapatra9e014cf2018-12-11 09:39:33 +05303266 if (sme_is_feature_supported_by_fw(RTT) &&
3267 hdd_ctx->config->enable_rtt_support) {
3268 hdd_debug("RTT is supported by firmware and framework");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003269 fset |= WIFI_FEATURE_D2D_RTT;
3270 fset |= WIFI_FEATURE_D2AP_RTT;
3271 }
3272#ifdef FEATURE_WLAN_SCAN_PNO
Pragaspathi Thilagaraj24789d32018-12-10 22:28:03 +05303273 if (ucfg_scan_get_pno_scan_support(hdd_ctx->psoc) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003274 sme_is_feature_supported_by_fw(PNO)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08003275 hdd_debug("PNO is supported by firmware");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003276 fset |= WIFI_FEATURE_PNO;
3277 }
3278#endif
3279 fset |= WIFI_FEATURE_ADDITIONAL_STA;
3280#ifdef FEATURE_WLAN_TDLS
Dustin Brown76cd2932018-09-11 16:03:05 -07003281 cfg_tdls_get_support_enable(hdd_ctx->psoc, &bvalue);
Wu Gaobdb7f272018-07-05 19:33:26 +08003282 if ((bvalue) && sme_is_feature_supported_by_fw(TDLS)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08003283 hdd_debug("TDLS is supported by firmware");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003284 fset |= WIFI_FEATURE_TDLS;
3285 }
Wu Gaobdb7f272018-07-05 19:33:26 +08003286
Dustin Brown76cd2932018-09-11 16:03:05 -07003287 cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &bvalue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003288 if (sme_is_feature_supported_by_fw(TDLS) &&
Wu Gaobdb7f272018-07-05 19:33:26 +08003289 bvalue && sme_is_feature_supported_by_fw(TDLS_OFF_CHANNEL)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08003290 hdd_debug("TDLS off-channel is supported by firmware");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003291 fset |= WIFI_FEATURE_TDLS_OFFCHANNEL;
3292 }
3293#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003294 fset |= WIFI_FEATURE_AP_STA;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003295 fset |= WIFI_FEATURE_RSSI_MONITOR;
Srinivas Girigowdaa2cad3e2016-10-25 14:14:23 -07003296 fset |= WIFI_FEATURE_TX_TRANSMIT_POWER;
Srinivas Girigowda5a1da622017-07-12 17:07:44 -07003297 fset |= WIFI_FEATURE_SET_TX_POWER_LIMIT;
Sourav Mohapatra804359e2017-12-07 13:52:05 +05303298 fset |= WIFI_FEATURE_CONFIG_NDO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003299
3300 if (hdd_link_layer_stats_supported())
3301 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
3302
Jeff Johnsonb8944722017-09-03 09:03:19 -07003303 if (hdd_roaming_supported(hdd_ctx))
Srinivas Girigowda8df27ea2017-01-06 12:42:16 -08003304 fset |= WIFI_FEATURE_CONTROL_ROAMING;
3305
3306 if (hdd_scan_random_mac_addr_supported())
3307 fset |= WIFI_FEATURE_SCAN_RAND;
3308
Sourav Mohapatrac457ae62018-12-06 15:19:41 +05303309 if (hdd_is_wlm_latency_manager_supported(hdd_ctx))
3310 fset |= WIFI_FEATURE_SET_LATENCY_MODE;
3311
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003312 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
3313 NLMSG_HDRLEN);
3314 if (!skb) {
Jeff Johnson020db452016-06-29 14:37:26 -07003315 hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003316 return -EINVAL;
3317 }
Srinivas Girigowda13d39252017-03-06 16:12:15 -08003318 hdd_debug("Supported Features : 0x%x", fset);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003319 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
Jeff Johnson020db452016-06-29 14:37:26 -07003320 hdd_err("nla put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003321 goto nla_put_failure;
3322 }
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303323 ret = cfg80211_vendor_cmd_reply(skb);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +05303324 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003325nla_put_failure:
3326 kfree_skb(skb);
3327 return -EINVAL;
3328}
3329
3330/**
3331 * wlan_hdd_cfg80211_get_supported_features() - get supported features
3332 * @wiphy: pointer to wireless wiphy structure.
3333 * @wdev: pointer to wireless_dev structure.
3334 * @data: Pointer to the data to be passed via vendor interface
3335 * @data_len:Length of the data to be passed
3336 *
3337 * Return: Return the Success or Failure code.
3338 */
3339static int
3340wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
3341 struct wireless_dev *wdev,
3342 const void *data, int data_len)
3343{
Dustin Brown363b4792019-02-05 16:11:55 -08003344 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08003345 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05303346
Dustin Brown363b4792019-02-05 16:11:55 -08003347 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08003348 if (errno)
3349 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003350
Dustin Brownf0f00612019-01-31 16:02:24 -08003351 errno = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev,
3352 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003353
Dustin Brown363b4792019-02-05 16:11:55 -08003354 osif_psoc_sync_op_stop(psoc_sync);
Arunk Khandavalli99716d12018-11-14 15:02:02 +05303355
Dustin Brownf0f00612019-01-31 16:02:24 -08003356 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003357}
3358
3359/**
3360 * __wlan_hdd_cfg80211_set_scanning_mac_oui() - set scan MAC
3361 * @wiphy: pointer to wireless wiphy structure.
3362 * @wdev: pointer to wireless_dev structure.
3363 * @data: Pointer to the data to be passed via vendor interface
3364 * @data_len:Length of the data to be passed
3365 *
3366 * Set the MAC address that is to be used for scanning.
3367 *
3368 * Return: Return the Success or Failure code.
3369 */
3370static int
3371__wlan_hdd_cfg80211_set_scanning_mac_oui(struct wiphy *wiphy,
3372 struct wireless_dev *wdev,
3373 const void *data,
3374 int data_len)
3375{
Jeff Johnson9d45f332019-01-29 08:42:00 -08003376 struct scan_mac_oui scan_mac_oui = { {0} };
Jeff Johnsonb8944722017-09-03 09:03:19 -07003377 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003378 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303379 QDF_STATUS status;
Pragaspathi Thilagarajf37f3932019-01-11 00:25:43 +05303380 int ret, len;
Rajeev Kumar Sirasanagandla686abd92017-06-08 18:09:01 +05303381 struct net_device *ndev = wdev->netdev;
Jeff Johnsone5006672017-08-29 14:39:02 -07003382 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003383 mac_handle_t mac_handle;
Pragaspathi Thilagarajf37f3932019-01-11 00:25:43 +05303384 bool mac_spoofing_enabled;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003385
Dustin Brownfdf17c12018-03-14 12:55:34 -07003386 hdd_enter_dev(wdev->netdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003387
Anurag Chouhan6d760662016-02-20 16:05:43 +05303388 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003389 hdd_err("Command not allowed in FTM mode");
3390 return -EPERM;
3391 }
3392
Jeff Johnsonb8944722017-09-03 09:03:19 -07003393 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05303394 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003395 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003396
Pragaspathi Thilagarajf37f3932019-01-11 00:25:43 +05303397 mac_spoofing_enabled = ucfg_scan_is_mac_spoofing_enabled(hdd_ctx->psoc);
3398 if (!mac_spoofing_enabled) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07003399 hdd_debug("MAC address spoofing is not enabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003400 return -ENOTSUPP;
3401 }
3402
Jeff Johnson63d1ac82017-06-01 09:06:48 -07003403 /*
3404 * audit note: it is ok to pass a NULL policy here since only
3405 * one attribute is parsed and it is explicitly validated
3406 */
Dustin Brown4ea21db2018-01-05 14:13:17 -08003407 if (wlan_cfg80211_nla_parse(tb,
3408 QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
3409 data, data_len, NULL)) {
Jeff Johnson020db452016-06-29 14:37:26 -07003410 hdd_err("Invalid ATTR");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003411 return -EINVAL;
3412 }
Jeff Johnson63d1ac82017-06-01 09:06:48 -07003413
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003414 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
Jeff Johnson020db452016-06-29 14:37:26 -07003415 hdd_err("attr mac oui failed");
Jeff Johnson9d45f332019-01-29 08:42:00 -08003416 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003417 }
Jeff Johnson63d1ac82017-06-01 09:06:48 -07003418
3419 len = nla_len(tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]);
Jeff Johnson9d45f332019-01-29 08:42:00 -08003420 if (len != sizeof(scan_mac_oui.oui)) {
Jeff Johnson63d1ac82017-06-01 09:06:48 -07003421 hdd_err("attr mac oui invalid size %d expected %zu",
Jeff Johnson9d45f332019-01-29 08:42:00 -08003422 len, sizeof(scan_mac_oui.oui));
3423 return -EINVAL;
Jeff Johnson63d1ac82017-06-01 09:06:48 -07003424 }
3425
Jeff Johnson9d45f332019-01-29 08:42:00 -08003426 nla_memcpy(scan_mac_oui.oui,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003427 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI],
Jeff Johnson9d45f332019-01-29 08:42:00 -08003428 sizeof(scan_mac_oui.oui));
Rajeev Kumar Sirasanagandla686abd92017-06-08 18:09:01 +05303429
Jeff Johnson9d45f332019-01-29 08:42:00 -08003430 /* populate rest of scan_mac_oui for mac addr randomization */
Jeff Johnsoncf07c312019-02-04 13:53:29 -08003431 scan_mac_oui.vdev_id = adapter->vdev_id;
Jeff Johnson9d45f332019-01-29 08:42:00 -08003432 scan_mac_oui.enb_probe_req_sno_randomization = true;
Rajeev Kumar Sirasanagandla686abd92017-06-08 18:09:01 +05303433
Jeff Johnson9d45f332019-01-29 08:42:00 -08003434 hdd_debug("Oui (%02x:%02x:%02x), vdev_id = %d",
3435 scan_mac_oui.oui[0], scan_mac_oui.oui[1],
3436 scan_mac_oui.oui[2], scan_mac_oui.vdev_id);
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05303437
Jeff Johnson9d45f332019-01-29 08:42:00 -08003438 hdd_update_ie_whitelist_attr(&scan_mac_oui.ie_whitelist, hdd_ctx);
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +05303439
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003440 mac_handle = hdd_ctx->mac_handle;
Jeff Johnson9d45f332019-01-29 08:42:00 -08003441 status = sme_set_scanning_mac_oui(mac_handle, &scan_mac_oui);
3442 if (!QDF_IS_STATUS_SUCCESS(status))
Jeff Johnson020db452016-06-29 14:37:26 -07003443 hdd_err("sme_set_scanning_mac_oui failed(err=%d)", status);
Jeff Johnson9d45f332019-01-29 08:42:00 -08003444
3445 return qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003446}
3447
3448/**
3449 * wlan_hdd_cfg80211_set_scanning_mac_oui() - set scan MAC
3450 * @wiphy: pointer to wireless wiphy structure.
3451 * @wdev: pointer to wireless_dev structure.
3452 * @data: Pointer to the data to be passed via vendor interface
3453 * @data_len:Length of the data to be passed
3454 *
3455 * Set the MAC address that is to be used for scanning. This is an
3456 * SSR-protecting wrapper function.
3457 *
3458 * Return: Return the Success or Failure code.
3459 */
3460static int
3461wlan_hdd_cfg80211_set_scanning_mac_oui(struct wiphy *wiphy,
3462 struct wireless_dev *wdev,
3463 const void *data,
3464 int data_len)
3465{
Dustin Browna09acf42018-11-08 12:32:26 +05303466 int errno;
3467 struct osif_vdev_sync *vdev_sync;
3468
3469 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
3470 if (errno)
3471 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003472
Dustin Browna09acf42018-11-08 12:32:26 +05303473 errno = __wlan_hdd_cfg80211_set_scanning_mac_oui(wiphy, wdev,
3474 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003475
Dustin Browna09acf42018-11-08 12:32:26 +05303476 osif_vdev_sync_op_stop(vdev_sync);
3477
3478 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003479}
3480
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +05303481/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003482 * wlan_hdd_cfg80211_set_feature() - Set the bitmask for supported features
3483 * @feature_flags: pointer to the byte array of features.
3484 * @feature: Feature to be turned ON in the byte array.
3485 *
3486 * Return: None
3487 *
3488 * This is called to turn ON or SET the feature flag for the requested feature.
3489 **/
3490#define NUM_BITS_IN_BYTE 8
Jeff Johnson8b8a04b2016-10-05 15:49:43 -07003491static void wlan_hdd_cfg80211_set_feature(uint8_t *feature_flags,
3492 uint8_t feature)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003493{
3494 uint32_t index;
3495 uint8_t bit_mask;
3496
3497 index = feature / NUM_BITS_IN_BYTE;
3498 bit_mask = 1 << (feature % NUM_BITS_IN_BYTE);
3499 feature_flags[index] |= bit_mask;
3500}
3501
3502/**
3503 * __wlan_hdd_cfg80211_get_features() - Get the Driver Supported features
3504 * @wiphy: pointer to wireless wiphy structure.
3505 * @wdev: pointer to wireless_dev structure.
3506 * @data: Pointer to the data to be passed via vendor interface
3507 * @data_len:Length of the data to be passed
3508 *
3509 * This is called when wlan driver needs to send supported feature set to
3510 * supplicant upon a request/query from the supplicant.
3511 *
3512 * Return: Return the Success or Failure code.
3513 **/
3514#define MAX_CONCURRENT_CHAN_ON_24G 2
3515#define MAX_CONCURRENT_CHAN_ON_5G 2
3516static int
3517__wlan_hdd_cfg80211_get_features(struct wiphy *wiphy,
3518 struct wireless_dev *wdev,
3519 const void *data, int data_len)
3520{
3521 struct sk_buff *skb = NULL;
3522 uint32_t dbs_capability = 0;
3523 bool one_by_one_dbs, two_by_two_dbs;
Ashish Kumar Dhanotiya12de5332019-03-27 14:45:27 +05303524 bool value, twt_req, twt_res;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303525 QDF_STATUS ret = QDF_STATUS_E_FAILURE;
Karthik Kantamneni2231a232018-09-11 15:45:55 +05303526 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003527 int ret_val;
3528
3529 uint8_t feature_flags[(NUM_QCA_WLAN_VENDOR_FEATURES + 7) / 8] = {0};
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003530 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003531
Dustin Brownfdf17c12018-03-14 12:55:34 -07003532 hdd_enter_dev(wdev->netdev);
Jeff Johnson1f61b612016-02-12 16:28:33 -08003533
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003534 ret_val = wlan_hdd_validate_context(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003535 if (ret_val)
3536 return ret_val;
3537
Anurag Chouhan6d760662016-02-20 16:05:43 +05303538 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003539 hdd_err("Command not allowed in FTM mode");
3540 return -EPERM;
3541 }
3542
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003543 if (roaming_offload_enabled(hdd_ctx)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08003544 hdd_debug("Key Mgmt Offload is supported");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003545 wlan_hdd_cfg80211_set_feature(feature_flags,
3546 QCA_WLAN_VENDOR_FEATURE_KEY_MGMT_OFFLOAD);
3547 }
3548
3549 wlan_hdd_cfg80211_set_feature(feature_flags,
3550 QCA_WLAN_VENDOR_FEATURE_SUPPORT_HW_MODE_ANY);
Dustin Brown76cd2932018-09-11 16:03:05 -07003551 if (policy_mgr_is_scan_simultaneous_capable(hdd_ctx->psoc))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003552 wlan_hdd_cfg80211_set_feature(feature_flags,
3553 QCA_WLAN_VENDOR_FEATURE_OFFCHANNEL_SIMULTANEOUS);
Peng Xu8fdaa492016-06-22 10:20:47 -07003554
3555 if (wma_is_p2p_lo_capable())
3556 wlan_hdd_cfg80211_set_feature(feature_flags,
3557 QCA_WLAN_VENDOR_FEATURE_P2P_LISTEN_OFFLOAD);
3558
Karthik Kantamneni2231a232018-09-11 15:45:55 +05303559 value = 0;
Dustin Brown05d81302018-09-11 16:49:22 -07003560 status = ucfg_mlme_get_oce_sta_enabled_info(hdd_ctx->psoc, &value);
Karthik Kantamneni2231a232018-09-11 15:45:55 +05303561 if (QDF_IS_STATUS_ERROR(status))
3562 hdd_err("could not get OCE STA enable info");
3563 if (value)
yeshwanth sriram guntuka1413dfb2017-06-23 14:09:48 +05303564 wlan_hdd_cfg80211_set_feature(feature_flags,
3565 QCA_WLAN_VENDOR_FEATURE_OCE_STA);
3566
Karthik Kantamneni2231a232018-09-11 15:45:55 +05303567 value = 0;
Dustin Brown05d81302018-09-11 16:49:22 -07003568 status = ucfg_mlme_get_oce_sap_enabled_info(hdd_ctx->psoc, &value);
Karthik Kantamneni2231a232018-09-11 15:45:55 +05303569 if (QDF_IS_STATUS_ERROR(status))
3570 hdd_err("could not get OCE SAP enable info");
3571 if (value)
yeshwanth sriram guntuka1413dfb2017-06-23 14:09:48 +05303572 wlan_hdd_cfg80211_set_feature(feature_flags,
3573 QCA_WLAN_VENDOR_FEATURE_OCE_STA_CFON);
3574
Ashish Kumar Dhanotiya12de5332019-03-27 14:45:27 +05303575 ucfg_mlme_get_twt_requestor(hdd_ctx->psoc, &twt_req);
3576 ucfg_mlme_get_twt_responder(hdd_ctx->psoc, &twt_res);
3577
3578 if (twt_req || twt_res)
3579 wlan_hdd_cfg80211_set_feature(feature_flags,
3580 QCA_WLAN_VENDOR_FEATURE_TWT);
3581
Kiran Kumar Lokere0508af92018-04-23 18:38:32 -07003582 /* Check the kernel version for upstream commit aced43ce780dc5 that
3583 * has support for processing user cell_base hints when wiphy is
3584 * self managed or check the backport flag for the same.
3585 */
3586#if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
3587 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
3588 wlan_hdd_cfg80211_set_feature(feature_flags,
3589 QCA_WLAN_VENDOR_FEATURE_SELF_MANAGED_REGULATORY);
3590#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003591 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(feature_flags) +
3592 NLMSG_HDRLEN);
3593
3594 if (!skb) {
Jeff Johnson020db452016-06-29 14:37:26 -07003595 hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003596 return -ENOMEM;
3597 }
3598
3599 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_FLAGS,
3600 sizeof(feature_flags), feature_flags))
3601 goto nla_put_failure;
3602
Dustin Brown76cd2932018-09-11 16:03:05 -07003603 ret = policy_mgr_get_dbs_hw_modes(hdd_ctx->psoc,
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003604 &one_by_one_dbs, &two_by_two_dbs);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303605 if (QDF_STATUS_SUCCESS == ret) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003606 if (one_by_one_dbs)
3607 dbs_capability = DRV_DBS_CAPABILITY_1X1;
3608
3609 if (two_by_two_dbs)
3610 dbs_capability = DRV_DBS_CAPABILITY_2X2;
3611
3612 if (!one_by_one_dbs && !two_by_two_dbs)
3613 dbs_capability = DRV_DBS_CAPABILITY_DISABLED;
3614 } else {
3615 hdd_err("wma_get_dbs_hw_mode failed");
3616 dbs_capability = DRV_DBS_CAPABILITY_DISABLED;
3617 }
3618
Srinivas Girigowda13d39252017-03-06 16:12:15 -08003619 hdd_debug("dbs_capability is %d", dbs_capability);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003620
3621 if (nla_put_u32(skb,
Ganesh Kondabattinid921ed92017-06-20 16:40:48 +05303622 QCA_WLAN_VENDOR_ATTR_CONCURRENCY_CAPA,
3623 dbs_capability))
3624 goto nla_put_failure;
3625
3626
3627 if (nla_put_u32(skb,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003628 QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_2_4_BAND,
3629 MAX_CONCURRENT_CHAN_ON_24G))
3630 goto nla_put_failure;
3631
3632 if (nla_put_u32(skb,
3633 QCA_WLAN_VENDOR_ATTR_MAX_CONCURRENT_CHANNELS_5_0_BAND,
3634 MAX_CONCURRENT_CHAN_ON_5G))
3635 goto nla_put_failure;
3636
3637 return cfg80211_vendor_cmd_reply(skb);
3638
3639nla_put_failure:
3640 kfree_skb(skb);
3641 return -EINVAL;
3642}
3643
3644/**
3645 * wlan_hdd_cfg80211_get_features() - Get the Driver Supported features
3646 * @wiphy: pointer to wireless wiphy structure.
3647 * @wdev: pointer to wireless_dev structure.
3648 * @data: Pointer to the data to be passed via vendor interface
3649 * @data_len:Length of the data to be passed
3650 *
3651 * This is called when wlan driver needs to send supported feature set to
3652 * supplicant upon a request/query from the supplicant.
3653 *
3654 * Return: Return the Success or Failure code.
3655 */
3656static int
3657wlan_hdd_cfg80211_get_features(struct wiphy *wiphy,
3658 struct wireless_dev *wdev,
3659 const void *data, int data_len)
3660{
Dustin Brown363b4792019-02-05 16:11:55 -08003661 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08003662 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05303663
Dustin Brown363b4792019-02-05 16:11:55 -08003664 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08003665 if (errno)
3666 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003667
Dustin Brownf0f00612019-01-31 16:02:24 -08003668 errno = __wlan_hdd_cfg80211_get_features(wiphy, wdev, data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003669
Dustin Brown363b4792019-02-05 16:11:55 -08003670 osif_psoc_sync_op_stop(psoc_sync);
Arunk Khandavalli99716d12018-11-14 15:02:02 +05303671
Dustin Brownf0f00612019-01-31 16:02:24 -08003672 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003673}
3674
Hanumanth Reddy Pothulaa1259ef2017-02-21 17:14:43 +05303675#define PARAM_NUM_NW \
3676 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_NUM_NETWORKS
3677#define PARAM_SET_BSSID \
3678 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_BSSID
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +05303679#define PARAM_SET_BSSID_HINT \
3680 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_HINT
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003681#define PARAM_SSID_LIST QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID_LIST
Hanumanth Reddy Pothulaa1259ef2017-02-21 17:14:43 +05303682#define PARAM_LIST_SSID QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_WHITE_LIST_SSID
Ravi Kumar Bokka6cb9b372017-06-08 20:12:39 +05303683#define MAX_ROAMING_PARAM \
3684 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003685#define PARAM_NUM_BSSID \
3686 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_NUM_BSSID
3687#define PARAM_BSSID_PREFS \
3688 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS
3689#define PARAM_ROAM_BSSID \
3690 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_BSSID
3691#define PARAM_RSSI_MODIFIER \
3692 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_RSSI_MODIFIER
3693#define PARAMS_NUM_BSSID \
3694 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS_NUM_BSSID
3695#define PARAM_BSSID_PARAMS \
3696 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PARAMS
3697#define PARAM_A_BAND_BOOST_THLD \
3698 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_THRESHOLD
3699#define PARAM_A_BAND_PELT_THLD \
3700 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_THRESHOLD
3701#define PARAM_A_BAND_BOOST_FACTOR \
3702 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_BOOST_FACTOR
3703#define PARAM_A_BAND_PELT_FACTOR \
3704 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_PENALTY_FACTOR
3705#define PARAM_A_BAND_MAX_BOOST \
3706 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_A_BAND_MAX_BOOST
3707#define PARAM_ROAM_HISTERESYS \
3708 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_LAZY_ROAM_HISTERESYS
3709#define PARAM_RSSI_TRIGGER \
3710 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_ALERT_ROAM_RSSI_TRIGGER
3711#define PARAM_ROAM_ENABLE \
3712 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_LAZY_ROAM_ENABLE
3713
Ravi Kumar Bokka6cb9b372017-06-08 20:12:39 +05303714
3715static const struct nla_policy
3716wlan_hdd_set_roam_param_policy[MAX_ROAMING_PARAM + 1] = {
3717 [QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD] = {.type = NLA_U32},
3718 [QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID] = {.type = NLA_U32},
3719 [PARAM_NUM_NW] = {.type = NLA_U32},
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003720 [PARAM_A_BAND_BOOST_FACTOR] = {.type = NLA_U32},
3721 [PARAM_A_BAND_PELT_FACTOR] = {.type = NLA_U32},
3722 [PARAM_A_BAND_MAX_BOOST] = {.type = NLA_U32},
3723 [PARAM_ROAM_HISTERESYS] = {.type = NLA_S32},
3724 [PARAM_A_BAND_BOOST_THLD] = {.type = NLA_S32},
Srinivas Girigowda4ffe7c82017-07-18 11:45:23 -07003725 [PARAM_A_BAND_PELT_THLD] = {.type = NLA_S32},
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003726 [PARAM_RSSI_TRIGGER] = {.type = NLA_U32},
3727 [PARAM_ROAM_ENABLE] = { .type = NLA_S32},
3728 [PARAM_NUM_BSSID] = {.type = NLA_U32},
3729 [PARAM_RSSI_MODIFIER] = {.type = NLA_U32},
3730 [PARAMS_NUM_BSSID] = {.type = NLA_U32},
3731 [PARAM_ROAM_BSSID] = {.type = NLA_UNSPEC, .len = QDF_MAC_ADDR_SIZE},
3732 [PARAM_SET_BSSID] = {.type = NLA_UNSPEC, .len = QDF_MAC_ADDR_SIZE},
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +05303733 [PARAM_SET_BSSID_HINT] = {.type = NLA_FLAG},
Ravi Kumar Bokka6cb9b372017-06-08 20:12:39 +05303734};
3735
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003736/**
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003737 * hdd_set_white_list() - parse white list
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003738 * @hdd_ctx: HDD context
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003739 * @roam_params: roam params
3740 * @tb: list of attributes
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003741 * @vdev_id: vdev id
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003742 *
3743 * Return: 0 on success; error number on failure
3744 */
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003745static int hdd_set_white_list(struct hdd_context *hdd_ctx,
3746 struct roam_ext_params *roam_params,
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003747 struct nlattr **tb, uint8_t vdev_id)
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003748{
3749 int rem, i;
3750 uint32_t buf_len = 0, count;
3751 struct nlattr *tb2[MAX_ROAMING_PARAM + 1];
3752 struct nlattr *curr_attr = NULL;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003753 mac_handle_t mac_handle;
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003754
3755 i = 0;
3756 if (tb[PARAM_NUM_NW]) {
3757 count = nla_get_u32(tb[PARAM_NUM_NW]);
3758 } else {
3759 hdd_err("Number of networks is not provided");
3760 goto fail;
3761 }
3762
3763 if (count && tb[PARAM_SSID_LIST]) {
3764 nla_for_each_nested(curr_attr,
Min Liudd308892019-05-16 18:48:41 +08003765 tb[PARAM_SSID_LIST], rem) {
3766 if (i == MAX_SSID_ALLOWED_LIST) {
3767 hdd_err("Excess MAX_SSID_ALLOWED_LIST");
3768 goto fail;
3769 }
Dustin Brown4ea21db2018-01-05 14:13:17 -08003770 if (wlan_cfg80211_nla_parse(tb2,
3771 QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_MAX,
3772 nla_data(curr_attr),
3773 nla_len(curr_attr),
3774 wlan_hdd_set_roam_param_policy)) {
3775 hdd_err("nla_parse failed");
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003776 goto fail;
3777 }
3778 /* Parse and Fetch allowed SSID list*/
3779 if (!tb2[PARAM_LIST_SSID]) {
3780 hdd_err("attr allowed ssid failed");
3781 goto fail;
3782 }
3783 buf_len = nla_len(tb2[PARAM_LIST_SSID]);
3784 /*
3785 * Upper Layers include a null termination
3786 * character. Check for the actual permissible
3787 * length of SSID and also ensure not to copy
3788 * the NULL termination character to the driver
3789 * buffer.
3790 */
Min Liudd308892019-05-16 18:48:41 +08003791 if (buf_len > 1 &&
Srinivas Girigowdab8fdc642019-03-19 15:33:03 -07003792 ((buf_len - 1) <= WLAN_SSID_MAX_LEN)) {
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003793 nla_memcpy(roam_params->ssid_allowed_list[i].ssId,
3794 tb2[PARAM_LIST_SSID], buf_len - 1);
3795 roam_params->ssid_allowed_list[i].length = buf_len - 1;
3796 hdd_debug("SSID[%d]: %.*s,length = %d",
3797 i,
3798 roam_params->ssid_allowed_list[i].length,
3799 roam_params->ssid_allowed_list[i].ssId,
3800 roam_params->ssid_allowed_list[i].length);
3801 i++;
3802 } else {
3803 hdd_err("Invalid buffer length");
3804 }
3805 }
3806 }
3807
3808 if (i != count) {
3809 hdd_err("Invalid number of SSIDs i = %d, count = %d", i, count);
3810 goto fail;
3811 }
3812
3813 roam_params->num_ssid_allowed_list = i;
3814 hdd_debug("Num of Allowed SSID %d", roam_params->num_ssid_allowed_list);
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003815 mac_handle = hdd_ctx->mac_handle;
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003816 sme_update_roam_params(mac_handle, vdev_id,
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003817 roam_params, REASON_ROAM_SET_SSID_ALLOWED);
3818 return 0;
3819
3820fail:
3821 return -EINVAL;
3822}
3823
3824/**
3825 * hdd_set_bssid_prefs() - parse set bssid prefs
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003826 * @hdd_ctx: HDD context
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003827 * @roam_params: roam params
3828 * @tb: list of attributes
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003829 * @vdev_id: vdev id
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003830 *
3831 * Return: 0 on success; error number on failure
3832 */
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003833static int hdd_set_bssid_prefs(struct hdd_context *hdd_ctx,
3834 struct roam_ext_params *roam_params,
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003835 struct nlattr **tb, uint8_t vdev_id)
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003836{
3837 int rem, i;
3838 uint32_t count;
3839 struct nlattr *tb2[MAX_ROAMING_PARAM + 1];
3840 struct nlattr *curr_attr = NULL;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003841 mac_handle_t mac_handle;
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003842
3843 /* Parse and fetch number of preferred BSSID */
3844 if (!tb[PARAM_NUM_BSSID]) {
3845 hdd_err("attr num of preferred bssid failed");
3846 goto fail;
3847 }
3848 count = nla_get_u32(tb[PARAM_NUM_BSSID]);
3849 if (count > MAX_BSSID_FAVORED) {
3850 hdd_err("Preferred BSSID count %u exceeds max %u",
3851 count, MAX_BSSID_FAVORED);
3852 goto fail;
3853 }
3854 hdd_debug("Num of Preferred BSSID (%d)", count);
3855 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS]) {
3856 hdd_err("attr Preferred BSSID failed");
3857 goto fail;
3858 }
3859
3860 i = 0;
3861 nla_for_each_nested(curr_attr,
3862 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_SET_BSSID_PREFS],
3863 rem) {
3864 if (i == count) {
3865 hdd_warn("Ignoring excess Preferred BSSID");
3866 break;
3867 }
3868
Dustin Brown4ea21db2018-01-05 14:13:17 -08003869 if (wlan_cfg80211_nla_parse(tb2,
3870 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX,
3871 nla_data(curr_attr),
3872 nla_len(curr_attr),
3873 wlan_hdd_set_roam_param_policy)) {
3874 hdd_err("nla_parse failed");
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003875 goto fail;
3876 }
3877 /* Parse and fetch MAC address */
3878 if (!tb2[PARAM_ROAM_BSSID]) {
3879 hdd_err("attr mac address failed");
3880 goto fail;
3881 }
3882 nla_memcpy(roam_params->bssid_favored[i].bytes,
3883 tb2[PARAM_ROAM_BSSID],
3884 QDF_MAC_ADDR_SIZE);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003885 hdd_debug(QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003886 QDF_MAC_ADDR_ARRAY(roam_params->bssid_favored[i].bytes));
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003887 /* Parse and fetch preference factor*/
3888 if (!tb2[PARAM_RSSI_MODIFIER]) {
3889 hdd_err("BSSID Preference score failed");
3890 goto fail;
3891 }
3892 roam_params->bssid_favored_factor[i] = nla_get_u32(
3893 tb2[PARAM_RSSI_MODIFIER]);
3894 hdd_debug("BSSID Preference score (%d)",
3895 roam_params->bssid_favored_factor[i]);
3896 i++;
3897 }
3898 if (i < count)
3899 hdd_warn("Num Preferred BSSID %u less than expected %u",
3900 i, count);
3901
3902 roam_params->num_bssid_favored = i;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003903 mac_handle = hdd_ctx->mac_handle;
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003904 sme_update_roam_params(mac_handle, vdev_id,
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003905 roam_params, REASON_ROAM_SET_FAVORED_BSSID);
3906
3907 return 0;
3908
3909fail:
3910 return -EINVAL;
3911}
3912
3913/**
3914 * hdd_set_blacklist_bssid() - parse set blacklist bssid
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003915 * @hdd_ctx: HDD context
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003916 * @roam_params: roam params
3917 * @tb: list of attributes
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003918 * @vdev_id: vdev id
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003919 *
3920 * Return: 0 on success; error number on failure
3921 */
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003922static int hdd_set_blacklist_bssid(struct hdd_context *hdd_ctx,
3923 struct roam_ext_params *roam_params,
3924 struct nlattr **tb,
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003925 uint8_t vdev_id)
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003926{
3927 int rem, i;
3928 uint32_t count;
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +05303929 uint8_t j = 0;
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003930 struct nlattr *tb2[MAX_ROAMING_PARAM + 1];
3931 struct nlattr *curr_attr = NULL;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07003932 mac_handle_t mac_handle;
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003933
3934 /* Parse and fetch number of blacklist BSSID */
3935 if (!tb[PARAMS_NUM_BSSID]) {
3936 hdd_err("attr num of blacklist bssid failed");
3937 goto fail;
3938 }
3939 count = nla_get_u32(tb[PARAMS_NUM_BSSID]);
3940 if (count > MAX_BSSID_AVOID_LIST) {
3941 hdd_err("Blacklist BSSID count %u exceeds max %u",
3942 count, MAX_BSSID_AVOID_LIST);
3943 goto fail;
3944 }
3945 hdd_debug("Num of blacklist BSSID (%d)", count);
3946
3947 i = 0;
3948 if (count && tb[PARAM_BSSID_PARAMS]) {
3949 nla_for_each_nested(curr_attr,
3950 tb[PARAM_BSSID_PARAMS],
3951 rem) {
3952 if (i == count) {
3953 hdd_warn("Ignoring excess Blacklist BSSID");
3954 break;
3955 }
3956
Dustin Brown4ea21db2018-01-05 14:13:17 -08003957 if (wlan_cfg80211_nla_parse(tb2,
Dustin Brown3fb15042017-08-15 15:54:49 -07003958 QCA_WLAN_VENDOR_ATTR_ROAMING_PARAM_MAX,
3959 nla_data(curr_attr),
3960 nla_len(curr_attr),
3961 wlan_hdd_set_roam_param_policy)) {
Dustin Brown4ea21db2018-01-05 14:13:17 -08003962 hdd_err("nla_parse failed");
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003963 goto fail;
3964 }
3965 /* Parse and fetch MAC address */
3966 if (!tb2[PARAM_SET_BSSID]) {
3967 hdd_err("attr blacklist addr failed");
3968 goto fail;
3969 }
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +05303970 if (tb2[PARAM_SET_BSSID_HINT]) {
3971 struct reject_ap_info ap_info;
3972
3973 nla_memcpy(ap_info.bssid.bytes,
3974 tb2[PARAM_SET_BSSID],
3975 QDF_MAC_ADDR_SIZE);
3976 ap_info.reject_ap_type = USERSPACE_AVOID_TYPE;
3977 /* This BSSID is avoided and not blacklisted */
3978 ucfg_blm_add_bssid_to_reject_list(hdd_ctx->pdev,
3979 &ap_info);
3980 i++;
3981 continue;
3982 }
3983 nla_memcpy(roam_params->bssid_avoid_list[j].bytes,
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003984 tb2[PARAM_SET_BSSID], QDF_MAC_ADDR_SIZE);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003985 hdd_debug(QDF_MAC_ADDR_STR,
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +05303986 QDF_MAC_ADDR_ARRAY(roam_params->
3987 bssid_avoid_list[j].bytes));
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003988 i++;
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +05303989 j++;
Srinivas Girigowda72f30392017-07-13 18:55:09 -07003990 }
3991 }
3992
3993 if (i < count)
3994 hdd_warn("Num Blacklist BSSID %u less than expected %u",
3995 i, count);
3996
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +05303997 roam_params->num_bssid_avoid_list = j;
3998 /* Send the blacklist to the blacklist mgr component */
3999 ucfg_blm_add_userspace_black_list(hdd_ctx->pdev,
4000 roam_params->bssid_avoid_list,
4001 roam_params->num_bssid_avoid_list);
4002
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004003 mac_handle = hdd_ctx->mac_handle;
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004004 sme_update_roam_params(mac_handle, vdev_id,
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004005 roam_params, REASON_ROAM_SET_BLACKLIST_BSSID);
4006
4007 return 0;
4008fail:
4009 return -EINVAL;
4010}
4011
4012/**
4013 * hdd_set_ext_roam_params() - parse ext roam params
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004014 * @hdd_ctx: HDD context
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004015 * @roam_params: roam params
4016 * @tb: list of attributes
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004017 * @vdev_id: vdev id
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004018 *
4019 * Return: 0 on success; error number on failure
4020 */
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004021static int hdd_set_ext_roam_params(struct hdd_context *hdd_ctx,
4022 const void *data, int data_len,
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004023 uint8_t vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004024 struct roam_ext_params *roam_params)
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004025{
4026 uint32_t cmd_type, req_id;
4027 struct nlattr *tb[MAX_ROAMING_PARAM + 1];
4028 int ret;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004029 mac_handle_t mac_handle;
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004030
Dustin Brown4ea21db2018-01-05 14:13:17 -08004031 if (wlan_cfg80211_nla_parse(tb, MAX_ROAMING_PARAM, data, data_len,
4032 wlan_hdd_set_roam_param_policy)) {
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004033 hdd_err("Invalid ATTR");
4034 return -EINVAL;
4035 }
4036 /* Parse and fetch Command Type */
4037 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD]) {
4038 hdd_err("roam cmd type failed");
4039 goto fail;
4040 }
4041
4042 cmd_type = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_ROAMING_SUBCMD]);
4043 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID]) {
4044 hdd_err("attr request id failed");
4045 goto fail;
4046 }
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004047 mac_handle = hdd_ctx->mac_handle;
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004048 req_id = nla_get_u32(
4049 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_REQ_ID]);
4050 hdd_debug("Req Id: %u Cmd Type: %u", req_id, cmd_type);
4051 switch (cmd_type) {
4052 case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SSID_WHITE_LIST:
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004053 ret = hdd_set_white_list(hdd_ctx, roam_params, tb, vdev_id);
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004054 if (ret)
4055 goto fail;
4056 break;
4057
4058 case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_EXTSCAN_ROAM_PARAMS:
4059 /* Parse and fetch 5G Boost Threshold */
4060 if (!tb[PARAM_A_BAND_BOOST_THLD]) {
4061 hdd_err("5G boost threshold failed");
4062 goto fail;
4063 }
4064 roam_params->raise_rssi_thresh_5g = nla_get_s32(
4065 tb[PARAM_A_BAND_BOOST_THLD]);
4066 hdd_debug("5G Boost Threshold (%d)",
4067 roam_params->raise_rssi_thresh_5g);
4068 /* Parse and fetch 5G Penalty Threshold */
Srinivas Girigowda4ffe7c82017-07-18 11:45:23 -07004069 if (!tb[PARAM_A_BAND_PELT_THLD]) {
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004070 hdd_err("5G penalty threshold failed");
4071 goto fail;
4072 }
4073 roam_params->drop_rssi_thresh_5g = nla_get_s32(
Srinivas Girigowda4ffe7c82017-07-18 11:45:23 -07004074 tb[PARAM_A_BAND_PELT_THLD]);
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004075 hdd_debug("5G Penalty Threshold (%d)",
4076 roam_params->drop_rssi_thresh_5g);
4077 /* Parse and fetch 5G Boost Factor */
4078 if (!tb[PARAM_A_BAND_BOOST_FACTOR]) {
4079 hdd_err("5G boost Factor failed");
4080 goto fail;
4081 }
4082 roam_params->raise_factor_5g = nla_get_u32(
4083 tb[PARAM_A_BAND_BOOST_FACTOR]);
4084 hdd_debug("5G Boost Factor (%d)",
4085 roam_params->raise_factor_5g);
4086 /* Parse and fetch 5G Penalty factor */
4087 if (!tb[PARAM_A_BAND_PELT_FACTOR]) {
4088 hdd_err("5G Penalty Factor failed");
4089 goto fail;
4090 }
4091 roam_params->drop_factor_5g = nla_get_u32(
4092 tb[PARAM_A_BAND_PELT_FACTOR]);
4093 hdd_debug("5G Penalty factor (%d)",
4094 roam_params->drop_factor_5g);
4095 /* Parse and fetch 5G Max Boost */
4096 if (!tb[PARAM_A_BAND_MAX_BOOST]) {
4097 hdd_err("5G Max Boost failed");
4098 goto fail;
4099 }
4100 roam_params->max_raise_rssi_5g = nla_get_u32(
4101 tb[PARAM_A_BAND_MAX_BOOST]);
4102 hdd_debug("5G Max Boost (%d)",
4103 roam_params->max_raise_rssi_5g);
4104 /* Parse and fetch Rssi Diff */
4105 if (!tb[PARAM_ROAM_HISTERESYS]) {
4106 hdd_err("Rssi Diff failed");
4107 goto fail;
4108 }
4109 roam_params->rssi_diff = nla_get_s32(
4110 tb[PARAM_ROAM_HISTERESYS]);
4111 hdd_debug("RSSI Diff (%d)",
4112 roam_params->rssi_diff);
4113 /* Parse and fetch Alert Rssi Threshold */
4114 if (!tb[PARAM_RSSI_TRIGGER]) {
4115 hdd_err("Alert Rssi Threshold failed");
4116 goto fail;
4117 }
4118 roam_params->alert_rssi_threshold = nla_get_u32(
4119 tb[PARAM_RSSI_TRIGGER]);
4120 hdd_debug("Alert RSSI Threshold (%d)",
4121 roam_params->alert_rssi_threshold);
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004122 sme_update_roam_params(mac_handle, vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004123 roam_params,
4124 REASON_ROAM_EXT_SCAN_PARAMS_CHANGED);
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004125 break;
4126 case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_LAZY_ROAM:
4127 /* Parse and fetch Activate Good Rssi Roam */
4128 if (!tb[PARAM_ROAM_ENABLE]) {
4129 hdd_err("Activate Good Rssi Roam failed");
4130 goto fail;
4131 }
4132 roam_params->good_rssi_roam = nla_get_s32(
4133 tb[PARAM_ROAM_ENABLE]);
4134 hdd_debug("Activate Good Rssi Roam (%d)",
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004135 roam_params->good_rssi_roam);
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004136 sme_update_roam_params(mac_handle, vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004137 roam_params,
4138 REASON_ROAM_GOOD_RSSI_CHANGED);
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004139 break;
4140 case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_BSSID_PREFS:
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004141 ret = hdd_set_bssid_prefs(hdd_ctx, roam_params, tb, vdev_id);
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004142 if (ret)
4143 goto fail;
4144 break;
4145 case QCA_WLAN_VENDOR_ATTR_ROAM_SUBCMD_SET_BLACKLIST_BSSID:
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004146 ret = hdd_set_blacklist_bssid(hdd_ctx, roam_params,
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004147 tb, vdev_id);
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004148 if (ret)
4149 goto fail;
4150 break;
4151 }
4152
4153 return 0;
4154
4155fail:
4156 return -EINVAL;
4157}
4158
4159/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004160 * __wlan_hdd_cfg80211_set_ext_roam_params() - Settings for roaming parameters
4161 * @wiphy: The wiphy structure
4162 * @wdev: The wireless device
4163 * @data: Data passed by framework
4164 * @data_len: Parameters to be configured passed as data
4165 *
4166 * The roaming related parameters are configured by the framework
4167 * using this interface.
4168 *
4169 * Return: Return either success or failure code.
4170 */
4171static int
4172__wlan_hdd_cfg80211_set_ext_roam_params(struct wiphy *wiphy,
4173 struct wireless_dev *wdev, const void *data, int data_len)
4174{
4175 struct net_device *dev = wdev->netdev;
Jeff Johnsonce2ba702017-10-02 13:30:24 -07004176 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsonb8944722017-09-03 09:03:19 -07004177 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004178 struct roam_ext_params *roam_params = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004179 int ret;
4180
Dustin Brownfdf17c12018-03-14 12:55:34 -07004181 hdd_enter_dev(dev);
Jeff Johnson1f61b612016-02-12 16:28:33 -08004182
Anurag Chouhan6d760662016-02-20 16:05:43 +05304183 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004184 hdd_err("Command not allowed in FTM mode");
4185 return -EPERM;
4186 }
4187
Jeff Johnsonb8944722017-09-03 09:03:19 -07004188 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05304189 if (ret)
4190 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004191
Jeff Johnsonb8944722017-09-03 09:03:19 -07004192 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
SaidiReddy Yenuga76047d02017-04-26 19:17:42 +05304193 hdd_err("Driver Modules are closed");
4194 return -EINVAL;
4195 }
4196
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004197 roam_params = qdf_mem_malloc(sizeof(*roam_params));
Min Liu74a1a502018-10-10 19:59:07 +08004198 if (!roam_params)
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004199 return -ENOMEM;
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004200
Jeff Johnsonb8944722017-09-03 09:03:19 -07004201 ret = hdd_set_ext_roam_params(hdd_ctx, data, data_len,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08004202 adapter->vdev_id, roam_params);
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004203 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004204 goto fail;
Hanumanth Reddy Pothulaa1259ef2017-02-21 17:14:43 +05304205
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004206 if (roam_params)
4207 qdf_mem_free(roam_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004208 return 0;
4209fail:
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004210 if (roam_params)
4211 qdf_mem_free(roam_params);
4212
4213 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004214}
Hanumanth Reddy Pothulaa1259ef2017-02-21 17:14:43 +05304215#undef PARAM_NUM_NW
4216#undef PARAM_SET_BSSID
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +05304217#undef PARAM_SET_BSSID_HINT
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004218#undef PARAM_SSID_LIST
Hanumanth Reddy Pothulaa1259ef2017-02-21 17:14:43 +05304219#undef PARAM_LIST_SSID
Srinivas Girigowda72f30392017-07-13 18:55:09 -07004220#undef MAX_ROAMING_PARAM
4221#undef PARAM_NUM_BSSID
4222#undef PARAM_BSSID_PREFS
4223#undef PARAM_ROAM_BSSID
4224#undef PARAM_RSSI_MODIFIER
4225#undef PARAMS_NUM_BSSID
4226#undef PARAM_BSSID_PARAMS
4227#undef PARAM_A_BAND_BOOST_THLD
4228#undef PARAM_A_BAND_PELT_THLD
4229#undef PARAM_A_BAND_BOOST_FACTOR
4230#undef PARAM_A_BAND_PELT_FACTOR
4231#undef PARAM_A_BAND_MAX_BOOST
4232#undef PARAM_ROAM_HISTERESYS
4233#undef PARAM_RSSI_TRIGGER
4234#undef PARAM_ROAM_ENABLE
Hanumanth Reddy Pothulaa1259ef2017-02-21 17:14:43 +05304235
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004236
4237/**
4238 * wlan_hdd_cfg80211_set_ext_roam_params() - set ext scan roam params
4239 * @wiphy: pointer to wireless wiphy structure.
4240 * @wdev: pointer to wireless_dev structure.
4241 * @data: Pointer to the data to be passed via vendor interface
4242 * @data_len:Length of the data to be passed
4243 *
4244 * Return: Return the Success or Failure code.
4245 */
4246static int
4247wlan_hdd_cfg80211_set_ext_roam_params(struct wiphy *wiphy,
4248 struct wireless_dev *wdev,
4249 const void *data,
4250 int data_len)
4251{
Dustin Browna09acf42018-11-08 12:32:26 +05304252 int errno;
4253 struct osif_vdev_sync *vdev_sync;
4254
4255 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
4256 if (errno)
4257 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004258
Dustin Browna09acf42018-11-08 12:32:26 +05304259 errno = __wlan_hdd_cfg80211_set_ext_roam_params(wiphy, wdev,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004260 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004261
Dustin Browna09acf42018-11-08 12:32:26 +05304262 osif_vdev_sync_op_stop(vdev_sync);
4263
4264 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004265}
4266
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05304267#define PWR_SAVE_FAIL_CMD_INDEX \
4268 QCA_NL80211_VENDOR_SUBCMD_PWR_SAVE_FAIL_DETECTED_INDEX
Jeff Johnsonb7fa2562018-07-02 08:36:17 -07004269
4270void hdd_chip_pwr_save_fail_detected_cb(hdd_handle_t hdd_handle,
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05304271 struct chip_pwr_save_fail_detected_params
4272 *data)
4273{
Jeff Johnsonb7fa2562018-07-02 08:36:17 -07004274 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05304275 struct sk_buff *skb;
4276 int flags = cds_get_gfp_flags();
4277
Dustin Brown491d54b2018-03-14 12:39:11 -07004278 hdd_enter();
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05304279
4280 if (wlan_hdd_validate_context(hdd_ctx))
4281 return;
4282
4283 if (!data) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07004284 hdd_debug("data is null");
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05304285 return;
4286 }
4287
4288 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
4289 NULL, NLMSG_HDRLEN +
4290 sizeof(data->failure_reason_code) +
4291 NLMSG_HDRLEN, PWR_SAVE_FAIL_CMD_INDEX,
4292 flags);
4293
4294 if (!skb) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07004295 hdd_info("cfg80211_vendor_event_alloc failed");
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05304296 return;
4297 }
4298
Dustin Brownbacc48f2018-03-14 14:48:44 -07004299 hdd_debug("failure reason code: %u", data->failure_reason_code);
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05304300
4301 if (nla_put_u32(skb,
4302 QCA_ATTR_CHIP_POWER_SAVE_FAILURE_REASON,
4303 data->failure_reason_code))
4304 goto fail;
4305
4306 cfg80211_vendor_event(skb, flags);
Dustin Browne74003f2018-03-14 12:51:58 -07004307 hdd_exit();
Ravi Kumar Bokka05c14e52017-03-27 14:48:23 +05304308 return;
4309
4310fail:
4311 kfree_skb(skb);
4312}
4313#undef PWR_SAVE_FAIL_CMD_INDEX
4314
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004315static const struct nla_policy
4316wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
4317 +1] = {
4318 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
4319};
4320
4321/**
4322 * wlan_hdd_check_dfs_channel_for_adapter() - check dfs channel in adapter
4323 * @hdd_ctx: HDD context
4324 * @device_mode: device mode
4325 * Return: bool
4326 */
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07004327static bool wlan_hdd_check_dfs_channel_for_adapter(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08004328 enum QDF_OPMODE device_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004329{
Jeff Johnsone5006672017-08-29 14:39:02 -07004330 struct hdd_adapter *adapter;
Jeff Johnson87251032017-08-29 13:31:11 -07004331 struct hdd_ap_ctx *ap_ctx;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07004332 struct hdd_station_ctx *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004333
Dustin Brown920397d2017-12-13 16:27:50 -08004334 hdd_for_each_adapter(hdd_ctx, adapter) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004335 if ((device_mode == adapter->device_mode) &&
Krunal Sonib4326f22016-03-10 13:05:51 -08004336 (device_mode == QDF_SAP_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004337 ap_ctx =
4338 WLAN_HDD_GET_AP_CTX_PTR(adapter);
4339
4340 /*
4341 * if there is SAP already running on DFS channel,
4342 * do not disable scan on dfs channels. Note that
4343 * with SAP on DFS, there cannot be conurrency on
4344 * single radio. But then we can have multiple
4345 * radios !!
4346 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07004347 if (CHANNEL_STATE_DFS == wlan_reg_get_channel_state(
Dustin Brown07901ec2018-09-07 11:02:41 -07004348 hdd_ctx->pdev,
Jeff Johnson01206862017-10-27 20:55:59 -07004349 ap_ctx->operating_channel)) {
Jeff Johnson020db452016-06-29 14:37:26 -07004350 hdd_err("SAP running on DFS channel");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004351 return true;
4352 }
4353 }
4354
4355 if ((device_mode == adapter->device_mode) &&
Krunal Sonib4326f22016-03-10 13:05:51 -08004356 (device_mode == QDF_STA_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004357 sta_ctx =
4358 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
4359
4360 /*
4361 * if STA is already connected on DFS channel,
4362 * do not disable scan on dfs channels
4363 */
4364 if (hdd_conn_is_connected(sta_ctx) &&
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07004365 (CHANNEL_STATE_DFS ==
Dustin Brown07901ec2018-09-07 11:02:41 -07004366 wlan_reg_get_channel_state(hdd_ctx->pdev,
Jeff Johnson8626e932019-02-27 18:35:22 -08004367 sta_ctx->conn_info.channel))) {
Jeff Johnson020db452016-06-29 14:37:26 -07004368 hdd_err("client connected on DFS channel");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004369 return true;
4370 }
4371 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004372 }
4373
4374 return false;
4375}
4376
4377/**
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07004378 * wlan_hdd_enable_dfs_chan_scan() - disable/enable DFS channels
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004379 * @hdd_ctx: HDD context within host driver
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07004380 * @enable_dfs_channels: If true, DFS channels can be used for scanning
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004381 *
4382 * Loops through devices to see who is operating on DFS channels
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07004383 * and then disables/enables DFS channels.
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004384 * Fails the disable request if any device is active on a DFS channel.
4385 *
4386 * Return: 0 or other error codes.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004387 */
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004388
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07004389int wlan_hdd_enable_dfs_chan_scan(struct hdd_context *hdd_ctx,
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07004390 bool enable_dfs_channels)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004391{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304392 QDF_STATUS status;
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07004393 bool err;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004394 mac_handle_t mac_handle;
gaurank kathpalia97c070b2019-01-07 17:23:06 +05304395 bool enable_dfs_scan = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004396
gaurank kathpalia97c070b2019-01-07 17:23:06 +05304397 ucfg_scan_cfg_get_dfs_chan_scan_allowed(hdd_ctx->psoc,
4398 &enable_dfs_scan);
4399
4400 if (enable_dfs_channels == enable_dfs_scan) {
Dustin Brown6a8d39b2018-08-14 15:27:26 -07004401 hdd_debug("DFS channels are already %s",
4402 enable_dfs_channels ? "enabled" : "disabled");
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07004403 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004404 }
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07004405
4406 if (!enable_dfs_channels) {
4407 err = wlan_hdd_check_dfs_channel_for_adapter(hdd_ctx,
4408 QDF_STA_MODE);
4409 if (err)
4410 return -EOPNOTSUPP;
4411
4412 err = wlan_hdd_check_dfs_channel_for_adapter(hdd_ctx,
4413 QDF_SAP_MODE);
4414 if (err)
4415 return -EOPNOTSUPP;
4416 }
4417
gaurank kathpalia97c070b2019-01-07 17:23:06 +05304418 ucfg_scan_cfg_set_dfs_chan_scan_allowed(hdd_ctx->psoc,
4419 enable_dfs_channels);
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07004420
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004421 mac_handle = hdd_ctx->mac_handle;
4422 status = sme_enable_dfs_chan_scan(mac_handle, enable_dfs_channels);
Min Liu5eaf7242018-03-13 17:32:15 +08004423 if (QDF_IS_STATUS_ERROR(status)) {
4424 hdd_err("Failed to set DFS channel scan flag to %d",
4425 enable_dfs_channels);
4426 return qdf_status_to_os_return(status);
4427 }
4428
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07004429 hdd_abort_mac_scan_all_adapters(hdd_ctx);
4430
4431 /* pass dfs channel status to regulatory component */
Dustin Brown07901ec2018-09-07 11:02:41 -07004432 status = ucfg_reg_enable_dfs_channels(hdd_ctx->pdev,
4433 enable_dfs_channels);
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07004434
4435 if (QDF_IS_STATUS_ERROR(status))
4436 hdd_err("Failed to %s DFS channels",
4437 enable_dfs_channels ? "enable" : "disable");
4438
4439 return qdf_status_to_os_return(status);
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004440}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004441
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004442/**
4443 * __wlan_hdd_cfg80211_disable_dfs_chan_scan() - DFS channel configuration
4444 * @wiphy: corestack handler
4445 * @wdev: wireless device
4446 * @data: data
4447 * @data_len: data length
4448 * Return: success(0) or reason code for failure
4449 */
4450static int __wlan_hdd_cfg80211_disable_dfs_chan_scan(struct wiphy *wiphy,
4451 struct wireless_dev *wdev,
4452 const void *data,
4453 int data_len)
4454{
4455 struct net_device *dev = wdev->netdev;
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07004456 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004457 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
4458 int ret_val;
4459 uint32_t no_dfs_flag = 0;
gaurank kathpalia97c070b2019-01-07 17:23:06 +05304460 bool enable_dfs_scan = true;
Dustin Brownfdf17c12018-03-14 12:55:34 -07004461 hdd_enter_dev(dev);
Jeff Johnson1f61b612016-02-12 16:28:33 -08004462
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004463 ret_val = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05304464 if (ret_val)
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004465 return ret_val;
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004466
Dustin Brown4ea21db2018-01-05 14:13:17 -08004467 if (wlan_cfg80211_nla_parse(tb,
4468 QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
4469 data, data_len,
4470 wlan_hdd_set_no_dfs_flag_config_policy)) {
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004471 hdd_err("invalid attr");
4472 return -EINVAL;
4473 }
4474
4475 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
4476 hdd_err("attr dfs flag failed");
4477 return -EINVAL;
4478 }
4479
4480 no_dfs_flag = nla_get_u32(
4481 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
4482
Srinivas Girigowda13d39252017-03-06 16:12:15 -08004483 hdd_debug("DFS flag: %d", no_dfs_flag);
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004484
4485 if (no_dfs_flag > 1) {
Jeff Johnson020db452016-06-29 14:37:26 -07004486 hdd_err("invalid value of dfs flag");
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004487 return -EINVAL;
4488 }
gaurank kathpalia97c070b2019-01-07 17:23:06 +05304489 ucfg_scan_cfg_get_dfs_chan_scan_allowed(hdd_ctx->psoc,
4490 &enable_dfs_scan);
Deepak Dhamdhere29b3b2f2015-01-22 11:09:55 -08004491
gaurank kathpalia97c070b2019-01-07 17:23:06 +05304492 if (enable_dfs_scan) {
bings50112bb2018-12-21 15:51:51 +08004493 ret_val = wlan_hdd_enable_dfs_chan_scan(hdd_ctx, !no_dfs_flag);
4494 } else {
gaurank kathpalia97c070b2019-01-07 17:23:06 +05304495 if ((!no_dfs_flag) != enable_dfs_scan) {
bings50112bb2018-12-21 15:51:51 +08004496 hdd_err("DFS chan ini configured %d, no dfs flag: %d",
gaurank kathpalia97c070b2019-01-07 17:23:06 +05304497 enable_dfs_scan,
bings50112bb2018-12-21 15:51:51 +08004498 no_dfs_flag);
4499 return -EINVAL;
4500 }
4501 }
4502
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004503 return ret_val;
4504}
4505
4506/**
4507 * wlan_hdd_cfg80211_disable_dfs_chan_scan () - DFS scan vendor command
4508 *
4509 * @wiphy: wiphy device pointer
4510 * @wdev: wireless device pointer
Manikandan Mohan80dea792016-04-28 16:36:48 -07004511 * @data: Vendor command data buffer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004512 * @data_len: Buffer length
4513 *
4514 * Handles QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX. Validate it and
4515 * call wlan_hdd_disable_dfs_chan_scan to send it to firmware.
4516 *
4517 * Return: EOK or other error codes.
4518 */
4519
4520static int wlan_hdd_cfg80211_disable_dfs_chan_scan(struct wiphy *wiphy,
4521 struct wireless_dev *wdev,
4522 const void *data,
4523 int data_len)
4524{
Dustin Brown363b4792019-02-05 16:11:55 -08004525 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08004526 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05304527
Dustin Brown363b4792019-02-05 16:11:55 -08004528 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08004529 if (errno)
4530 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004531
Dustin Brownf0f00612019-01-31 16:02:24 -08004532 errno = __wlan_hdd_cfg80211_disable_dfs_chan_scan(wiphy, wdev,
4533 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004534
Dustin Brown363b4792019-02-05 16:11:55 -08004535 osif_psoc_sync_op_stop(psoc_sync);
Arunk Khandavalli99716d12018-11-14 15:02:02 +05304536
Dustin Brownf0f00612019-01-31 16:02:24 -08004537 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004538}
4539
Manikandan Mohan80dea792016-04-28 16:36:48 -07004540static const struct nla_policy
4541wlan_hdd_wisa_cmd_policy[QCA_WLAN_VENDOR_ATTR_WISA_MAX + 1] = {
4542 [QCA_WLAN_VENDOR_ATTR_WISA_MODE] = {.type = NLA_U32 },
4543};
4544
4545/**
4546 * __wlan_hdd_cfg80211_handle_wisa_cmd() - Handle WISA vendor cmd
4547 * @wiphy: wiphy device pointer
4548 * @wdev: wireless device pointer
4549 * @data: Vendor command data buffer
4550 * @data_len: Buffer length
4551 *
4552 * Handles QCA_WLAN_VENDOR_SUBCMD_WISA. Validate cmd attributes and
4553 * setup WISA Mode features.
4554 *
4555 * Return: Success(0) or reason code for failure
4556 */
4557static int __wlan_hdd_cfg80211_handle_wisa_cmd(struct wiphy *wiphy,
4558 struct wireless_dev *wdev, const void *data, int data_len)
4559{
4560 struct net_device *dev = wdev->netdev;
Jeff Johnsone5006672017-08-29 14:39:02 -07004561 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07004562 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Manikandan Mohan80dea792016-04-28 16:36:48 -07004563 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WISA_MAX + 1];
4564 struct sir_wisa_params wisa;
4565 int ret_val;
4566 QDF_STATUS status;
4567 bool wisa_mode;
Leo Changfdb45c32016-10-28 11:09:23 -07004568 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
4569 void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004570 mac_handle_t mac_handle;
Mohit Khannae1b86022019-04-12 10:04:57 -07004571 struct cdp_vdev *txrx_vdev = NULL;
Manikandan Mohan80dea792016-04-28 16:36:48 -07004572
Dustin Brownfdf17c12018-03-14 12:55:34 -07004573 hdd_enter_dev(dev);
Manikandan Mohan80dea792016-04-28 16:36:48 -07004574 ret_val = wlan_hdd_validate_context(hdd_ctx);
4575 if (ret_val)
4576 goto err;
4577
4578 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
4579 hdd_err("Command not allowed in FTM mode");
4580 return -EPERM;
4581 }
4582
Dustin Brown4ea21db2018-01-05 14:13:17 -08004583 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WISA_MAX, data,
4584 data_len, wlan_hdd_wisa_cmd_policy)) {
Manikandan Mohan80dea792016-04-28 16:36:48 -07004585 hdd_err("Invalid WISA cmd attributes");
4586 ret_val = -EINVAL;
4587 goto err;
4588 }
4589 if (!tb[QCA_WLAN_VENDOR_ATTR_WISA_MODE]) {
4590 hdd_err("Invalid WISA mode");
4591 ret_val = -EINVAL;
4592 goto err;
4593 }
4594
4595 wisa_mode = !!nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_WISA_MODE]);
Srinivas Girigowda13d39252017-03-06 16:12:15 -08004596 hdd_debug("WISA Mode: %d", wisa_mode);
Manikandan Mohan80dea792016-04-28 16:36:48 -07004597 wisa.mode = wisa_mode;
Jeff Johnsoncf07c312019-02-04 13:53:29 -08004598 wisa.vdev_id = adapter->vdev_id;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004599 mac_handle = hdd_ctx->mac_handle;
4600 status = sme_set_wisa_params(mac_handle, &wisa);
Manikandan Mohanb6315dd2016-05-10 16:16:36 -07004601 if (!QDF_IS_STATUS_SUCCESS(status)) {
4602 hdd_err("Unable to set WISA mode: %d to FW", wisa_mode);
Manikandan Mohan80dea792016-04-28 16:36:48 -07004603 ret_val = -EINVAL;
Manikandan Mohanb6315dd2016-05-10 16:16:36 -07004604 }
Mohit Khannae1b86022019-04-12 10:04:57 -07004605 if (QDF_IS_STATUS_SUCCESS(status) || !wisa_mode) {
4606 txrx_vdev = cdp_get_vdev_from_vdev_id(soc,
4607 (struct cdp_pdev *)pdev,
4608 adapter->vdev_id);
4609 if (!txrx_vdev)
4610 ret_val = -EINVAL;
4611 else
4612 cdp_set_wisa_mode(soc, txrx_vdev, wisa_mode);
4613 }
Manikandan Mohan80dea792016-04-28 16:36:48 -07004614err:
Dustin Browne74003f2018-03-14 12:51:58 -07004615 hdd_exit();
Manikandan Mohan80dea792016-04-28 16:36:48 -07004616 return ret_val;
4617}
4618
4619/**
4620 * wlan_hdd_cfg80211_handle_wisa_cmd() - Handle WISA vendor cmd
4621 * @wiphy: corestack handler
4622 * @wdev: wireless device
4623 * @data: data
4624 * @data_len: data length
4625 *
4626 * Handles QCA_WLAN_VENDOR_SUBCMD_WISA. Validate cmd attributes and
4627 * setup WISA mode features.
4628 *
4629 * Return: Success(0) or reason code for failure
4630 */
4631static int wlan_hdd_cfg80211_handle_wisa_cmd(struct wiphy *wiphy,
4632 struct wireless_dev *wdev,
4633 const void *data,
4634 int data_len)
4635{
Dustin Browna09acf42018-11-08 12:32:26 +05304636 int errno;
4637 struct osif_vdev_sync *vdev_sync;
4638
4639 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
4640 if (errno)
4641 return errno;
Manikandan Mohan80dea792016-04-28 16:36:48 -07004642
Dustin Browna09acf42018-11-08 12:32:26 +05304643 errno = __wlan_hdd_cfg80211_handle_wisa_cmd(wiphy, wdev,
4644 data, data_len);
Manikandan Mohan80dea792016-04-28 16:36:48 -07004645
Dustin Browna09acf42018-11-08 12:32:26 +05304646 osif_vdev_sync_op_stop(vdev_sync);
4647
4648 return errno;
Manikandan Mohan80dea792016-04-28 16:36:48 -07004649}
4650
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05304651struct hdd_station_info *hdd_get_stainfo(struct hdd_station_info *astainfo,
4652 struct qdf_mac_addr mac_addr)
Will Huang496b36c2017-07-11 16:38:50 +08004653{
Jeff Johnson82155922017-09-30 16:54:14 -07004654 struct hdd_station_info *stainfo = NULL;
Will Huang496b36c2017-07-11 16:38:50 +08004655 int i;
4656
4657 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05304658 if (!qdf_mem_cmp(&astainfo[i].sta_mac,
Will Huang496b36c2017-07-11 16:38:50 +08004659 &mac_addr,
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +05304660 QDF_MAC_ADDR_SIZE)) {
4661 stainfo = &astainfo[i];
4662 break;
4663 }
Will Huang496b36c2017-07-11 16:38:50 +08004664 }
4665
4666 return stainfo;
4667}
4668
Anurag Chouhan96919482016-07-13 16:36:57 +05304669/*
4670 * undef short names defined for get station command
4671 * used by __wlan_hdd_cfg80211_get_station_cmd()
4672 */
4673#undef STATION_INVALID
4674#undef STATION_INFO
4675#undef STATION_ASSOC_FAIL_REASON
Will Huang496b36c2017-07-11 16:38:50 +08004676#undef STATION_REMOTE
Anurag Chouhan96919482016-07-13 16:36:57 +05304677#undef STATION_MAX
Will Huang496b36c2017-07-11 16:38:50 +08004678#undef LINK_INFO_STANDARD_NL80211_ATTR
4679#undef AP_INFO_STANDARD_NL80211_ATTR
4680#undef INFO_ROAM_COUNT
4681#undef INFO_AKM
4682#undef WLAN802_11_MODE
4683#undef AP_INFO_HS20_INDICATION
4684#undef HT_OPERATION
4685#undef VHT_OPERATION
4686#undef INFO_ASSOC_FAIL_REASON
4687#undef REMOTE_MAX_PHY_RATE
4688#undef REMOTE_TX_PACKETS
4689#undef REMOTE_TX_BYTES
4690#undef REMOTE_RX_PACKETS
4691#undef REMOTE_RX_BYTES
4692#undef REMOTE_LAST_TX_RATE
4693#undef REMOTE_LAST_RX_RATE
4694#undef REMOTE_WMM
4695#undef REMOTE_SUPPORTED_MODE
4696#undef REMOTE_AMPDU
4697#undef REMOTE_TX_STBC
4698#undef REMOTE_RX_STBC
4699#undef REMOTE_CH_WIDTH
4700#undef REMOTE_SGI_ENABLE
4701#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
4702#undef REMOTE_PAD
4703#endif
Anurag Chouhan96919482016-07-13 16:36:57 +05304704
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004705#ifdef WLAN_FEATURE_ROAM_OFFLOAD
sheenam monga6e49e5c2019-04-04 12:49:04 +05304706
4707/**
4708 * hdd_get_roam_reason() - convert wmi roam reason to
4709 * enum qca_roam_reason
4710 * @roam_scan_trigger: wmi roam scan trigger ID
4711 *
4712 * Return: Meaningful qca_roam_reason from enum WMI_ROAM_TRIGGER_REASON_ID
4713 */
4714static enum qca_roam_reason hdd_get_roam_reason(uint16_t roam_scan_trigger)
4715{
4716 switch (roam_scan_trigger) {
4717 case WMI_ROAM_TRIGGER_REASON_PER:
4718 return QCA_ROAM_REASON_PER;
4719 case WMI_ROAM_TRIGGER_REASON_BMISS:
4720 return QCA_ROAM_REASON_BEACON_MISS;
4721 case WMI_ROAM_TRIGGER_REASON_LOW_RSSI:
4722 case WMI_ROAM_TRIGGER_REASON_BACKGROUND:
4723 return QCA_ROAM_REASON_POOR_RSSI;
4724 case WMI_ROAM_TRIGGER_REASON_HIGH_RSSI:
4725 return QCA_ROAM_REASON_BETTER_RSSI;
4726 case WMI_ROAM_TRIGGER_REASON_DENSE:
4727 return QCA_ROAM_REASON_CONGESTION;
4728 case WMI_ROAM_TRIGGER_REASON_FORCED:
4729 return QCA_ROAM_REASON_USER_TRIGGER;
4730 case WMI_ROAM_TRIGGER_REASON_BTM:
4731 return QCA_ROAM_REASON_BTM;
4732 case WMI_ROAM_TRIGGER_REASON_BSS_LOAD:
4733 return QCA_ROAM_REASON_BSS_LOAD;
4734 default:
4735 return QCA_ROAM_REASON_UNKNOWN;
4736 }
4737
4738 return QCA_ROAM_REASON_UNKNOWN;
4739}
4740
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004741/**
4742 * __wlan_hdd_cfg80211_keymgmt_set_key() - Store the Keys in the driver session
4743 * @wiphy: pointer to wireless wiphy structure.
4744 * @wdev: pointer to wireless_dev structure.
4745 * @data: Pointer to the Key data
4746 * @data_len:Length of the data passed
4747 *
4748 * This is called when wlan driver needs to save the keys received via
4749 * vendor specific command.
4750 *
4751 * Return: Return the Success or Failure code.
4752 */
4753static int __wlan_hdd_cfg80211_keymgmt_set_key(struct wiphy *wiphy,
4754 struct wireless_dev *wdev,
4755 const void *data, int data_len)
4756{
4757 uint8_t local_pmk[SIR_ROAM_SCAN_PSK_SIZE];
4758 struct net_device *dev = wdev->netdev;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004759 struct hdd_adapter *hdd_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4760 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004761 int status;
Deepak Dhamdhere828f1892017-02-09 11:51:19 -08004762 struct pmkid_mode_bits pmkid_modes;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004763 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004764
Dustin Brownfdf17c12018-03-14 12:55:34 -07004765 hdd_enter_dev(dev);
Jeff Johnson1f61b612016-02-12 16:28:33 -08004766
Anurag Chouhan6d760662016-02-20 16:05:43 +05304767 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004768 hdd_err("Command not allowed in FTM mode");
4769 return -EPERM;
4770 }
4771
Jeff Johnsond36fa332019-03-18 13:42:25 -07004772 if ((!data) || (data_len <= 0) ||
Hanumanth Reddy Pothula53874852018-03-08 19:57:49 +05304773 (data_len > SIR_ROAM_SCAN_PSK_SIZE)) {
Jeff Johnson020db452016-06-29 14:37:26 -07004774 hdd_err("Invalid data");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004775 return -EINVAL;
4776 }
4777
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004778 hdd_ctx = WLAN_HDD_GET_CTX(hdd_adapter);
4779 if (!hdd_ctx) {
Jeff Johnson020db452016-06-29 14:37:26 -07004780 hdd_err("HDD context is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004781 return -EINVAL;
4782 }
4783
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004784 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05304785 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004786 return status;
Deepak Dhamdhere828f1892017-02-09 11:51:19 -08004787
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004788 hdd_get_pmkid_modes(hdd_ctx, &pmkid_modes);
Deepak Dhamdhere828f1892017-02-09 11:51:19 -08004789
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004790 mac_handle = hdd_ctx->mac_handle;
4791 sme_update_roam_key_mgmt_offload_enabled(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08004792 hdd_adapter->vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004793 true, &pmkid_modes);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304794 qdf_mem_zero(&local_pmk, SIR_ROAM_SCAN_PSK_SIZE);
4795 qdf_mem_copy(local_pmk, data, data_len);
Jeff Johnsoncf07c312019-02-04 13:53:29 -08004796 sme_roam_set_psk_pmk(mac_handle, hdd_adapter->vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -07004797 local_pmk, data_len);
Ashish Kumar Dhanotiya36510832019-02-20 22:13:25 +05304798 qdf_mem_zero(&local_pmk, SIR_ROAM_SCAN_PSK_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004799 return 0;
4800}
4801
4802/**
4803 * wlan_hdd_cfg80211_keymgmt_set_key() - Store the Keys in the driver session
4804 * @wiphy: pointer to wireless wiphy structure.
4805 * @wdev: pointer to wireless_dev structure.
4806 * @data: Pointer to the Key data
4807 * @data_len:Length of the data passed
4808 *
4809 * This is called when wlan driver needs to save the keys received via
4810 * vendor specific command.
4811 *
4812 * Return: Return the Success or Failure code.
4813 */
4814static int wlan_hdd_cfg80211_keymgmt_set_key(struct wiphy *wiphy,
4815 struct wireless_dev *wdev,
4816 const void *data, int data_len)
4817{
Dustin Browna09acf42018-11-08 12:32:26 +05304818 int errno;
4819 struct osif_vdev_sync *vdev_sync;
4820
4821 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
4822 if (errno)
4823 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004824
Dustin Browna09acf42018-11-08 12:32:26 +05304825 errno = __wlan_hdd_cfg80211_keymgmt_set_key(wiphy, wdev,
4826 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004827
Dustin Browna09acf42018-11-08 12:32:26 +05304828 osif_vdev_sync_op_stop(vdev_sync);
4829
4830 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004831}
Varun Reddy Yeturubbbbe232016-02-29 14:01:57 -08004832#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004833
4834static const struct nla_policy qca_wlan_vendor_get_wifi_info_policy[
4835 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1] = {
4836 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
4837 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
Ryan Hsu7ac88852016-04-28 10:20:34 -07004838 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX] = {.type = NLA_U32 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004839};
4840
4841/**
4842 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
4843 * @wiphy: pointer to wireless wiphy structure.
4844 * @wdev: pointer to wireless_dev structure.
4845 * @data: Pointer to the data to be passed via vendor interface
4846 * @data_len:Length of the data to be passed
4847 *
4848 * This is called when wlan driver needs to send wifi driver related info
4849 * (driver/fw version) to the user space application upon request.
4850 *
4851 * Return: Return the Success or Failure code.
4852 */
4853static int
4854__wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
4855 struct wireless_dev *wdev,
4856 const void *data, int data_len)
4857{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07004858 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004859 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
Ryan Hsu7ac88852016-04-28 10:20:34 -07004860 tSirVersionString driver_version;
4861 tSirVersionString firmware_version;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004862 int status;
Ryan Hsu7ac88852016-04-28 10:20:34 -07004863 struct sk_buff *reply_skb;
4864 uint32_t skb_len = 0, count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004865
Dustin Brownfdf17c12018-03-14 12:55:34 -07004866 hdd_enter_dev(wdev->netdev);
Jeff Johnson1f61b612016-02-12 16:28:33 -08004867
Anurag Chouhan6d760662016-02-20 16:05:43 +05304868 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004869 hdd_err("Command not allowed in FTM mode");
4870 return -EPERM;
4871 }
4872
4873 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05304874 if (status)
4875 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004876
Dustin Brown4ea21db2018-01-05 14:13:17 -08004877 if (wlan_cfg80211_nla_parse(tb_vendor,
4878 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX,
4879 data, data_len,
4880 qca_wlan_vendor_get_wifi_info_policy)) {
Ryan Hsu7ac88852016-04-28 10:20:34 -07004881 hdd_err("WIFI_INFO_GET NL CMD parsing failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004882 return -EINVAL;
4883 }
4884
4885 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
Srinivas Girigowdac06543c2017-03-09 15:10:03 -08004886 hdd_debug("Rcvd req for Driver version");
Ryan Hsu7ac88852016-04-28 10:20:34 -07004887 strlcpy(driver_version, QWLAN_VERSIONSTR,
4888 sizeof(driver_version));
4889 skb_len += strlen(driver_version) + 1;
4890 count++;
4891 }
4892
4893 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08004894 hdd_debug("Rcvd req for FW version");
Ryan Hsu7ac88852016-04-28 10:20:34 -07004895 snprintf(firmware_version, sizeof(firmware_version),
Ashish Kumar Dhanotiyaeadb28b2019-06-28 14:34:19 +05304896 "FW:%d.%d.%d.%d.%d.%d HW:%s",
4897 hdd_ctx->fw_version_info.major_spid,
4898 hdd_ctx->fw_version_info.minor_spid,
4899 hdd_ctx->fw_version_info.siid,
4900 hdd_ctx->fw_version_info.rel_id,
4901 hdd_ctx->fw_version_info.crmid,
4902 hdd_ctx->fw_version_info.sub_id,
4903 hdd_ctx->target_hw_name);
Ryan Hsu7ac88852016-04-28 10:20:34 -07004904 skb_len += strlen(firmware_version) + 1;
4905 count++;
4906 }
4907
Rajeev Kumar Sirasanagandla551613d2018-05-16 17:21:01 +05304908 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX]) {
4909 hdd_debug("Rcvd req for Radio index");
4910 skb_len += sizeof(uint32_t);
4911 count++;
4912 }
4913
Ryan Hsu7ac88852016-04-28 10:20:34 -07004914 if (count == 0) {
4915 hdd_err("unknown attribute in get_wifi_info request");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004916 return -EINVAL;
4917 }
4918
Ryan Hsu7ac88852016-04-28 10:20:34 -07004919 skb_len += (NLA_HDRLEN * count) + NLMSG_HDRLEN;
4920 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, skb_len);
4921
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004922 if (!reply_skb) {
Ryan Hsu7ac88852016-04-28 10:20:34 -07004923 hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004924 return -ENOMEM;
4925 }
4926
Ryan Hsu7ac88852016-04-28 10:20:34 -07004927 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
4928 if (nla_put_string(reply_skb,
4929 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION,
4930 driver_version))
4931 goto error_nla_fail;
4932 }
4933
Hanumanth Reddy Pothula1046ccc2016-10-14 14:33:44 +05304934 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
Ryan Hsu7ac88852016-04-28 10:20:34 -07004935 if (nla_put_string(reply_skb,
4936 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION,
4937 firmware_version))
4938 goto error_nla_fail;
4939 }
4940
4941 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX]) {
4942 if (nla_put_u32(reply_skb,
4943 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_RADIO_INDEX,
4944 hdd_ctx->radio_index))
4945 goto error_nla_fail;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004946 }
4947
4948 return cfg80211_vendor_cmd_reply(reply_skb);
Ryan Hsu7ac88852016-04-28 10:20:34 -07004949
4950error_nla_fail:
4951 hdd_err("nla put fail");
4952 kfree_skb(reply_skb);
4953 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004954}
4955
4956/**
4957 * wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
4958 * @wiphy: pointer to wireless wiphy structure.
4959 * @wdev: pointer to wireless_dev structure.
4960 * @data: Pointer to the data to be passed via vendor interface
4961 * @data_len:Length of the data to be passed
4962 *
4963 * This is called when wlan driver needs to send wifi driver related info
4964 * (driver/fw version) to the user space application upon request.
4965 *
4966 * Return: Return the Success or Failure code.
4967 */
4968static int
4969wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
4970 struct wireless_dev *wdev,
4971 const void *data, int data_len)
4972{
Dustin Brown363b4792019-02-05 16:11:55 -08004973 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08004974 int errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004975
Dustin Brown363b4792019-02-05 16:11:55 -08004976 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08004977 if (errno)
4978 return errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05304979
Dustin Brownf0f00612019-01-31 16:02:24 -08004980 errno = __wlan_hdd_cfg80211_get_wifi_info(wiphy, wdev, data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004981
Dustin Brown363b4792019-02-05 16:11:55 -08004982 osif_psoc_sync_op_stop(psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08004983
4984 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004985}
4986
4987/**
4988 * __wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
4989 * @wiphy: pointer to wireless wiphy structure.
4990 * @wdev: pointer to wireless_dev structure.
4991 * @data: Pointer to the data to be passed via vendor interface
4992 * @data_len:Length of the data to be passed
4993 *
4994 * This is called by userspace to know the supported logger features
4995 *
4996 * Return: Return the Success or Failure code.
4997 */
4998static int
4999__wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
5000 struct wireless_dev *wdev,
5001 const void *data, int data_len)
5002{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07005003 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005004 int status;
5005 uint32_t features;
5006 struct sk_buff *reply_skb = NULL;
5007
Dustin Brownfdf17c12018-03-14 12:55:34 -07005008 hdd_enter_dev(wdev->netdev);
Jeff Johnson1f61b612016-02-12 16:28:33 -08005009
Anurag Chouhan6d760662016-02-20 16:05:43 +05305010 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005011 hdd_err("Command not allowed in FTM mode");
5012 return -EPERM;
5013 }
5014
5015 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305016 if (status)
5017 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005018
5019 features = 0;
5020
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005021 features |= WIFI_LOGGER_PER_PACKET_TX_RX_STATUS_SUPPORTED;
5022 features |= WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
5023 features |= WIFI_LOGGER_WAKE_LOCK_SUPPORTED;
Srinivas Girigowdaa26eac02018-01-23 12:49:20 -08005024 features |= WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
Dundi Ravitejab189b742018-05-08 15:59:57 +05305025 features |= WIFI_LOGGER_PACKET_FATE_SUPPORTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005026
5027 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
5028 sizeof(uint32_t) + NLA_HDRLEN + NLMSG_HDRLEN);
5029 if (!reply_skb) {
Jeff Johnson020db452016-06-29 14:37:26 -07005030 hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005031 return -ENOMEM;
5032 }
5033
Srinivas Girigowda13d39252017-03-06 16:12:15 -08005034 hdd_debug("Supported logger features: 0x%0x", features);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005035 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_LOGGER_SUPPORTED,
5036 features)) {
Jeff Johnson020db452016-06-29 14:37:26 -07005037 hdd_err("nla put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005038 kfree_skb(reply_skb);
5039 return -EINVAL;
5040 }
5041
5042 return cfg80211_vendor_cmd_reply(reply_skb);
5043}
5044
5045/**
5046 * wlan_hdd_cfg80211_get_logger_supp_feature() - Get the wifi logger features
5047 * @wiphy: pointer to wireless wiphy structure.
5048 * @wdev: pointer to wireless_dev structure.
5049 * @data: Pointer to the data to be passed via vendor interface
5050 * @data_len:Length of the data to be passed
5051 *
5052 * This is called by userspace to know the supported logger features
5053 *
5054 * Return: Return the Success or Failure code.
5055 */
5056static int
5057wlan_hdd_cfg80211_get_logger_supp_feature(struct wiphy *wiphy,
5058 struct wireless_dev *wdev,
5059 const void *data, int data_len)
5060{
Dustin Brown363b4792019-02-05 16:11:55 -08005061 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08005062 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05305063
Dustin Brown363b4792019-02-05 16:11:55 -08005064 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08005065 if (errno)
5066 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005067
Dustin Brownf0f00612019-01-31 16:02:24 -08005068 errno = __wlan_hdd_cfg80211_get_logger_supp_feature(wiphy, wdev,
5069 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005070
Dustin Brown363b4792019-02-05 16:11:55 -08005071 osif_psoc_sync_op_stop(psoc_sync);
Arunk Khandavalli99716d12018-11-14 15:02:02 +05305072
Dustin Brownf0f00612019-01-31 16:02:24 -08005073 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005074}
5075
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305076#ifdef WLAN_FEATURE_GTK_OFFLOAD
5077void wlan_hdd_save_gtk_offload_params(struct hdd_adapter *adapter,
Pragaspathi Thilagarajeb367282019-02-19 00:42:28 +05305078 uint8_t *kck_ptr, uint8_t kck_len,
5079 uint8_t *kek_ptr, uint32_t kek_len,
5080 uint8_t *replay_ctr, bool big_endian)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305081{
5082 struct hdd_station_ctx *hdd_sta_ctx;
5083 uint8_t *buf;
5084 int i;
5085 struct pmo_gtk_req *gtk_req = NULL;
Min Liu8c5d99e2018-09-10 17:18:44 +08005086 struct wlan_objmgr_vdev *vdev;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305087 QDF_STATUS status = QDF_STATUS_E_FAILURE;
5088
5089 gtk_req = qdf_mem_malloc(sizeof(*gtk_req));
Min Liu74a1a502018-10-10 19:59:07 +08005090 if (!gtk_req)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305091 return;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305092
5093 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Pragaspathi Thilagarajeb367282019-02-19 00:42:28 +05305094 if (kck_ptr) {
5095 if (kck_len > sizeof(gtk_req->kck)) {
5096 kck_len = sizeof(gtk_req->kck);
5097 QDF_ASSERT(0);
5098 }
5099 qdf_mem_copy(gtk_req->kck, kck_ptr, kck_len);
5100 }
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305101
Jeff Johnsone1f2b0e2017-11-14 14:42:55 -08005102 if (kek_ptr) {
5103 /* paranoia */
5104 if (kek_len > sizeof(gtk_req->kek)) {
5105 kek_len = sizeof(gtk_req->kek);
5106 QDF_ASSERT(0);
5107 }
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305108 qdf_mem_copy(gtk_req->kek, kek_ptr, kek_len);
Jeff Johnsone1f2b0e2017-11-14 14:42:55 -08005109 }
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305110
Jeff Johnsone04b6992019-02-27 14:06:55 -08005111 qdf_copy_macaddr(&gtk_req->bssid, &hdd_sta_ctx->conn_info.bssid);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305112
5113 gtk_req->kek_len = kek_len;
gaurank kathpalia82a1b2b2018-07-10 16:49:10 +05305114 gtk_req->is_fils_connection = hdd_is_fils_connection(adapter);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305115
5116 /* convert big to little endian since driver work on little endian */
5117 buf = (uint8_t *)&gtk_req->replay_counter;
5118 for (i = 0; i < 8; i++)
5119 buf[7 - i] = replay_ctr[i];
5120
Min Liu8c5d99e2018-09-10 17:18:44 +08005121 vdev = hdd_objmgr_get_vdev(adapter);
5122 if (!vdev)
5123 goto end;
5124 status = ucfg_pmo_cache_gtk_offload_req(vdev, gtk_req);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05305125 hdd_objmgr_put_vdev(vdev);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305126 if (status != QDF_STATUS_SUCCESS)
5127 hdd_err("Failed to cache GTK Offload");
5128
Min Liu8c5d99e2018-09-10 17:18:44 +08005129end:
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305130 qdf_mem_free(gtk_req);
5131}
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305132#endif
5133
Sridhar Selvaraje5260442017-08-19 10:12:03 +05305134#if defined(WLAN_FEATURE_FILS_SK) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305135/**
5136 * wlan_hdd_add_fils_params_roam_auth_event() - Adds FILS params in roam auth
5137 * @skb: SK buffer
5138 * @roam_info: Roam info
5139 *
5140 * API adds fils params[pmk, pmkid, next sequence number] to roam auth event
5141 *
5142 * Return: zero on success, error code on failure
5143 */
Jeff Johnson172237b2017-11-07 15:32:59 -08005144static int
5145wlan_hdd_add_fils_params_roam_auth_event(struct sk_buff *skb,
5146 struct csr_roam_info *roam_info)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305147{
5148 if (roam_info->pmk_len &&
5149 nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMK,
5150 roam_info->pmk_len, roam_info->pmk)) {
5151 hdd_err("pmk send fail");
5152 return -EINVAL;
5153 }
5154
5155 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PMKID,
Srinivas Girigowdaff8f5ef2019-03-26 17:20:55 -07005156 PMKID_LEN, roam_info->pmkid)) {
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305157 hdd_err("pmkid send fail");
5158 return -EINVAL;
5159 }
5160
Vignesh Viswanathan8da68cf2017-09-07 14:00:04 +05305161 hdd_debug("Update ERP Seq Num %d, Next ERP Seq Num %d",
5162 roam_info->update_erp_next_seq_num,
5163 roam_info->next_erp_seq_num);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305164 if (roam_info->update_erp_next_seq_num &&
5165 nla_put_u16(skb,
5166 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_FILS_ERP_NEXT_SEQ_NUM,
5167 roam_info->next_erp_seq_num)) {
5168 hdd_err("ERP seq num send fail");
5169 return -EINVAL;
5170 }
5171
5172 return 0;
5173}
5174#else
Jeff Johnson172237b2017-11-07 15:32:59 -08005175static inline int
5176wlan_hdd_add_fils_params_roam_auth_event(struct sk_buff *skb,
5177 struct csr_roam_info *roam_info)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305178{
5179 return 0;
5180}
5181#endif
5182
Varun Reddy Yeturubbbbe232016-02-29 14:01:57 -08005183#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005184/**
5185 * wlan_hdd_send_roam_auth_event() - Send the roamed and authorized event
Prakash Dhavali989127d2016-11-29 14:56:44 +05305186 * @adapter: Pointer to adapter struct
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005187 * @bssid: pointer to bssid of roamed AP.
5188 * @req_rsn_ie: Pointer to request RSN IE
5189 * @req_rsn_len: Length of the request RSN IE
5190 * @rsp_rsn_ie: Pointer to response RSN IE
5191 * @rsp_rsn_len: Length of the response RSN IE
5192 * @roam_info_ptr: Pointer to the roaming related information
5193 *
5194 * This is called when wlan driver needs to send the roaming and
5195 * authorization information after roaming.
5196 *
5197 * The information that would be sent is the request RSN IE, response
5198 * RSN IE and BSSID of the newly roamed AP.
5199 *
5200 * If the Authorized status is authenticated, then additional parameters
5201 * like PTK's KCK and KEK and Replay Counter would also be passed to the
5202 * supplicant.
5203 *
5204 * The supplicant upon receiving this event would ignore the legacy
5205 * cfg80211_roamed call and use the entire information from this event.
5206 * The cfg80211_roamed should still co-exist since the kernel will
5207 * make use of the parameters even if the supplicant ignores it.
5208 *
5209 * Return: Return the Success or Failure code.
5210 */
Jeff Johnsone5006672017-08-29 14:39:02 -07005211int wlan_hdd_send_roam_auth_event(struct hdd_adapter *adapter, uint8_t *bssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005212 uint8_t *req_rsn_ie, uint32_t req_rsn_len, uint8_t *rsp_rsn_ie,
Jeff Johnson172237b2017-11-07 15:32:59 -08005213 uint32_t rsp_rsn_len, struct csr_roam_info *roam_info_ptr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005214{
Jeff Johnson34fc63a2018-06-14 10:10:02 -07005215 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005216 struct sk_buff *skb = NULL;
Pragaspathi Thilagaraj7a1a08e2019-05-29 01:20:29 +05305217 enum csr_akm_type auth_type;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305218 uint32_t fils_params_len;
5219 int status;
sheenam monga6e49e5c2019-04-04 12:49:04 +05305220 enum qca_roam_reason hdd_roam_reason;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07005221
Dustin Brown491d54b2018-03-14 12:39:11 -07005222 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005223
Jeff Johnson34fc63a2018-06-14 10:10:02 -07005224 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005225 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005226
Jeff Johnson34fc63a2018-06-14 10:10:02 -07005227 if (!roaming_offload_enabled(hdd_ctx) ||
5228 !roam_info_ptr->roamSynchInProgress)
Prashanth Bhattabfc25292015-11-05 11:16:21 -08005229 return 0;
5230
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305231 /*
5232 * PMK is sent from FW in Roam Synch Event for FILS Roaming.
5233 * In that case, add three more NL attributes.ie. PMK, PMKID
5234 * and ERP next sequence number. Add corresponding lengths
5235 * with 3 extra NL message headers for each of the
5236 * aforementioned params.
5237 */
Srinivas Girigowdaff8f5ef2019-03-26 17:20:55 -07005238 fils_params_len = roam_info_ptr->pmk_len + PMKID_LEN +
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305239 sizeof(uint16_t) + (3 * NLMSG_HDRLEN);
5240
Jeff Johnson34fc63a2018-06-14 10:10:02 -07005241 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
Prakash Dhavali989127d2016-11-29 14:56:44 +05305242 &(adapter->wdev),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005243 ETH_ALEN + req_rsn_len + rsp_rsn_len +
5244 sizeof(uint8_t) + SIR_REPLAY_CTR_LEN +
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305245 SIR_KCK_KEY_LEN + roam_info_ptr->kek_len +
sheenam monga6e49e5c2019-04-04 12:49:04 +05305246 sizeof(uint16_t) + sizeof(uint8_t) +
5247 (9 * NLMSG_HDRLEN) + fils_params_len,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005248 QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH_INDEX,
5249 GFP_KERNEL);
5250
5251 if (!skb) {
Jeff Johnson020db452016-06-29 14:37:26 -07005252 hdd_err("cfg80211_vendor_event_alloc failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005253 return -EINVAL;
5254 }
5255
5256 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_BSSID,
5257 ETH_ALEN, bssid) ||
5258 nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REQ_IE,
5259 req_rsn_len, req_rsn_ie) ||
5260 nla_put(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_RESP_IE,
5261 rsp_rsn_len, rsp_rsn_ie)) {
Jeff Johnson020db452016-06-29 14:37:26 -07005262 hdd_err("nla put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005263 goto nla_put_failure;
5264 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005265 if (roam_info_ptr->synchAuthStatus ==
5266 CSR_ROAM_AUTH_STATUS_AUTHENTICATED) {
Jeff Johnson020db452016-06-29 14:37:26 -07005267 hdd_debug("Include Auth Params TLV's");
Naveen Rawat14298b92015-11-25 16:27:41 -08005268 if (nla_put_u8(skb,
5269 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED, true)) {
5270 hdd_err("nla put fail");
5271 goto nla_put_failure;
5272 }
Varun Reddy Yeturu16e8f012016-02-03 17:21:09 -08005273 auth_type = roam_info_ptr->u.pConnectedProfile->AuthType;
5274 /* if FT or CCKM connection: dont send replay counter */
5275 if (auth_type != eCSR_AUTH_TYPE_FT_RSN &&
5276 auth_type != eCSR_AUTH_TYPE_FT_RSN_PSK &&
Pragaspathi Thilagaraj96259b22019-02-15 01:08:27 +05305277 auth_type != eCSR_AUTH_TYPE_FT_SAE &&
5278 auth_type != eCSR_AUTH_TYPE_FT_SUITEB_EAP_SHA384 &&
Varun Reddy Yeturu16e8f012016-02-03 17:21:09 -08005279 auth_type != eCSR_AUTH_TYPE_CCKM_WPA &&
5280 auth_type != eCSR_AUTH_TYPE_CCKM_RSN &&
5281 nla_put(skb,
5282 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR,
5283 SIR_REPLAY_CTR_LEN,
5284 roam_info_ptr->replay_ctr)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08005285 hdd_err("non FT/non CCKM connection");
5286 hdd_err("failed to send replay counter");
Naveen Rawat14298b92015-11-25 16:27:41 -08005287 goto nla_put_failure;
5288 }
Vignesh Viswanathan62d98992017-11-30 12:30:37 +05305289 if (roam_info_ptr->kek_len > SIR_KEK_KEY_LEN_FILS ||
5290 nla_put(skb,
Naveen Rawat14298b92015-11-25 16:27:41 -08005291 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK,
Pragaspathi Thilagarajeb367282019-02-19 00:42:28 +05305292 roam_info_ptr->kck_len, roam_info_ptr->kck) ||
Naveen Rawat14298b92015-11-25 16:27:41 -08005293 nla_put(skb,
5294 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305295 roam_info_ptr->kek_len, roam_info_ptr->kek)) {
Vignesh Viswanathan62d98992017-11-30 12:30:37 +05305296 hdd_err("nla put fail, kek_len %d",
5297 roam_info_ptr->kek_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005298 goto nla_put_failure;
5299 }
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305300
sheenam monga6e49e5c2019-04-04 12:49:04 +05305301 hdd_roam_reason =
5302 hdd_get_roam_reason(roam_info_ptr->roam_reason);
5303
5304 if (nla_put_u16(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_REASON,
5305 hdd_roam_reason)) {
5306 hdd_err("roam reason send failure");
5307 goto nla_put_failure;
5308 }
5309
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305310 status = wlan_hdd_add_fils_params_roam_auth_event(skb,
5311 roam_info_ptr);
5312 if (status)
5313 goto nla_put_failure;
5314
5315 /*
5316 * Save the gtk rekey parameters in HDD STA context. They will
5317 * be used next time when host enables GTK offload and goes
5318 * into power save state.
5319 */
5320 wlan_hdd_save_gtk_offload_params(adapter, roam_info_ptr->kck,
Pragaspathi Thilagarajeb367282019-02-19 00:42:28 +05305321 roam_info_ptr->kck_len,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05305322 roam_info_ptr->kek,
5323 roam_info_ptr->kek_len,
5324 roam_info_ptr->replay_ctr,
5325 true);
5326 hdd_debug("roam_info_ptr->replay_ctr 0x%llx",
5327 *((uint64_t *)roam_info_ptr->replay_ctr));
5328
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005329 } else {
Jeff Johnson020db452016-06-29 14:37:26 -07005330 hdd_debug("No Auth Params TLV's");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005331 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED,
5332 false)) {
Jeff Johnson020db452016-06-29 14:37:26 -07005333 hdd_err("nla put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005334 goto nla_put_failure;
5335 }
5336 }
5337
Selvaraj, Sridhard1225e62017-03-17 12:56:58 +05305338 hdd_debug("Auth Status = %d Subnet Change Status = %d",
5339 roam_info_ptr->synchAuthStatus,
5340 roam_info_ptr->subnet_change_status);
Ravi Joshi277ae9b2015-11-13 11:30:43 -08005341
5342 /*
5343 * Add subnet change status if subnet has changed
5344 * 0 = unchanged
5345 * 1 = changed
5346 * 2 = unknown
5347 */
5348 if (roam_info_ptr->subnet_change_status) {
5349 if (nla_put_u8(skb,
5350 QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS,
5351 roam_info_ptr->subnet_change_status)) {
Jeff Johnson020db452016-06-29 14:37:26 -07005352 hdd_err("nla put fail");
Ravi Joshi277ae9b2015-11-13 11:30:43 -08005353 goto nla_put_failure;
5354 }
5355 }
5356
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005357 cfg80211_vendor_event(skb, GFP_KERNEL);
5358 return 0;
5359
5360nla_put_failure:
5361 kfree_skb(skb);
5362 return -EINVAL;
5363}
Varun Reddy Yeturubbbbe232016-02-29 14:01:57 -08005364#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005365
Jeff Johnson91f90ff2018-11-16 07:53:37 -08005366#define ANT_DIV_SET_PERIOD(probe_period, stay_period) \
5367 ((1 << 26) | \
5368 (((probe_period) & 0x1fff) << 13) | \
5369 ((stay_period) & 0x1fff))
5370
5371#define ANT_DIV_SET_SNR_DIFF(snr_diff) \
5372 ((1 << 27) | \
5373 ((snr_diff) & 0x1fff))
5374
5375#define ANT_DIV_SET_PROBE_DWELL_TIME(probe_dwell_time) \
5376 ((1 << 28) | \
5377 ((probe_dwell_time) & 0x1fff))
5378
5379#define ANT_DIV_SET_WEIGHT(mgmt_snr_weight, data_snr_weight, ack_snr_weight) \
5380 ((1 << 29) | \
5381 (((mgmt_snr_weight) & 0xff) << 16) | \
5382 (((data_snr_weight) & 0xff) << 8) | \
5383 ((ack_snr_weight) & 0xff))
5384
lifeng66831662017-05-19 16:01:35 +08005385#define RX_REORDER_TIMEOUT_VOICE \
5386 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VOICE
5387#define RX_REORDER_TIMEOUT_VIDEO \
5388 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_VIDEO
5389#define RX_REORDER_TIMEOUT_BESTEFFORT \
5390 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BESTEFFORT
5391#define RX_REORDER_TIMEOUT_BACKGROUND \
5392 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_REORDER_TIMEOUT_BACKGROUND
5393#define RX_BLOCKSIZE_PEER_MAC \
5394 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_PEER_MAC
5395#define RX_BLOCKSIZE_WINLIMIT \
5396 QCA_WLAN_VENDOR_ATTR_CONFIG_RX_BLOCKSIZE_WINLIMIT
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005397static const struct nla_policy
5398wlan_hdd_wifi_config_policy[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1] = {
5399
5400 [QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM] = {.type = NLA_U32 },
Sourav Mohapatra0dbdfb42019-03-19 14:31:20 +05305401 [QCA_WLAN_VENDOR_ATTR_CONFIG_IGNORE_ASSOC_DISALLOWED] = {
5402 .type = NLA_U8 },
5403 [QCA_WLAN_VENDOR_ATTR_CONFIG_DISABLE_FILS] = {.type = NLA_U8 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005404 [QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR] = {.type = NLA_U16 },
5405 [QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME] = {.type = NLA_U32 },
Jeff Johnson79f6a602017-06-15 09:48:25 -07005406 [QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT] = {.type = NLA_U32},
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +05305407 [QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND] = {.type = NLA_U8 },
Padma, Santhosh Kumara7119672016-08-16 16:05:14 +05305408 [QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION] = {.type = NLA_U8 },
5409 [QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION] = {.type = NLA_U8 },
Zhang Qiana3bcbe02016-08-12 16:20:36 +08005410 [QCA_WLAN_VENDOR_ATTR_CONFIG_NON_AGG_RETRY] = {.type = NLA_U8 },
5411 [QCA_WLAN_VENDOR_ATTR_CONFIG_AGG_RETRY] = {.type = NLA_U8 },
5412 [QCA_WLAN_VENDOR_ATTR_CONFIG_MGMT_RETRY] = {.type = NLA_U8 },
5413 [QCA_WLAN_VENDOR_ATTR_CONFIG_CTRL_RETRY] = {.type = NLA_U8 },
5414 [QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_DELAY] = {.type = NLA_U8 },
Jeff Johnson8fb9ded2018-11-15 20:44:56 -08005415 [QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_ABS_DELAY] = {
5416 .type = NLA_U32 },
Agrawal, Ashishb45599a2016-10-27 14:55:30 +05305417 [QCA_WLAN_VENDOR_ATTR_CONFIG_TX_FAIL_COUNT] = {.type = NLA_U32 },
Jeff Johnson7bf20cb2018-11-16 17:38:27 -08005418 [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_PERIOD] = {.type = NLA_U32},
5419 [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_STAY_PERIOD] = {.type = NLA_U32},
Jeff Johnson91f90ff2018-11-16 07:53:37 -08005420 [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SNR_DIFF] = {.type = NLA_U32},
Jeff Johnson77177bc2018-11-16 08:14:20 -08005421 [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_DWELL_TIME] = {
5422 .type = NLA_U32},
Jeff Johnson1350e622018-11-16 18:36:55 -08005423 [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_MGMT_SNR_WEIGHT] = {
5424 .type = NLA_U32},
5425 [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_DATA_SNR_WEIGHT] = {
5426 .type = NLA_U32},
5427 [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ACK_SNR_WEIGHT] = {
5428 .type = NLA_U32},
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305429 [QCA_WLAN_VENDOR_ATTR_CONFIG_RESTRICT_OFFCHANNEL] = {.type = NLA_U8},
lifeng66831662017-05-19 16:01:35 +08005430 [RX_REORDER_TIMEOUT_VOICE] = {.type = NLA_U32},
5431 [RX_REORDER_TIMEOUT_VIDEO] = {.type = NLA_U32},
5432 [RX_REORDER_TIMEOUT_BESTEFFORT] = {.type = NLA_U32},
5433 [RX_REORDER_TIMEOUT_BACKGROUND] = {.type = NLA_U32},
Jeff Johnson19a5a7e2017-06-15 14:51:26 -07005434 [RX_BLOCKSIZE_PEER_MAC] = {
5435 .type = NLA_UNSPEC,
5436 .len = QDF_MAC_ADDR_SIZE},
lifeng66831662017-05-19 16:01:35 +08005437 [RX_BLOCKSIZE_WINLIMIT] = {.type = NLA_U32},
Mukul Sharma6398b252017-05-01 17:58:12 +05305438 [QCA_WLAN_VENDOR_ATTR_CONFIG_LISTEN_INTERVAL] = {.type = NLA_U32 },
Poddar, Siddarth4b3f7312017-11-02 17:00:20 +05305439 [QCA_WLAN_VENDOR_ATTR_CONFIG_LRO] = {.type = NLA_U8 },
Jeff Johnson1feb8a62018-11-14 13:18:41 -08005440 [QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER] = {.type = NLA_U8 },
lifengd217d192017-05-09 19:44:16 +08005441 [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA] = {.type = NLA_U32 },
5442 [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN] = {.type = NLA_U32 },
5443 [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST] = {.type = NLA_U32 },
5444 [QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL] = {.type = NLA_U32 },
Paul Zhang99fe8842017-12-08 14:43:46 +08005445 [QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL] = {.type = NLA_U16 },
Nachiket Kukadeaaf8a712017-07-27 19:15:36 +05305446 [QCA_WLAN_VENDOR_ATTR_CONFIG_TOTAL_BEACON_MISS_COUNT] = {.type = NLA_U8},
Sandeep Puligilla24b7aa72017-10-13 18:05:14 -07005447 [QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE] = {.type = NLA_U8 },
Abhishek Singh6454ad32017-12-20 10:42:21 +05305448 [QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE] = {.type = NLA_U8},
Ashish Kumar Dhanotiya1e20bcc2018-06-15 11:28:51 +05305449 [QCA_WLAN_VENDOR_ATTR_CONFIG_GTX] = {.type = NLA_U8},
Jeff Johnsonaffc4da2018-11-16 14:10:07 -08005450 [QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY] = {.type = NLA_U32 },
5451 [QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST] = {
5452 .type = NLA_BINARY,
Srinivas Girigowdacf161402019-03-14 11:37:33 -07005453 .len = WLAN_MAX_IE_LEN + 2},
Srinivas Dasari37e37312019-06-30 23:50:24 +05305454 [QCA_WLAN_VENDOR_ATTR_DISCONNECT_IES] = {
5455 .type = NLA_BINARY,
5456 .len = SIR_MAC_MAX_ADD_IE_LENGTH + 2},
Jeff Johnsonaffc4da2018-11-16 14:10:07 -08005457
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005458};
5459
Arif Hussain1f58cbb2019-03-14 17:06:56 -07005460static const struct nla_policy qca_wlan_vendor_twt_add_dialog_policy[
5461 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1] = {
5462 [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP] = {.type = NLA_U8 },
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05305463 [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST] = {.type = NLA_FLAG },
Arif Hussain1f58cbb2019-03-14 17:06:56 -07005464 [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE] = {.type = NLA_U8 },
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05305465 [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER] = {.type = NLA_FLAG },
Arif Hussain1f58cbb2019-03-14 17:06:56 -07005466 [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE] = {.type = NLA_U8 },
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05305467 [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION] = {.type = NLA_FLAG },
Arif Hussain1f58cbb2019-03-14 17:06:56 -07005468 [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME] = {.type = NLA_U32 },
5469 [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION] = {.type = NLA_U32 },
5470 [QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA] = {
5471 .type = NLA_U32 },
5472};
5473
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08005474static const struct nla_policy
Kiran Kumar Lokereacd107d2019-01-09 15:02:11 -08005475qca_wlan_vendor_attr_he_omi_tx_policy [QCA_WLAN_VENDOR_ATTR_HE_OMI_MAX + 1] = {
5476 [QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS] = {.type = NLA_U8 },
5477 [QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW] = {.type = NLA_U8 },
5478 [QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE] = {.type = NLA_U8 },
5479 [QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS] = {.type = NLA_U8 },
Kiran Kumar Lokere49e3aff2019-02-06 17:00:48 -08005480 [QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE] = {.type = NLA_U8 },
Kiran Kumar Lokereacd107d2019-01-09 15:02:11 -08005481};
5482
5483static const struct nla_policy
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08005484wlan_hdd_wifi_test_config_policy[
5485 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX + 1] = {
5486 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE] = {
5487 .type = NLA_U8},
5488 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ] = {
5489 .type = NLA_U8},
Kiran Kumar Lokere96246e52018-01-24 16:44:35 -08005490 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS] = {
5491 .type = NLA_U8},
Kiran Kumar Lokerea9345612018-02-08 14:28:24 -08005492 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ] = {
5493 .type = NLA_U8},
Kiran Kumar Lokere5cc2f0d2018-02-08 17:10:05 -08005494 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION] = {
5495 .type = NLA_U8},
Kiran Kumar Lokere722dccd2018-02-23 13:23:52 -08005496 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE] = {
5497 .type = NLA_U8},
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08005498 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION] = {
5499 .type = NLA_U8},
5500 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID] = {
5501 .type = NLA_U8},
5502 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE] = {
Kiran Kumar Lokereeac7fe92018-07-24 16:56:01 -07005503 .type = NLA_U16},
Kiran Kumar Lokere3324f632018-03-01 21:43:21 -08005504 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK] = {
5505 .type = NLA_U8},
5506 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC] = {
5507 .type = NLA_U8},
Kiran Kumar Lokerea006a302018-03-07 20:58:13 -08005508 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF] = {
5509 .type = NLA_U8},
Kiran Kumar Lokere6c7f3fa2018-05-14 18:12:27 -07005510 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE] = {
5511 .type = NLA_U8},
Kiran Kumar Lokeref3044852018-06-27 14:14:24 -07005512 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS] = {
5513 .type = NLA_U8},
Kiran Kumar Lokeref54b8552018-07-10 00:53:38 -07005514 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR] = {
5515 .type = NLA_U8},
Kiran Kumar Lokere8d685d12018-07-23 17:17:26 -07005516 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MU_EDCA_AC] = {
5517 .type = NLA_U8},
5518 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA] = {
5519 .type = NLA_U8},
Kiran Kumar Lokeref1a96f42018-08-29 18:53:47 -07005520 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP] = {
5521 .type = NLA_U8},
Kiran Kumar Lokere94634152018-09-24 19:08:35 -07005522 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_BW] = {
5523 .type = NLA_U8},
5524 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_NSS] = {
5525 .type = NLA_U8},
5526 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG] = {
5527 .type = NLA_FLAG},
Kiran Kumar Lokereefdbd0b2018-09-25 18:53:46 -07005528 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU] = {
5529 .type = NLA_U8},
Kiran Kumar Lokereacd107d2019-01-09 15:02:11 -08005530 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP] = {
5531 .type = NLA_U8},
5532 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX] = {
5533 .type = NLA_NESTED},
Kiran Kumar Lokereee205772018-09-27 00:27:27 -07005534 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU] = {
5535 .type = NLA_U8},
Kiran Kumar Lokere921b5a52019-02-24 21:53:20 -08005536 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS]
5537 = {.type = NLA_U8},
Kiran Kumar Lokerea1c29ec2019-02-25 18:19:00 -08005538 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT] = {
5539 .type = NLA_U8},
Arif Hussain1f58cbb2019-03-14 17:06:56 -07005540 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP] = {
5541 .type = NLA_NESTED},
5542 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE] = {
5543 .type = NLA_NESTED},
5544 [QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT] = {
5545 .type = NLA_U8},
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08005546};
5547
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005548/**
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +05305549 * wlan_hdd_add_qcn_ie() - Add QCN IE to a given IE buffer
5550 * @ie_data: IE buffer
5551 * @ie_len: length of the @ie_data
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05305552 *
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +05305553 * Return: QDF_STATUS
5554 */
5555static QDF_STATUS wlan_hdd_add_qcn_ie(uint8_t *ie_data, uint16_t *ie_len)
5556{
5557 tDot11fIEQCN_IE qcn_ie;
5558 uint8_t qcn_ie_hdr[QCN_IE_HDR_LEN]
Srinivas Girigowda8e7ecab2019-05-16 11:31:19 -07005559 = {WLAN_ELEMID_VENDOR, DOT11F_IE_QCN_IE_MAX_LEN,
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +05305560 0x8C, 0xFD, 0xF0, 0x1};
5561
5562 if (((*ie_len) + QCN_IE_HDR_LEN +
5563 QCN_IE_VERSION_SUBATTR_DATA_LEN) > MAX_DEFAULT_SCAN_IE_LEN) {
5564 hdd_err("IE buffer not enough for QCN IE");
5565 return QDF_STATUS_E_FAILURE;
5566 }
5567
5568 /* Add QCN IE header */
5569 qdf_mem_copy(ie_data + (*ie_len), qcn_ie_hdr, QCN_IE_HDR_LEN);
5570 (*ie_len) += QCN_IE_HDR_LEN;
5571
5572 /* Retrieve Version sub-attribute data */
5573 populate_dot11f_qcn_ie(&qcn_ie);
5574
5575 /* Add QCN IE data[version sub attribute] */
5576 qdf_mem_copy(ie_data + (*ie_len), qcn_ie.version,
5577 (QCN_IE_VERSION_SUBATTR_LEN));
5578 (*ie_len) += (QCN_IE_VERSION_SUBATTR_LEN);
5579
5580 return QDF_STATUS_SUCCESS;
5581}
5582
5583/**
5584 * wlan_hdd_save_default_scan_ies() - API to store the default scan IEs
5585 * @hdd_ctx: HDD context
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05305586 * @adapter: Pointer to HDD adapter
5587 * @ie_data: Pointer to Scan IEs buffer
5588 * @ie_len: Length of Scan IEs
5589 *
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +05305590 * This API is used to store the default scan ies received from
5591 * supplicant. Also saves QCN IE if g_qcn_ie_support INI is enabled
5592 *
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05305593 * Return: 0 on success; error number otherwise
5594 */
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07005595static int wlan_hdd_save_default_scan_ies(struct hdd_context *hdd_ctx,
Jeff Johnsone5006672017-08-29 14:39:02 -07005596 struct hdd_adapter *adapter,
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +05305597 uint8_t *ie_data, uint16_t ie_len)
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05305598{
Jeff Johnson37588942017-08-15 16:11:41 -07005599 struct hdd_scan_info *scan_info = &adapter->scan_info;
Wu Gao93816212018-08-31 16:49:54 +08005600 bool add_qcn_ie;
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +05305601
5602 if (!scan_info)
5603 return -EINVAL;
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05305604
5605 if (scan_info->default_scan_ies) {
5606 qdf_mem_free(scan_info->default_scan_ies);
5607 scan_info->default_scan_ies = NULL;
5608 }
5609
Selvaraj, Sridhar8048dea2017-04-20 10:02:19 +05305610 scan_info->default_scan_ies_len = ie_len;
Dustin Brown1dbefe62018-09-11 16:32:03 -07005611 ucfg_mlme_get_qcn_ie_support(hdd_ctx->psoc, &add_qcn_ie);
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +05305612 if (add_qcn_ie)
Selvaraj, Sridhar8048dea2017-04-20 10:02:19 +05305613 ie_len += (QCN_IE_HDR_LEN + QCN_IE_VERSION_SUBATTR_LEN);
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +05305614
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05305615 scan_info->default_scan_ies = qdf_mem_malloc(ie_len);
Selvaraj, Sridhar8048dea2017-04-20 10:02:19 +05305616 if (!scan_info->default_scan_ies) {
5617 scan_info->default_scan_ies_len = 0;
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05305618 return -ENOMEM;
Selvaraj, Sridhar8048dea2017-04-20 10:02:19 +05305619 }
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05305620
Selvaraj, Sridhar8048dea2017-04-20 10:02:19 +05305621 qdf_mem_copy(scan_info->default_scan_ies, ie_data,
5622 scan_info->default_scan_ies_len);
Selvaraj, Sridhar021ee0a2017-04-07 16:53:31 +05305623
5624 /* Add QCN IE if g_qcn_ie_support INI is enabled */
5625 if (add_qcn_ie)
5626 wlan_hdd_add_qcn_ie(scan_info->default_scan_ies,
5627 &(scan_info->default_scan_ies_len));
5628
5629 hdd_debug("Saved default scan IE:");
5630 qdf_trace_hex_dump(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
5631 (uint8_t *) scan_info->default_scan_ies,
5632 scan_info->default_scan_ies_len);
5633
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05305634 return 0;
5635}
5636
5637/**
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305638 * wlan_hdd_handle_restrict_offchan_config() -
5639 * Handle wifi configuration attribute :
5640 * QCA_WLAN_VENDOR_ATTR_CONFIG_RESTRICT_OFFCHANNEL
5641 * @adapter: Pointer to HDD adapter
5642 * @restrict_offchan: Restrict offchannel setting done by
5643 * application
5644 *
5645 * Return: 0 on success; error number otherwise
5646 */
Jeff Johnsone5006672017-08-29 14:39:02 -07005647static int wlan_hdd_handle_restrict_offchan_config(struct hdd_adapter *adapter,
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305648 u8 restrict_offchan)
5649{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07005650 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnsonc1e62782017-11-09 09:50:17 -08005651 enum QDF_OPMODE dev_mode = adapter->device_mode;
Min Liu8c5d99e2018-09-10 17:18:44 +08005652 struct wlan_objmgr_vdev *vdev;
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305653 int ret_val = 0;
5654
5655 if (!(dev_mode == QDF_SAP_MODE || dev_mode == QDF_P2P_GO_MODE)) {
5656 hdd_err("Invalid interface type:%d", dev_mode);
5657 return -EINVAL;
5658 }
Min Liu8c5d99e2018-09-10 17:18:44 +08005659 vdev = hdd_objmgr_get_vdev(adapter);
5660 if (!vdev)
Liangwei Dongcf5a5062017-12-28 00:51:32 -05005661 return -EINVAL;
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305662 if (restrict_offchan == 1) {
5663 enum policy_mgr_con_mode pmode =
5664 policy_mgr_convert_device_mode_to_qdf_type(dev_mode);
5665 int chan;
5666
Min Liu8c5d99e2018-09-10 17:18:44 +08005667 u32 vdev_id = wlan_vdev_get_id(vdev);
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305668
Min Liu8c5d99e2018-09-10 17:18:44 +08005669 wlan_vdev_obj_lock(vdev);
5670 wlan_vdev_mlme_cap_set(vdev, WLAN_VDEV_C_RESTRICT_OFFCHAN);
5671 wlan_vdev_obj_unlock(vdev);
Dustin Brown76cd2932018-09-11 16:03:05 -07005672 chan = policy_mgr_get_channel(hdd_ctx->psoc, pmode,
Liangwei Dongcf5a5062017-12-28 00:51:32 -05005673 &vdev_id);
5674 if (!chan ||
5675 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, chan)) {
5676 hdd_err("unable to send avoid_freq");
5677 ret_val = -EINVAL;
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305678 }
Liangwei Dongcf5a5062017-12-28 00:51:32 -05005679 hdd_info("vdev %d mode %d dnbs enabled", vdev_id, dev_mode);
5680 } else if (restrict_offchan == 0) {
Min Liu8c5d99e2018-09-10 17:18:44 +08005681 wlan_vdev_obj_lock(vdev);
5682 wlan_vdev_mlme_cap_clear(vdev, WLAN_VDEV_C_RESTRICT_OFFCHAN);
5683 wlan_vdev_obj_unlock(vdev);
Liangwei Dongcf5a5062017-12-28 00:51:32 -05005684 if (wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0)) {
5685 hdd_err("unable to clear avoid_freq");
5686 ret_val = -EINVAL;
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305687 }
Liangwei Dongcf5a5062017-12-28 00:51:32 -05005688 hdd_info("vdev mode %d dnbs disabled", dev_mode);
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305689 } else {
5690 ret_val = -EINVAL;
5691 hdd_err("Invalid RESTRICT_OFFCHAN setting");
5692 }
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05305693 hdd_objmgr_put_vdev(vdev);
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305694 return ret_val;
5695}
5696
5697/**
Jeff Johnson0dd687e2018-11-16 20:11:27 -08005698 * wlan_hdd_cfg80211_wifi_set_reorder_timeout() - set reorder timeout
5699 * @adapter: Pointer to HDD adapter
lifeng66831662017-05-19 16:01:35 +08005700 * @tb: array of pointer to struct nlattr
5701 *
5702 * Return: 0 on success; error number otherwise
5703 */
Jeff Johnson34fc63a2018-06-14 10:10:02 -07005704static
Jeff Johnson0dd687e2018-11-16 20:11:27 -08005705int wlan_hdd_cfg80211_wifi_set_reorder_timeout(struct hdd_adapter *adapter,
Jeff Johnson34fc63a2018-06-14 10:10:02 -07005706 struct nlattr *tb[])
lifeng66831662017-05-19 16:01:35 +08005707{
Jeff Johnson0dd687e2018-11-16 20:11:27 -08005708 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Min Liuab6ed4f2018-01-09 13:13:57 +08005709 int ret_val = 0;
lifeng66831662017-05-19 16:01:35 +08005710 QDF_STATUS qdf_status;
5711 struct sir_set_rx_reorder_timeout_val reorder_timeout;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07005712 mac_handle_t mac_handle;
lifeng66831662017-05-19 16:01:35 +08005713
5714#define RX_TIMEOUT_VAL_MIN 10
5715#define RX_TIMEOUT_VAL_MAX 1000
5716
5717 if (tb[RX_REORDER_TIMEOUT_VOICE] ||
5718 tb[RX_REORDER_TIMEOUT_VIDEO] ||
5719 tb[RX_REORDER_TIMEOUT_BESTEFFORT] ||
5720 tb[RX_REORDER_TIMEOUT_BACKGROUND]) {
5721
5722 /* if one is specified, all must be specified */
5723 if (!tb[RX_REORDER_TIMEOUT_VOICE] ||
5724 !tb[RX_REORDER_TIMEOUT_VIDEO] ||
5725 !tb[RX_REORDER_TIMEOUT_BESTEFFORT] ||
5726 !tb[RX_REORDER_TIMEOUT_BACKGROUND]) {
5727 hdd_err("four AC timeout val are required MAC");
5728 return -EINVAL;
5729 }
5730
5731 reorder_timeout.rx_timeout_pri[0] = nla_get_u32(
5732 tb[RX_REORDER_TIMEOUT_VOICE]);
5733 reorder_timeout.rx_timeout_pri[1] = nla_get_u32(
5734 tb[RX_REORDER_TIMEOUT_VIDEO]);
5735 reorder_timeout.rx_timeout_pri[2] = nla_get_u32(
5736 tb[RX_REORDER_TIMEOUT_BESTEFFORT]);
5737 reorder_timeout.rx_timeout_pri[3] = nla_get_u32(
5738 tb[RX_REORDER_TIMEOUT_BACKGROUND]);
5739 /* timeout value is required to be in the rang 10 to 1000ms */
5740 if (reorder_timeout.rx_timeout_pri[0] >= RX_TIMEOUT_VAL_MIN &&
5741 reorder_timeout.rx_timeout_pri[0] <= RX_TIMEOUT_VAL_MAX &&
5742 reorder_timeout.rx_timeout_pri[1] >= RX_TIMEOUT_VAL_MIN &&
5743 reorder_timeout.rx_timeout_pri[1] <= RX_TIMEOUT_VAL_MAX &&
5744 reorder_timeout.rx_timeout_pri[2] >= RX_TIMEOUT_VAL_MIN &&
5745 reorder_timeout.rx_timeout_pri[2] <= RX_TIMEOUT_VAL_MAX &&
5746 reorder_timeout.rx_timeout_pri[3] >= RX_TIMEOUT_VAL_MIN &&
5747 reorder_timeout.rx_timeout_pri[3] <= RX_TIMEOUT_VAL_MAX) {
Jeff Johnson34fc63a2018-06-14 10:10:02 -07005748 mac_handle = hdd_ctx->mac_handle;
5749 qdf_status = sme_set_reorder_timeout(mac_handle,
lifeng66831662017-05-19 16:01:35 +08005750 &reorder_timeout);
5751 if (qdf_status != QDF_STATUS_SUCCESS) {
5752 hdd_err("failed to set reorder timeout err %d",
5753 qdf_status);
5754 ret_val = -EPERM;
5755 }
5756 } else {
5757 hdd_err("one of the timeout value is not in range");
5758 ret_val = -EINVAL;
5759 }
5760 }
5761
5762 return ret_val;
5763}
5764
5765/**
Jeff Johnson339ede82018-11-16 20:27:52 -08005766 * wlan_hdd_cfg80211_wifi_set_rx_blocksize() - set rx blocksize
lifeng66831662017-05-19 16:01:35 +08005767 * @adapter: hdd adapter
5768 * @tb: array of pointer to struct nlattr
5769 *
5770 * Return: 0 on success; error number otherwise
5771 */
Jeff Johnson339ede82018-11-16 20:27:52 -08005772static int wlan_hdd_cfg80211_wifi_set_rx_blocksize(struct hdd_adapter *adapter,
lifeng66831662017-05-19 16:01:35 +08005773 struct nlattr *tb[])
5774{
Jeff Johnson339ede82018-11-16 20:27:52 -08005775 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Min Liuab6ed4f2018-01-09 13:13:57 +08005776 int ret_val = 0;
lifeng66831662017-05-19 16:01:35 +08005777 uint32_t set_value;
5778 QDF_STATUS qdf_status;
5779 struct sir_peer_set_rx_blocksize rx_blocksize;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07005780 mac_handle_t mac_handle;
lifeng66831662017-05-19 16:01:35 +08005781
5782#define WINDOW_SIZE_VAL_MIN 1
5783#define WINDOW_SIZE_VAL_MAX 64
5784
5785 if (tb[RX_BLOCKSIZE_PEER_MAC] ||
5786 tb[RX_BLOCKSIZE_WINLIMIT]) {
5787
5788 /* if one is specified, both must be specified */
5789 if (!tb[RX_BLOCKSIZE_PEER_MAC] ||
5790 !tb[RX_BLOCKSIZE_WINLIMIT]) {
Dustin Brownbacc48f2018-03-14 14:48:44 -07005791 hdd_err("Both Peer MAC and windows limit required");
lifeng66831662017-05-19 16:01:35 +08005792 return -EINVAL;
5793 }
5794
5795 memcpy(&rx_blocksize.peer_macaddr,
5796 nla_data(tb[RX_BLOCKSIZE_PEER_MAC]),
5797 sizeof(rx_blocksize.peer_macaddr)),
5798
Jeff Johnsoncf07c312019-02-04 13:53:29 -08005799 rx_blocksize.vdev_id = adapter->vdev_id;
lifeng66831662017-05-19 16:01:35 +08005800 set_value = nla_get_u32(tb[RX_BLOCKSIZE_WINLIMIT]);
5801 /* maximum window size is 64 */
5802 if (set_value >= WINDOW_SIZE_VAL_MIN &&
5803 set_value <= WINDOW_SIZE_VAL_MAX) {
5804 rx_blocksize.rx_block_ack_win_limit = set_value;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07005805 mac_handle = hdd_ctx->mac_handle;
5806 qdf_status = sme_set_rx_set_blocksize(mac_handle,
lifeng66831662017-05-19 16:01:35 +08005807 &rx_blocksize);
5808 if (qdf_status != QDF_STATUS_SUCCESS) {
5809 hdd_err("failed to set aggr sizes err %d",
5810 qdf_status);
5811 ret_val = -EPERM;
5812 }
5813 } else {
5814 hdd_err("window size val is not in range");
5815 ret_val = -EINVAL;
5816 }
5817 }
5818
5819 return ret_val;
5820}
5821
Jeff Johnsonaffc4da2018-11-16 14:10:07 -08005822static int hdd_config_access_policy(struct hdd_adapter *adapter,
5823 struct nlattr *tb[])
5824{
5825 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5826 struct nlattr *policy_attr =
5827 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY];
5828 struct nlattr *ielist_attr =
5829 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ACCESS_POLICY_IE_LIST];
5830 uint32_t access_policy;
Srinivas Girigowdacf161402019-03-14 11:37:33 -07005831 uint8_t ie[WLAN_MAX_IE_LEN + 2];
Jeff Johnsonaffc4da2018-11-16 14:10:07 -08005832 QDF_STATUS status;
5833
5834 /* nothing to do if neither attribute is present */
5835 if (!ielist_attr && !policy_attr)
5836 return 0;
5837
5838 /* if one is present, both must be present */
5839 if (!ielist_attr || !policy_attr) {
5840 hdd_err("Missing attribute for %s",
5841 policy_attr ?
5842 "ACCESS_POLICY_IE_LIST" : "ACCESS_POLICY");
5843 return -EINVAL;
5844 }
5845
5846 /* validate the access policy */
5847 access_policy = nla_get_u32(policy_attr);
5848 switch (access_policy) {
5849 case QCA_ACCESS_POLICY_ACCEPT_UNLESS_LISTED:
5850 case QCA_ACCESS_POLICY_DENY_UNLESS_LISTED:
5851 /* valid */
5852 break;
5853 default:
5854 hdd_err("Invalid value. access_policy %u", access_policy);
5855 return -EINVAL;
5856 }
5857
5858 /*
5859 * ie length is validated by the nla_policy. need to make a
Srinivas Girigowdacf161402019-03-14 11:37:33 -07005860 * copy since SME will always read WLAN_MAX_IE_LEN+2 bytes
Jeff Johnsonaffc4da2018-11-16 14:10:07 -08005861 */
5862 nla_memcpy(ie, ielist_attr, sizeof(ie));
5863
5864 hdd_debug("calling sme_update_access_policy_vendor_ie");
5865 status = sme_update_access_policy_vendor_ie(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08005866 adapter->vdev_id,
Jeff Johnsonaffc4da2018-11-16 14:10:07 -08005867 ie, access_policy);
5868 if (QDF_IS_STATUS_ERROR(status))
5869 hdd_err("Failed to set vendor ie and access policy, %d",
5870 status);
5871
5872 return qdf_status_to_os_return(status);
5873}
5874
Jeff Johnson0fbb43b2018-11-16 15:38:56 -08005875static int hdd_config_mpdu_aggregation(struct hdd_adapter *adapter,
5876 struct nlattr *tb[])
5877{
5878 struct nlattr *tx_attr =
5879 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_TX_MPDU_AGGREGATION];
5880 struct nlattr *rx_attr =
5881 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_RX_MPDU_AGGREGATION];
5882 uint8_t tx_size, rx_size;
5883 struct sir_set_tx_rx_aggregation_size request;
5884 QDF_STATUS status;
5885
5886 /* nothing to do if neither attribute is present */
5887 if (!tx_attr && !rx_attr)
5888 return 0;
5889
5890 /* if one is present, both must be present */
5891 if (!tx_attr || !rx_attr) {
5892 hdd_err("Missing attribute for %s",
5893 tx_attr ? "RX" : "TX");
5894 return -EINVAL;
5895 }
5896
5897 tx_size = nla_get_u8(tx_attr);
5898 rx_size = nla_get_u8(rx_attr);
5899 if (!cfg_in_range(CFG_TX_AGGREGATION_SIZE, tx_size) ||
5900 !cfg_in_range(CFG_RX_AGGREGATION_SIZE, rx_size)) {
5901 hdd_err("TX %d RX %d MPDU aggr size not in range",
5902 tx_size, rx_size);
5903
5904 return -EINVAL;
5905 }
5906
5907 qdf_mem_zero(&request, sizeof(request));
5908 request.tx_aggregation_size = tx_size;
5909 request.rx_aggregation_size = rx_size;
Jeff Johnsoncf07c312019-02-04 13:53:29 -08005910 request.vdev_id = adapter->vdev_id;
Jeff Johnson0fbb43b2018-11-16 15:38:56 -08005911 request.aggr_type = WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU;
5912
5913 status = wma_set_tx_rx_aggregation_size(&request);
5914 if (QDF_IS_STATUS_ERROR(status))
5915 hdd_err("failed to set aggr sizes err %d", status);
5916
5917 return qdf_status_to_os_return(status);
5918}
5919
Jeff Johnson7bf20cb2018-11-16 17:38:27 -08005920static int hdd_config_ant_div_period(struct hdd_adapter *adapter,
5921 struct nlattr *tb[])
5922{
5923 struct nlattr *probe_attr =
5924 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_PERIOD];
5925 struct nlattr *stay_attr =
5926 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_STAY_PERIOD];
5927 uint32_t probe_period, stay_period, ant_div_usrcfg;
5928 int errno;
5929
5930 /* nothing to do if neither attribute is present */
5931 if (!probe_attr && !stay_attr)
5932 return 0;
5933
5934 /* if one is present, both must be present */
5935 if (!probe_attr || !stay_attr) {
5936 hdd_err("Missing attribute for %s",
5937 probe_attr ? "STAY" : "PROBE");
5938 return -EINVAL;
5939 }
5940
5941 probe_period = nla_get_u32(probe_attr);
5942 stay_period = nla_get_u32(stay_attr);
5943 ant_div_usrcfg = ANT_DIV_SET_PERIOD(probe_period, stay_period);
5944 hdd_debug("ant div set period: %x", ant_div_usrcfg);
Jeff Johnsoncf07c312019-02-04 13:53:29 -08005945 errno = wma_cli_set_command(adapter->vdev_id,
Jeff Johnson7bf20cb2018-11-16 17:38:27 -08005946 WMI_PDEV_PARAM_ANT_DIV_USRCFG,
5947 ant_div_usrcfg, PDEV_CMD);
5948 if (errno)
5949 hdd_err("Failed to set ant div period, %d", errno);
5950
5951 return errno;
5952}
5953
Jeff Johnson1350e622018-11-16 18:36:55 -08005954static int hdd_config_ant_div_snr_weight(struct hdd_adapter *adapter,
5955 struct nlattr *tb[])
5956{
5957 struct nlattr *mgmt_attr =
5958 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_MGMT_SNR_WEIGHT];
5959 struct nlattr *data_attr =
5960 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_DATA_SNR_WEIGHT];
5961 struct nlattr *ack_attr =
5962 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ACK_SNR_WEIGHT];
5963 uint32_t mgmt_snr, data_snr, ack_snr, ant_div_usrcfg;
5964 int errno;
5965
5966 /* nothing to do if none of the attributes are present */
5967 if (!mgmt_attr && !data_attr && !ack_attr)
5968 return 0;
5969
5970 /* if one is present, all must be present */
5971 if (!mgmt_attr || !data_attr || !ack_attr) {
5972 hdd_err("Missing attribute");
5973 return -EINVAL;
5974 }
5975
5976 mgmt_snr = nla_get_u32(mgmt_attr);
5977 data_snr = nla_get_u32(data_attr);
5978 ack_snr = nla_get_u32(ack_attr);
5979 ant_div_usrcfg = ANT_DIV_SET_WEIGHT(mgmt_snr, data_snr, ack_snr);
5980 hdd_debug("ant div set weight: %x", ant_div_usrcfg);
Jeff Johnsoncf07c312019-02-04 13:53:29 -08005981 errno = wma_cli_set_command(adapter->vdev_id,
Jeff Johnson1350e622018-11-16 18:36:55 -08005982 WMI_PDEV_PARAM_ANT_DIV_USRCFG,
5983 ant_div_usrcfg, PDEV_CMD);
5984 if (errno)
5985 hdd_err("Failed to set ant div weight, %d", errno);
5986
5987 return errno;
5988}
5989
Jeff Johnson7f4fd702018-11-14 11:19:52 -08005990static int hdd_config_fine_time_measurement(struct hdd_adapter *adapter,
5991 const struct nlattr *attr)
5992{
5993 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5994 uint32_t user_capability;
5995 uint32_t target_capability;
5996 uint32_t final_capability;
5997 QDF_STATUS status;
5998
5999 user_capability = nla_get_u32(attr);
6000 target_capability = hdd_ctx->fine_time_meas_cap_target;
6001 final_capability = user_capability & target_capability;
6002
6003 status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc,
6004 final_capability);
6005 if (QDF_IS_STATUS_ERROR(status)) {
6006 hdd_err("Unable to set value, status %d", status);
6007 return -EINVAL;
6008 }
6009
6010 sme_update_fine_time_measurement_capab(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006011 adapter->vdev_id,
Jeff Johnson7f4fd702018-11-14 11:19:52 -08006012 final_capability);
6013 ucfg_wifi_pos_set_ftm_cap(hdd_ctx->psoc, final_capability);
6014
6015 hdd_debug("user: 0x%x, target: 0x%x, final: 0x%x",
6016 user_capability, target_capability, final_capability);
6017
6018 return 0;
6019}
6020
Jeff Johnsonbcaeafb2018-11-14 12:14:24 -08006021static int hdd_config_modulated_dtim(struct hdd_adapter *adapter,
6022 const struct nlattr *attr)
6023{
6024 struct wlan_objmgr_vdev *vdev;
6025 uint32_t modulated_dtim;
6026 QDF_STATUS status;
6027
6028 modulated_dtim = nla_get_u32(attr);
6029
6030 vdev = hdd_objmgr_get_vdev(adapter);
6031 if (!vdev)
6032 return -EINVAL;
6033
6034 status = ucfg_pmo_config_modulated_dtim(vdev, modulated_dtim);
6035
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05306036 hdd_objmgr_put_vdev(vdev);
Jeff Johnsonbcaeafb2018-11-14 12:14:24 -08006037
6038 return qdf_status_to_os_return(status);
6039}
6040
Jeff Johnson6db91622018-11-14 12:33:28 -08006041static int hdd_config_listen_interval(struct hdd_adapter *adapter,
6042 const struct nlattr *attr)
6043{
6044 struct wlan_objmgr_vdev *vdev;
6045 uint32_t listen_interval;
6046 QDF_STATUS status;
6047
6048 listen_interval = nla_get_u32(attr);
6049 if (listen_interval > cfg_max(CFG_PMO_ENABLE_DYNAMIC_DTIM)) {
6050 hdd_err_rl("Invalid value for listen interval - %d",
6051 listen_interval);
6052 return -EINVAL;
6053 }
6054
6055 vdev = hdd_objmgr_get_vdev(adapter);
6056 if (!vdev)
6057 return -EINVAL;
6058
6059 status = ucfg_pmo_config_listen_interval(vdev, listen_interval);
6060
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05306061 hdd_objmgr_put_vdev(vdev);
Jeff Johnson6db91622018-11-14 12:33:28 -08006062
6063 return qdf_status_to_os_return(status);
6064}
6065
Jeff Johnson9381d032018-11-14 12:42:22 -08006066static int hdd_config_lro(struct hdd_adapter *adapter,
6067 const struct nlattr *attr)
6068{
6069 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6070 uint8_t enable_flag;
6071
6072 enable_flag = nla_get_u8(attr);
6073
6074 return hdd_lro_set_reset(hdd_ctx, adapter, enable_flag);
6075}
6076
Jeff Johnson3d4f64c2018-11-14 13:13:04 -08006077static int hdd_config_scan_enable(struct hdd_adapter *adapter,
6078 const struct nlattr *attr)
6079{
6080 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6081 uint8_t enable_flag;
6082
6083 enable_flag = nla_get_u8(attr);
6084 if (enable_flag)
6085 ucfg_scan_psoc_set_enable(hdd_ctx->psoc,
6086 REASON_USER_SPACE);
6087 else
6088 ucfg_scan_psoc_set_disable(hdd_ctx->psoc,
6089 REASON_USER_SPACE);
6090
6091 return 0;
6092}
6093
Jeff Johnson1feb8a62018-11-14 13:18:41 -08006094static int hdd_config_qpower(struct hdd_adapter *adapter,
6095 const struct nlattr *attr)
6096{
6097 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6098 uint8_t qpower;
6099
6100 qpower = nla_get_u8(attr);
6101
6102 return hdd_set_qpower_config(hdd_ctx, adapter, qpower);
6103}
6104
Jeff Johnsonf15ede02018-11-14 13:27:13 -08006105static int hdd_config_stats_avg_factor(struct hdd_adapter *adapter,
6106 const struct nlattr *attr)
6107{
6108 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6109 uint16_t stats_avg_factor;
6110 QDF_STATUS status;
6111
6112 stats_avg_factor = nla_get_u16(attr);
6113 status = sme_configure_stats_avg_factor(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006114 adapter->vdev_id,
Jeff Johnsonf15ede02018-11-14 13:27:13 -08006115 stats_avg_factor);
6116
6117 return qdf_status_to_os_return(status);
6118}
6119
Jeff Johnsonf3827502018-11-14 14:00:58 -08006120static int hdd_config_non_agg_retry(struct hdd_adapter *adapter,
6121 const struct nlattr *attr)
6122{
6123 uint8_t retry;
6124 int param_id;
6125
6126 retry = nla_get_u8(attr);
6127 retry = retry > CFG_NON_AGG_RETRY_MAX ?
6128 CFG_NON_AGG_RETRY_MAX : retry;
6129 param_id = WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH;
6130
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006131 return wma_cli_set_command(adapter->vdev_id, param_id,
Jeff Johnsonf3827502018-11-14 14:00:58 -08006132 retry, PDEV_CMD);
6133}
6134
Jeff Johnsonb9021002018-11-15 15:51:36 -08006135static int hdd_config_agg_retry(struct hdd_adapter *adapter,
6136 const struct nlattr *attr)
6137{
6138 uint8_t retry;
6139 int param_id;
6140
6141 retry = nla_get_u8(attr);
6142 retry = retry > CFG_AGG_RETRY_MAX ?
6143 CFG_AGG_RETRY_MAX : retry;
6144
6145 /* Value less than CFG_AGG_RETRY_MIN has side effect to t-put */
6146 retry = ((retry > 0) && (retry < CFG_AGG_RETRY_MIN)) ?
6147 CFG_AGG_RETRY_MIN : retry;
6148 param_id = WMI_PDEV_PARAM_AGG_SW_RETRY_TH;
6149
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006150 return wma_cli_set_command(adapter->vdev_id, param_id,
Jeff Johnsonb9021002018-11-15 15:51:36 -08006151 retry, PDEV_CMD);
6152}
6153
Jeff Johnson0e8259c2018-11-15 19:44:57 -08006154static int hdd_config_mgmt_retry(struct hdd_adapter *adapter,
6155 const struct nlattr *attr)
6156{
6157 uint8_t retry;
6158 int param_id;
6159
6160 retry = nla_get_u8(attr);
6161 retry = retry > CFG_MGMT_RETRY_MAX ?
6162 CFG_MGMT_RETRY_MAX : retry;
6163 param_id = WMI_PDEV_PARAM_MGMT_RETRY_LIMIT;
6164
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006165 return wma_cli_set_command(adapter->vdev_id, param_id,
Jeff Johnson0e8259c2018-11-15 19:44:57 -08006166 retry, PDEV_CMD);
6167}
6168
Jeff Johnson6b48a2f2018-11-15 19:48:47 -08006169static int hdd_config_ctrl_retry(struct hdd_adapter *adapter,
6170 const struct nlattr *attr)
6171{
6172 uint8_t retry;
6173 int param_id;
6174
6175 retry = nla_get_u8(attr);
6176 retry = retry > CFG_CTRL_RETRY_MAX ?
6177 CFG_CTRL_RETRY_MAX : retry;
6178 param_id = WMI_PDEV_PARAM_CTRL_RETRY_LIMIT;
6179
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006180 return wma_cli_set_command(adapter->vdev_id, param_id,
Jeff Johnson6b48a2f2018-11-15 19:48:47 -08006181 retry, PDEV_CMD);
6182}
6183
Jeff Johnson98214742018-11-15 19:56:37 -08006184static int hdd_config_propagation_delay(struct hdd_adapter *adapter,
6185 const struct nlattr *attr)
6186{
6187 uint8_t delay;
6188 uint32_t abs_delay;
6189 int param_id;
6190
6191 delay = nla_get_u8(attr);
6192 delay = delay > CFG_PROPAGATION_DELAY_MAX ?
6193 CFG_PROPAGATION_DELAY_MAX : delay;
6194 abs_delay = delay + CFG_PROPAGATION_DELAY_BASE;
6195 param_id = WMI_PDEV_PARAM_PROPAGATION_DELAY;
6196
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006197 return wma_cli_set_command(adapter->vdev_id, param_id,
Jeff Johnson98214742018-11-15 19:56:37 -08006198 abs_delay, PDEV_CMD);
6199}
6200
Jeff Johnson8fb9ded2018-11-15 20:44:56 -08006201static int hdd_config_propagation_abs_delay(struct hdd_adapter *adapter,
6202 const struct nlattr *attr)
6203{
6204 uint32_t abs_delay;
6205 int param_id;
6206
6207 abs_delay = nla_get_u32(attr);
6208 param_id = WMI_PDEV_PARAM_PROPAGATION_DELAY;
6209
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006210 return wma_cli_set_command(adapter->vdev_id, param_id,
Jeff Johnson8fb9ded2018-11-15 20:44:56 -08006211 abs_delay, PDEV_CMD);
6212}
6213
Jeff Johnson7c5e6dc2018-11-15 21:20:18 -08006214static int hdd_config_tx_fail_count(struct hdd_adapter *adapter,
6215 const struct nlattr *attr)
6216{
6217 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6218 uint32_t tx_fail_count;
6219 QDF_STATUS status;
6220
6221 tx_fail_count = nla_get_u32(attr);
6222 if (!tx_fail_count)
6223 return 0;
6224
6225 status = sme_update_tx_fail_cnt_threshold(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006226 adapter->vdev_id,
Jeff Johnson7c5e6dc2018-11-15 21:20:18 -08006227 tx_fail_count);
6228 if (QDF_IS_STATUS_ERROR(status))
6229 hdd_err("sme_update_tx_fail_cnt_threshold (err=%d)",
6230 status);
6231
6232 return qdf_status_to_os_return(status);
6233}
6234
Jeff Johnson7766fd22018-11-15 21:52:37 -08006235static int hdd_config_channel_avoidance_ind(struct hdd_adapter *adapter,
6236 const struct nlattr *attr)
6237{
6238 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6239 uint8_t set_value;
6240
6241 set_value = nla_get_u8(attr);
6242 hdd_debug("set_value: %d", set_value);
6243
6244 return hdd_enable_disable_ca_event(hdd_ctx, set_value);
6245}
6246
Jeff Johnson47e2e842018-11-14 13:49:43 -08006247static int hdd_config_guard_time(struct hdd_adapter *adapter,
6248 const struct nlattr *attr)
6249{
6250 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6251 uint32_t guard_time;
6252 QDF_STATUS status;
6253
6254 guard_time = nla_get_u32(attr);
6255 status = sme_configure_guard_time(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006256 adapter->vdev_id,
Jeff Johnson47e2e842018-11-14 13:49:43 -08006257 guard_time);
6258
6259 return qdf_status_to_os_return(status);
6260}
6261
Jeff Johnson3b2abe92017-12-15 09:03:47 -08006262static int hdd_config_scan_default_ies(struct hdd_adapter *adapter,
6263 const struct nlattr *attr)
6264{
6265 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6266 uint8_t *scan_ie;
6267 uint16_t scan_ie_len;
6268 QDF_STATUS status;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07006269 mac_handle_t mac_handle;
Jeff Johnson3b2abe92017-12-15 09:03:47 -08006270
Jeff Johnson3b2abe92017-12-15 09:03:47 -08006271 scan_ie_len = nla_len(attr);
6272 hdd_debug("IE len %d session %d device mode %d",
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006273 scan_ie_len, adapter->vdev_id, adapter->device_mode);
Jeff Johnson3b2abe92017-12-15 09:03:47 -08006274
6275 if (!scan_ie_len) {
6276 hdd_err("zero-length IE prohibited");
6277 return -EINVAL;
6278 }
6279
6280 if (scan_ie_len > MAX_DEFAULT_SCAN_IE_LEN) {
6281 hdd_err("IE length %d exceeds max of %d",
6282 scan_ie_len, MAX_DEFAULT_SCAN_IE_LEN);
6283 return -EINVAL;
6284 }
6285
6286 scan_ie = nla_data(attr);
Jeff Johnson4933c3a2018-01-10 19:33:33 -08006287 if (!wlan_is_ie_valid(scan_ie, scan_ie_len)) {
Jeff Johnson3b2abe92017-12-15 09:03:47 -08006288 hdd_err("Invalid default scan IEs");
6289 return -EINVAL;
6290 }
6291
6292 if (wlan_hdd_save_default_scan_ies(hdd_ctx, adapter,
6293 scan_ie, scan_ie_len))
6294 hdd_err("Failed to save default scan IEs");
6295
6296 if (adapter->device_mode == QDF_STA_MODE) {
Jeff Johnson34fc63a2018-06-14 10:10:02 -07006297 mac_handle = hdd_ctx->mac_handle;
6298 status = sme_set_default_scan_ie(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006299 adapter->vdev_id, scan_ie,
Jeff Johnson3b2abe92017-12-15 09:03:47 -08006300 scan_ie_len);
6301 if (QDF_STATUS_SUCCESS != status) {
6302 hdd_err("failed to set default scan IEs in sme: %d",
6303 status);
6304 return -EPERM;
6305 }
6306 }
6307
6308 return 0;
6309}
6310
Jeff Johnsonf9871e42018-11-15 22:24:06 -08006311static int hdd_config_ant_div_ena(struct hdd_adapter *adapter,
6312 const struct nlattr *attr)
6313{
6314 uint32_t antdiv_enable;
6315 int errno;
6316
6317 antdiv_enable = nla_get_u32(attr);
6318 hdd_debug("antdiv_enable: %d", antdiv_enable);
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006319 errno = wma_cli_set_command(adapter->vdev_id,
Jeff Johnsonf9871e42018-11-15 22:24:06 -08006320 WMI_PDEV_PARAM_ENA_ANT_DIV,
6321 antdiv_enable, PDEV_CMD);
6322 if (errno)
6323 hdd_err("Failed to set antdiv_enable, %d", errno);
6324
6325 return errno;
6326}
6327
Jeff Johnson91f90ff2018-11-16 07:53:37 -08006328static int hdd_config_ant_div_snr_diff(struct hdd_adapter *adapter,
6329 const struct nlattr *attr)
6330{
6331 uint32_t ant_div_snr_diff;
6332 uint32_t ant_div_usrcfg;
6333 int errno;
6334
6335 ant_div_snr_diff = nla_get_u32(attr);
6336 hdd_debug("snr diff: %x", ant_div_snr_diff);
6337
6338 ant_div_usrcfg = ANT_DIV_SET_SNR_DIFF(ant_div_snr_diff);
6339 hdd_debug("usrcfg: %x", ant_div_usrcfg);
6340
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006341 errno = wma_cli_set_command(adapter->vdev_id,
Jeff Johnson91f90ff2018-11-16 07:53:37 -08006342 WMI_PDEV_PARAM_ANT_DIV_USRCFG,
6343 ant_div_usrcfg, PDEV_CMD);
6344 if (errno)
6345 hdd_err("Failed to set snr diff, %d", errno);
6346
6347 return errno;
6348}
6349
Jeff Johnson77177bc2018-11-16 08:14:20 -08006350static int hdd_config_ant_div_probe_dwell_time(struct hdd_adapter *adapter,
6351 const struct nlattr *attr)
6352{
6353 uint32_t dwell_time;
6354 uint32_t ant_div_usrcfg;
6355 int errno;
6356
6357 dwell_time = nla_get_u32(attr);
6358 hdd_debug("dwell time: %x", dwell_time);
6359
6360 ant_div_usrcfg = ANT_DIV_SET_PROBE_DWELL_TIME(dwell_time);
6361 hdd_debug("usrcfg: %x", ant_div_usrcfg);
6362
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006363 errno = wma_cli_set_command(adapter->vdev_id,
Jeff Johnson77177bc2018-11-16 08:14:20 -08006364 WMI_PDEV_PARAM_ANT_DIV_USRCFG,
6365 ant_div_usrcfg, PDEV_CMD);
6366 if (errno)
6367 hdd_err("Failed to set probe dwell time, %d", errno);
6368
6369 return errno;
6370}
6371
Jeff Johnsonaa172222018-11-16 09:16:11 -08006372static int hdd_config_ant_div_chain(struct hdd_adapter *adapter,
6373 const struct nlattr *attr)
6374{
6375 uint32_t antdiv_chain;
6376 int errno;
6377
6378 antdiv_chain = nla_get_u32(attr);
6379 hdd_debug("antdiv_chain: %d", antdiv_chain);
6380
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006381 errno = wma_cli_set_command(adapter->vdev_id,
Jeff Johnsonaa172222018-11-16 09:16:11 -08006382 WMI_PDEV_PARAM_FORCE_CHAIN_ANT,
6383 antdiv_chain, PDEV_CMD);
6384 if (errno)
6385 hdd_err("Failed to set chain, %d", errno);
6386
6387 return errno;
6388}
6389
Jeff Johnsonef427ad2018-11-16 09:22:17 -08006390static int hdd_config_ant_div_selftest(struct hdd_adapter *adapter,
6391 const struct nlattr *attr)
6392{
6393 uint32_t antdiv_selftest;
6394 int errno;
6395
6396 antdiv_selftest = nla_get_u32(attr);
6397 hdd_debug("antdiv_selftest: %d", antdiv_selftest);
6398
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006399 errno = wma_cli_set_command(adapter->vdev_id,
Jeff Johnsonef427ad2018-11-16 09:22:17 -08006400 WMI_PDEV_PARAM_ANT_DIV_SELFTEST,
6401 antdiv_selftest, PDEV_CMD);
6402 if (errno)
6403 hdd_err("Failed to set selftest, %d", errno);
6404
6405 return errno;
6406}
6407
Jeff Johnsonae21be82018-11-16 09:43:53 -08006408static int hdd_config_ant_div_selftest_intvl(struct hdd_adapter *adapter,
6409 const struct nlattr *attr)
6410{
6411 uint32_t antdiv_selftest_intvl;
6412 int errno;
6413
6414 antdiv_selftest_intvl = nla_get_u32(attr);
6415 hdd_debug("antdiv_selftest_intvl: %d", antdiv_selftest_intvl);
6416
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006417 errno = wma_cli_set_command(adapter->vdev_id,
Jeff Johnsonae21be82018-11-16 09:43:53 -08006418 WMI_PDEV_PARAM_ANT_DIV_SELFTEST_INTVL,
6419 antdiv_selftest_intvl, PDEV_CMD);
6420 if (errno)
6421 hdd_err("Failed to set selftest interval, %d", errno);
6422
6423 return errno;
6424}
6425
Jeff Johnson3a25de82018-11-16 07:26:46 -08006426static int hdd_config_ignore_assoc_disallowed(struct hdd_adapter *adapter,
6427 const struct nlattr *attr)
6428{
6429 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6430 uint8_t ignore_assoc_disallowed;
6431
6432 ignore_assoc_disallowed = nla_get_u8(attr);
6433 hdd_debug("%u", ignore_assoc_disallowed);
6434 if ((ignore_assoc_disallowed < QCA_IGNORE_ASSOC_DISALLOWED_DISABLE) ||
6435 (ignore_assoc_disallowed > QCA_IGNORE_ASSOC_DISALLOWED_ENABLE))
6436 return -EINVAL;
6437
6438 sme_update_session_param(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006439 adapter->vdev_id,
Jeff Johnson3a25de82018-11-16 07:26:46 -08006440 SIR_PARAM_IGNORE_ASSOC_DISALLOWED,
6441 ignore_assoc_disallowed);
6442
6443 return 0;
6444}
6445
Jeff Johnson72dc91e2018-11-16 08:46:12 -08006446static int hdd_config_restrict_offchannel(struct hdd_adapter *adapter,
6447 const struct nlattr *attr)
6448{
6449 uint8_t restrict_offchan;
6450
6451 restrict_offchan = nla_get_u8(attr);
6452 hdd_debug("%u", restrict_offchan);
6453
6454 if (restrict_offchan > 1) {
6455 hdd_err("Invalid value %u", restrict_offchan);
6456 return -EINVAL;
6457 }
6458
6459 return wlan_hdd_handle_restrict_offchan_config(adapter,
6460 restrict_offchan);
6461}
6462
Jeff Johnson320feeb2018-11-16 10:14:24 -08006463static int hdd_config_total_beacon_miss_count(struct hdd_adapter *adapter,
6464 const struct nlattr *attr)
6465{
6466 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6467 uint8_t first_miss_count;
6468 uint8_t final_miss_count;
6469 uint8_t total_miss_count;
6470 QDF_STATUS status;
6471
6472 total_miss_count = nla_get_u8(attr);
6473 ucfg_mlme_get_roam_bmiss_first_bcnt(hdd_ctx->psoc,
6474 &first_miss_count);
6475 if (total_miss_count <= first_miss_count) {
6476 hdd_err("Total %u needs to exceed first %u",
6477 total_miss_count, first_miss_count);
6478 return -EINVAL;
6479 }
6480
6481 final_miss_count = total_miss_count - first_miss_count;
6482
6483 hdd_debug("First count %u, final count %u",
6484 first_miss_count, final_miss_count);
6485
6486 /*****
Jeff Johnson55d2ab42019-03-06 11:43:49 -08006487 * TODO: research why is 0 being passed for vdev id???
Jeff Johnson320feeb2018-11-16 10:14:24 -08006488 */
6489 status = sme_set_roam_bmiss_final_bcnt(hdd_ctx->mac_handle,
6490 0,
6491 final_miss_count);
6492 if (QDF_IS_STATUS_ERROR(status)) {
6493 hdd_err("Failed to set final count, status %u", status);
6494 return qdf_status_to_os_return(status);
6495 }
6496
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006497 status = sme_set_bmiss_bcnt(adapter->vdev_id,
Jeff Johnson320feeb2018-11-16 10:14:24 -08006498 first_miss_count,
6499 final_miss_count);
6500 if (QDF_IS_STATUS_ERROR(status))
6501 hdd_err("Failed to set count, status %u", status);
6502
6503 return qdf_status_to_os_return(status);
6504}
6505
Jeff Johnson2502ddd2018-11-16 10:59:30 -08006506static int hdd_config_latency_level(struct hdd_adapter *adapter,
6507 const struct nlattr *attr)
6508{
6509 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6510 uint16_t latency_level;
6511 QDF_STATUS status;
6512
6513 latency_level = nla_get_u16(attr);
6514 switch (latency_level) {
6515 case QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_NORMAL:
6516 case QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_MODERATE:
6517 case QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_LOW:
6518 case QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL_ULTRALOW:
6519 /* valid values */
6520 break;
6521 default:
6522 hdd_err("Invalid value %u", latency_level);
6523 return -EINVAL;
6524 }
6525
6526 /* Map the latency value to the level which fw expected
6527 * 0 - normal, 1 - moderate, 2 - low, 3 - ultralow
6528 */
6529 latency_level = latency_level - 1;
6530 status = sme_set_wlm_latency_level(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006531 adapter->vdev_id,
Jeff Johnson2502ddd2018-11-16 10:59:30 -08006532 latency_level);
6533 if (QDF_IS_STATUS_ERROR(status))
6534 hdd_err("set latency level failed, %u", status);
6535
6536 return qdf_status_to_os_return(status);
6537}
6538
Jeff Johnson0a315912018-11-16 11:18:21 -08006539static int hdd_config_disable_fils(struct hdd_adapter *adapter,
6540 const struct nlattr *attr)
6541{
6542 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6543 uint8_t disable_fils;
6544 bool enabled;
6545 QDF_STATUS status;
6546
6547 /* ignore unless in STA mode */
6548 if (adapter->device_mode != QDF_STA_MODE)
6549 return 0;
6550
6551 disable_fils = nla_get_u8(attr);
6552 hdd_debug("%u", disable_fils);
6553
6554 enabled = !disable_fils;
6555 status = ucfg_mlme_set_fils_enabled_info(hdd_ctx->psoc, enabled);
6556 if (QDF_IS_STATUS_ERROR(status))
6557 hdd_err("could not set fils enabled info, %d", status);
6558
6559 status = ucfg_mlme_set_enable_bcast_probe_rsp(hdd_ctx->psoc, enabled);
6560 if (QDF_IS_STATUS_ERROR(status))
6561 hdd_err("could not set enable bcast probe resp info, %d",
6562 status);
6563
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006564 status = wma_cli_set_command(adapter->vdev_id,
Jeff Johnson0a315912018-11-16 11:18:21 -08006565 WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE,
6566 !disable_fils, VDEV_CMD);
6567 if (QDF_IS_STATUS_ERROR(status))
6568 hdd_err("failed to set enable bcast probe resp, %d",
6569 status);
6570
6571 return qdf_status_to_os_return(status);
6572}
6573
Jeff Johnson0bdbb962018-11-16 11:42:10 -08006574static int hdd_config_rsn_ie(struct hdd_adapter *adapter,
6575 const struct nlattr *attr)
6576{
6577 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6578 bool override_enabled;
6579 uint8_t force_rsne_override;
6580
6581 /* ignore unless support explicitly enabled */
6582 ucfg_mlme_get_force_rsne_override(hdd_ctx->psoc, &override_enabled);
6583 if (!override_enabled)
6584 return 0;
6585
6586 force_rsne_override = nla_get_u8(attr);
6587 if (force_rsne_override > 1) {
6588 hdd_err("Invalid value %d", force_rsne_override);
6589 return -EINVAL;
6590 }
6591
6592 hdd_ctx->force_rsne_override = force_rsne_override;
6593 hdd_debug("force_rsne_override - %d", force_rsne_override);
6594
6595 return 0;
6596}
6597
Jeff Johnson7acca0d2018-11-16 11:53:18 -08006598static int hdd_config_gtx(struct hdd_adapter *adapter,
6599 const struct nlattr *attr)
6600{
6601 uint8_t config_gtx;
6602 int errno;
6603
6604 config_gtx = nla_get_u8(attr);
6605 if (config_gtx > 1) {
6606 hdd_err_rl("Invalid config_gtx value %d", config_gtx);
6607 return -EINVAL;
6608 }
6609
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006610 errno = sme_cli_set_command(adapter->vdev_id,
Jeff Johnson7acca0d2018-11-16 11:53:18 -08006611 WMI_VDEV_PARAM_GTX_ENABLE,
6612 config_gtx, VDEV_CMD);
6613 if (errno)
6614 hdd_err("Failed to set GTX, %d", errno);
6615
6616 return errno;
6617}
6618
lifeng66831662017-05-19 16:01:35 +08006619/**
Srinivas Dasari37e37312019-06-30 23:50:24 +05306620 * hdd_config_disconnect_ies() - Configure disconnect IEs
6621 * @adapter: Pointer to HDD adapter
6622 * @attr: array of pointer to struct nlattr
6623 *
6624 * Return: 0 on success; error number otherwise
6625 */
6626static int hdd_config_disconnect_ies(struct hdd_adapter *adapter,
6627 const struct nlattr *attr)
6628{
6629 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6630 QDF_STATUS status;
6631
6632 hdd_debug("IE len %u session %u device mode %u",
6633 nla_len(attr), adapter->vdev_id, adapter->device_mode);
6634 if (!nla_len(attr) ||
6635 nla_len(attr) > SIR_MAC_MAX_ADD_IE_LENGTH + 2 ||
6636 !wlan_is_ie_valid(nla_data(attr), nla_len(attr))) {
6637 hdd_err("Invalid disconnect IEs");
6638 return -EINVAL;
6639 }
6640
6641 status = sme_set_disconnect_ies(hdd_ctx->mac_handle,
6642 adapter->vdev_id,
6643 nla_data(attr),
6644 nla_len(attr));
6645 if (QDF_IS_STATUS_ERROR(status))
6646 hdd_err("Failed to set disconnect_ies");
6647
6648 return qdf_status_to_os_return(status);
6649}
6650
6651/**
Jeff Johnsonb48efe22018-11-15 11:53:09 -08006652 * typedef independent_setter_fn - independent attribute handler
6653 * @adapter: The adapter being configured
6654 * @attr: The nl80211 attribute being applied
6655 *
6656 * Defines the signature of functions in the independent attribute vtable
6657 *
6658 * Return: 0 if the attribute was handled successfully, otherwise an errno
6659 */
6660typedef int (*independent_setter_fn)(struct hdd_adapter *adapter,
6661 const struct nlattr *attr);
6662
6663/**
6664 * struct independent_setters
6665 * @id: vendor attribute which this entry handles
6666 * @cb: callback function to invoke to process the attribute when present
6667 */
6668struct independent_setters {
6669 uint32_t id;
6670 independent_setter_fn cb;
6671};
6672
6673/* vtable for independent setters */
6674static const struct independent_setters independent_setters[] = {
Jeff Johnson522464b2018-11-15 13:07:26 -08006675 {QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_DEFAULT_IES,
6676 hdd_config_scan_default_ies},
Jeff Johnson7f4fd702018-11-14 11:19:52 -08006677 {QCA_WLAN_VENDOR_ATTR_CONFIG_FINE_TIME_MEASUREMENT,
6678 hdd_config_fine_time_measurement},
Jeff Johnsonbcaeafb2018-11-14 12:14:24 -08006679 {QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM,
6680 hdd_config_modulated_dtim},
Jeff Johnson6db91622018-11-14 12:33:28 -08006681 {QCA_WLAN_VENDOR_ATTR_CONFIG_LISTEN_INTERVAL,
6682 hdd_config_listen_interval},
Jeff Johnson9381d032018-11-14 12:42:22 -08006683 {QCA_WLAN_VENDOR_ATTR_CONFIG_LRO,
6684 hdd_config_lro},
Jeff Johnson3d4f64c2018-11-14 13:13:04 -08006685 {QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE,
6686 hdd_config_scan_enable},
Jeff Johnson1feb8a62018-11-14 13:18:41 -08006687 {QCA_WLAN_VENDOR_ATTR_CONFIG_QPOWER,
6688 hdd_config_qpower},
Jeff Johnsonf15ede02018-11-14 13:27:13 -08006689 {QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR,
6690 hdd_config_stats_avg_factor},
Jeff Johnson47e2e842018-11-14 13:49:43 -08006691 {QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME,
6692 hdd_config_guard_time},
Jeff Johnsonf3827502018-11-14 14:00:58 -08006693 {QCA_WLAN_VENDOR_ATTR_CONFIG_NON_AGG_RETRY,
6694 hdd_config_non_agg_retry},
Jeff Johnsonb9021002018-11-15 15:51:36 -08006695 {QCA_WLAN_VENDOR_ATTR_CONFIG_AGG_RETRY,
6696 hdd_config_agg_retry},
Jeff Johnson0e8259c2018-11-15 19:44:57 -08006697 {QCA_WLAN_VENDOR_ATTR_CONFIG_MGMT_RETRY,
6698 hdd_config_mgmt_retry},
Jeff Johnson6b48a2f2018-11-15 19:48:47 -08006699 {QCA_WLAN_VENDOR_ATTR_CONFIG_CTRL_RETRY,
6700 hdd_config_ctrl_retry},
Jeff Johnson98214742018-11-15 19:56:37 -08006701 {QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_DELAY,
6702 hdd_config_propagation_delay},
Jeff Johnson8fb9ded2018-11-15 20:44:56 -08006703 {QCA_WLAN_VENDOR_ATTR_CONFIG_PROPAGATION_ABS_DELAY,
6704 hdd_config_propagation_abs_delay},
Jeff Johnson7c5e6dc2018-11-15 21:20:18 -08006705 {QCA_WLAN_VENDOR_ATTR_CONFIG_TX_FAIL_COUNT,
6706 hdd_config_tx_fail_count},
Jeff Johnson7766fd22018-11-15 21:52:37 -08006707 {QCA_WLAN_VENDOR_ATTR_CONFIG_CHANNEL_AVOIDANCE_IND,
6708 hdd_config_channel_avoidance_ind},
Jeff Johnsonf9871e42018-11-15 22:24:06 -08006709 {QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_ENA,
6710 hdd_config_ant_div_ena},
Jeff Johnson91f90ff2018-11-16 07:53:37 -08006711 {QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SNR_DIFF,
6712 hdd_config_ant_div_snr_diff},
Jeff Johnson77177bc2018-11-16 08:14:20 -08006713 {QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_PROBE_DWELL_TIME,
6714 hdd_config_ant_div_probe_dwell_time},
Jeff Johnsonaa172222018-11-16 09:16:11 -08006715 {QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_CHAIN,
6716 hdd_config_ant_div_chain},
Jeff Johnsonef427ad2018-11-16 09:22:17 -08006717 {QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST,
6718 hdd_config_ant_div_selftest},
Jeff Johnsonae21be82018-11-16 09:43:53 -08006719 {QCA_WLAN_VENDOR_ATTR_CONFIG_ANT_DIV_SELFTEST_INTVL,
6720 hdd_config_ant_div_selftest_intvl},
Jeff Johnson3a25de82018-11-16 07:26:46 -08006721 {QCA_WLAN_VENDOR_ATTR_CONFIG_IGNORE_ASSOC_DISALLOWED,
6722 hdd_config_ignore_assoc_disallowed},
Jeff Johnson72dc91e2018-11-16 08:46:12 -08006723 {QCA_WLAN_VENDOR_ATTR_CONFIG_RESTRICT_OFFCHANNEL,
6724 hdd_config_restrict_offchannel},
Jeff Johnson320feeb2018-11-16 10:14:24 -08006725 {QCA_WLAN_VENDOR_ATTR_CONFIG_TOTAL_BEACON_MISS_COUNT,
6726 hdd_config_total_beacon_miss_count},
Jeff Johnson2502ddd2018-11-16 10:59:30 -08006727 {QCA_WLAN_VENDOR_ATTR_CONFIG_LATENCY_LEVEL,
6728 hdd_config_latency_level},
Jeff Johnson0a315912018-11-16 11:18:21 -08006729 {QCA_WLAN_VENDOR_ATTR_CONFIG_DISABLE_FILS,
6730 hdd_config_disable_fils},
Jeff Johnson0bdbb962018-11-16 11:42:10 -08006731 {QCA_WLAN_VENDOR_ATTR_CONFIG_RSN_IE,
6732 hdd_config_rsn_ie},
Jeff Johnson7acca0d2018-11-16 11:53:18 -08006733 {QCA_WLAN_VENDOR_ATTR_CONFIG_GTX,
6734 hdd_config_gtx},
Srinivas Dasari37e37312019-06-30 23:50:24 +05306735 {QCA_WLAN_VENDOR_ATTR_DISCONNECT_IES,
6736 hdd_config_disconnect_ies},
Jeff Johnsonb48efe22018-11-15 11:53:09 -08006737};
6738
6739/**
6740 * hdd_set_independent_configuration() - Handle independent attributes
6741 * @adapter: adapter upon which the vendor command was received
6742 * @tb: parsed attribute array
6743 *
6744 * This is a table-driven function which dispatches independent
6745 * attributes in a QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION
6746 * vendor command. An attribute is considered independent if it
6747 * doesn't depend upon any other attributes
6748 *
6749 * Return: 0 if there were no issues, otherwise errno of the last issue
6750 */
6751static int hdd_set_independent_configuration(struct hdd_adapter *adapter,
6752 struct nlattr **tb)
6753{
6754 uint32_t i;
6755 uint32_t id;
6756 struct nlattr *attr;
6757 independent_setter_fn cb;
6758 int errno = 0;
6759 int ret;
6760
6761 for (i = 0; i < QDF_ARRAY_SIZE(independent_setters); i++) {
6762 id = independent_setters[i].id;
6763 attr = tb[id];
6764 if (!attr)
6765 continue;
6766
6767 cb = independent_setters[i].cb;
6768 ret = cb(adapter, attr);
6769 if (ret)
6770 errno = ret;
6771 }
6772
6773 return errno;
6774}
6775
6776/**
6777 * typedef interdependent_setter_fn - interdependent attribute handler
6778 * @adapter: The adapter being configured
6779 * @tb: The parsed nl80211 attributes being applied
6780 *
6781 * Defines the signature of functions in the interdependent attribute vtable
6782 *
6783 * Return: 0 if attributes were handled successfully, otherwise an errno
6784 */
6785typedef int (*interdependent_setter_fn)(struct hdd_adapter *adapter,
6786 struct nlattr **tb);
6787
6788/* vtable for interdependent setters */
6789static const interdependent_setter_fn interdependent_setters[] = {
Jeff Johnsonaffc4da2018-11-16 14:10:07 -08006790 hdd_config_access_policy,
Jeff Johnson0fbb43b2018-11-16 15:38:56 -08006791 hdd_config_mpdu_aggregation,
Jeff Johnson7bf20cb2018-11-16 17:38:27 -08006792 hdd_config_ant_div_period,
Jeff Johnson1350e622018-11-16 18:36:55 -08006793 hdd_config_ant_div_snr_weight,
Jeff Johnson0dd687e2018-11-16 20:11:27 -08006794 wlan_hdd_cfg80211_wifi_set_reorder_timeout,
Jeff Johnson339ede82018-11-16 20:27:52 -08006795 wlan_hdd_cfg80211_wifi_set_rx_blocksize,
Jeff Johnsonb48efe22018-11-15 11:53:09 -08006796};
6797
6798/**
6799 * hdd_set_interdependent_configuration() - Handle interdependent attributes
6800 * @adapter: adapter upon which the vendor command was received
6801 * @tb: parsed attribute array
6802 *
6803 * This is a table-driven function which handles interdependent
6804 * attributes in a QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION
6805 * vendor command. A set of attributes is considered interdependent if
6806 * they depend upon each other. In the typical case if one of the
6807 * attributes is present in the the attribute array, then all of the
6808 * attributes must be present.
6809 *
6810 * Return: 0 if there were no issues, otherwise errno of the last issue
6811 */
6812static int hdd_set_interdependent_configuration(struct hdd_adapter *adapter,
6813 struct nlattr **tb)
6814{
6815 uint32_t i;
6816 interdependent_setter_fn cb;
6817 int errno = 0;
6818 int ret;
6819
6820 for (i = 0; i < QDF_ARRAY_SIZE(interdependent_setters); i++) {
6821 cb = interdependent_setters[i];
6822 ret = cb(adapter, tb);
6823 if (ret)
6824 errno = ret;
6825 }
6826
6827 return errno;
6828}
6829
6830/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006831 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
6832 * vendor command
6833 *
6834 * @wiphy: wiphy device pointer
6835 * @wdev: wireless device pointer
6836 * @data: Vendor command data buffer
6837 * @data_len: Buffer length
6838 *
6839 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
6840 *
6841 * Return: Error code.
6842 */
6843static int
6844__wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
6845 struct wireless_dev *wdev,
6846 const void *data,
6847 int data_len)
6848{
6849 struct net_device *dev = wdev->netdev;
Jeff Johnsone5006672017-08-29 14:39:02 -07006850 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07006851 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006852 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_CONFIG_MAX + 1];
Jeff Johnsonb48efe22018-11-15 11:53:09 -08006853 int errno;
Jeff Johnson3b2abe92017-12-15 09:03:47 -08006854 int ret;
Deepak Dhamdhereb106ae52016-08-10 20:55:30 +05306855
Dustin Brownfdf17c12018-03-14 12:55:34 -07006856 hdd_enter_dev(dev);
Jeff Johnson1f61b612016-02-12 16:28:33 -08006857
Anurag Chouhan6d760662016-02-20 16:05:43 +05306858 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006859 hdd_err("Command not allowed in FTM mode");
6860 return -EPERM;
6861 }
6862
Jeff Johnsonb48efe22018-11-15 11:53:09 -08006863 errno = wlan_hdd_validate_context(hdd_ctx);
6864 if (errno)
6865 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006866
Dustin Brown4ea21db2018-01-05 14:13:17 -08006867 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_CONFIG_MAX, data,
6868 data_len, wlan_hdd_wifi_config_policy)) {
Jeff Johnson77848112016-06-29 14:52:06 -07006869 hdd_err("invalid attr");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006870 return -EINVAL;
6871 }
6872
Jeff Johnsonb48efe22018-11-15 11:53:09 -08006873 ret = hdd_set_independent_configuration(adapter, tb);
6874 if (ret)
6875 errno = ret;
6876
6877 ret = hdd_set_interdependent_configuration(adapter, tb);
6878 if (ret)
6879 errno = ret;
6880
Jeff Johnsonb48efe22018-11-15 11:53:09 -08006881 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006882}
6883
6884/**
6885 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
6886 * vendor command
6887 *
6888 * @wiphy: wiphy device pointer
6889 * @wdev: wireless device pointer
6890 * @data: Vendor command data buffer
6891 * @data_len: Buffer length
6892 *
6893 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
6894 *
6895 * Return: EOK or other error codes.
6896 */
6897static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
6898 struct wireless_dev *wdev,
6899 const void *data,
6900 int data_len)
6901{
Dustin Browna09acf42018-11-08 12:32:26 +05306902 int errno;
6903 struct osif_vdev_sync *vdev_sync;
6904
6905 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
6906 if (errno)
6907 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006908
Dustin Browna09acf42018-11-08 12:32:26 +05306909 errno = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
6910 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006911
Dustin Browna09acf42018-11-08 12:32:26 +05306912 osif_vdev_sync_op_stop(vdev_sync);
6913
6914 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006915}
6916
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08006917/**
6918 * __wlan_hdd_cfg80211_set_wifi_test_config() - Wifi test configuration
6919 * vendor command
6920 *
6921 * @wiphy: wiphy device pointer
6922 * @wdev: wireless device pointer
6923 * @data: Vendor command data buffer
6924 * @data_len: Buffer length
6925 *
6926 * Handles QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX
6927 *
6928 * Return: Error code.
6929 */
6930static int
6931__wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
Srinivas Girigowdaa19eafd2018-09-07 15:28:21 -07006932 struct wireless_dev *wdev, const void *data, int data_len)
6933{
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08006934 struct net_device *dev = wdev->netdev;
6935 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6936 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
6937 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX + 1];
6938 int ret_val = 0;
6939 uint8_t cfg_val = 0;
Kiran Kumar Lokerea9345612018-02-08 14:28:24 -08006940 uint8_t set_val = 0;
Jeff Johnson46b4f0e2019-03-08 10:48:35 -08006941 struct sme_config_params *sme_config;
Kiran Kumar Lokere722dccd2018-02-23 13:23:52 -08006942 bool update_sme_cfg = false;
Kiran Kumar Lokere3324f632018-03-01 21:43:21 -08006943 uint8_t tid = 0, ac;
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08006944 uint16_t buff_size = 0;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07006945 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05306946 QDF_STATUS status;
6947 bool bval = false;
6948 uint8_t value = 0;
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05306949 uint8_t wmm_mode = 0;
Kiran Kumar Lokere94634152018-09-24 19:08:35 -07006950 uint32_t cmd_id;
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08006951
Dustin Brownfdf17c12018-03-14 12:55:34 -07006952 hdd_enter_dev(dev);
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08006953
Kiran Kumar Lokere722dccd2018-02-23 13:23:52 -08006954 sme_config = qdf_mem_malloc(sizeof(*sme_config));
Min Liu74a1a502018-10-10 19:59:07 +08006955 if (!sme_config)
Kiran Kumar Lokere722dccd2018-02-23 13:23:52 -08006956 return -ENOMEM;
Min Liu74a1a502018-10-10 19:59:07 +08006957
Jeff Johnson34fc63a2018-06-14 10:10:02 -07006958 mac_handle = hdd_ctx->mac_handle;
6959 sme_get_config_param(mac_handle, sme_config);
Kiran Kumar Lokere722dccd2018-02-23 13:23:52 -08006960
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08006961 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
6962 hdd_err("Command not allowed in FTM mode");
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08006963 ret_val = -EPERM;
6964 goto send_err;
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08006965 }
6966
6967 ret_val = wlan_hdd_validate_context(hdd_ctx);
6968 if (ret_val)
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08006969 goto send_err;
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08006970
6971 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
6972 hdd_err("Driver Modules are closed, can not start logger");
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08006973 ret_val = -EINVAL;
6974 goto send_err;
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08006975 }
6976
6977 if (wlan_cfg80211_nla_parse(tb,
6978 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX,
6979 data, data_len, wlan_hdd_wifi_test_config_policy)) {
6980 hdd_err("invalid attr");
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08006981 ret_val = -EINVAL;
6982 goto send_err;
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08006983 }
6984
6985 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ]) {
6986 cfg_val = nla_get_u8(tb[
6987 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ACCEPT_ADDBA_REQ]
6988 );
6989 hdd_debug("set addba accept req from peer value %d", cfg_val);
Jeff Johnsoncf07c312019-02-04 13:53:29 -08006990 ret_val = sme_set_addba_accept(mac_handle, adapter->vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -07006991 cfg_val);
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08006992 if (ret_val)
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08006993 goto send_err;
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08006994 }
6995
Kiran Kumar Lokere96246e52018-01-24 16:44:35 -08006996 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS]) {
6997 cfg_val = nla_get_u8(tb[
6998 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MCS]);
6999 hdd_debug("set HE MCS value 0x%0X", cfg_val);
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007000 ret_val = sme_update_he_mcs(mac_handle, adapter->vdev_id,
Kiran Kumar Lokere96246e52018-01-24 16:44:35 -08007001 cfg_val);
7002 if (ret_val)
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08007003 goto send_err;
Kiran Kumar Lokere96246e52018-01-24 16:44:35 -08007004 }
7005
Krunal Soni707eb782018-01-18 12:04:19 -08007006 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE]) {
7007 cfg_val = nla_get_u8(tb[
7008 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WMM_ENABLE]);
Krunal Soni707eb782018-01-18 12:04:19 -08007009 if (!cfg_val) {
Jeff Johnsone94ccd02019-04-02 15:02:56 -07007010 sme_config->csr_config.WMMSupportMode =
Krunal Soni707eb782018-01-18 12:04:19 -08007011 hdd_to_csr_wmm_mode(HDD_WMM_USER_MODE_NO_QOS);
7012 hdd_debug("wmm is disabled");
7013 } else {
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05307014 status = ucfg_mlme_get_wmm_mode(hdd_ctx->psoc,
7015 &wmm_mode);
7016 if (!QDF_IS_STATUS_SUCCESS(status)) {
7017 hdd_err("Get wmm_mode failed");
7018 return QDF_STATUS_E_FAILURE;
7019 }
Jeff Johnsone94ccd02019-04-02 15:02:56 -07007020 sme_config->csr_config.WMMSupportMode =
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +05307021 hdd_to_csr_wmm_mode(wmm_mode);
Krunal Soni707eb782018-01-18 12:04:19 -08007022 hdd_debug("using wmm default value");
7023 }
Kiran Kumar Lokere722dccd2018-02-23 13:23:52 -08007024 update_sme_cfg = true;
Krunal Soni707eb782018-01-18 12:04:19 -08007025 }
7026
Kiran Kumar Lokerea9345612018-02-08 14:28:24 -08007027 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ]) {
7028 cfg_val = nla_get_u8(tb[
7029 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SEND_ADDBA_REQ]);
7030 if (cfg_val) {
7031 /*Auto BA mode*/
7032 set_val = 0;
7033 hdd_debug("BA operating mode is set to auto");
7034 } else {
7035 /*Manual BA mode*/
7036 set_val = 1;
7037 hdd_debug("BA operating mode is set to Manual");
7038 }
7039
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007040 ret_val = wma_cli_set_command(adapter->vdev_id,
Kiran Kumar Lokerea9345612018-02-08 14:28:24 -08007041 WMI_VDEV_PARAM_BA_MODE, set_val, VDEV_CMD);
Kiran Kumar Lokere015f77f2018-04-24 18:25:28 -07007042 if (ret_val) {
7043 hdd_err("Set BA operating mode failed");
7044 goto send_err;
7045 }
7046 if (!cfg_val) {
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007047 ret_val = wma_cli_set_command(adapter->vdev_id,
Kiran Kumar Lokere015f77f2018-04-24 18:25:28 -07007048 WMI_VDEV_PARAM_AMSDU_AGGREGATION_SIZE_OPTIMIZATION,
7049 0, VDEV_CMD);
7050 }
Kiran Kumar Lokerea9345612018-02-08 14:28:24 -08007051 }
7052
Kiran Kumar Lokere5cc2f0d2018-02-08 17:10:05 -08007053 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION]) {
7054 cfg_val = nla_get_u8(tb[
7055 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_FRAGMENTATION]
7056 );
7057 if (cfg_val > HE_FRAG_LEVEL1)
7058 set_val = HE_FRAG_LEVEL1;
7059 else
7060 set_val = cfg_val;
7061
7062 hdd_debug("set HE fragmention to %d", set_val);
Jeff Johnson34fc63a2018-06-14 10:10:02 -07007063 ret_val = sme_update_he_frag_supp(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007064 adapter->vdev_id, set_val);
Kiran Kumar Lokere5cc2f0d2018-02-08 17:10:05 -08007065 }
7066
Kiran Kumar Lokere722dccd2018-02-23 13:23:52 -08007067 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE]) {
7068 cfg_val = nla_get_u8(tb[
7069 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_WEP_TKIP_IN_HE]);
Jeff Johnsone94ccd02019-04-02 15:02:56 -07007070 sme_config->csr_config.wep_tkip_in_he = cfg_val;
Kiran Kumar Lokere722dccd2018-02-23 13:23:52 -08007071 hdd_debug("Set WEP/TKIP allow in HE %d", cfg_val);
7072
7073 update_sme_cfg = true;
7074 }
7075
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08007076 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION]) {
7077 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID]) {
7078 tid = nla_get_u8(tb[
7079 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_BA_TID]);
7080 } else {
7081 hdd_err("TID is not set for ADD/DEL BA cfg");
7082 ret_val = -EINVAL;
7083 goto send_err;
7084 }
7085 cfg_val = nla_get_u8(tb[
7086 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADD_DEL_BA_SESSION]);
7087 if (cfg_val == QCA_WLAN_ADD_BA) {
7088 if (tb[
7089 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE])
Kiran Kumar Lokereeac7fe92018-07-24 16:56:01 -07007090 buff_size = nla_get_u16(tb[
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08007091 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE]);
Jeff Johnson34fc63a2018-06-14 10:10:02 -07007092 ret_val = sme_send_addba_req(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007093 adapter->vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -07007094 tid, buff_size);
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08007095 } else if (cfg_val == QCA_WLAN_DELETE_BA) {
7096 } else {
7097 hdd_err("Invalid BA session cfg");
7098 ret_val = -EINVAL;
7099 goto send_err;
7100 }
7101 } else if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE]) {
Kiran Kumar Lokereeac7fe92018-07-24 16:56:01 -07007102 buff_size = nla_get_u16(tb[
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08007103 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ADDBA_BUFF_SIZE]);
7104 hdd_debug("set buff size to %d for all tids", buff_size);
Jeff Johnson34fc63a2018-06-14 10:10:02 -07007105 ret_val = sme_set_ba_buff_size(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007106 adapter->vdev_id, buff_size);
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08007107 if (ret_val)
7108 goto send_err;
7109 if (buff_size > 64)
7110 /* Configure ADDBA req buffer size to 256 */
7111 set_val = 3;
7112 else
7113 /* Configure ADDBA req buffer size to 64 */
7114 set_val = 2;
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007115 ret_val = wma_cli_set_command(adapter->vdev_id,
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08007116 WMI_VDEV_PARAM_BA_MODE, set_val, VDEV_CMD);
Kiran Kumar Lokere427a20f2018-08-23 18:47:27 -07007117 if (ret_val)
7118 hdd_err("Failed to set BA operating mode %d", set_val);
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007119 ret_val = wma_cli_set_command(adapter->vdev_id,
Kiran Kumar Lokere427a20f2018-08-23 18:47:27 -07007120 GEN_VDEV_PARAM_AMPDU,
7121 buff_size, GEN_CMD);
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08007122 }
7123
Kiran Kumar Lokere3324f632018-03-01 21:43:21 -08007124 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK]) {
Kiran Kumar Lokere30313a32018-04-30 18:20:06 -07007125 int he_mcs_val;
Srinivas Girigowda50335342018-09-07 15:21:01 -07007126
Kiran Kumar Lokere3324f632018-03-01 21:43:21 -08007127 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC]) {
7128 ac = nla_get_u8(tb[
7129 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_NO_ACK_AC]);
7130 } else {
7131 hdd_err("AC is not set for NO ACK policy config");
7132 ret_val = -EINVAL;
7133 goto send_err;
7134 }
7135 cfg_val = nla_get_u8(tb[
7136 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_NO_ACK]);
7137 hdd_debug("Set NO_ACK to %d for ac %d", cfg_val, ac);
Jeff Johnson34fc63a2018-06-14 10:10:02 -07007138 ret_val = sme_set_no_ack_policy(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007139 adapter->vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -07007140 cfg_val, ac);
Kiran Kumar Lokere30313a32018-04-30 18:20:06 -07007141 if (cfg_val) {
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05307142 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc,
7143 &bval);
7144 if (!QDF_IS_STATUS_SUCCESS(status))
7145 hdd_err("unable to get vht_enable2x2");
7146 if (bval)
Kiran Kumar Lokere30313a32018-04-30 18:20:06 -07007147 /*2x2 MCS 5 value*/
7148 he_mcs_val = 0x45;
7149 else
7150 /*1x1 MCS 5 value*/
7151 he_mcs_val = 0x25;
7152
7153 if (hdd_set_11ax_rate(adapter, he_mcs_val, NULL))
7154 hdd_err("HE MCS set failed, MCS val %0x",
7155 he_mcs_val);
7156 } else {
7157 if (hdd_set_11ax_rate(adapter, 0xFF, NULL))
7158 hdd_err("disable fixed rate failed");
7159 }
Kiran Kumar Lokere3324f632018-03-01 21:43:21 -08007160 }
7161
Kiran Kumar Lokerea006a302018-03-07 20:58:13 -08007162 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF]) {
7163 cfg_val = nla_get_u8(tb[
7164 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_LTF]);
7165 hdd_debug("Set HE LTF to %d", cfg_val);
Jeff Johnson34fc63a2018-06-14 10:10:02 -07007166 ret_val = sme_set_auto_rate_he_ltf(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007167 adapter->vdev_id,
Kiran Kumar Lokerea006a302018-03-07 20:58:13 -08007168 cfg_val);
7169 if (ret_val)
7170 sme_err("Failed to set auto rate HE LTF");
7171
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007172 ret_val = wma_cli_set_command(adapter->vdev_id,
Kiran Kumar Lokerea006a302018-03-07 20:58:13 -08007173 WMI_VDEV_PARAM_HE_LTF,
7174 cfg_val, VDEV_CMD);
7175 if (ret_val)
7176 goto send_err;
7177 }
7178
Kiran Kumar Lokere6c7f3fa2018-05-14 18:12:27 -07007179 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE]) {
7180 cfg_val = nla_get_u8(tb[
7181 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_TX_BEAMFORMEE]);
7182 hdd_debug("Set Tx beamformee to %d", cfg_val);
Jeff Johnson34fc63a2018-06-14 10:10:02 -07007183 ret_val = sme_update_tx_bfee_supp(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007184 adapter->vdev_id,
Kiran Kumar Lokere6c7f3fa2018-05-14 18:12:27 -07007185 cfg_val);
7186 if (ret_val)
7187 sme_err("Failed to set Tx beamformee cap");
7188
7189 }
7190
Kiran Kumar Lokeref3044852018-06-27 14:14:24 -07007191 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS]) {
7192 cfg_val = nla_get_u8(tb[
7193 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_BEAMFORMEE_NSTS]);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05307194 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
Abhinav Kumare057b412018-10-09 17:28:16 +05307195 &value);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05307196 if (!QDF_IS_STATUS_SUCCESS(status))
7197 hdd_err("unable to get tx_bfee_ant_supp");
7198
Kiran Kumar Lokerea67af052018-12-12 19:18:51 -08007199 if (!cfg_in_range(CFG_VHT_BEAMFORMEE_ANT_SUPP, cfg_val)) {
Kiran Kumar Lokeref3044852018-06-27 14:14:24 -07007200 hdd_err("NSTS %d not supported, supp_val %d", cfg_val,
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05307201 value);
Kiran Kumar Lokeref3044852018-06-27 14:14:24 -07007202 ret_val = -ENOTSUPP;
7203 goto send_err;
7204 }
7205 hdd_debug("Set Tx beamformee NSTS to %d", cfg_val);
7206 ret_val = sme_update_tx_bfee_nsts(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007207 adapter->vdev_id,
Kiran Kumar Lokeref3044852018-06-27 14:14:24 -07007208 cfg_val,
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05307209 value);
Kiran Kumar Lokeref3044852018-06-27 14:14:24 -07007210 if (ret_val)
7211 sme_err("Failed to set Tx beamformee cap");
7212
7213 }
7214
Kiran Kumar Lokeref54b8552018-07-10 00:53:38 -07007215 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR]) {
7216 cfg_val = nla_get_u8(tb[
7217 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_MAC_PADDING_DUR]);
7218 if (cfg_val) {
Kiran Kumar Lokere427a20f2018-08-23 18:47:27 -07007219 hdd_debug("Set HE mac padding dur to %d", cfg_val);
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007220 ret_val = sme_cli_set_command(adapter->vdev_id,
Kiran Kumar Lokeref54b8552018-07-10 00:53:38 -07007221 WMI_VDEV_PARAM_MU_EDCA_FW_UPDATE_EN,
7222 0, VDEV_CMD);
7223 if (ret_val)
7224 hdd_err("MU_EDCA update disable failed");
7225 sme_set_usr_cfg_mu_edca(hdd_ctx->mac_handle, true);
7226 sme_set_he_mu_edca_def_cfg(hdd_ctx->mac_handle);
7227 if (sme_update_mu_edca_params(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007228 adapter->vdev_id))
Kiran Kumar Lokeref54b8552018-07-10 00:53:38 -07007229 hdd_err("Failed to send mu edca params");
7230 } else {
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007231 ret_val = sme_cli_set_command(adapter->vdev_id,
Kiran Kumar Lokeref54b8552018-07-10 00:53:38 -07007232 WMI_VDEV_PARAM_MU_EDCA_FW_UPDATE_EN,
7233 1, VDEV_CMD);
7234 sme_set_usr_cfg_mu_edca(hdd_ctx->mac_handle, false);
7235 }
7236 ret_val = sme_update_he_trigger_frm_mac_pad(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007237 adapter->vdev_id,
Kiran Kumar Lokeref54b8552018-07-10 00:53:38 -07007238 cfg_val);
7239 if (ret_val)
7240 hdd_err("Failed to set Trig frame mac padding cap");
7241 }
7242
Kiran Kumar Lokere8d685d12018-07-23 17:17:26 -07007243 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA]) {
7244 cfg_val = nla_get_u8(tb[
7245 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_OVERRIDE_MU_EDCA]);
7246 if (cfg_val) {
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007247 ret_val = sme_cli_set_command(adapter->vdev_id,
Kiran Kumar Lokere8d685d12018-07-23 17:17:26 -07007248 WMI_VDEV_PARAM_MU_EDCA_FW_UPDATE_EN,
7249 0, VDEV_CMD);
7250 if (ret_val)
7251 hdd_err("MU_EDCA update disable failed");
7252 sme_set_usr_cfg_mu_edca(hdd_ctx->mac_handle, true);
7253 sme_set_he_mu_edca_def_cfg(hdd_ctx->mac_handle);
7254 if (sme_update_mu_edca_params(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007255 adapter->vdev_id))
Kiran Kumar Lokere8d685d12018-07-23 17:17:26 -07007256 hdd_err("Failed to send mu edca params");
7257 } else {
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007258 ret_val = sme_cli_set_command(adapter->vdev_id,
Kiran Kumar Lokere8d685d12018-07-23 17:17:26 -07007259 WMI_VDEV_PARAM_MU_EDCA_FW_UPDATE_EN,
7260 1, VDEV_CMD);
7261 sme_set_usr_cfg_mu_edca(hdd_ctx->mac_handle, false);
7262 }
7263 }
Kiran Kumar Lokeref1a96f42018-08-29 18:53:47 -07007264
7265 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP]) {
7266 cfg_val = nla_get_u8(tb[
7267 QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OM_CTRL_SUPP]);
7268 ret_val = sme_update_he_om_ctrl_supp(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007269 adapter->vdev_id,
Kiran Kumar Lokeref1a96f42018-08-29 18:53:47 -07007270 cfg_val);
7271 }
7272
Kiran Kumar Lokereacd107d2019-01-09 15:02:11 -08007273 cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_OMI_TX;
Kiran Kumar Lokere94634152018-09-24 19:08:35 -07007274 if (tb[cmd_id]) {
Kiran Kumar Lokereacd107d2019-01-09 15:02:11 -08007275 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_HE_OMI_MAX + 1];
7276 struct nlattr *curr_attr;
7277 int tmp, rc;
7278 nla_for_each_nested(curr_attr, tb[cmd_id], tmp) {
7279 rc = wlan_cfg80211_nla_parse(
7280 tb2, QCA_WLAN_VENDOR_ATTR_HE_OMI_MAX,
7281 nla_data(curr_attr),
7282 nla_len(curr_attr),
7283 qca_wlan_vendor_attr_he_omi_tx_policy);
7284 if (rc) {
7285 hdd_err("Invalid ATTR");
7286 goto send_err;
7287 }
7288 cmd_id = QCA_WLAN_VENDOR_ATTR_HE_OMI_CH_BW;
7289 if (tb2[cmd_id]) {
7290 cfg_val = nla_get_u8(tb2[cmd_id]);
7291 ret_val = sme_set_he_om_ctrl_param(
7292 hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007293 adapter->vdev_id,
Kiran Kumar Lokereacd107d2019-01-09 15:02:11 -08007294 cmd_id, cfg_val);
7295 }
7296 cmd_id = QCA_WLAN_VENDOR_ATTR_HE_OMI_RX_NSS;
7297 if (tb2[cmd_id]) {
7298 cfg_val = nla_get_u8(tb2[cmd_id]);
7299 ret_val = sme_set_he_om_ctrl_param(
7300 hdd_ctx->mac_handle,
7301 adapter->vdev_id,
7302 cmd_id, cfg_val);
7303 }
7304
7305 cmd_id = QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DISABLE;
7306 if (tb2[cmd_id]) {
7307 cfg_val = nla_get_u8(tb2[cmd_id]);
7308 ret_val = sme_set_he_om_ctrl_param(
7309 hdd_ctx->mac_handle,
7310 adapter->vdev_id,
7311 cmd_id, cfg_val);
7312 }
7313
7314 cmd_id = QCA_WLAN_VENDOR_ATTR_HE_OMI_TX_NSTS;
7315 if (tb2[cmd_id]) {
7316 cfg_val = nla_get_u8(tb2[cmd_id]);
7317 ret_val = sme_set_he_om_ctrl_param(
7318 hdd_ctx->mac_handle,
7319 adapter->vdev_id,
7320 cmd_id, cfg_val);
7321 }
Kiran Kumar Lokere49e3aff2019-02-06 17:00:48 -08007322
7323 cmd_id = QCA_WLAN_VENDOR_ATTR_HE_OMI_ULMU_DATA_DISABLE;
7324 if (tb2[cmd_id]) {
7325 cfg_val = nla_get_u8(tb2[cmd_id]);
7326 ret_val = sme_set_he_om_ctrl_param(
7327 hdd_ctx->mac_handle,
7328 adapter->vdev_id,
7329 cmd_id, cfg_val);
7330 }
7331
Kiran Kumar Lokereacd107d2019-01-09 15:02:11 -08007332 }
7333 if (ret_val) {
7334 sme_reset_he_om_ctrl(hdd_ctx->mac_handle);
7335 goto send_err;
7336 }
7337 ret_val = sme_send_he_om_ctrl_update(hdd_ctx->mac_handle,
7338 adapter->vdev_id);
Kiran Kumar Lokere94634152018-09-24 19:08:35 -07007339 }
7340
7341 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_CLEAR_HE_OM_CTRL_CONFIG])
7342 sme_reset_he_om_ctrl(hdd_ctx->mac_handle);
7343
Kiran Kumar Lokereefdbd0b2018-09-25 18:53:46 -07007344 cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TX_SUPPDU;
7345 if (tb[cmd_id]) {
7346 cfg_val = nla_get_u8(tb[cmd_id]);
7347 hdd_debug("Configure Tx SU PPDU enable %d", cfg_val);
7348 if (cfg_val)
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007349 sme_config_su_ppdu_queue(adapter->vdev_id, true);
Kiran Kumar Lokereefdbd0b2018-09-25 18:53:46 -07007350 else
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007351 sme_config_su_ppdu_queue(adapter->vdev_id, false);
Kiran Kumar Lokereefdbd0b2018-09-25 18:53:46 -07007352 }
7353
Kiran Kumar Lokerea1c29ec2019-02-25 18:19:00 -08007354 cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_ENABLE_2G_VHT;
7355 if (tb[cmd_id]) {
7356 cfg_val = nla_get_u8(tb[cmd_id]);
7357 hdd_debug("Configure 2G VHT support %d", cfg_val);
7358 ucfg_mlme_set_vht_for_24ghz(hdd_ctx->psoc,
7359 (cfg_val ? true : false));
7360 }
7361
Kiran Kumar Lokereacd107d2019-01-09 15:02:11 -08007362 cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_HTC_HE_SUPP;
7363 if (tb[cmd_id]) {
7364 cfg_val = nla_get_u8(tb[cmd_id]);
7365 hdd_debug("Configure +HTC_HE support %d", cfg_val);
7366 sme_update_he_htc_he_supp(hdd_ctx->mac_handle,
7367 adapter->vdev_id,
7368 (cfg_val ? true : false));
7369 }
7370
Kiran Kumar Lokere921b5a52019-02-24 21:53:20 -08007371 cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_SET_HE_TESTBED_DEFAULTS;
7372 if (tb[cmd_id]) {
7373 cfg_val = nla_get_u8(tb[cmd_id]);
7374 hdd_debug("Configure HE testbed defaults %d", cfg_val);
7375 if (!cfg_val)
7376 sme_reset_he_caps(hdd_ctx->mac_handle,
7377 adapter->vdev_id);
7378 else
7379 sme_set_he_testbed_def(hdd_ctx->mac_handle,
7380 adapter->vdev_id);
7381 }
7382
Kiran Kumar Lokereee205772018-09-27 00:27:27 -07007383 cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_ACTION_TX_TB_PPDU;
7384 if (tb[cmd_id]) {
7385 cfg_val = nla_get_u8(tb[cmd_id]);
7386 hdd_debug("Configure Action frame Tx in TB PPDU %d", cfg_val);
7387 sme_config_action_tx_in_tb_ppdu(hdd_ctx->mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08007388 adapter->vdev_id, cfg_val);
Kiran Kumar Lokereee205772018-09-27 00:27:27 -07007389 }
7390
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007391 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP]) {
7392 struct wmi_twt_add_dialog_param params = {0};
7393 struct hdd_station_ctx *hdd_sta_ctx =
7394 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7395 uint32_t wake_intvl_exp = 0, result = 0;
7396 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1];
7397 struct nlattr *twt_session;
7398 int tmp, rc;
7399
7400 if ((adapter->device_mode != QDF_STA_MODE &&
7401 adapter->device_mode != QDF_P2P_CLIENT_MODE) ||
7402 hdd_sta_ctx->conn_info.conn_state !=
7403 eConnectionState_Associated) {
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05307404 hdd_err_rl("Invalid state, vdev %d mode %d state %d",
7405 adapter->vdev_id, adapter->device_mode,
7406 hdd_sta_ctx->conn_info.conn_state);
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007407 goto send_err;
7408 }
7409
7410 qdf_mem_copy(params.peer_macaddr,
7411 hdd_sta_ctx->conn_info.bssid.bytes,
7412 QDF_MAC_ADDR_SIZE);
7413 params.vdev_id = adapter->vdev_id;
7414 params.dialog_id = 0;
7415
7416 cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_SETUP;
7417 nla_for_each_nested(twt_session, tb[cmd_id], tmp) {
7418 rc = wlan_cfg80211_nla_parse(
7419 tb2, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX,
7420 nla_data(twt_session),
7421 nla_len(twt_session),
7422 qca_wlan_vendor_twt_add_dialog_policy);
7423 if (rc) {
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05307424 hdd_err_rl("Invalid twt ATTR");
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007425 goto send_err;
7426 }
7427
7428 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP;
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05307429 if (!tb2[cmd_id]) {
7430 hdd_err_rl("TWT_SETUP_WAKE_INTVL_EXP is must");
7431 goto send_err;
7432 }
7433 wake_intvl_exp = nla_get_u8(tb2[cmd_id]);
7434 if (wake_intvl_exp > TWT_SETUP_WAKE_INTVL_EXP_MAX) {
7435 hdd_err_rl("Invalid wake_intvl_exp %u > %u",
7436 wake_intvl_exp,
7437 TWT_SETUP_WAKE_INTVL_EXP_MAX);
7438 goto send_err;
7439 }
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007440
7441 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_BCAST;
7442 if (tb2[cmd_id])
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05307443 params.flag_bcast = nla_get_flag(tb2[cmd_id]);
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007444
7445 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_REQ_TYPE;
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05307446 if (!tb2[cmd_id]) {
7447 hdd_err_rl("TWT_SETUP_REQ_TYPE is must");
7448 goto send_err;
7449 }
7450 params.twt_cmd = nla_get_u8(tb2[cmd_id]);
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007451
7452 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_TRIGGER;
7453 if (tb2[cmd_id])
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05307454 params.flag_trigger = nla_get_flag(tb2[cmd_id]);
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007455
7456 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_TYPE;
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05307457 if (!tb2[cmd_id]) {
7458 hdd_err_rl("TWT_SETUP_FLOW_TYPE is must");
7459 goto send_err;
7460 }
7461 params.flag_flow_type = nla_get_u8(tb2[cmd_id]);
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007462
7463 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_PROTECTION;
7464 if (tb2[cmd_id])
7465 params.flag_protection =
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05307466 nla_get_flag(tb2[cmd_id]);
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007467
7468 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_TIME;
7469 if (tb2[cmd_id])
7470 params.sp_offset_us = nla_get_u32(tb2[cmd_id]);
7471
7472 cmd_id = QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_DURATION;
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05307473 if (!tb2[cmd_id]) {
7474 hdd_err_rl("TWT_SETUP_WAKE_DURATION is must");
7475 goto send_err;
7476 }
7477 params.wake_dura_us = 256 * nla_get_u32(tb2[cmd_id]);
7478 if (params.wake_dura_us > TWT_SETUP_WAKE_DURATION_MAX) {
7479 hdd_err_rl("Invalid wake_dura_us %u",
7480 params.wake_dura_us);
7481 goto send_err;
7482 }
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007483
7484 cmd_id =
7485 QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_MANTISSA;
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05307486 if (!tb2[cmd_id]) {
7487 hdd_err_rl("SETUP_WAKE_INTVL_MANTISSA is must");
7488 goto send_err;
7489 }
7490 params.wake_intvl_mantis = nla_get_u32(tb2[cmd_id]);
7491 if (params.wake_intvl_mantis >
7492 TWT_SETUP_WAKE_INTVL_MANTISSA_MAX) {
7493 hdd_err_rl("Invalid wake_intvl_mantis %u",
7494 params.wake_dura_us);
7495 goto send_err;
7496 }
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007497
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05307498 if (wake_intvl_exp && params.wake_intvl_mantis) {
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007499 result = 2 << (wake_intvl_exp - 1);
7500 if (result >
7501 (UINT_MAX / params.wake_intvl_mantis)) {
Rajeev Kumar Sirasanagandla05f1f2d2019-05-02 17:01:36 +05307502 hdd_err_rl("Invalid exp %d mantissa %d",
7503 wake_intvl_exp,
7504 params.wake_intvl_mantis);
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007505 goto send_err;
7506 }
7507 params.wake_intvl_us =
7508 params.wake_intvl_mantis * result;
7509 } else {
7510 params.wake_intvl_us = params.wake_intvl_mantis;
7511 }
7512
Arif Hussain1f58cbb2019-03-14 17:06:56 -07007513 hdd_debug("twt: vdev %d, intvl_us %d, mantis %d",
7514 params.vdev_id, params.wake_intvl_us,
7515 params.wake_intvl_mantis);
7516 hdd_debug("twt: dura %d, offset %d, cmd %d",
7517 params.wake_dura_us, params.sp_offset_us,
7518 params.twt_cmd);
7519 hdd_debug("twt: bcast %d, trigger %d, type %d, prot %d",
7520 params.flag_bcast, params.flag_trigger,
7521 params.flag_flow_type,
7522 params.flag_protection);
7523
7524 ret_val = qdf_status_to_os_return(
7525 wma_twt_process_add_dialog(&params));
7526 if (ret_val)
7527 goto send_err;
7528 }
7529 }
7530
7531 if (tb[QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_TWT_TERMINATE]) {
7532 struct wmi_twt_del_dialog_param params = {0};
7533 struct hdd_station_ctx *hdd_sta_ctx =
7534 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7535
7536 if ((adapter->device_mode != QDF_STA_MODE &&
7537 adapter->device_mode != QDF_P2P_CLIENT_MODE) ||
7538 hdd_sta_ctx->conn_info.conn_state !=
7539 eConnectionState_Associated) {
7540 hdd_err("Invalid state, vdev %d mode %d state %d",
7541 adapter->vdev_id, adapter->device_mode,
7542 hdd_sta_ctx->conn_info.conn_state);
7543 goto send_err;
7544 }
7545 qdf_mem_copy(params.peer_macaddr,
7546 hdd_sta_ctx->conn_info.bssid.bytes,
7547 QDF_MAC_ADDR_SIZE);
7548 params.vdev_id = adapter->vdev_id;
7549 params.dialog_id = 0;
7550 hdd_debug("twt_terminate: vdev_id %d", params.vdev_id);
7551 ret_val = qdf_status_to_os_return(
7552 wma_twt_process_del_dialog(&params));
7553 if (ret_val)
7554 goto send_err;
7555 }
7556
7557 cmd_id = QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_HE_TWT_REQ_SUPPORT;
7558 if (tb[cmd_id]) {
7559 cfg_val = nla_get_u8(tb[cmd_id]);
7560 hdd_debug("twt_request: val %d", cfg_val);
7561 ret_val = sme_update_he_twt_req_support(hdd_ctx->mac_handle,
7562 adapter->vdev_id,
7563 cfg_val);
7564 }
7565
Kiran Kumar Lokere722dccd2018-02-23 13:23:52 -08007566 if (update_sme_cfg)
Jeff Johnson34fc63a2018-06-14 10:10:02 -07007567 sme_update_config(mac_handle, sme_config);
Kiran Kumar Lokere722dccd2018-02-23 13:23:52 -08007568
Kiran Kumar Lokerebc87bec2018-02-27 20:06:42 -08007569send_err:
Kiran Kumar Lokere722dccd2018-02-23 13:23:52 -08007570 qdf_mem_free(sme_config);
7571
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08007572 return ret_val;
7573}
7574
7575/**
7576 * wlan_hdd_cfg80211_set_wifi_test_config() - Wifi test configuration
7577 * vendor command
7578 *
7579 * @wiphy: wiphy device pointer
7580 * @wdev: wireless device pointer
7581 * @data: Vendor command data buffer
7582 * @data_len: Buffer length
7583 *
7584 * Handles QCA_WLAN_VENDOR_ATTR_WIFI_TEST_CONFIG_MAX
7585 *
7586 * Return: EOK or other error codes.
7587 */
7588static int wlan_hdd_cfg80211_set_wifi_test_config(struct wiphy *wiphy,
7589 struct wireless_dev *wdev, const void *data, int data_len)
7590{
Dustin Browna09acf42018-11-08 12:32:26 +05307591 int errno;
7592 struct osif_vdev_sync *vdev_sync;
7593
7594 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
7595 if (errno)
7596 return errno;
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08007597
Dustin Browna09acf42018-11-08 12:32:26 +05307598 errno = __wlan_hdd_cfg80211_set_wifi_test_config(wiphy, wdev,
7599 data, data_len);
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08007600
Dustin Browna09acf42018-11-08 12:32:26 +05307601 osif_vdev_sync_op_stop(vdev_sync);
7602
7603 return errno;
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -08007604}
7605
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007606static const struct
7607nla_policy
7608qca_wlan_vendor_wifi_logger_start_policy
7609[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
7610 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
7611 = {.type = NLA_U32 },
7612 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
7613 = {.type = NLA_U32 },
7614 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
7615 = {.type = NLA_U32 },
7616};
7617
7618/**
7619 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
7620 * or disable the collection of packet statistics from the firmware
7621 * @wiphy: WIPHY structure pointer
7622 * @wdev: Wireless device structure pointer
7623 * @data: Pointer to the data received
7624 * @data_len: Length of the data received
7625 *
7626 * This function enables or disables the collection of packet statistics from
7627 * the firmware
7628 *
7629 * Return: 0 on success and errno on failure
7630 */
7631static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
7632 struct wireless_dev *wdev,
7633 const void *data,
7634 int data_len)
7635{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307636 QDF_STATUS status;
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07007637 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007638 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
Hanumanth Reddy Pothulae9af1162018-06-13 13:41:44 +05307639 struct sir_wifi_start_log start_log = { 0 };
Jeff Johnson34fc63a2018-06-14 10:10:02 -07007640 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007641
Dustin Brownfdf17c12018-03-14 12:55:34 -07007642 hdd_enter_dev(wdev->netdev);
Jeff Johnson1f61b612016-02-12 16:28:33 -08007643
Anurag Chouhan6d760662016-02-20 16:05:43 +05307644 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007645 hdd_err("Command not allowed in FTM mode");
7646 return -EPERM;
7647 }
7648
7649 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307650 if (status)
7651 return status;
7652
Ashish Kumar Dhanotiya3c308422017-03-02 16:48:56 +05307653 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
7654 hdd_err("Driver Modules are closed, can not start logger");
7655 return -EINVAL;
7656 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007657
Dustin Brown4ea21db2018-01-05 14:13:17 -08007658 if (wlan_cfg80211_nla_parse(tb,
7659 QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
7660 data, data_len,
7661 qca_wlan_vendor_wifi_logger_start_policy)) {
Jeff Johnson77848112016-06-29 14:52:06 -07007662 hdd_err("Invalid attribute");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007663 return -EINVAL;
7664 }
7665
7666 /* Parse and fetch ring id */
7667 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
Jeff Johnson77848112016-06-29 14:52:06 -07007668 hdd_err("attr ATTR failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007669 return -EINVAL;
7670 }
7671 start_log.ring_id = nla_get_u32(
7672 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
Srinivas Girigowda13d39252017-03-06 16:12:15 -08007673 hdd_debug("Ring ID=%d", start_log.ring_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007674
7675 /* Parse and fetch verbose level */
7676 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
Jeff Johnson77848112016-06-29 14:52:06 -07007677 hdd_err("attr verbose_level failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007678 return -EINVAL;
7679 }
7680 start_log.verbose_level = nla_get_u32(
7681 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
Srinivas Girigowda13d39252017-03-06 16:12:15 -08007682 hdd_debug("verbose_level=%d", start_log.verbose_level);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007683
7684 /* Parse and fetch flag */
7685 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
Jeff Johnson77848112016-06-29 14:52:06 -07007686 hdd_err("attr flag failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007687 return -EINVAL;
7688 }
Poddar, Siddartheefe3482016-09-21 18:12:59 +05307689 start_log.is_iwpriv_command = nla_get_u32(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007690 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007691
Hanumanth Reddy Pothulae9af1162018-06-13 13:41:44 +05307692 start_log.user_triggered = 1;
7693
Poddar, Siddarth176c4362016-10-03 12:25:00 +05307694 /* size is buff size which can be set using iwpriv command*/
7695 start_log.size = 0;
Poddar, Siddarthab99a272017-04-10 12:53:26 +05307696 start_log.is_pktlog_buff_clear = false;
Poddar, Siddarth176c4362016-10-03 12:25:00 +05307697
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007698 cds_set_ring_log_level(start_log.ring_id, start_log.verbose_level);
7699
7700 if (start_log.ring_id == RING_ID_WAKELOCK) {
7701 /* Start/stop wakelock events */
7702 if (start_log.verbose_level > WLAN_LOG_LEVEL_OFF)
7703 cds_set_wakelock_logging(true);
7704 else
7705 cds_set_wakelock_logging(false);
7706 return 0;
7707 }
7708
Jeff Johnson34fc63a2018-06-14 10:10:02 -07007709 mac_handle = hdd_ctx->mac_handle;
7710 status = sme_wifi_start_logger(mac_handle, start_log);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307711 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnson77848112016-06-29 14:52:06 -07007712 hdd_err("sme_wifi_start_logger failed(err=%d)",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007713 status);
7714 return -EINVAL;
7715 }
7716 return 0;
7717}
7718
7719/**
7720 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
7721 * or disable the collection of packet statistics from the firmware
7722 * @wiphy: WIPHY structure pointer
7723 * @wdev: Wireless device structure pointer
7724 * @data: Pointer to the data received
7725 * @data_len: Length of the data received
7726 *
7727 * This function is used to enable or disable the collection of packet
7728 * statistics from the firmware
7729 *
7730 * Return: 0 on success and errno on failure
7731 */
7732static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
7733 struct wireless_dev *wdev,
7734 const void *data,
7735 int data_len)
7736{
Dustin Brown363b4792019-02-05 16:11:55 -08007737 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08007738 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05307739
Dustin Brown363b4792019-02-05 16:11:55 -08007740 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08007741 if (errno)
7742 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007743
Dustin Brownf0f00612019-01-31 16:02:24 -08007744 errno = __wlan_hdd_cfg80211_wifi_logger_start(wiphy, wdev,
7745 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007746
Dustin Brown363b4792019-02-05 16:11:55 -08007747 osif_psoc_sync_op_stop(psoc_sync);
Arunk Khandavalli99716d12018-11-14 15:02:02 +05307748
Dustin Brownf0f00612019-01-31 16:02:24 -08007749 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007750}
7751
7752static const struct
7753nla_policy
7754qca_wlan_vendor_wifi_logger_get_ring_data_policy
7755[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
7756 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
7757 = {.type = NLA_U32 },
7758};
7759
7760/**
7761 * __wlan_hdd_cfg80211_wifi_logger_get_ring_data() - Flush per packet stats
7762 * @wiphy: WIPHY structure pointer
7763 * @wdev: Wireless device structure pointer
7764 * @data: Pointer to the data received
7765 * @data_len: Length of the data received
7766 *
7767 * This function is used to flush or retrieve the per packet statistics from
7768 * the driver
7769 *
7770 * Return: 0 on success and errno on failure
7771 */
7772static int __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
7773 struct wireless_dev *wdev,
7774 const void *data,
7775 int data_len)
7776{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307777 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007778 uint32_t ring_id;
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07007779 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007780 struct nlattr *tb
7781 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
7782
Dustin Brownfdf17c12018-03-14 12:55:34 -07007783 hdd_enter_dev(wdev->netdev);
Jeff Johnson1f61b612016-02-12 16:28:33 -08007784
Anurag Chouhan6d760662016-02-20 16:05:43 +05307785 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007786 hdd_err("Command not allowed in FTM mode");
7787 return -EPERM;
7788 }
7789
7790 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307791 if (status)
7792 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007793
Dustin Brown4ea21db2018-01-05 14:13:17 -08007794 if (wlan_cfg80211_nla_parse(tb,
7795 QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
7796 data, data_len,
7797 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
Jeff Johnson77848112016-06-29 14:52:06 -07007798 hdd_err("Invalid attribute");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007799 return -EINVAL;
7800 }
7801
7802 /* Parse and fetch ring id */
7803 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
Jeff Johnson77848112016-06-29 14:52:06 -07007804 hdd_err("attr ATTR failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007805 return -EINVAL;
7806 }
7807
7808 ring_id = nla_get_u32(
7809 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
7810
7811 if (ring_id == RING_ID_PER_PACKET_STATS) {
7812 wlan_logging_set_per_pkt_stats();
Srinivas Girigowda13d39252017-03-06 16:12:15 -08007813 hdd_debug("Flushing/Retrieving packet stats");
Sreelakshmi Konamkic3815ba2016-08-18 12:01:57 +05307814 } else if (ring_id == RING_ID_DRIVER_DEBUG) {
7815 /*
7816 * As part of DRIVER ring ID, flush both driver and fw logs.
7817 * For other Ring ID's driver doesn't have any rings to flush
7818 */
Dustin Brown5e89ef82018-03-14 11:50:23 -07007819 hdd_info("Bug report triggered by framework");
Sreelakshmi Konamkic3815ba2016-08-18 12:01:57 +05307820
7821 status = cds_flush_logs(WLAN_LOG_TYPE_NON_FATAL,
7822 WLAN_LOG_INDICATOR_FRAMEWORK,
7823 WLAN_LOG_REASON_CODE_UNUSED,
7824 true, false);
7825 if (QDF_STATUS_SUCCESS != status) {
7826 hdd_err("Failed to trigger bug report");
7827 return -EINVAL;
7828 }
7829 } else {
7830 wlan_report_log_completion(WLAN_LOG_TYPE_NON_FATAL,
7831 WLAN_LOG_INDICATOR_FRAMEWORK,
Agrawal Ashishaff28982017-05-30 15:25:47 +05307832 WLAN_LOG_REASON_CODE_UNUSED,
7833 ring_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007834 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007835 return 0;
7836}
7837
7838/**
7839 * wlan_hdd_cfg80211_wifi_logger_get_ring_data() - Wrapper to flush packet stats
7840 * @wiphy: WIPHY structure pointer
7841 * @wdev: Wireless device structure pointer
7842 * @data: Pointer to the data received
7843 * @data_len: Length of the data received
7844 *
7845 * This function is used to flush or retrieve the per packet statistics from
7846 * the driver
7847 *
7848 * Return: 0 on success and errno on failure
7849 */
7850static int wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
7851 struct wireless_dev *wdev,
7852 const void *data,
7853 int data_len)
7854{
Dustin Brown363b4792019-02-05 16:11:55 -08007855 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08007856 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05307857
Dustin Brown363b4792019-02-05 16:11:55 -08007858 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08007859 if (errno)
7860 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007861
Dustin Brownf0f00612019-01-31 16:02:24 -08007862 errno = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy, wdev,
7863 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007864
Dustin Brown363b4792019-02-05 16:11:55 -08007865 osif_psoc_sync_op_stop(psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08007866
7867 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007868}
7869
7870#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7871/**
7872 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7873 * @hdd_ctx: HDD context
7874 * @request_id: [input] request id
7875 * @pattern_id: [output] pattern id
7876 *
7877 * This function loops through request id to pattern id array
7878 * if the slot is available, store the request id and return pattern id
7879 * if entry exists, return the pattern id
7880 *
7881 * Return: 0 on success and errno on failure
7882 */
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07007883static int hdd_map_req_id_to_pattern_id(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007884 uint32_t request_id,
7885 uint8_t *pattern_id)
7886{
7887 uint32_t i;
7888
7889 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7890 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
7891 if (hdd_ctx->op_ctx.op_table[i].request_id == MAX_REQUEST_ID) {
7892 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7893 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7894 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7895 return 0;
7896 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7897 request_id) {
7898 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7899 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7900 return 0;
7901 }
7902 }
7903 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05307904 return -ENOBUFS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007905}
7906
7907/**
7908 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7909 * @hdd_ctx: HDD context
7910 * @request_id: [input] request id
7911 * @pattern_id: [output] pattern id
7912 *
7913 * This function loops through request id to pattern id array
7914 * reset request id to 0 (slot available again) and
7915 * return pattern id
7916 *
7917 * Return: 0 on success and errno on failure
7918 */
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07007919static int hdd_unmap_req_id_to_pattern_id(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007920 uint32_t request_id,
7921 uint8_t *pattern_id)
7922{
7923 uint32_t i;
7924
7925 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7926 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
7927 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id) {
7928 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
7929 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7930 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7931 return 0;
7932 }
7933 }
7934 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7935 return -EINVAL;
7936}
7937
7938
7939/*
7940 * define short names for the global vendor params
7941 * used by __wlan_hdd_cfg80211_offloaded_packets()
7942 */
7943#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7944#define PARAM_REQUEST_ID \
7945 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7946#define PARAM_CONTROL \
7947 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7948#define PARAM_IP_PACKET \
7949 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7950#define PARAM_SRC_MAC_ADDR \
7951 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7952#define PARAM_DST_MAC_ADDR \
7953 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7954#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
Arun Kumar Khandavallif1f65922019-02-27 16:00:24 +05307955#define PARAM_PROTO_TYPE \
7956 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_ETHER_PROTO_TYPE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007957
7958/**
7959 * wlan_hdd_add_tx_ptrn() - add tx pattern
7960 * @adapter: adapter pointer
7961 * @hdd_ctx: hdd context
7962 * @tb: nl attributes
7963 *
7964 * This function reads the NL attributes and forms a AddTxPtrn message
7965 * posts it to SME.
7966 *
7967 */
7968static int
Jeff Johnsone5006672017-08-29 14:39:02 -07007969wlan_hdd_add_tx_ptrn(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007970 struct nlattr **tb)
7971{
7972 struct sSirAddPeriodicTxPtrn *add_req;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307973 QDF_STATUS status;
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05307974 uint32_t request_id, len;
7975 int32_t ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007976 uint8_t pattern_id = 0;
Anurag Chouhan6d760662016-02-20 16:05:43 +05307977 struct qdf_mac_addr dst_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007978 uint16_t eth_type = htons(ETH_P_IP);
Jeff Johnson34fc63a2018-06-14 10:10:02 -07007979 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007980
7981 if (!hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Jeff Johnson77848112016-06-29 14:52:06 -07007982 hdd_err("Not in Connected state!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007983 return -ENOTSUPP;
7984 }
7985
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307986 add_req = qdf_mem_malloc(sizeof(*add_req));
Min Liu74a1a502018-10-10 19:59:07 +08007987 if (!add_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007988 return -ENOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007989
7990 /* Parse and fetch request Id */
7991 if (!tb[PARAM_REQUEST_ID]) {
Jeff Johnson77848112016-06-29 14:52:06 -07007992 hdd_err("attr request id failed");
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05307993 ret = -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007994 goto fail;
7995 }
7996
7997 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7998 if (request_id == MAX_REQUEST_ID) {
Jeff Johnson77848112016-06-29 14:52:06 -07007999 hdd_err("request_id cannot be MAX");
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05308000 ret = -EINVAL;
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05308001 goto fail;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008002 }
Srinivas Girigowda13d39252017-03-06 16:12:15 -08008003 hdd_debug("Request Id: %u", request_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008004
8005 if (!tb[PARAM_PERIOD]) {
Jeff Johnson77848112016-06-29 14:52:06 -07008006 hdd_err("attr period failed");
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05308007 ret = -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008008 goto fail;
8009 }
Arun Kumar Khandavallif1f65922019-02-27 16:00:24 +05308010
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008011 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
Srinivas Girigowda13d39252017-03-06 16:12:15 -08008012 hdd_debug("Period: %u ms", add_req->usPtrnIntervalMs);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008013 if (add_req->usPtrnIntervalMs == 0) {
Jeff Johnson77848112016-06-29 14:52:06 -07008014 hdd_err("Invalid interval zero, return failure");
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05308015 ret = -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008016 goto fail;
8017 }
8018
8019 if (!tb[PARAM_SRC_MAC_ADDR]) {
Jeff Johnson77848112016-06-29 14:52:06 -07008020 hdd_err("attr source mac address failed");
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05308021 ret = -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008022 goto fail;
8023 }
Srinivas Girigowda31896552015-11-18 22:59:52 -08008024 nla_memcpy(add_req->mac_address.bytes, tb[PARAM_SRC_MAC_ADDR],
Anurag Chouhan6d760662016-02-20 16:05:43 +05308025 QDF_MAC_ADDR_SIZE);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07008026 hdd_debug("input src mac address: "QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07008027 QDF_MAC_ADDR_ARRAY(add_req->mac_address.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008028
Anurag Chouhanc5548422016-02-24 18:33:27 +05308029 if (!qdf_is_macaddr_equal(&add_req->mac_address,
Jeff Johnson1e851a12017-10-28 14:36:12 -07008030 &adapter->mac_addr)) {
Srinivas Girigowda31896552015-11-18 22:59:52 -08008031 hdd_err("input src mac address and connected ap bssid are different");
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05308032 ret = -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008033 goto fail;
8034 }
8035
8036 if (!tb[PARAM_DST_MAC_ADDR]) {
Jeff Johnson77848112016-06-29 14:52:06 -07008037 hdd_err("attr dst mac address failed");
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05308038 ret = -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008039 goto fail;
8040 }
Anurag Chouhan6d760662016-02-20 16:05:43 +05308041 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], QDF_MAC_ADDR_SIZE);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07008042 hdd_debug("input dst mac address: "QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07008043 QDF_MAC_ADDR_ARRAY(dst_addr.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008044
8045 if (!tb[PARAM_IP_PACKET]) {
Jeff Johnson77848112016-06-29 14:52:06 -07008046 hdd_err("attr ip packet failed");
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05308047 ret = -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008048 goto fail;
8049 }
8050 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
Srinivas Girigowda13d39252017-03-06 16:12:15 -08008051 hdd_debug("IP packet len: %u", add_req->ucPtrnSize);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008052
8053 if (add_req->ucPtrnSize < 0 ||
8054 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
8055 ETH_HLEN)) {
Jeff Johnson77848112016-06-29 14:52:06 -07008056 hdd_err("Invalid IP packet len: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008057 add_req->ucPtrnSize);
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05308058 ret = -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008059 goto fail;
8060 }
8061
Arun Kumar Khandavallif1f65922019-02-27 16:00:24 +05308062 if (!tb[PARAM_PROTO_TYPE])
8063 eth_type = htons(ETH_P_IP);
8064 else
8065 eth_type = htons(nla_get_u16(tb[PARAM_PROTO_TYPE]));
8066
8067 hdd_debug("packet proto type: %u", eth_type);
8068
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008069 len = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308070 qdf_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, QDF_MAC_ADDR_SIZE);
Anurag Chouhan6d760662016-02-20 16:05:43 +05308071 len += QDF_MAC_ADDR_SIZE;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308072 qdf_mem_copy(&add_req->ucPattern[len], add_req->mac_address.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05308073 QDF_MAC_ADDR_SIZE);
8074 len += QDF_MAC_ADDR_SIZE;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308075 qdf_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008076 len += 2;
8077
8078 /*
8079 * This is the IP packet, add 14 bytes Ethernet (802.3) header
8080 * ------------------------------------------------------------
8081 * | 14 bytes Ethernet (802.3) header | IP header and payload |
8082 * ------------------------------------------------------------
8083 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308084 qdf_mem_copy(&add_req->ucPattern[len],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008085 nla_data(tb[PARAM_IP_PACKET]),
8086 add_req->ucPtrnSize);
8087 add_req->ucPtrnSize += len;
8088
8089 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
8090 if (ret) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08008091 hdd_err("req id to pattern id failed (ret=%d)", ret);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008092 goto fail;
8093 }
8094 add_req->ucPtrnId = pattern_id;
Srinivas Girigowda13d39252017-03-06 16:12:15 -08008095 hdd_debug("pattern id: %d", add_req->ucPtrnId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008096
Jeff Johnson34fc63a2018-06-14 10:10:02 -07008097 mac_handle = hdd_ctx->mac_handle;
8098 status = sme_add_periodic_tx_ptrn(mac_handle, add_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308099 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnson77848112016-06-29 14:52:06 -07008100 hdd_err("sme_add_periodic_tx_ptrn failed (err=%d)", status);
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05308101 ret = qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008102 goto fail;
8103 }
8104
Dustin Browne74003f2018-03-14 12:51:58 -07008105 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008106
8107fail:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308108 qdf_mem_free(add_req);
Ankita Bajaj5ea0f032019-05-02 19:29:09 +05308109 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008110}
8111
8112/**
8113 * wlan_hdd_del_tx_ptrn() - delete tx pattern
8114 * @adapter: adapter pointer
8115 * @hdd_ctx: hdd context
8116 * @tb: nl attributes
8117 *
8118 * This function reads the NL attributes and forms a DelTxPtrn message
8119 * posts it to SME.
8120 *
8121 */
8122static int
Jeff Johnsone5006672017-08-29 14:39:02 -07008123wlan_hdd_del_tx_ptrn(struct hdd_adapter *adapter, struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008124 struct nlattr **tb)
8125{
8126 struct sSirDelPeriodicTxPtrn *del_req;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308127 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008128 uint32_t request_id, ret;
8129 uint8_t pattern_id = 0;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07008130 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008131
8132 /* Parse and fetch request Id */
8133 if (!tb[PARAM_REQUEST_ID]) {
Jeff Johnson77848112016-06-29 14:52:06 -07008134 hdd_err("attr request id failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008135 return -EINVAL;
8136 }
8137 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
8138 if (request_id == MAX_REQUEST_ID) {
Jeff Johnson77848112016-06-29 14:52:06 -07008139 hdd_err("request_id cannot be MAX");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008140 return -EINVAL;
8141 }
8142
8143 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
8144 if (ret) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08008145 hdd_err("req id to pattern id failed (ret=%d)", ret);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008146 return -EINVAL;
8147 }
8148
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308149 del_req = qdf_mem_malloc(sizeof(*del_req));
Min Liu74a1a502018-10-10 19:59:07 +08008150 if (!del_req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008151 return -ENOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008152
Jeff Johnson1e851a12017-10-28 14:36:12 -07008153 qdf_copy_macaddr(&del_req->mac_address, &adapter->mac_addr);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07008154 hdd_debug(QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07008155 QDF_MAC_ADDR_ARRAY(del_req->mac_address.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008156 del_req->ucPtrnId = pattern_id;
Srinivas Girigowda13d39252017-03-06 16:12:15 -08008157 hdd_debug("Request Id: %u Pattern id: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008158 request_id, del_req->ucPtrnId);
8159
Jeff Johnson34fc63a2018-06-14 10:10:02 -07008160 mac_handle = hdd_ctx->mac_handle;
8161 status = sme_del_periodic_tx_ptrn(mac_handle, del_req);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308162 if (!QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnson77848112016-06-29 14:52:06 -07008163 hdd_err("sme_del_periodic_tx_ptrn failed (err=%d)", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008164 goto fail;
8165 }
8166
Dustin Browne74003f2018-03-14 12:51:58 -07008167 hdd_exit();
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308168 qdf_mem_free(del_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008169 return 0;
8170
8171fail:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308172 qdf_mem_free(del_req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008173 return -EINVAL;
8174}
8175
8176
8177/**
8178 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
8179 * @wiphy: Pointer to wireless phy
8180 * @wdev: Pointer to wireless device
8181 * @data: Pointer to data
8182 * @data_len: Data length
8183 *
8184 * Return: 0 on success, negative errno on failure
8185 */
8186static int
8187__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
8188 struct wireless_dev *wdev,
8189 const void *data,
8190 int data_len)
8191{
8192 struct net_device *dev = wdev->netdev;
Jeff Johnsone5006672017-08-29 14:39:02 -07008193 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07008194 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008195 struct nlattr *tb[PARAM_MAX + 1];
8196 uint8_t control;
8197 int ret;
8198 static const struct nla_policy policy[PARAM_MAX + 1] = {
8199 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
8200 [PARAM_CONTROL] = { .type = NLA_U32 },
8201 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
Anurag Chouhan6d760662016-02-20 16:05:43 +05308202 .len = QDF_MAC_ADDR_SIZE },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008203 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
Anurag Chouhan6d760662016-02-20 16:05:43 +05308204 .len = QDF_MAC_ADDR_SIZE },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008205 [PARAM_PERIOD] = { .type = NLA_U32 },
Arun Kumar Khandavallif1f65922019-02-27 16:00:24 +05308206 [PARAM_PROTO_TYPE] = {.type = NLA_U16},
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008207 };
8208
Dustin Brownfdf17c12018-03-14 12:55:34 -07008209 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008210
Anurag Chouhan6d760662016-02-20 16:05:43 +05308211 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008212 hdd_err("Command not allowed in FTM mode");
8213 return -EPERM;
8214 }
8215
8216 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05308217 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008218 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008219
8220 if (!sme_is_feature_supported_by_fw(WLAN_PERIODIC_TX_PTRN)) {
Jeff Johnson77848112016-06-29 14:52:06 -07008221 hdd_err("Periodic Tx Pattern Offload feature is not supported in FW!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008222 return -ENOTSUPP;
8223 }
8224
Dustin Brown4ea21db2018-01-05 14:13:17 -08008225 if (wlan_cfg80211_nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
Jeff Johnson77848112016-06-29 14:52:06 -07008226 hdd_err("Invalid ATTR");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008227 return -EINVAL;
8228 }
8229
8230 if (!tb[PARAM_CONTROL]) {
Jeff Johnson77848112016-06-29 14:52:06 -07008231 hdd_err("attr control failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008232 return -EINVAL;
8233 }
8234 control = nla_get_u32(tb[PARAM_CONTROL]);
Srinivas Girigowda13d39252017-03-06 16:12:15 -08008235 hdd_debug("Control: %d", control);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008236
8237 if (control == WLAN_START_OFFLOADED_PACKETS)
8238 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
Jeff Johnson68755312017-02-10 11:46:55 -08008239 if (control == WLAN_STOP_OFFLOADED_PACKETS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008240 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
Jeff Johnson68755312017-02-10 11:46:55 -08008241
8242 hdd_err("Invalid control: %d", control);
Jeff Johnson68755312017-02-10 11:46:55 -08008243 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008244}
8245
8246/*
8247 * done with short names for the global vendor params
8248 * used by __wlan_hdd_cfg80211_offloaded_packets()
8249 */
8250#undef PARAM_MAX
8251#undef PARAM_REQUEST_ID
8252#undef PARAM_CONTROL
8253#undef PARAM_IP_PACKET
8254#undef PARAM_SRC_MAC_ADDR
8255#undef PARAM_DST_MAC_ADDR
8256#undef PARAM_PERIOD
Arun Kumar Khandavallif1f65922019-02-27 16:00:24 +05308257#undef PARAM_PROTO_TYPE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008258
8259/**
8260 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
8261 * @wiphy: wiphy structure pointer
8262 * @wdev: Wireless device structure pointer
8263 * @data: Pointer to the data received
8264 * @data_len: Length of @data
8265 *
8266 * Return: 0 on success; errno on failure
8267 */
8268static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
8269 struct wireless_dev *wdev,
8270 const void *data,
8271 int data_len)
8272{
Dustin Browna09acf42018-11-08 12:32:26 +05308273 int errno;
8274 struct osif_vdev_sync *vdev_sync;
8275
8276 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
8277 if (errno)
8278 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008279
Dustin Browna09acf42018-11-08 12:32:26 +05308280 errno = __wlan_hdd_cfg80211_offloaded_packets(wiphy, wdev,
8281 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008282
Dustin Browna09acf42018-11-08 12:32:26 +05308283 osif_vdev_sync_op_stop(vdev_sync);
8284
8285 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008286}
8287#endif
8288
Qiwei Cai1083f5b2018-07-02 19:10:11 +08008289#ifdef WLAN_NS_OFFLOAD
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308290static const struct nla_policy
8291ns_offload_set_policy[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX + 1] = {
8292 [QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG] = {.type = NLA_U8},
8293};
8294
8295/**
8296 * __wlan_hdd_cfg80211_set_ns_offload() - enable/disable NS offload
8297 * @wiphy: Pointer to wireless phy
8298 * @wdev: Pointer to wireless device
8299 * @data: Pointer to data
8300 * @data_len: Length of @data
8301 *
8302 * Return: 0 on success, negative errno on failure
8303 */
8304static int
8305__wlan_hdd_cfg80211_set_ns_offload(struct wiphy *wiphy,
8306 struct wireless_dev *wdev,
8307 const void *data, int data_len)
8308{
8309 int status;
8310 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX + 1];
Jeff Johnsonb8944722017-09-03 09:03:19 -07008311 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Dustin Brownd8279d22016-09-07 14:52:57 -07008312 struct net_device *dev = wdev->netdev;
Jeff Johnsone5006672017-08-29 14:39:02 -07008313 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308314
Dustin Brownfdf17c12018-03-14 12:55:34 -07008315 hdd_enter_dev(wdev->netdev);
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308316
Jeff Johnsonb8944722017-09-03 09:03:19 -07008317 status = wlan_hdd_validate_context(hdd_ctx);
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308318 if (0 != status)
8319 return status;
Wu Gao66454f12018-09-26 19:55:41 +08008320
8321 if (!ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc)) {
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308322 hdd_err("ND Offload not supported");
8323 return -EINVAL;
8324 }
8325
Wu Gao66454f12018-09-26 19:55:41 +08008326 if (!ucfg_pmo_is_active_mode_offloaded(hdd_ctx->psoc)) {
Mukul Sharma495df602017-09-25 14:52:18 +05308327 hdd_warn("Active mode offload is disabled");
8328 return -EINVAL;
8329 }
8330
Dustin Brown4ea21db2018-01-05 14:13:17 -08008331 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_MAX,
8332 (struct nlattr *)data, data_len,
8333 ns_offload_set_policy)) {
8334 hdd_err("nla_parse failed");
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308335 return -EINVAL;
8336 }
8337
8338 if (!tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG]) {
8339 hdd_err("ND Offload flag attribute not present");
8340 return -EINVAL;
8341 }
8342
Jeff Johnsonb8944722017-09-03 09:03:19 -07008343 hdd_ctx->ns_offload_enable =
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308344 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ND_OFFLOAD_FLAG]);
8345
Nachiket Kukadedbffab82017-04-25 19:26:02 +05308346 if (QDF_IBSS_MODE == adapter->device_mode) {
8347 hdd_debug("NS Offload is not supported in IBSS mode");
8348 return -EINVAL;
8349 }
8350
Dustin Brownd8279d22016-09-07 14:52:57 -07008351 /* update ns offload in case it is already enabled/disabled */
Jeff Johnsonb8944722017-09-03 09:03:19 -07008352 if (hdd_ctx->ns_offload_enable)
Mukul Sharma3ba26b82017-01-12 21:59:41 +05308353 hdd_enable_ns_offload(adapter, pmo_ns_offload_dynamic_update);
8354 else
8355 hdd_disable_ns_offload(adapter, pmo_ns_offload_dynamic_update);
Dustin Brownd8279d22016-09-07 14:52:57 -07008356
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308357 return 0;
8358}
8359
8360/**
8361 * wlan_hdd_cfg80211_set_ns_offload() - enable/disable NS offload
8362 * @wiphy: pointer to wireless wiphy structure.
8363 * @wdev: pointer to wireless_dev structure.
8364 * @data: Pointer to the data to be passed via vendor interface
8365 * @data_len:Length of the data to be passed
8366 *
8367 * Return: Return the Success or Failure code.
8368 */
8369static int wlan_hdd_cfg80211_set_ns_offload(struct wiphy *wiphy,
8370 struct wireless_dev *wdev,
8371 const void *data, int data_len)
8372{
Dustin Browna09acf42018-11-08 12:32:26 +05308373 int errno;
8374 struct osif_vdev_sync *vdev_sync;
8375
8376 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
8377 if (errno)
8378 return errno;
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308379
Dustin Browna09acf42018-11-08 12:32:26 +05308380 errno = __wlan_hdd_cfg80211_set_ns_offload(wiphy, wdev, data, data_len);
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308381
Dustin Browna09acf42018-11-08 12:32:26 +05308382 osif_vdev_sync_op_stop(vdev_sync);
8383
8384 return errno;
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308385}
Qiwei Cai1083f5b2018-07-02 19:10:11 +08008386#endif /* WLAN_NS_OFFLOAD */
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +05308387
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308388/**
8389 * struct weighed_pcl: Preferred channel info
8390 * @freq: Channel frequency
8391 * @weight: Weightage of the channel
8392 * @flag: Validity of the channel in p2p negotiation
8393 */
8394struct weighed_pcl {
8395 u32 freq;
8396 u32 weight;
8397 u32 flag;
8398};
8399
Jeff Johnsondd7bd3e2017-06-05 13:25:24 -07008400static const struct nla_policy get_preferred_freq_list_policy
8401 [QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_MAX + 1] = {
8402 [QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE] = {
8403 .type = NLA_U32},
8404};
8405
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308406static uint32_t wlan_hdd_populate_weigh_pcl(
8407 struct policy_mgr_pcl_chan_weights *
8408 chan_weights,
8409 struct weighed_pcl *w_pcl,
8410 enum policy_mgr_con_mode intf_mode)
8411{
8412 int i, j;
8413 uint32_t chan_idx = 0;
8414 uint32_t set = 0;
8415 uint32_t pcl_len = chan_weights->pcl_len;
8416 uint32_t valid_weight;
8417
8418 /* convert channel number to frequency */
8419 for (i = 0; i < chan_weights->pcl_len; i++) {
8420 if (chan_weights->pcl_list[i] <=
8421 ARRAY_SIZE(hdd_channels_2_4_ghz))
8422 w_pcl[i].freq = ieee80211_channel_to_frequency(
8423 chan_weights->pcl_list[i],
8424 HDD_NL80211_BAND_2GHZ);
8425 else
8426 w_pcl[i].freq = ieee80211_channel_to_frequency(
8427 chan_weights->pcl_list[i],
8428 HDD_NL80211_BAND_5GHZ);
8429 w_pcl[i].weight = chan_weights->weight_list[i];
8430
8431 if (intf_mode == PM_SAP_MODE || intf_mode == PM_P2P_GO_MODE)
8432 w_pcl[i].flag = set | PCL_CHANNEL_SUPPORT_GO;
8433 else
8434 w_pcl[i].flag = set | PCL_CHANNEL_SUPPORT_CLI;
8435 }
8436 chan_idx = pcl_len;
Rajeev Kumar Sirasanagandla50b2c102019-07-18 19:27:49 +05308437 if (pcl_len && chan_weights->weight_list[pcl_len - 1] >
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308438 PCL_GROUPS_WEIGHT_DIFFERENCE)
8439 /* Set non-pcl channels weight 20 point less than the last PCL entry */
8440 valid_weight = chan_weights->weight_list[pcl_len - 1] -
8441 PCL_GROUPS_WEIGHT_DIFFERENCE;
8442 else
8443 valid_weight = 1;
8444
8445 /* Include rest of the valid channels */
8446 for (i = 0; i < chan_weights->saved_num_chan; i++) {
8447 for (j = 0; j < chan_weights->pcl_len; j++) {
8448 if (chan_weights->saved_chan_list[i] ==
8449 chan_weights->pcl_list[j])
8450 break;
8451 }
8452 if (j == chan_weights->pcl_len) {
8453 if (chan_weights->saved_chan_list[i] <=
8454 ARRAY_SIZE(hdd_channels_2_4_ghz))
8455 w_pcl[chan_idx].freq =
8456 ieee80211_channel_to_frequency(
8457 chan_weights->saved_chan_list[i],
8458 HDD_NL80211_BAND_2GHZ);
8459 else
8460 w_pcl[chan_idx].freq =
8461 ieee80211_channel_to_frequency(
8462 chan_weights->saved_chan_list[i],
8463 HDD_NL80211_BAND_5GHZ);
8464
8465 if (!chan_weights->weighed_valid_list[i]) {
8466 w_pcl[chan_idx].flag =
8467 set | PCL_CHANNEL_EXCLUDE_IN_GO_NEG;
8468 w_pcl[chan_idx].weight = 0;
8469 } else {
8470 if (intf_mode == PM_SAP_MODE ||
8471 intf_mode == PM_P2P_GO_MODE)
8472 w_pcl[chan_idx].flag =
8473 set | PCL_CHANNEL_SUPPORT_GO;
8474 else
8475 w_pcl[chan_idx].flag =
8476 set | PCL_CHANNEL_SUPPORT_CLI;
8477 w_pcl[chan_idx].weight = valid_weight;
8478 }
8479 chan_idx++;
8480 }
8481 }
8482 return chan_idx;
8483}
8484
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008485/** __wlan_hdd_cfg80211_get_preferred_freq_list() - get preferred frequency list
8486 * @wiphy: Pointer to wireless phy
8487 * @wdev: Pointer to wireless device
8488 * @data: Pointer to data
8489 * @data_len: Data length
8490 *
8491 * This function return the preferred frequency list generated by the policy
8492 * manager.
8493 *
8494 * Return: success or failure code
8495 */
8496static int __wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy,
8497 struct wireless_dev
8498 *wdev, const void *data,
8499 int data_len)
8500{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07008501 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008502 int i, ret = 0;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308503 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008504 uint32_t pcl_len = 0;
Manishekar Chandrasekaran1db3abe2016-06-24 03:27:07 +05308505 uint32_t freq_list[QDF_MAX_NUM_CHAN];
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -08008506 enum policy_mgr_con_mode intf_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008507 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_MAX + 1];
8508 struct sk_buff *reply_skb;
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308509 struct weighed_pcl *w_pcl;
8510 struct nlattr *nla_attr, *channel;
8511 struct policy_mgr_pcl_chan_weights *chan_weights;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008512
Dustin Brownfdf17c12018-03-14 12:55:34 -07008513 hdd_enter_dev(wdev->netdev);
Jeff Johnson1f61b612016-02-12 16:28:33 -08008514
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008515 ret = wlan_hdd_validate_context(hdd_ctx);
8516 if (ret)
8517 return -EINVAL;
8518
Dustin Brown4ea21db2018-01-05 14:13:17 -08008519 if (wlan_cfg80211_nla_parse(tb,
8520 QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_MAX,
8521 data, data_len,
8522 get_preferred_freq_list_policy)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008523 hdd_err("Invalid ATTR");
8524 return -EINVAL;
8525 }
8526
8527 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE]) {
8528 hdd_err("attr interface type failed");
8529 return -EINVAL;
8530 }
8531
8532 intf_mode = nla_get_u32(tb
8533 [QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE]);
8534
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -08008535 if (intf_mode < PM_STA_MODE || intf_mode >= PM_MAX_NUM_OF_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008536 hdd_err("Invalid interface type");
8537 return -EINVAL;
8538 }
8539
8540 hdd_debug("Userspace requested pref freq list");
8541
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308542 chan_weights =
8543 qdf_mem_malloc(sizeof(struct policy_mgr_pcl_chan_weights));
8544 if (!chan_weights)
8545 return -ENOMEM;
8546
Dustin Brown76cd2932018-09-11 16:03:05 -07008547 status = policy_mgr_get_pcl(hdd_ctx->psoc,
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308548 intf_mode, chan_weights->pcl_list,
8549 &chan_weights->pcl_len,
8550 chan_weights->weight_list,
8551 QDF_ARRAY_SIZE(chan_weights->weight_list));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05308552 if (status != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008553 hdd_err("Get pcl failed");
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308554 qdf_mem_free(chan_weights);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008555 return -EINVAL;
8556 }
gaurank kathpalia5aafb672019-06-24 17:11:15 +05308557 chan_weights->saved_num_chan = POLICY_MGR_MAX_CHANNEL_LIST;
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308558 sme_get_valid_channels(chan_weights->saved_chan_list,
8559 &chan_weights->saved_num_chan);
8560 policy_mgr_get_valid_chan_weights(hdd_ctx->psoc, chan_weights);
8561 w_pcl = qdf_mem_malloc(sizeof(struct weighed_pcl) * QDF_MAX_NUM_CHAN);
8562 if (!w_pcl) {
8563 qdf_mem_free(chan_weights);
8564 return -ENOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008565 }
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308566 pcl_len = wlan_hdd_populate_weigh_pcl(chan_weights, w_pcl, intf_mode);
8567 qdf_mem_free(chan_weights);
8568
8569 for (i = 0; i < pcl_len; i++)
8570 freq_list[i] = w_pcl[i].freq;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008571
8572 /* send the freq_list back to supplicant */
8573 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308574 sizeof(u32) * pcl_len +
8575 sizeof(struct weighed_pcl) * pcl_len +
8576 NLMSG_HDRLEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008577
8578 if (!reply_skb) {
8579 hdd_err("Allocate reply_skb failed");
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308580 qdf_mem_free(w_pcl);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008581 return -EINVAL;
8582 }
8583
8584 if (nla_put_u32(reply_skb,
8585 QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_IFACE_TYPE,
8586 intf_mode) ||
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308587 nla_put(reply_skb,
8588 QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST,
8589 sizeof(uint32_t) * pcl_len,
8590 freq_list)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008591 hdd_err("nla put fail");
8592 kfree_skb(reply_skb);
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308593 qdf_mem_free(w_pcl);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008594 return -EINVAL;
8595 }
8596
Jayachandran Sreekumaran91f96ec2019-01-09 17:37:33 +05308597 i = QCA_WLAN_VENDOR_ATTR_GET_PREFERRED_FREQ_LIST_WEIGHED_PCL;
8598 nla_attr = nla_nest_start(reply_skb, i);
8599
8600 if (!nla_attr) {
8601 hdd_err("nla nest start fail");
8602 kfree_skb(reply_skb);
8603 qdf_mem_free(w_pcl);
8604 return -EINVAL;
8605 }
8606
8607 for (i = 0; i < pcl_len; i++) {
8608 channel = nla_nest_start(reply_skb, i);
8609 if (!channel) {
8610 hdd_err("updating pcl list failed");
8611 kfree_skb(reply_skb);
8612 qdf_mem_free(w_pcl);
8613 return -EINVAL;
8614 }
8615 if (nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_PCL_FREQ,
8616 w_pcl[i].freq) ||
8617 nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_PCL_WEIGHT,
8618 w_pcl[i].weight) ||
8619 nla_put_u32(reply_skb, QCA_WLAN_VENDOR_ATTR_PCL_FLAG,
8620 w_pcl[i].flag)) {
8621 hdd_err("nla put fail");
8622 kfree_skb(reply_skb);
8623 qdf_mem_free(w_pcl);
8624 return -EINVAL;
8625 }
8626 nla_nest_end(reply_skb, channel);
8627 }
8628 nla_nest_end(reply_skb, nla_attr);
8629 qdf_mem_free(w_pcl);
8630
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008631 return cfg80211_vendor_cmd_reply(reply_skb);
8632}
8633
8634/** wlan_hdd_cfg80211_get_preferred_freq_list () - get preferred frequency list
8635 * @wiphy: Pointer to wireless phy
8636 * @wdev: Pointer to wireless device
8637 * @data: Pointer to data
8638 * @data_len: Data length
8639 *
8640 * This function return the preferred frequency list generated by the policy
8641 * manager.
8642 *
8643 * Return: success or failure code
8644 */
8645static int wlan_hdd_cfg80211_get_preferred_freq_list(struct wiphy *wiphy,
8646 struct wireless_dev
8647 *wdev, const void *data,
8648 int data_len)
8649{
Dustin Brown363b4792019-02-05 16:11:55 -08008650 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08008651 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05308652
Dustin Brown363b4792019-02-05 16:11:55 -08008653 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08008654 if (errno)
8655 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008656
Dustin Brownf0f00612019-01-31 16:02:24 -08008657 errno = __wlan_hdd_cfg80211_get_preferred_freq_list(wiphy, wdev,
8658 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008659
Dustin Brown363b4792019-02-05 16:11:55 -08008660 osif_psoc_sync_op_stop(psoc_sync);
Arunk Khandavalli99716d12018-11-14 15:02:02 +05308661
Dustin Brownf0f00612019-01-31 16:02:24 -08008662 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008663}
8664
Jeff Johnsone5f33ba2017-06-05 14:48:48 -07008665static const struct nla_policy set_probable_oper_channel_policy
8666 [QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_MAX + 1] = {
8667 [QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_IFACE_TYPE] = {
8668 .type = NLA_U32},
8669 [QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ] = {
8670 .type = NLA_U32},
8671};
8672
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008673/**
8674 * __wlan_hdd_cfg80211_set_probable_oper_channel () - set probable channel
8675 * @wiphy: Pointer to wireless phy
8676 * @wdev: Pointer to wireless device
8677 * @data: Pointer to data
8678 * @data_len: Data length
8679 *
8680 * Return: 0 on success, negative errno on failure
8681 */
8682static int __wlan_hdd_cfg80211_set_probable_oper_channel(struct wiphy *wiphy,
8683 struct wireless_dev *wdev,
8684 const void *data,
8685 int data_len)
8686{
Chandrasekaran, Manishekaref70c0d2015-10-20 19:54:55 +05308687 struct net_device *ndev = wdev->netdev;
Jeff Johnsone5006672017-08-29 14:39:02 -07008688 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07008689 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008690 int ret = 0;
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -08008691 enum policy_mgr_con_mode intf_mode;
Jeff Johnsone5f33ba2017-06-05 14:48:48 -07008692 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_MAX + 1];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008693 uint32_t channel_hint;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008694
Dustin Brownfdf17c12018-03-14 12:55:34 -07008695 hdd_enter_dev(ndev);
Jeff Johnson1f61b612016-02-12 16:28:33 -08008696
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008697 ret = wlan_hdd_validate_context(hdd_ctx);
8698 if (ret)
8699 return ret;
8700
Dustin Brown4ea21db2018-01-05 14:13:17 -08008701 if (wlan_cfg80211_nla_parse(tb,
8702 QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_MAX,
8703 data, data_len,
8704 set_probable_oper_channel_policy)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008705 hdd_err("Invalid ATTR");
8706 return -EINVAL;
8707 }
8708
8709 if (!tb[QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_IFACE_TYPE]) {
8710 hdd_err("attr interface type failed");
8711 return -EINVAL;
8712 }
8713
8714 intf_mode = nla_get_u32(tb
8715 [QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_IFACE_TYPE]);
8716
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -08008717 if (intf_mode < PM_STA_MODE || intf_mode >= PM_MAX_NUM_OF_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008718 hdd_err("Invalid interface type");
8719 return -EINVAL;
8720 }
8721
8722 if (!tb[QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ]) {
8723 hdd_err("attr probable freq failed");
8724 return -EINVAL;
8725 }
8726
8727 channel_hint = cds_freq_to_chan(nla_get_u32(tb
8728 [QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ]));
8729
8730 /* check pcl table */
Dustin Brown76cd2932018-09-11 16:03:05 -07008731 if (!policy_mgr_allow_concurrency(hdd_ctx->psoc, intf_mode,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008732 channel_hint, HW_MODE_20_MHZ)) {
8733 hdd_err("Set channel hint failed due to concurrency check");
8734 return -EINVAL;
8735 }
8736
Krunal Soni09e55032016-06-07 10:06:55 -07008737 if (0 != wlan_hdd_check_remain_on_channel(adapter))
8738 hdd_warn("Remain On Channel Pending");
8739
Krunal Sonied3bc8e2018-01-26 12:13:34 -08008740 if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, channel_hint,
8741 POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
8742 hdd_err("Failed to change hw mode");
Krunal Soni3091bcc2016-06-23 12:28:21 -07008743 return -EINVAL;
8744 }
8745
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008746 return 0;
8747}
8748
8749/**
8750 * wlan_hdd_cfg80211_set_probable_oper_channel () - set probable channel
8751 * @wiphy: Pointer to wireless phy
8752 * @wdev: Pointer to wireless device
8753 * @data: Pointer to data
8754 * @data_len: Data length
8755 *
8756 * Return: 0 on success, negative errno on failure
8757 */
8758static int wlan_hdd_cfg80211_set_probable_oper_channel(struct wiphy *wiphy,
8759 struct wireless_dev *wdev,
8760 const void *data,
8761 int data_len)
8762{
Dustin Browna09acf42018-11-08 12:32:26 +05308763 int errno;
8764 struct osif_vdev_sync *vdev_sync;
8765
8766 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
8767 if (errno)
8768 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008769
Dustin Browna09acf42018-11-08 12:32:26 +05308770 errno = __wlan_hdd_cfg80211_set_probable_oper_channel(wiphy, wdev,
8771 data, data_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008772
Dustin Browna09acf42018-11-08 12:32:26 +05308773 osif_vdev_sync_op_stop(vdev_sync);
8774
8775 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008776}
8777
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308778static const struct
8779nla_policy
8780qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Ashish Kumar Dhanotiya81e2acc2017-06-21 12:30:32 +05308781 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
8782 .type = NLA_BINARY, .len = QDF_MAC_ADDR_SIZE },
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308783};
8784
8785/**
8786 * __wlan_hdd_cfg80211_get_link_properties() - Get link properties
8787 * @wiphy: WIPHY structure pointer
8788 * @wdev: Wireless device structure pointer
8789 * @data: Pointer to the data received
8790 * @data_len: Length of the data received
8791 *
8792 * This function is used to get link properties like nss, rate flags and
8793 * operating frequency for the active connection with the given peer.
8794 *
8795 * Return: 0 on success and errno on failure
8796 */
8797static int __wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
8798 struct wireless_dev *wdev,
8799 const void *data,
8800 int data_len)
8801{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07008802 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308803 struct net_device *dev = wdev->netdev;
Jeff Johnsone5006672017-08-29 14:39:02 -07008804 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson40dae4e2017-08-29 14:00:25 -07008805 struct hdd_station_ctx *hdd_sta_ctx;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308806 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
Anurag Chouhan6d760662016-02-20 16:05:43 +05308807 uint8_t peer_mac[QDF_MAC_ADDR_SIZE];
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308808 uint32_t sta_id;
8809 struct sk_buff *reply_skb;
8810 uint32_t rate_flags = 0;
8811 uint8_t nss;
8812 uint8_t final_rate_flags = 0;
8813 uint32_t freq;
8814
Dustin Brownfdf17c12018-03-14 12:55:34 -07008815 hdd_enter_dev(dev);
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308816
Anurag Chouhan6d760662016-02-20 16:05:43 +05308817 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308818 hdd_err("Command not allowed in FTM mode");
8819 return -EPERM;
8820 }
8821
8822 if (0 != wlan_hdd_validate_context(hdd_ctx))
8823 return -EINVAL;
8824
Dustin Brown4ea21db2018-01-05 14:13:17 -08008825 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data,
8826 data_len, qca_wlan_vendor_attr_policy)) {
Jeff Johnson77848112016-06-29 14:52:06 -07008827 hdd_err("Invalid attribute");
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308828 return -EINVAL;
8829 }
8830
8831 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
Jeff Johnson77848112016-06-29 14:52:06 -07008832 hdd_err("Attribute peerMac not provided for mode=%d",
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308833 adapter->device_mode);
8834 return -EINVAL;
8835 }
8836
Ashish Kumar Dhanotiya81e2acc2017-06-21 12:30:32 +05308837 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < QDF_MAC_ADDR_SIZE) {
8838 hdd_err("Attribute peerMac is invalid for mode=%d",
8839 adapter->device_mode);
8840 return -EINVAL;
8841 }
8842
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308843 qdf_mem_copy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
Anurag Chouhan6d760662016-02-20 16:05:43 +05308844 QDF_MAC_ADDR_SIZE);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07008845 hdd_debug("peerMac="QDF_MAC_ADDR_STR" for device_mode:%d",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07008846 QDF_MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308847
Krunal Sonib4326f22016-03-10 13:05:51 -08008848 if (adapter->device_mode == QDF_STA_MODE ||
8849 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308850 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnsone7951512019-02-27 10:02:51 -08008851 if ((hdd_sta_ctx->conn_info.conn_state !=
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308852 eConnectionState_Associated) ||
Jeff Johnsone04b6992019-02-27 14:06:55 -08008853 qdf_mem_cmp(hdd_sta_ctx->conn_info.bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05308854 peer_mac, QDF_MAC_ADDR_SIZE)) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07008855 hdd_err("Not Associated to mac "QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07008856 QDF_MAC_ADDR_ARRAY(peer_mac));
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308857 return -EINVAL;
8858 }
8859
8860 nss = hdd_sta_ctx->conn_info.nss;
8861 freq = cds_chan_to_freq(
Jeff Johnson8626e932019-02-27 18:35:22 -08008862 hdd_sta_ctx->conn_info.channel);
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308863 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
Krunal Sonib4326f22016-03-10 13:05:51 -08008864 } else if (adapter->device_mode == QDF_P2P_GO_MODE ||
8865 adapter->device_mode == QDF_SAP_MODE) {
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308866
8867 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -07008868 if (adapter->sta_info[sta_id].in_use &&
Anurag Chouhanc5548422016-02-24 18:33:27 +05308869 !qdf_is_macaddr_broadcast(
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -07008870 &adapter->sta_info[sta_id].sta_mac) &&
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308871 !qdf_mem_cmp(
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -07008872 &adapter->sta_info[sta_id].sta_mac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05308873 peer_mac, QDF_MAC_ADDR_SIZE))
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308874 break;
8875 }
8876
8877 if (WLAN_MAX_STA_COUNT == sta_id) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07008878 hdd_err("No active peer with mac="QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07008879 QDF_MAC_ADDR_ARRAY(peer_mac));
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308880 return -EINVAL;
8881 }
8882
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -07008883 nss = adapter->sta_info[sta_id].nss;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308884 freq = cds_chan_to_freq(
Jeff Johnson01206862017-10-27 20:55:59 -07008885 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operating_channel);
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -07008886 rate_flags = adapter->sta_info[sta_id].rate_flags;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308887 } else {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07008888 hdd_err("Not Associated! with mac "QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07008889 QDF_MAC_ADDR_ARRAY(peer_mac));
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308890 return -EINVAL;
8891 }
8892
Naveen Rawatea1564b2018-05-17 15:56:11 -07008893 if (!(rate_flags & TX_RATE_LEGACY)) {
8894 if (rate_flags & TX_RATE_VHT80) {
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308895 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Ryan Hsu3a0f5232016-01-21 14:40:11 -08008896#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308897 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Ryan Hsu3a0f5232016-01-21 14:40:11 -08008898#endif
Naveen Rawatea1564b2018-05-17 15:56:11 -07008899 } else if (rate_flags & TX_RATE_VHT40) {
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308900 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Ryan Hsu3a0f5232016-01-21 14:40:11 -08008901#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308902 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Ryan Hsu3a0f5232016-01-21 14:40:11 -08008903#endif
Naveen Rawatea1564b2018-05-17 15:56:11 -07008904 } else if (rate_flags & TX_RATE_VHT20) {
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308905 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
8906 } else if (rate_flags &
Naveen Rawatea1564b2018-05-17 15:56:11 -07008907 (TX_RATE_HT20 | TX_RATE_HT40)) {
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308908 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Ryan Hsu3a0f5232016-01-21 14:40:11 -08008909#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && !defined(WITH_BACKPORTS)
Naveen Rawatea1564b2018-05-17 15:56:11 -07008910 if (rate_flags & TX_RATE_HT40)
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308911 final_rate_flags |=
8912 RATE_INFO_FLAGS_40_MHZ_WIDTH;
Ryan Hsu3a0f5232016-01-21 14:40:11 -08008913#endif
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308914 }
8915
Naveen Rawatea1564b2018-05-17 15:56:11 -07008916 if (rate_flags & TX_RATE_SGI) {
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308917 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
8918 final_rate_flags |= RATE_INFO_FLAGS_MCS;
8919 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
8920 }
8921 }
8922
8923 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8924 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
8925
Jeff Johnsond36fa332019-03-18 13:42:25 -07008926 if (!reply_skb) {
Jeff Johnson77848112016-06-29 14:52:06 -07008927 hdd_err("getLinkProperties: skb alloc failed");
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308928 return -EINVAL;
8929 }
8930
8931 if (nla_put_u8(reply_skb,
8932 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
8933 nss) ||
8934 nla_put_u8(reply_skb,
8935 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
8936 final_rate_flags) ||
8937 nla_put_u32(reply_skb,
8938 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
8939 freq)) {
Jeff Johnson77848112016-06-29 14:52:06 -07008940 hdd_err("nla_put failed");
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308941 kfree_skb(reply_skb);
8942 return -EINVAL;
8943 }
8944
8945 return cfg80211_vendor_cmd_reply(reply_skb);
8946}
8947
8948/**
8949 * wlan_hdd_cfg80211_get_link_properties() - Wrapper function to get link
8950 * properties.
8951 * @wiphy: WIPHY structure pointer
8952 * @wdev: Wireless device structure pointer
8953 * @data: Pointer to the data received
8954 * @data_len: Length of the data received
8955 *
8956 * This function is used to get link properties like nss, rate flags and
8957 * operating frequency for the active connection with the given peer.
8958 *
8959 * Return: 0 on success and errno on failure
8960 */
8961static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
8962 struct wireless_dev *wdev,
8963 const void *data,
8964 int data_len)
8965{
Dustin Browna09acf42018-11-08 12:32:26 +05308966 int errno;
8967 struct osif_vdev_sync *vdev_sync;
8968
8969 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
8970 if (errno)
8971 return errno;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308972
Dustin Browna09acf42018-11-08 12:32:26 +05308973 errno = __wlan_hdd_cfg80211_get_link_properties(wiphy, wdev,
8974 data, data_len);
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308975
Dustin Browna09acf42018-11-08 12:32:26 +05308976 osif_vdev_sync_op_stop(vdev_sync);
8977
8978 return errno;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +05308979}
8980
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05308981static const struct nla_policy
8982wlan_hdd_sap_config_policy[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX + 1] = {
8983 [QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL] = {.type = NLA_U8 },
Ganesh Kondabattini099e6e82017-06-28 12:24:20 +05308984 [QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST] = {
8985 .type = NLA_NESTED },
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05308986};
8987
Agrawal Ashish65634612016-08-18 13:24:32 +05308988static const struct nla_policy
8989wlan_hdd_set_acs_dfs_config_policy[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX + 1] = {
8990 [QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE] = {.type = NLA_U8 },
8991 [QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT] = {.type = NLA_U8 },
8992};
8993
8994/**
8995 * __wlan_hdd_cfg80211_acs_dfs_mode() - set ACS DFS mode and channel
8996 * @wiphy: Pointer to wireless phy
8997 * @wdev: Pointer to wireless device
8998 * @data: Pointer to data
8999 * @data_len: Length of @data
9000 *
9001 * This function parses the incoming NL vendor command data attributes and
9002 * updates the SAP context about channel_hint and DFS mode.
9003 * If channel_hint is set, SAP will choose that channel
9004 * as operating channel.
9005 *
9006 * If DFS mode is enabled, driver will include DFS channels
9007 * in ACS else driver will skip DFS channels.
9008 *
9009 * Return: 0 on success, negative errno on failure
9010 */
9011static int
9012__wlan_hdd_cfg80211_acs_dfs_mode(struct wiphy *wiphy,
9013 struct wireless_dev *wdev,
9014 const void *data, int data_len)
9015{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07009016 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Agrawal Ashish65634612016-08-18 13:24:32 +05309017 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX + 1];
9018 int ret;
9019 struct acs_dfs_policy *acs_policy;
9020 int mode = DFS_MODE_NONE;
9021 int channel_hint = 0;
9022
Dustin Brownfdf17c12018-03-14 12:55:34 -07009023 hdd_enter_dev(wdev->netdev);
Agrawal Ashish65634612016-08-18 13:24:32 +05309024
9025 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
9026 hdd_err("Command not allowed in FTM mode");
9027 return -EINVAL;
9028 }
9029
9030 ret = wlan_hdd_validate_context(hdd_ctx);
9031 if (0 != ret)
9032 return ret;
9033
Dustin Brown4ea21db2018-01-05 14:13:17 -08009034 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX,
9035 data, data_len,
9036 wlan_hdd_set_acs_dfs_config_policy)) {
Agrawal Ashish65634612016-08-18 13:24:32 +05309037 hdd_err("invalid attr");
9038 return -EINVAL;
9039 }
9040
9041 acs_policy = &hdd_ctx->acs_policy;
9042 /*
9043 * SCM sends this attribute to restrict SAP from choosing
9044 * DFS channels from ACS.
9045 */
9046 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE])
9047 mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE]);
9048
9049 if (!IS_DFS_MODE_VALID(mode)) {
9050 hdd_err("attr acs dfs mode is not valid");
9051 return -EINVAL;
9052 }
9053 acs_policy->acs_dfs_mode = mode;
9054
9055 /*
9056 * SCM sends this attribute to provide an active channel,
9057 * to skip redundant ACS between drivers, and save driver start up time
9058 */
9059 if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT])
9060 channel_hint = nla_get_u8(
9061 tb[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT]);
9062
9063 if (!IS_CHANNEL_VALID(channel_hint)) {
9064 hdd_err("acs channel is not valid");
9065 return -EINVAL;
9066 }
9067 acs_policy->acs_channel = channel_hint;
9068
9069 return 0;
9070}
9071
9072/**
9073 * wlan_hdd_cfg80211_acs_dfs_mode() - Wrapper to set ACS DFS mode
9074 * @wiphy: wiphy structure pointer
9075 * @wdev: Wireless device structure pointer
9076 * @data: Pointer to the data received
9077 * @data_len: Length of @data
9078 *
9079 * This function parses the incoming NL vendor command data attributes and
9080 * updates the SAP context about channel_hint and DFS mode.
9081 *
9082 * Return: 0 on success; errno on failure
9083 */
9084static int wlan_hdd_cfg80211_acs_dfs_mode(struct wiphy *wiphy,
9085 struct wireless_dev *wdev,
9086 const void *data, int data_len)
9087{
Dustin Brown363b4792019-02-05 16:11:55 -08009088 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08009089 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05309090
Dustin Brown363b4792019-02-05 16:11:55 -08009091 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08009092 if (errno)
9093 return errno;
Agrawal Ashish65634612016-08-18 13:24:32 +05309094
Dustin Brownf0f00612019-01-31 16:02:24 -08009095 errno = __wlan_hdd_cfg80211_acs_dfs_mode(wiphy, wdev, data, data_len);
Agrawal Ashish65634612016-08-18 13:24:32 +05309096
Dustin Brown363b4792019-02-05 16:11:55 -08009097 osif_psoc_sync_op_stop(psoc_sync);
Arunk Khandavalli99716d12018-11-14 15:02:02 +05309098
Dustin Brownf0f00612019-01-31 16:02:24 -08009099 return errno;
Agrawal Ashish65634612016-08-18 13:24:32 +05309100}
9101
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309102/**
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309103 * wlan_hdd_get_sta_roam_dfs_mode() - get sta roam dfs mode policy
9104 * @mode : cfg80211 dfs mode
9105 *
9106 * Return: return csr sta roam dfs mode else return NONE
9107 */
9108static enum sta_roam_policy_dfs_mode wlan_hdd_get_sta_roam_dfs_mode(
9109 enum dfs_mode mode)
9110{
9111 switch (mode) {
9112 case DFS_MODE_ENABLE:
9113 return CSR_STA_ROAM_POLICY_DFS_ENABLED;
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309114 case DFS_MODE_DISABLE:
9115 return CSR_STA_ROAM_POLICY_DFS_DISABLED;
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309116 case DFS_MODE_DEPRIORITIZE:
9117 return CSR_STA_ROAM_POLICY_DFS_DEPRIORITIZE;
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309118 default:
9119 hdd_err("STA Roam policy dfs mode is NONE");
9120 return CSR_STA_ROAM_POLICY_NONE;
9121 }
9122}
9123
Agrawal, Ashish9f84c402016-11-30 16:19:44 +05309124/*
9125 * hdd_get_sap_operating_band: Get current operating channel
9126 * for sap.
9127 * @hdd_ctx: hdd context
9128 *
9129 * Return : Corresponding band for SAP operating channel
9130 */
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07009131uint8_t hdd_get_sap_operating_band(struct hdd_context *hdd_ctx)
Agrawal, Ashish9f84c402016-11-30 16:19:44 +05309132{
Jeff Johnsone5006672017-08-29 14:39:02 -07009133 struct hdd_adapter *adapter;
Agrawal, Ashish9f84c402016-11-30 16:19:44 +05309134 uint8_t operating_channel = 0;
9135 uint8_t sap_operating_band = 0;
Srinivas Girigowda576b2352017-08-25 14:44:26 -07009136
Dustin Brown920397d2017-12-13 16:27:50 -08009137 hdd_for_each_adapter(hdd_ctx, adapter) {
9138 if (adapter->device_mode != QDF_SAP_MODE)
Agrawal, Ashish9f84c402016-11-30 16:19:44 +05309139 continue;
Dustin Brown920397d2017-12-13 16:27:50 -08009140
Jeff Johnsonb9424862017-10-30 08:49:35 -07009141 operating_channel = adapter->session.ap.operating_channel;
Agrawal, Ashish9f84c402016-11-30 16:19:44 +05309142 if (IS_24G_CH(operating_channel))
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08009143 sap_operating_band = BAND_2G;
Agrawal, Ashish9f84c402016-11-30 16:19:44 +05309144 else if (IS_5G_CH(operating_channel))
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08009145 sap_operating_band = BAND_5G;
Agrawal, Ashish9f84c402016-11-30 16:19:44 +05309146 else
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08009147 sap_operating_band = BAND_ALL;
Agrawal, Ashish9f84c402016-11-30 16:19:44 +05309148 }
Dustin Brown920397d2017-12-13 16:27:50 -08009149
Agrawal, Ashish9f84c402016-11-30 16:19:44 +05309150 return sap_operating_band;
9151}
9152
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309153static const struct nla_policy
9154wlan_hdd_set_sta_roam_config_policy[
9155QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX + 1] = {
9156 [QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE] = {.type = NLA_U8 },
9157 [QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL] = {.type = NLA_U8 },
9158};
9159
9160/**
9161 * __wlan_hdd_cfg80211_sta_roam_policy() - Set params to restrict scan channels
9162 * for station connection or roaming.
9163 * @wiphy: Pointer to wireless phy
9164 * @wdev: Pointer to wireless device
9165 * @data: Pointer to data
9166 * @data_len: Length of @data
9167 *
9168 * __wlan_hdd_cfg80211_sta_roam_policy will decide if DFS channels or unsafe
9169 * channels needs to be skipped in scanning or not.
9170 * If dfs_mode is disabled, driver will not scan DFS channels.
9171 * If skip_unsafe_channels is set, driver will skip unsafe channels
9172 * in Scanning.
9173 *
9174 * Return: 0 on success, negative errno on failure
9175 */
9176static int
9177__wlan_hdd_cfg80211_sta_roam_policy(struct wiphy *wiphy,
9178 struct wireless_dev *wdev,
9179 const void *data, int data_len)
9180{
9181 struct net_device *dev = wdev->netdev;
Jeff Johnsone5006672017-08-29 14:39:02 -07009182 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07009183 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309184 struct nlattr *tb[
9185 QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX + 1];
9186 int ret;
9187 enum sta_roam_policy_dfs_mode sta_roam_dfs_mode;
9188 enum dfs_mode mode = DFS_MODE_NONE;
9189 bool skip_unsafe_channels = false;
9190 QDF_STATUS status;
Agrawal, Ashish9f84c402016-11-30 16:19:44 +05309191 uint8_t sap_operating_band;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07009192 mac_handle_t mac_handle;
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309193
Dustin Brownfdf17c12018-03-14 12:55:34 -07009194 hdd_enter_dev(dev);
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309195
9196 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
9197 hdd_err("Command not allowed in FTM mode");
9198 return -EINVAL;
9199 }
9200
9201 ret = wlan_hdd_validate_context(hdd_ctx);
9202 if (0 != ret)
9203 return ret;
Dustin Brown4ea21db2018-01-05 14:13:17 -08009204 if (wlan_cfg80211_nla_parse(tb,
9205 QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX,
9206 data, data_len,
9207 wlan_hdd_set_sta_roam_config_policy)) {
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309208 hdd_err("invalid attr");
9209 return -EINVAL;
9210 }
9211 if (tb[QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE])
9212 mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE]);
9213 if (!IS_DFS_MODE_VALID(mode)) {
9214 hdd_err("attr sta roam dfs mode policy is not valid");
9215 return -EINVAL;
9216 }
9217
9218 sta_roam_dfs_mode = wlan_hdd_get_sta_roam_dfs_mode(mode);
9219
9220 if (tb[QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL])
9221 skip_unsafe_channels = nla_get_u8(
9222 tb[QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL]);
Agrawal, Ashish9f84c402016-11-30 16:19:44 +05309223 sap_operating_band = hdd_get_sap_operating_band(hdd_ctx);
Jeff Johnson34fc63a2018-06-14 10:10:02 -07009224 mac_handle = hdd_ctx->mac_handle;
9225 status = sme_update_sta_roam_policy(mac_handle, sta_roam_dfs_mode,
9226 skip_unsafe_channels,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08009227 adapter->vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -07009228 sap_operating_band);
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309229
9230 if (!QDF_IS_STATUS_SUCCESS(status)) {
9231 hdd_err("sme_update_sta_roam_policy (err=%d)", status);
9232 return -EINVAL;
9233 }
9234 return 0;
9235}
9236
9237/**
9238 * wlan_hdd_cfg80211_sta_roam_policy() - Wrapper to restrict scan channels,
9239 * connection and roaming for station.
9240 * @wiphy: wiphy structure pointer
9241 * @wdev: Wireless device structure pointer
9242 * @data: Pointer to the data received
9243 * @data_len: Length of @data
9244 *
9245 * __wlan_hdd_cfg80211_sta_roam_policy will decide if DFS channels or unsafe
9246 * channels needs to be skipped in scanning or not.
9247 * If dfs_mode is disabled, driver will not scan DFS channels.
9248 * If skip_unsafe_channels is set, driver will skip unsafe channels
9249 * in Scanning.
9250 * Return: 0 on success; errno on failure
9251 */
9252static int wlan_hdd_cfg80211_sta_roam_policy(struct wiphy *wiphy,
9253 struct wireless_dev *wdev,
9254 const void *data, int data_len)
9255{
Dustin Browna09acf42018-11-08 12:32:26 +05309256 int errno;
9257 struct osif_vdev_sync *vdev_sync;
9258
9259 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
9260 if (errno)
9261 return errno;
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309262
Dustin Browna09acf42018-11-08 12:32:26 +05309263 errno = __wlan_hdd_cfg80211_sta_roam_policy(wiphy, wdev,
9264 data, data_len);
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309265
Dustin Browna09acf42018-11-08 12:32:26 +05309266 osif_vdev_sync_op_stop(vdev_sync);
9267
9268 return errno;
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309269}
9270
Agrawal Ashish467dde42016-09-08 18:44:22 +05309271#ifdef FEATURE_WLAN_CH_AVOID
Ashish Kumar Dhanotiya4be2a7b2018-02-09 20:08:21 +05309272
9273static int hdd_validate_avoid_freq_chanlist(
9274 struct hdd_context *hdd_ctx,
9275 struct ch_avoid_ind_type *channel_list)
9276{
9277 unsigned int range_idx, ch_idx;
9278 unsigned int unsafe_channel_index, unsafe_channel_count = 0;
9279 bool ch_found = false;
9280
9281 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
9282 (uint16_t)NUM_CHANNELS);
9283
9284 for (range_idx = 0; range_idx < channel_list->ch_avoid_range_cnt;
9285 range_idx++) {
9286 if ((channel_list->avoid_freq_range[range_idx].start_freq <
9287 CDS_24_GHZ_CHANNEL_1) ||
9288 (channel_list->avoid_freq_range[range_idx].end_freq >
9289 CDS_5_GHZ_CHANNEL_165) ||
9290 (channel_list->avoid_freq_range[range_idx].start_freq >
9291 channel_list->avoid_freq_range[range_idx].end_freq))
9292 continue;
9293
9294 for (ch_idx = channel_list->
9295 avoid_freq_range[range_idx].start_freq;
9296 ch_idx <= channel_list->
9297 avoid_freq_range[range_idx].end_freq;
9298 ch_idx++) {
Ashish Kumar Dhanotiyaaa9fdbb2018-12-14 15:29:14 +05309299 if (INVALID_CHANNEL == wlan_reg_get_chan_enum(ch_idx))
Ashish Kumar Dhanotiyabf00f822018-11-30 20:29:09 +05309300 continue;
Ashish Kumar Dhanotiya4be2a7b2018-02-09 20:08:21 +05309301 for (unsafe_channel_index = 0;
9302 unsafe_channel_index < unsafe_channel_count;
9303 unsafe_channel_index++) {
9304 if (ch_idx ==
9305 hdd_ctx->unsafe_channel_list[
9306 unsafe_channel_index]) {
Dustin Brown632af712018-03-14 15:03:55 -07009307 hdd_info("Duplicate channel %d",
9308 ch_idx);
Ashish Kumar Dhanotiya4be2a7b2018-02-09 20:08:21 +05309309 ch_found = true;
9310 break;
9311 }
9312 }
9313 if (!ch_found) {
9314 hdd_ctx->unsafe_channel_list[
9315 unsafe_channel_count++] = ch_idx;
9316 }
9317 ch_found = false;
9318 }
9319 }
9320 return unsafe_channel_count;
9321}
9322
Agrawal Ashish467dde42016-09-08 18:44:22 +05309323/**
9324 * __wlan_hdd_cfg80211_avoid_freq() - ask driver to restart SAP if SAP
9325 * is on unsafe channel.
9326 * @wiphy: wiphy structure pointer
9327 * @wdev: Wireless device structure pointer
9328 * @data: Pointer to the data received
9329 * @data_len: Length of @data
9330 *
9331 * wlan_hdd_cfg80211_avoid_freq do restart the sap if sap is already
9332 * on any of unsafe channels.
9333 * If sap is on any of unsafe channel, hdd_unsafe_channel_restart_sap
9334 * will send WLAN_SVC_LTE_COEX_IND indication to userspace to restart.
9335 *
9336 * Return: 0 on success; errno on failure
9337 */
9338static int
9339__wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy,
9340 struct wireless_dev *wdev,
9341 const void *data, int data_len)
9342{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07009343 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Agrawal Ashish467dde42016-09-08 18:44:22 +05309344 int ret;
Agrawal Ashish467dde42016-09-08 18:44:22 +05309345 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
Liangwei Dong6e1a2092017-08-30 16:29:06 +08009346 uint16_t *local_unsafe_list;
hqubf1b6182018-08-14 17:22:41 +08009347 uint16_t unsafe_channel_count;
Ashish Kumar Dhanotiya4be2a7b2018-02-09 20:08:21 +05309348 uint16_t unsafe_channel_index, local_unsafe_list_count;
9349 struct ch_avoid_ind_type *channel_list;
Jeff Johnson2e60a142018-05-20 12:08:12 -07009350 enum QDF_GLOBAL_MODE curr_mode;
Ashish Kumar Dhanotiya7e345d02018-06-28 12:43:41 +05309351 uint8_t num_args = 0;
hqubf1b6182018-08-14 17:22:41 +08009352 bool user_set_avoid_channel = true;
Agrawal Ashish467dde42016-09-08 18:44:22 +05309353
Dustin Brownfdf17c12018-03-14 12:55:34 -07009354 hdd_enter_dev(wdev->netdev);
Agrawal Ashish467dde42016-09-08 18:44:22 +05309355
9356 if (!qdf_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -07009357 hdd_err("qdf_ctx is NULL");
Agrawal Ashish467dde42016-09-08 18:44:22 +05309358 return -EINVAL;
9359 }
Ashish Kumar Dhanotiya4be2a7b2018-02-09 20:08:21 +05309360 curr_mode = hdd_get_conparam();
9361 if (QDF_GLOBAL_FTM_MODE == curr_mode ||
9362 QDF_GLOBAL_MONITOR_MODE == curr_mode) {
9363 hdd_err("Command not allowed in FTM/MONITOR mode");
Agrawal Ashish467dde42016-09-08 18:44:22 +05309364 return -EINVAL;
9365 }
9366
9367 ret = wlan_hdd_validate_context(hdd_ctx);
9368 if (0 != ret)
9369 return ret;
hqubf1b6182018-08-14 17:22:41 +08009370 if (!data && data_len == 0) {
9371 hdd_debug("Userspace doesn't set avoid frequency channel list");
9372 user_set_avoid_channel = false;
9373 goto process_unsafe_channel;
9374 }
Ashish Kumar Dhanotiya7e345d02018-06-28 12:43:41 +05309375 if (!data || data_len < (sizeof(channel_list->ch_avoid_range_cnt) +
9376 sizeof(struct ch_avoid_freq_type))) {
9377 hdd_err("Avoid frequency channel list empty");
9378 return -EINVAL;
9379 }
9380 num_args = (data_len - sizeof(channel_list->ch_avoid_range_cnt)) /
9381 sizeof(channel_list->avoid_freq_range[0].start_freq);
9382
9383 if (num_args < 2 || num_args > CH_AVOID_MAX_RANGE * 2 ||
9384 num_args % 2 != 0) {
9385 hdd_err("Invalid avoid frequency channel list");
9386 return -EINVAL;
9387 }
Ashish Kumar Dhanotiya4be2a7b2018-02-09 20:08:21 +05309388
9389 channel_list = (struct ch_avoid_ind_type *)data;
Ashish Kumar Dhanotiya7e345d02018-06-28 12:43:41 +05309390 if (channel_list->ch_avoid_range_cnt == 0 ||
9391 channel_list->ch_avoid_range_cnt > CH_AVOID_MAX_RANGE ||
9392 2 * channel_list->ch_avoid_range_cnt != num_args) {
9393 hdd_err("Invalid frequency range count %d",
9394 channel_list->ch_avoid_range_cnt);
Ashish Kumar Dhanotiya4be2a7b2018-02-09 20:08:21 +05309395 return -EINVAL;
9396 }
9397
hqubf1b6182018-08-14 17:22:41 +08009398process_unsafe_channel:
Liangwei Dong6e1a2092017-08-30 16:29:06 +08009399 ret = hdd_clone_local_unsafe_chan(hdd_ctx,
9400 &local_unsafe_list,
9401 &local_unsafe_list_count);
9402 if (0 != ret) {
9403 hdd_err("failed to clone the cur unsafe chan list");
9404 return ret;
9405 }
9406
Agrawal Ashish467dde42016-09-08 18:44:22 +05309407 pld_get_wlan_unsafe_channel(qdf_ctx->dev, hdd_ctx->unsafe_channel_list,
9408 &(hdd_ctx->unsafe_channel_count),
9409 sizeof(hdd_ctx->unsafe_channel_list));
hqubf1b6182018-08-14 17:22:41 +08009410 if (user_set_avoid_channel) {
9411 hdd_ctx->unsafe_channel_count =
9412 hdd_validate_avoid_freq_chanlist(
Ashish Kumar Dhanotiya4be2a7b2018-02-09 20:08:21 +05309413 hdd_ctx,
9414 channel_list);
hqubf1b6182018-08-14 17:22:41 +08009415 unsafe_channel_count = hdd_ctx->unsafe_channel_count;
Ashish Kumar Dhanotiya4be2a7b2018-02-09 20:08:21 +05309416
hqubf1b6182018-08-14 17:22:41 +08009417 pld_set_wlan_unsafe_channel(qdf_ctx->dev,
9418 hdd_ctx->unsafe_channel_list,
9419 hdd_ctx->unsafe_channel_count);
9420 } else {
9421 unsafe_channel_count = QDF_MIN(
9422 (uint16_t)hdd_ctx->unsafe_channel_count,
9423 (uint16_t)NUM_CHANNELS);
9424 }
Ashish Kumar Dhanotiya4be2a7b2018-02-09 20:08:21 +05309425
Agrawal Ashish467dde42016-09-08 18:44:22 +05309426 for (unsafe_channel_index = 0;
hqubf1b6182018-08-14 17:22:41 +08009427 unsafe_channel_index < unsafe_channel_count;
Ashish Kumar Dhanotiya4be2a7b2018-02-09 20:08:21 +05309428 unsafe_channel_index++) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -08009429 hdd_debug("Channel %d is not safe",
Ashish Kumar Dhanotiya4be2a7b2018-02-09 20:08:21 +05309430 hdd_ctx->unsafe_channel_list[unsafe_channel_index]);
Agrawal Ashish467dde42016-09-08 18:44:22 +05309431 }
Liangwei Dong6e1a2092017-08-30 16:29:06 +08009432 if (hdd_local_unsafe_channel_updated(hdd_ctx, local_unsafe_list,
9433 local_unsafe_list_count))
9434 hdd_unsafe_channel_restart_sap(hdd_ctx);
9435 qdf_mem_free(local_unsafe_list);
9436
Agrawal Ashish467dde42016-09-08 18:44:22 +05309437 return 0;
9438}
9439
9440/**
9441 * wlan_hdd_cfg80211_avoid_freq() - ask driver to restart SAP if SAP
9442 * is on unsafe channel.
9443 * @wiphy: wiphy structure pointer
9444 * @wdev: Wireless device structure pointer
9445 * @data: Pointer to the data received
9446 * @data_len: Length of @data
9447 *
9448 * wlan_hdd_cfg80211_avoid_freq do restart the sap if sap is already
9449 * on any of unsafe channels.
9450 * If sap is on any of unsafe channel, hdd_unsafe_channel_restart_sap
9451 * will send WLAN_SVC_LTE_COEX_IND indication to userspace to restart.
9452 *
9453 * Return: 0 on success; errno on failure
9454 */
9455static int wlan_hdd_cfg80211_avoid_freq(struct wiphy *wiphy,
9456 struct wireless_dev *wdev,
9457 const void *data, int data_len)
9458{
Dustin Brown363b4792019-02-05 16:11:55 -08009459 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08009460 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05309461
Dustin Brown363b4792019-02-05 16:11:55 -08009462 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08009463 if (errno)
9464 return errno;
Agrawal Ashish467dde42016-09-08 18:44:22 +05309465
Dustin Brownf0f00612019-01-31 16:02:24 -08009466 errno = __wlan_hdd_cfg80211_avoid_freq(wiphy, wdev, data, data_len);
Agrawal Ashish467dde42016-09-08 18:44:22 +05309467
Dustin Brown363b4792019-02-05 16:11:55 -08009468 osif_psoc_sync_op_stop(psoc_sync);
Arunk Khandavalli99716d12018-11-14 15:02:02 +05309469
Dustin Brownf0f00612019-01-31 16:02:24 -08009470 return errno;
Agrawal Ashish467dde42016-09-08 18:44:22 +05309471}
9472
9473#endif
Agrawal Ashish21ba2572016-09-03 16:40:10 +05309474/**
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309475 * __wlan_hdd_cfg80211_sap_configuration_set() - ask driver to restart SAP if
9476 * SAP is on unsafe channel.
9477 * @wiphy: wiphy structure pointer
9478 * @wdev: Wireless device structure pointer
9479 * @data: Pointer to the data received
9480 * @data_len: Length of @data
9481 *
9482 * __wlan_hdd_cfg80211_sap_configuration_set function set SAP params to
9483 * driver.
9484 * QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHAN will set sap config channel and
9485 * will initiate restart of sap.
9486 *
9487 * Return: 0 on success; errno on failure
9488 */
9489static int
9490__wlan_hdd_cfg80211_sap_configuration_set(struct wiphy *wiphy,
9491 struct wireless_dev *wdev,
9492 const void *data, int data_len)
9493{
9494 struct net_device *ndev = wdev->netdev;
Jeff Johnsone5006672017-08-29 14:39:02 -07009495 struct hdd_adapter *hostapd_adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07009496 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309497 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX + 1];
9498 uint8_t config_channel = 0;
Jeff Johnson87251032017-08-29 13:31:11 -07009499 struct hdd_ap_ctx *ap_ctx;
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309500 int ret;
Manishekar Chandrasekaran1db3abe2016-06-24 03:27:07 +05309501 QDF_STATUS status;
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309502
Dustin Brown491d54b2018-03-14 12:39:11 -07009503 hdd_enter();
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309504
9505 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson77848112016-06-29 14:52:06 -07009506 hdd_err("Command not allowed in FTM mode");
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309507 return -EINVAL;
9508 }
9509
9510 ret = wlan_hdd_validate_context(hdd_ctx);
9511 if (0 != ret)
9512 return -EINVAL;
9513
Dustin Brown4ea21db2018-01-05 14:13:17 -08009514 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX,
9515 data, data_len,
9516 wlan_hdd_sap_config_policy)) {
Jeff Johnson77848112016-06-29 14:52:06 -07009517 hdd_err("invalid attr");
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309518 return -EINVAL;
9519 }
9520
9521 if (tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL]) {
9522 if (!test_bit(SOFTAP_BSS_STARTED,
9523 &hostapd_adapter->event_flags)) {
9524 hdd_err("SAP is not started yet. Restart sap will be invalid");
9525 return -EINVAL;
9526 }
9527
9528 config_channel =
9529 nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL]);
9530
9531 if (!((IS_24G_CH(config_channel)) ||
9532 (IS_5G_CH(config_channel)))) {
9533 hdd_err("Channel %d is not valid to restart SAP",
9534 config_channel);
9535 return -ENOTSUPP;
9536 }
9537
9538 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(hostapd_adapter);
Jeff Johnson91df29d2017-10-27 19:29:50 -07009539 ap_ctx->sap_config.channel = config_channel;
9540 ap_ctx->sap_config.ch_params.ch_width =
9541 ap_ctx->sap_config.ch_width_orig;
hqu73bccf22017-10-28 15:34:17 +08009542 ap_ctx->bss_stop_reason = BSS_STOP_DUE_TO_VENDOR_CONFIG_CHAN;
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309543
Dustin Brown07901ec2018-09-07 11:02:41 -07009544 wlan_reg_set_channel_params(hdd_ctx->pdev,
9545 ap_ctx->sap_config.channel,
9546 ap_ctx->sap_config.sec_ch,
9547 &ap_ctx->sap_config.ch_params);
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309548
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08009549 hdd_restart_sap(hostapd_adapter);
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309550 }
9551
Manishekar Chandrasekaran1db3abe2016-06-24 03:27:07 +05309552 if (tb[QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST]) {
9553 uint32_t freq_len, i;
9554 uint32_t *freq;
9555 uint8_t chans[QDF_MAX_NUM_CHAN];
9556
9557 hdd_debug("setting mandatory freq/chan list");
9558
9559 freq_len = nla_len(
9560 tb[QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST])/
9561 sizeof(uint32_t);
9562
9563 if (freq_len > QDF_MAX_NUM_CHAN) {
9564 hdd_err("insufficient space to hold channels");
9565 return -ENOMEM;
9566 }
9567
9568 freq = nla_data(
9569 tb[QCA_WLAN_VENDOR_ATTR_SAP_MANDATORY_FREQUENCY_LIST]);
9570
9571 hdd_debug("freq_len=%d", freq_len);
9572
9573 for (i = 0; i < freq_len; i++) {
9574 chans[i] = ieee80211_frequency_to_channel(freq[i]);
9575 hdd_debug("freq[%d]=%d", i, freq[i]);
9576 }
9577
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -08009578 status = policy_mgr_set_sap_mandatory_channels(
Dustin Brown76cd2932018-09-11 16:03:05 -07009579 hdd_ctx->psoc, chans, freq_len);
Manishekar Chandrasekaran1db3abe2016-06-24 03:27:07 +05309580 if (QDF_IS_STATUS_ERROR(status))
9581 return -EINVAL;
9582 }
9583
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309584 return 0;
9585}
9586
9587/**
9588 * wlan_hdd_cfg80211_sap_configuration_set() - sap configuration vendor command
9589 * @wiphy: wiphy structure pointer
9590 * @wdev: Wireless device structure pointer
9591 * @data: Pointer to the data received
9592 * @data_len: Length of @data
9593 *
9594 * __wlan_hdd_cfg80211_sap_configuration_set function set SAP params to
9595 * driver.
9596 * QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHAN will set sap config channel and
9597 * will initiate restart of sap.
9598 *
9599 * Return: 0 on success; errno on failure
9600 */
9601static int wlan_hdd_cfg80211_sap_configuration_set(struct wiphy *wiphy,
9602 struct wireless_dev *wdev,
9603 const void *data, int data_len)
9604{
Dustin Browna09acf42018-11-08 12:32:26 +05309605 int errno;
9606 struct osif_vdev_sync *vdev_sync;
9607
9608 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
9609 if (errno)
9610 return errno;
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309611
Dustin Browna09acf42018-11-08 12:32:26 +05309612 errno = __wlan_hdd_cfg80211_sap_configuration_set(wiphy, wdev,
9613 data, data_len);
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309614
Dustin Browna09acf42018-11-08 12:32:26 +05309615 osif_vdev_sync_op_stop(vdev_sync);
9616
9617 return errno;
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +05309618}
9619
Naveen Rawat3ff5cff2018-01-29 14:31:16 -08009620/**
9621 * wlan_hdd_process_wake_lock_stats() - wrapper function to absract cp_stats
9622 * or legacy get_wake_lock_stats API.
9623 * @hdd_ctx: pointer to hdd_ctx
9624 *
9625 * Return: 0 on success; error number otherwise.
9626 */
9627static int wlan_hdd_process_wake_lock_stats(struct hdd_context *hdd_ctx)
9628{
Ashish Kumar Dhanotiya136bc8e2019-06-04 16:20:31 +05309629 return wlan_cfg80211_mc_cp_stats_get_wakelock_stats(hdd_ctx->psoc,
9630 hdd_ctx->wiphy);
Naveen Rawat3ff5cff2018-01-29 14:31:16 -08009631}
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05309632
9633/**
9634 * __wlan_hdd_cfg80211_get_wakelock_stats() - gets wake lock stats
9635 * @wiphy: wiphy pointer
9636 * @wdev: pointer to struct wireless_dev
9637 * @data: pointer to incoming NL vendor data
9638 * @data_len: length of @data
9639 *
9640 * This function parses the incoming NL vendor command data attributes and
9641 * invokes the SME Api and blocks on a completion variable.
9642 * WMA copies required data and invokes callback
9643 * wlan_hdd_cfg80211_wakelock_stats_rsp_callback to send wake lock stats.
9644 *
9645 * Return: 0 on success; error number otherwise.
9646 */
9647static int __wlan_hdd_cfg80211_get_wakelock_stats(struct wiphy *wiphy,
9648 struct wireless_dev *wdev,
9649 const void *data,
9650 int data_len)
9651{
Naveen Rawat3ff5cff2018-01-29 14:31:16 -08009652 int ret;
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07009653 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05309654
Dustin Brown491d54b2018-03-14 12:39:11 -07009655 hdd_enter();
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05309656
9657 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson64943bd2016-08-23 13:14:06 -07009658 hdd_err("Command not allowed in FTM mode");
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05309659 return -EINVAL;
9660 }
9661
Naveen Rawat3ff5cff2018-01-29 14:31:16 -08009662 ret = wlan_hdd_validate_context(hdd_ctx);
9663 if (0 != ret)
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05309664 return -EINVAL;
9665
Naveen Rawat3ff5cff2018-01-29 14:31:16 -08009666 ret = wlan_hdd_process_wake_lock_stats(hdd_ctx);
Dustin Browne74003f2018-03-14 12:51:58 -07009667 hdd_exit();
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05309668 return ret;
9669}
9670
9671/**
9672 * wlan_hdd_cfg80211_get_wakelock_stats() - gets wake lock stats
9673 * @wiphy: wiphy pointer
9674 * @wdev: pointer to struct wireless_dev
9675 * @data: pointer to incoming NL vendor data
9676 * @data_len: length of @data
9677 *
9678 * This function parses the incoming NL vendor command data attributes and
9679 * invokes the SME Api and blocks on a completion variable.
9680 * WMA copies required data and invokes callback
9681 * wlan_hdd_cfg80211_wakelock_stats_rsp_callback to send wake lock stats.
9682 *
9683 * Return: 0 on success; error number otherwise.
9684 */
9685static int wlan_hdd_cfg80211_get_wakelock_stats(struct wiphy *wiphy,
9686 struct wireless_dev *wdev,
9687 const void *data, int data_len)
9688{
Dustin Brown363b4792019-02-05 16:11:55 -08009689 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08009690 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05309691
Dustin Brown363b4792019-02-05 16:11:55 -08009692 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08009693 if (errno)
9694 return errno;
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05309695
Dustin Brownf0f00612019-01-31 16:02:24 -08009696 errno = __wlan_hdd_cfg80211_get_wakelock_stats(wiphy, wdev,
9697 data, data_len);
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05309698
Dustin Brown363b4792019-02-05 16:11:55 -08009699 osif_psoc_sync_op_stop(psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08009700
9701 return errno;
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +05309702}
9703
Srinivas Dasari510e7fe2016-04-28 11:51:30 +05309704/**
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05309705 * __wlan_hdd_cfg80211_get_bus_size() - Get WMI Bus size
9706 * @wiphy: wiphy structure pointer
9707 * @wdev: Wireless device structure pointer
9708 * @data: Pointer to the data received
9709 * @data_len: Length of @data
9710 *
9711 * This function reads wmi max bus size and fill in the skb with
9712 * NL attributes and send up the NL event.
9713 * Return: 0 on success; errno on failure
9714 */
9715static int
9716__wlan_hdd_cfg80211_get_bus_size(struct wiphy *wiphy,
9717 struct wireless_dev *wdev,
9718 const void *data, int data_len)
9719{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07009720 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05309721 int ret_val;
9722 struct sk_buff *skb;
9723 uint32_t nl_buf_len;
9724
Dustin Brown491d54b2018-03-14 12:39:11 -07009725 hdd_enter();
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05309726
9727 ret_val = wlan_hdd_validate_context(hdd_ctx);
9728 if (ret_val)
9729 return ret_val;
9730
9731 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
9732 hdd_err("Command not allowed in FTM mode");
9733 return -EINVAL;
9734 }
9735
Srinivas Girigowda13d39252017-03-06 16:12:15 -08009736 hdd_debug("WMI Max Bus size: %d", hdd_ctx->wmi_max_len);
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05309737
9738 nl_buf_len = NLMSG_HDRLEN;
9739 nl_buf_len += (sizeof(hdd_ctx->wmi_max_len) + NLA_HDRLEN);
9740
9741 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
9742 if (!skb) {
9743 hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
9744 return -ENOMEM;
9745 }
9746
9747 if (nla_put_u16(skb, QCA_WLAN_VENDOR_ATTR_DRV_INFO_BUS_SIZE,
9748 hdd_ctx->wmi_max_len)) {
9749 hdd_err("nla put failure");
9750 goto nla_put_failure;
9751 }
9752
9753 cfg80211_vendor_cmd_reply(skb);
9754
Dustin Browne74003f2018-03-14 12:51:58 -07009755 hdd_exit();
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05309756
9757 return 0;
9758
9759nla_put_failure:
9760 kfree_skb(skb);
9761 return -EINVAL;
9762}
9763
9764/**
9765 * wlan_hdd_cfg80211_get_bus_size() - SSR Wrapper to Get Bus size
9766 * @wiphy: wiphy structure pointer
9767 * @wdev: Wireless device structure pointer
9768 * @data: Pointer to the data received
9769 * @data_len: Length of @data
9770 *
9771 * Return: 0 on success; errno on failure
9772 */
9773static int wlan_hdd_cfg80211_get_bus_size(struct wiphy *wiphy,
9774 struct wireless_dev *wdev,
9775 const void *data, int data_len)
9776{
Dustin Brown363b4792019-02-05 16:11:55 -08009777 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -08009778 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +05309779
Dustin Brown363b4792019-02-05 16:11:55 -08009780 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08009781 if (errno)
9782 return errno;
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05309783
Dustin Brownf0f00612019-01-31 16:02:24 -08009784 errno = __wlan_hdd_cfg80211_get_bus_size(wiphy, wdev, data, data_len);
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05309785
Dustin Brown363b4792019-02-05 16:11:55 -08009786 osif_psoc_sync_op_stop(psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -08009787
9788 return errno;
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05309789}
9790
9791/**
Srinivas Dasari510e7fe2016-04-28 11:51:30 +05309792 *__wlan_hdd_cfg80211_setband() - set band
9793 * @wiphy: Pointer to wireless phy
9794 * @wdev: Pointer to wireless device
9795 * @data: Pointer to data
9796 * @data_len: Length of @data
9797 *
9798 * Return: 0 on success, negative errno on failure
9799 */
9800static int __wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
9801 struct wireless_dev *wdev,
9802 const void *data, int data_len)
9803{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07009804 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07009805 struct net_device *dev = wdev->netdev;
Srinivas Dasari510e7fe2016-04-28 11:51:30 +05309806 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
9807 int ret;
9808 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
9809 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 } };
9810
Dustin Brown491d54b2018-03-14 12:39:11 -07009811 hdd_enter();
Srinivas Dasari510e7fe2016-04-28 11:51:30 +05309812
9813 ret = wlan_hdd_validate_context(hdd_ctx);
9814 if (ret)
9815 return ret;
9816
Dustin Brown4ea21db2018-01-05 14:13:17 -08009817 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
9818 data, data_len, policy)) {
Dustin Brownbacc48f2018-03-14 14:48:44 -07009819 hdd_err("Invalid ATTR");
Srinivas Dasari510e7fe2016-04-28 11:51:30 +05309820 return -EINVAL;
9821 }
9822
9823 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
Dustin Brownbacc48f2018-03-14 14:48:44 -07009824 hdd_err("attr SETBAND_VALUE failed");
Srinivas Dasari510e7fe2016-04-28 11:51:30 +05309825 return -EINVAL;
9826 }
9827
Kiran Kumar Lokereb1d412e2017-04-23 17:19:43 -07009828 ret = hdd_reg_set_band(dev,
9829 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Srinivas Dasari510e7fe2016-04-28 11:51:30 +05309830
Dustin Browne74003f2018-03-14 12:51:58 -07009831 hdd_exit();
Srinivas Dasari510e7fe2016-04-28 11:51:30 +05309832 return ret;
9833}
9834
9835/**
Kapil Gupta94ca6f62016-12-11 18:43:12 +05309836 *wlan_hdd_validate_acs_channel() - validate channel provided by ACS
9837 * @adapter: hdd adapter
9838 * @channel: channel number
9839 *
9840 * return: QDF status based on success or failure
9841 */
Jeff Johnsone5006672017-08-29 14:39:02 -07009842static QDF_STATUS wlan_hdd_validate_acs_channel(struct hdd_adapter *adapter,
Kapil Gupta94ca6f62016-12-11 18:43:12 +05309843 int channel, int chan_bw)
9844{
9845 if (QDF_STATUS_SUCCESS !=
9846 wlan_hdd_validate_operation_channel(adapter, channel))
9847 return QDF_STATUS_E_FAILURE;
9848 if ((wlansap_is_channel_in_nol_list(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
9849 channel,
9850 PHY_SINGLE_CHANNEL_CENTERED))) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07009851 hdd_info("channel %d is in nol", channel);
Kapil Gupta94ca6f62016-12-11 18:43:12 +05309852 return -EINVAL;
9853 }
9854
9855 if ((wlansap_is_channel_leaking_in_nol(
9856 WLAN_HDD_GET_SAP_CTX_PTR(adapter),
9857 channel, chan_bw))) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07009858 hdd_info("channel %d is leaking in nol", channel);
Kapil Gupta94ca6f62016-12-11 18:43:12 +05309859 return -EINVAL;
9860 }
9861
9862 return 0;
9863
9864}
9865
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07009866static void hdd_update_acs_sap_config(struct hdd_context *hdd_ctx,
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07009867 struct sap_config *sap_config,
Kapil Gupta8878ad92017-02-13 11:56:04 +05309868 struct hdd_vendor_chan_info *channel_list)
9869{
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05309870 uint8_t ch_width;
9871 QDF_STATUS status;
Wu Gaoed616a12019-01-16 15:19:21 +08009872 uint32_t channel_bonding_mode;
9873
Kapil Gupta8878ad92017-02-13 11:56:04 +05309874 sap_config->channel = channel_list->pri_ch;
9875
9876 sap_config->ch_params.center_freq_seg0 =
9877 channel_list->vht_seg0_center_ch;
9878 sap_config->ch_params.center_freq_seg1 =
9879 channel_list->vht_seg1_center_ch;
9880
9881 sap_config->ch_params.sec_ch_offset = channel_list->ht_sec_ch;
9882 sap_config->ch_params.ch_width = channel_list->chan_width;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05309883 if (sap_config->channel >= 36) {
9884 status =
9885 ucfg_mlme_get_vht_channel_width(hdd_ctx->psoc,
9886 &ch_width);
9887 if (!QDF_IS_STATUS_SUCCESS(status))
9888 hdd_err("Failed to set channel_width");
9889 sap_config->ch_width_orig = ch_width;
9890 } else {
Wu Gaoed616a12019-01-16 15:19:21 +08009891 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
9892 &channel_bonding_mode);
9893 sap_config->ch_width_orig = channel_bonding_mode ?
9894 eHT_CHANNEL_WIDTH_40MHZ : eHT_CHANNEL_WIDTH_20MHZ;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05309895 }
Kapil Gupta8878ad92017-02-13 11:56:04 +05309896 sap_config->acs_cfg.pri_ch = channel_list->pri_ch;
9897 sap_config->acs_cfg.ch_width = channel_list->chan_width;
9898 sap_config->acs_cfg.vht_seg0_center_ch =
9899 channel_list->vht_seg0_center_ch;
9900 sap_config->acs_cfg.vht_seg1_center_ch =
9901 channel_list->vht_seg1_center_ch;
9902 sap_config->acs_cfg.ht_sec_ch = channel_list->ht_sec_ch;
9903}
9904
Jeff Johnsone5006672017-08-29 14:39:02 -07009905static int hdd_update_acs_channel(struct hdd_adapter *adapter, uint8_t reason,
Kapil Gupta8878ad92017-02-13 11:56:04 +05309906 uint8_t channel_cnt,
9907 struct hdd_vendor_chan_info *channel_list)
9908{
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07009909 struct sap_config *sap_config;
Jeff Johnson87251032017-08-29 13:31:11 -07009910 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnson7aeb95b2017-08-28 12:06:33 -07009911 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309912 QDF_STATUS status = QDF_STATUS_SUCCESS;
Jeff Johnson34fc63a2018-06-14 10:10:02 -07009913 mac_handle_t mac_handle;
Kapil Gupta8878ad92017-02-13 11:56:04 +05309914
Min Liuab6ed4f2018-01-09 13:13:57 +08009915 if (!channel_list) {
9916 hdd_err("channel_list is NULL");
9917 return -EINVAL;
9918 }
9919
Kapil Gupta8878ad92017-02-13 11:56:04 +05309920 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -07009921 sap_config = &adapter->session.ap.sap_config;
Kapil Gupta8878ad92017-02-13 11:56:04 +05309922
9923 if (QDF_TIMER_STATE_RUNNING ==
Jeff Johnsonb9424862017-10-30 08:49:35 -07009924 qdf_mc_timer_get_current_state(&adapter->session.
Kapil Gupta8878ad92017-02-13 11:56:04 +05309925 ap.vendor_acs_timer)) {
Jeff Johnsonb9424862017-10-30 08:49:35 -07009926 qdf_mc_timer_stop(&adapter->session.ap.vendor_acs_timer);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309927 }
9928
Min Liuab6ed4f2018-01-09 13:13:57 +08009929 if (channel_list->pri_ch == 0) {
Kapil Gupta8878ad92017-02-13 11:56:04 +05309930 /* Check mode, set default channel */
9931 channel_list->pri_ch = 6;
9932 /*
Jeff Johnson34fc63a2018-06-14 10:10:02 -07009933 * sap_select_default_oper_chan(mac_handle,
Kapil Gupta8878ad92017-02-13 11:56:04 +05309934 * sap_config->acs_cfg.hw_mode);
9935 */
9936 }
9937
Jeff Johnson34fc63a2018-06-14 10:10:02 -07009938 mac_handle = hdd_ctx->mac_handle;
Kapil Gupta8878ad92017-02-13 11:56:04 +05309939 switch (reason) {
9940 /* SAP init case */
9941 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
9942 hdd_update_acs_sap_config(hdd_ctx, sap_config, channel_list);
9943 /* Update Hostapd */
9944 wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
9945 break;
9946
9947 /* DFS detected on current channel */
9948 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
9949 wlan_sap_update_next_channel(
9950 WLAN_HDD_GET_SAP_CTX_PTR(adapter),
9951 channel_list->pri_ch,
9952 channel_list->chan_width);
9953 status = sme_update_new_channel_event(
Jeff Johnson34fc63a2018-06-14 10:10:02 -07009954 mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -08009955 adapter->vdev_id);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309956 break;
9957
9958 /* LTE coex event on current channel */
9959 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
9960 sap_config->acs_cfg.pri_ch = channel_list->pri_ch;
9961 sap_config->acs_cfg.ch_width = channel_list->chan_width;
Jeff Johnson91df29d2017-10-27 19:29:50 -07009962 hdd_ap_ctx->sap_config.ch_width_orig =
Kapil Gupta8878ad92017-02-13 11:56:04 +05309963 channel_list->chan_width;
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +05309964 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->vdev_id,
9965 CSA_REASON_LTE_COEX);
Min Liu2fef5792018-01-19 17:59:42 +08009966 hdd_switch_sap_channel(adapter, sap_config->acs_cfg.pri_ch,
9967 true);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309968 break;
9969
9970 default:
9971 hdd_info("invalid reason for timer invoke");
9972 }
Dustin Browne74003f2018-03-14 12:51:58 -07009973 hdd_exit();
Min Liuab6ed4f2018-01-09 13:13:57 +08009974 return qdf_status_to_os_return(status);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309975}
9976
9977/**
9978 * Define short name for vendor channel set config
9979 */
9980#define SET_CHAN_REASON QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_REASON
Kapil Gupta8878ad92017-02-13 11:56:04 +05309981#define SET_CHAN_CHAN_LIST QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_LIST
9982#define SET_CHAN_PRIMARY_CHANNEL \
9983 QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_PRIMARY
9984#define SET_CHAN_SECONDARY_CHANNEL \
9985 QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_SECONDARY
9986#define SET_CHAN_SEG0_CENTER_CHANNEL \
9987 QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG0
9988#define SET_CHAN_SEG1_CENTER_CHANNEL \
9989 QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_CENTER_SEG1
9990#define SET_CHAN_CHANNEL_WIDTH \
9991 QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_WIDTH
9992#define SET_CHAN_MAX QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_MAX
Kapil Gupta63e75282017-05-18 20:55:10 +05309993#define SET_EXT_ACS_BAND QCA_WLAN_VENDOR_ATTR_EXTERNAL_ACS_CHANNEL_BAND
Kapil Gupta8878ad92017-02-13 11:56:04 +05309994
Rajeev Kumar Sirasanagandla5054f662019-03-14 21:25:58 +05309995static const struct nla_policy acs_chan_config_policy[SET_CHAN_MAX + 1] = {
9996 [SET_CHAN_REASON] = {.type = NLA_U8},
9997 [SET_CHAN_CHAN_LIST] = {.type = NLA_NESTED},
9998};
9999
10000static const struct nla_policy acs_chan_list_policy[SET_CHAN_MAX + 1] = {
10001 [SET_CHAN_PRIMARY_CHANNEL] = {.type = NLA_U8},
10002 [SET_CHAN_SECONDARY_CHANNEL] = {.type = NLA_U8},
10003 [SET_CHAN_SEG0_CENTER_CHANNEL] = {.type = NLA_U8},
10004 [SET_CHAN_SEG1_CENTER_CHANNEL] = {.type = NLA_U8},
10005 [SET_CHAN_CHANNEL_WIDTH] = {.type = NLA_U8},
10006 [SET_EXT_ACS_BAND] = {.type = NLA_U8},
10007};
10008
Kapil Gupta8878ad92017-02-13 11:56:04 +053010009/**
10010 * hdd_parse_vendor_acs_chan_config() - API to parse vendor acs channel config
10011 * @channel_list: pointer to hdd_vendor_chan_info
10012 * @reason: channel change reason
10013 * @channel_cnt: channel count
10014 * @data: data
10015 * @data_len: data len
10016 *
10017 * Return: 0 on success, negative errno on failure
10018 */
10019static int hdd_parse_vendor_acs_chan_config(struct hdd_vendor_chan_info
10020 **chan_list_ptr, uint8_t *reason, uint8_t *channel_cnt,
10021 const void *data, int data_len)
10022{
Rajeev Kumar Sirasanagandla5054f662019-03-14 21:25:58 +053010023 int rem;
10024 uint32_t i = 0;
Kapil Gupta8878ad92017-02-13 11:56:04 +053010025 struct nlattr *tb[SET_CHAN_MAX + 1];
10026 struct nlattr *tb2[SET_CHAN_MAX + 1];
10027 struct nlattr *curr_attr;
10028 struct hdd_vendor_chan_info *channel_list;
10029
Rajeev Kumar Sirasanagandla5054f662019-03-14 21:25:58 +053010030 if (wlan_cfg80211_nla_parse(tb, SET_CHAN_MAX, data, data_len,
10031 acs_chan_config_policy)) {
Kapil Gupta8878ad92017-02-13 11:56:04 +053010032 hdd_err("Invalid ATTR");
10033 return -EINVAL;
10034 }
10035
10036 if (tb[SET_CHAN_REASON])
10037 *reason = nla_get_u8(tb[SET_CHAN_REASON]);
10038
sheenam monga5440bdd2019-03-11 17:32:37 +053010039 if (!tb[SET_CHAN_CHAN_LIST]) {
10040 hdd_err("channel list empty");
10041 return -EINVAL;
10042 }
10043
Kapil Gupta63e75282017-05-18 20:55:10 +053010044 nla_for_each_nested(curr_attr, tb[SET_CHAN_CHAN_LIST], rem)
10045 i++;
Kapil Gupta8878ad92017-02-13 11:56:04 +053010046
Rajeev Kumar Sirasanagandla5054f662019-03-14 21:25:58 +053010047 if (i > MAX_CHANNEL) {
10048 hdd_err("Error: Exceeded max channels: %u", MAX_CHANNEL);
10049 return -ENOMEM;
10050 }
10051
10052 *channel_cnt = (uint8_t)i;
Kapil Gupta63e75282017-05-18 20:55:10 +053010053
10054 if (i == 0)
10055 hdd_err("incorrect channel count");
Kapil Gupta8878ad92017-02-13 11:56:04 +053010056
10057 channel_list = qdf_mem_malloc(sizeof(struct hdd_vendor_chan_info) *
10058 (*channel_cnt));
Min Liu74a1a502018-10-10 19:59:07 +080010059 if (!channel_list)
Nachiket Kukadec3f92f72017-08-07 17:04:50 +053010060 return -ENOMEM;
Kapil Gupta8878ad92017-02-13 11:56:04 +053010061
Kapil Gupta63e75282017-05-18 20:55:10 +053010062 i = 0;
Kapil Gupta8878ad92017-02-13 11:56:04 +053010063 nla_for_each_nested(curr_attr, tb[SET_CHAN_CHAN_LIST], rem) {
Rajeev Kumar Sirasanagandla5054f662019-03-14 21:25:58 +053010064 if (wlan_cfg80211_nla_parse_nested(tb2, SET_CHAN_MAX,
10065 curr_attr,
10066 acs_chan_list_policy)) {
Dustin Brown4ea21db2018-01-05 14:13:17 -080010067 hdd_err("nla_parse failed");
Rajeev Kumar Sirasanagandla2feb4212019-03-14 22:15:02 +053010068 qdf_mem_free(channel_list);
Kapil Gupta8878ad92017-02-13 11:56:04 +053010069 return -EINVAL;
10070 }
Kapil Gupta63e75282017-05-18 20:55:10 +053010071 if (tb2[SET_EXT_ACS_BAND]) {
10072 channel_list[i].band =
10073 nla_get_u8(tb2[SET_EXT_ACS_BAND]);
10074 }
Kapil Gupta8878ad92017-02-13 11:56:04 +053010075 /* Parse and Fetch allowed SSID list*/
10076 if (tb2[SET_CHAN_PRIMARY_CHANNEL]) {
10077 channel_list[i].pri_ch =
10078 nla_get_u8(
10079 tb2[SET_CHAN_PRIMARY_CHANNEL]);
10080 }
10081 if (tb2[SET_CHAN_SECONDARY_CHANNEL]) {
10082 channel_list[i].ht_sec_ch =
10083 nla_get_u8(tb2[SET_CHAN_SECONDARY_CHANNEL]);
10084 }
10085 if (tb2[SET_CHAN_SEG0_CENTER_CHANNEL]) {
10086 channel_list[i].vht_seg0_center_ch =
10087 nla_get_u8(tb2[SET_CHAN_SEG0_CENTER_CHANNEL]);
10088 }
10089 if (tb2[SET_CHAN_SEG1_CENTER_CHANNEL]) {
10090 channel_list[i].vht_seg1_center_ch =
10091 nla_get_u8(tb2[SET_CHAN_SEG1_CENTER_CHANNEL]);
10092 }
10093 if (tb2[SET_CHAN_CHANNEL_WIDTH]) {
10094 channel_list[i].chan_width =
10095 nla_get_u8(tb2[SET_CHAN_CHANNEL_WIDTH]);
10096 }
Kapil Gupta63e75282017-05-18 20:55:10 +053010097 hdd_debug("index %d pri %d sec %d seg0 %d seg1 %d width %d",
Kapil Gupta8878ad92017-02-13 11:56:04 +053010098 i, channel_list[i].pri_ch,
10099 channel_list[i].ht_sec_ch,
10100 channel_list[i].vht_seg0_center_ch,
10101 channel_list[i].vht_seg1_center_ch,
10102 channel_list[i].chan_width);
10103 i++;
Kapil Gupta8878ad92017-02-13 11:56:04 +053010104 }
10105 *chan_list_ptr = channel_list;
10106
10107 return 0;
10108}
10109
10110/**
10111 * Undef short names for vendor set channel configuration
10112 */
10113#undef SET_CHAN_REASON
Kapil Gupta8878ad92017-02-13 11:56:04 +053010114#undef SET_CHAN_CHAN_LIST
10115#undef SET_CHAN_PRIMARY_CHANNEL
10116#undef SET_CHAN_SECONDARY_CHANNEL
10117#undef SET_CHAN_SEG0_CENTER_CHANNEL
10118#undef SET_CHAN_SEG1_CENTER_CHANNEL
10119#undef SET_CHAN_CHANNEL_WIDTH
10120#undef SET_CHAN_MAX
10121
10122/**
10123 * __wlan_hdd_cfg80211_update_vendor_channel() - update vendor channel
10124 * @wiphy: Pointer to wireless phy
10125 * @wdev: Pointer to wireless device
10126 * @data: Pointer to data
10127 * @data_len: Length of @data
10128 *
10129 * Return: 0 on success, negative errno on failure
10130 */
10131static int __wlan_hdd_cfg80211_update_vendor_channel(struct wiphy *wiphy,
10132 struct wireless_dev *wdev,
10133 const void *data, int data_len)
10134{
10135 int ret_val;
10136 QDF_STATUS qdf_status;
10137 uint8_t channel_cnt = 0, reason = -1;
10138 struct hdd_vendor_chan_info *channel_list = NULL;
Jeff Johnsone5006672017-08-29 14:39:02 -070010139 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070010140 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Nachiket Kukadec3f92f72017-08-07 17:04:50 +053010141 struct hdd_vendor_chan_info *channel_list_ptr;
Kapil Gupta8878ad92017-02-13 11:56:04 +053010142
Dustin Brown491d54b2018-03-14 12:39:11 -070010143 hdd_enter();
Kapil Gupta8878ad92017-02-13 11:56:04 +053010144
10145 ret_val = wlan_hdd_validate_context(hdd_ctx);
10146 if (ret_val)
10147 return ret_val;
10148
10149 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
10150 hdd_err("Command not allowed in FTM mode");
10151 return -EINVAL;
10152 }
10153
10154 if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags))
10155 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
10156 else {
10157 hdd_err("already timeout happened for acs");
10158 return -EINVAL;
10159 }
10160
10161 ret_val = hdd_parse_vendor_acs_chan_config(&channel_list, &reason,
10162 &channel_cnt, data, data_len);
Nachiket Kukadec3f92f72017-08-07 17:04:50 +053010163 channel_list_ptr = channel_list;
Kapil Gupta8878ad92017-02-13 11:56:04 +053010164 if (ret_val)
10165 return ret_val;
10166
10167 /* Validate channel to be set */
10168 while (channel_cnt && channel_list) {
10169 qdf_status = wlan_hdd_validate_acs_channel(adapter,
10170 channel_list->pri_ch,
10171 channel_list->chan_width);
10172 if (qdf_status == QDF_STATUS_SUCCESS)
10173 break;
Nachiket Kukadec3f92f72017-08-07 17:04:50 +053010174 else if (channel_cnt == 1) {
10175 hdd_err("invalid channel %d received from app",
10176 channel_list->pri_ch);
10177 channel_list->pri_ch = 0;
10178 break;
10179 }
10180
Kapil Gupta8878ad92017-02-13 11:56:04 +053010181 channel_cnt--;
10182 channel_list++;
10183 }
Min Liuab6ed4f2018-01-09 13:13:57 +080010184
Kapil Gupta8878ad92017-02-13 11:56:04 +053010185 if ((channel_cnt <= 0) || !channel_list) {
Jeff Johnson36e74c42017-09-18 08:15:42 -070010186 hdd_err("no available channel/chanlist %d/%pK", channel_cnt,
Nachiket Kukadec3f92f72017-08-07 17:04:50 +053010187 channel_list);
10188 qdf_mem_free(channel_list_ptr);
Kapil Gupta8878ad92017-02-13 11:56:04 +053010189 return -EINVAL;
10190 }
10191
Min Liuab6ed4f2018-01-09 13:13:57 +080010192 hdd_debug("received primary channel as %d", channel_list->pri_ch);
10193
10194 ret_val = hdd_update_acs_channel(adapter, reason,
Kapil Gupta8878ad92017-02-13 11:56:04 +053010195 channel_cnt, channel_list);
Nachiket Kukadec3f92f72017-08-07 17:04:50 +053010196 qdf_mem_free(channel_list_ptr);
Min Liuab6ed4f2018-01-09 13:13:57 +080010197 return ret_val;
Kapil Gupta8878ad92017-02-13 11:56:04 +053010198}
10199
10200/**
10201 * wlan_hdd_cfg80211_update_vendor_channel() - update vendor channel
10202 * @wiphy: Pointer to wireless phy
10203 * @wdev: Pointer to wireless device
10204 * @data: Pointer to data
10205 * @data_len: Length of @data
10206 *
10207 * Return: 0 on success, negative errno on failure
10208 */
10209static int wlan_hdd_cfg80211_update_vendor_channel(struct wiphy *wiphy,
10210 struct wireless_dev *wdev,
10211 const void *data, int data_len)
10212{
Dustin Browna09acf42018-11-08 12:32:26 +053010213 int errno;
10214 struct osif_vdev_sync *vdev_sync;
10215
10216 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
10217 if (errno)
10218 return errno;
Kapil Gupta8878ad92017-02-13 11:56:04 +053010219
Dustin Browna09acf42018-11-08 12:32:26 +053010220 errno = __wlan_hdd_cfg80211_update_vendor_channel(wiphy, wdev,
10221 data, data_len);
Kapil Gupta8878ad92017-02-13 11:56:04 +053010222
Dustin Browna09acf42018-11-08 12:32:26 +053010223 osif_vdev_sync_op_stop(vdev_sync);
10224
10225 return errno;
Kapil Gupta8878ad92017-02-13 11:56:04 +053010226}
Kapil Gupta94ca6f62016-12-11 18:43:12 +053010227
10228/**
Srinivas Dasari510e7fe2016-04-28 11:51:30 +053010229 * wlan_hdd_cfg80211_setband() - Wrapper to setband
10230 * @wiphy: wiphy structure pointer
10231 * @wdev: Wireless device structure pointer
10232 * @data: Pointer to the data received
10233 * @data_len: Length of @data
10234 *
10235 * Return: 0 on success; errno on failure
10236 */
10237static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
10238 struct wireless_dev *wdev,
10239 const void *data, int data_len)
10240{
Dustin Browna09acf42018-11-08 12:32:26 +053010241 int errno;
10242 struct osif_vdev_sync *vdev_sync;
10243
10244 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
10245 if (errno)
10246 return errno;
Srinivas Dasari510e7fe2016-04-28 11:51:30 +053010247
Dustin Browna09acf42018-11-08 12:32:26 +053010248 errno = __wlan_hdd_cfg80211_setband(wiphy, wdev, data, data_len);
Srinivas Dasari510e7fe2016-04-28 11:51:30 +053010249
Dustin Browna09acf42018-11-08 12:32:26 +053010250 osif_vdev_sync_op_stop(vdev_sync);
10251
10252 return errno;
Srinivas Dasari510e7fe2016-04-28 11:51:30 +053010253}
10254
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010255/**
10256 * wlan_hdd_cfg80211_sar_convert_limit_set() - Convert limit set value
10257 * @nl80211_value: Vendor command attribute value
10258 * @wmi_value: Pointer to return converted WMI return value
10259 *
10260 * Convert NL80211 vendor command value for SAR limit set to WMI value
10261 * Return: 0 on success, -1 on invalid value
10262 */
10263static int wlan_hdd_cfg80211_sar_convert_limit_set(u32 nl80211_value,
10264 u32 *wmi_value)
10265{
10266 int ret = 0;
10267
10268 switch (nl80211_value) {
10269 case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE:
10270 *wmi_value = WMI_SAR_FEATURE_OFF;
10271 break;
10272 case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0:
10273 *wmi_value = WMI_SAR_FEATURE_ON_SET_0;
10274 break;
10275 case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF1:
10276 *wmi_value = WMI_SAR_FEATURE_ON_SET_1;
10277 break;
10278 case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF2:
10279 *wmi_value = WMI_SAR_FEATURE_ON_SET_2;
10280 break;
10281 case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF3:
10282 *wmi_value = WMI_SAR_FEATURE_ON_SET_3;
10283 break;
10284 case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4:
10285 *wmi_value = WMI_SAR_FEATURE_ON_SET_4;
10286 break;
10287 case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_USER:
10288 *wmi_value = WMI_SAR_FEATURE_ON_USER_DEFINED;
10289 break;
Kabilan Kannancaa85502018-04-13 18:04:58 -070010290 case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0:
10291 *wmi_value = WMI_SAR_FEATURE_ON_SAR_V2_0;
10292 break;
10293
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010294 default:
10295 ret = -1;
10296 }
10297 return ret;
10298}
10299
Jeff Johnson354c20b2018-07-17 20:15:56 -070010300#ifdef WLAN_FEATURE_SARV1_TO_SARV2
10301/**
10302 * hdd_convert_sarv1_to_sarv2() - convert SAR V1 BDF reference to SAR V2
10303 * @hdd_ctx: The HDD global context
10304 * @tb: The parsed array of netlink attributes
10305 * @sar_limit_cmd: The WMI command to be filled
10306 *
10307 * This feature/function is designed to solve the following problem:
10308 * 1) Userspace application was written to use SARv1 BDF entries
10309 * 2) Product is configured with SAR V2 BDF entries
10310 *
10311 * So if this feature is enabled, and if the firmware is configured
10312 * with SAR V2 support, and if the incoming request is to enable a SAR
10313 * V1 BDF entry, then the WMI command is generated to actually
10314 * configure a SAR V2 BDF entry.
10315 *
10316 * Return: true if conversion was performed and @sar_limit_cmd is
10317 * ready to be sent to firmware. Otherwise false in which case the
10318 * normal parsing logic should be applied.
10319 */
10320
10321static bool
10322hdd_convert_sarv1_to_sarv2(struct hdd_context *hdd_ctx,
10323 struct nlattr *tb[],
10324 struct sar_limit_cmd_params *sar_limit_cmd)
10325{
10326 struct nlattr *attr;
10327 uint32_t bdf_index, set;
10328 struct sar_limit_cmd_row *row;
10329
10330 if (hdd_ctx->sar_version != SAR_VERSION_2) {
10331 hdd_debug("SAR version: %d", hdd_ctx->sar_version);
10332 return false;
10333 }
10334
10335 attr = tb[QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE];
10336 if (!attr)
10337 return false;
10338
10339 bdf_index = nla_get_u32(attr);
10340
10341 if ((bdf_index >= QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0) &&
10342 (bdf_index <= QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF4)) {
10343 set = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_V2_0;
10344 } else if (bdf_index == QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE) {
10345 set = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_NONE;
10346 bdf_index = QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SELECT_BDF0;
10347 } else {
10348 return false;
10349 }
10350
10351 /* Need two rows to hold the per-chain V2 power index
10352 * To disable SARv2 limit, send chain, num_limits_row and
10353 * power limit set to 0 (except power index 0xff)
10354 */
10355 row = qdf_mem_malloc(2 * sizeof(*row));
10356 if (!row)
10357 return false;
10358
10359 if (wlan_hdd_cfg80211_sar_convert_limit_set(
10360 set, &sar_limit_cmd->sar_enable)) {
10361 hdd_err("Failed to convert SAR limit to WMI value");
10362 return false;
10363 }
10364
10365 sar_limit_cmd->commit_limits = 1;
10366 sar_limit_cmd->num_limit_rows = 2;
10367 sar_limit_cmd->sar_limit_row_list = row;
10368 row[0].limit_value = bdf_index;
10369 row[1].limit_value = row[0].limit_value;
10370 row[0].chain_id = 0;
10371 row[1].chain_id = 1;
10372 row[0].validity_bitmap = WMI_SAR_CHAIN_ID_VALID_MASK;
10373 row[1].validity_bitmap = WMI_SAR_CHAIN_ID_VALID_MASK;
10374
10375 return true;
10376}
10377
10378#else /* WLAN_FEATURE_SARV1_TO_SARV2 */
Jeff Johnson354c20b2018-07-17 20:15:56 -070010379static bool
10380hdd_convert_sarv1_to_sarv2(struct hdd_context *hdd_ctx,
10381 struct nlattr *tb[],
10382 struct sar_limit_cmd_params *sar_limit_cmd)
10383{
10384 return false;
10385}
10386
10387#endif /* WLAN_FEATURE_SARV1_TO_SARV2 */
10388
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010389/**
10390 * wlan_hdd_cfg80211_sar_convert_band() - Convert WLAN band value
10391 * @nl80211_value: Vendor command attribute value
10392 * @wmi_value: Pointer to return converted WMI return value
10393 *
10394 * Convert NL80211 vendor command value for SAR BAND to WMI value
10395 * Return: 0 on success, -1 on invalid value
10396 */
10397static int wlan_hdd_cfg80211_sar_convert_band(u32 nl80211_value, u32 *wmi_value)
10398{
10399 int ret = 0;
10400
10401 switch (nl80211_value) {
Srinivas Girigowda11c28e02017-06-27 20:06:21 -070010402 case HDD_NL80211_BAND_2GHZ:
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010403 *wmi_value = WMI_SAR_2G_ID;
10404 break;
Srinivas Girigowda11c28e02017-06-27 20:06:21 -070010405 case HDD_NL80211_BAND_5GHZ:
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010406 *wmi_value = WMI_SAR_5G_ID;
10407 break;
10408 default:
10409 ret = -1;
10410 }
10411 return ret;
10412}
10413
10414/**
10415 * wlan_hdd_cfg80211_sar_convert_modulation() - Convert WLAN modulation value
10416 * @nl80211_value: Vendor command attribute value
10417 * @wmi_value: Pointer to return converted WMI return value
10418 *
10419 * Convert NL80211 vendor command value for SAR Modulation to WMI value
10420 * Return: 0 on success, -1 on invalid value
10421 */
10422static int wlan_hdd_cfg80211_sar_convert_modulation(u32 nl80211_value,
10423 u32 *wmi_value)
10424{
10425 int ret = 0;
10426
10427 switch (nl80211_value) {
10428 case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_CCK:
10429 *wmi_value = WMI_SAR_MOD_CCK;
10430 break;
10431 case QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION_OFDM:
10432 *wmi_value = WMI_SAR_MOD_OFDM;
10433 break;
10434 default:
10435 ret = -1;
10436 }
10437 return ret;
10438}
10439
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010440void hdd_store_sar_config(struct hdd_context *hdd_ctx,
10441 struct sar_limit_cmd_params *sar_limit_cmd)
10442{
10443 /* Free the previously stored sar_limit_cmd */
10444 wlan_hdd_free_sar_config(hdd_ctx);
10445
10446 hdd_ctx->sar_cmd_params = sar_limit_cmd;
10447}
10448
10449void wlan_hdd_free_sar_config(struct hdd_context *hdd_ctx)
10450{
10451 struct sar_limit_cmd_params *sar_limit_cmd;
10452
10453 if (!hdd_ctx->sar_cmd_params)
10454 return;
10455
10456 sar_limit_cmd = hdd_ctx->sar_cmd_params;
10457 hdd_ctx->sar_cmd_params = NULL;
10458 qdf_mem_free(sar_limit_cmd->sar_limit_row_list);
10459 qdf_mem_free(sar_limit_cmd);
10460}
10461
10462#define SAR_LIMITS_SAR_ENABLE QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SAR_ENABLE
10463#define SAR_LIMITS_NUM_SPECS QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_NUM_SPECS
10464#define SAR_LIMITS_SPEC QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC
10465#define SAR_LIMITS_SPEC_BAND QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_BAND
10466#define SAR_LIMITS_SPEC_CHAIN QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_CHAIN
10467#define SAR_LIMITS_SPEC_MODULATION \
10468 QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_MODULATION
10469#define SAR_LIMITS_SPEC_POWER_LIMIT \
10470 QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT
10471#define SAR_LIMITS_SPEC_POWER_LIMIT_INDEX \
10472 QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_SPEC_POWER_LIMIT_INDEX
10473#define SAR_LIMITS_MAX QCA_WLAN_VENDOR_ATTR_SAR_LIMITS_MAX
10474
Jeff Johnsonb17a93c2017-06-02 12:26:55 -070010475static const struct nla_policy
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010476sar_limits_policy[SAR_LIMITS_MAX + 1] = {
10477 [SAR_LIMITS_SAR_ENABLE] = {.type = NLA_U32},
10478 [SAR_LIMITS_NUM_SPECS] = {.type = NLA_U32},
10479 [SAR_LIMITS_SPEC_BAND] = {.type = NLA_U32},
10480 [SAR_LIMITS_SPEC_CHAIN] = {.type = NLA_U32},
10481 [SAR_LIMITS_SPEC_MODULATION] = {.type = NLA_U32},
10482 [SAR_LIMITS_SPEC_POWER_LIMIT] = {.type = NLA_U32},
10483 [SAR_LIMITS_SPEC_POWER_LIMIT_INDEX] = {.type = NLA_U32},
Jeff Johnsonb17a93c2017-06-02 12:26:55 -070010484};
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010485
10486/**
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010487 * hdd_extract_sar_nested_attrs() - Extract nested SAR attribute
10488 * @spec: nested nla attribue
10489 * @row: output to hold extract nested attribute
10490 *
10491 * This function extracts nested SAR attribute one at a time which means
10492 * for each nested attribute this has to be invoked from
10493 * __wlan_hdd_set_sar_power_limits().
10494 *
10495 * Return: On success - 0
10496 * On Failure - Negative value
10497 */
10498static int hdd_extract_sar_nested_attrs(struct nlattr *spec[],
10499 struct sar_limit_cmd_row *row)
10500{
10501 uint32_t limit;
10502 uint32_t band;
10503 uint32_t modulation;
10504 int ret;
10505
10506 row->validity_bitmap = 0;
10507
10508 if (spec[SAR_LIMITS_SPEC_POWER_LIMIT]) {
10509 limit = nla_get_u32(spec[SAR_LIMITS_SPEC_POWER_LIMIT]);
10510 row->limit_value = limit;
10511 } else if (spec[SAR_LIMITS_SPEC_POWER_LIMIT_INDEX]) {
10512 limit = nla_get_u32(spec[SAR_LIMITS_SPEC_POWER_LIMIT_INDEX]);
10513 row->limit_value = limit;
10514 } else {
10515 hdd_err("SAR Spec does not have power limit or index value");
10516 return -EINVAL;
10517 }
10518
10519 if (spec[SAR_LIMITS_SPEC_BAND]) {
10520 band = nla_get_u32(spec[SAR_LIMITS_SPEC_BAND]);
10521 ret = wlan_hdd_cfg80211_sar_convert_band(band, &row->band_id);
10522 if (ret) {
10523 hdd_err("Invalid SAR Band attr");
10524 return ret;
10525 }
10526
10527 row->validity_bitmap |= WMI_SAR_BAND_ID_VALID_MASK;
10528 }
10529
10530 if (spec[SAR_LIMITS_SPEC_CHAIN]) {
10531 row->chain_id = nla_get_u32(spec[SAR_LIMITS_SPEC_CHAIN]);
10532 row->validity_bitmap |= WMI_SAR_CHAIN_ID_VALID_MASK;
10533 }
10534
10535 if (spec[SAR_LIMITS_SPEC_MODULATION]) {
10536 modulation = nla_get_u32(spec[SAR_LIMITS_SPEC_MODULATION]);
10537 ret = wlan_hdd_cfg80211_sar_convert_modulation(modulation,
10538 &row->mod_id);
10539 if (ret) {
10540 hdd_err("Invalid SAR Modulation attr");
10541 return ret;
10542 }
10543
10544 row->validity_bitmap |= WMI_SAR_MOD_ID_VALID_MASK;
10545 }
10546
10547 return 0;
10548}
10549
10550/**
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010551 * __wlan_hdd_set_sar_power_limits() - Set SAR power limits
10552 * @wiphy: Pointer to wireless phy
10553 * @wdev: Pointer to wireless device
10554 * @data: Pointer to data
10555 * @data_len: Length of @data
10556 *
10557 * This function is used to setup Specific Absorption Rate limit specs.
10558 *
10559 * Return: 0 on success, negative errno on failure
10560 */
10561static int __wlan_hdd_set_sar_power_limits(struct wiphy *wiphy,
10562 struct wireless_dev *wdev,
10563 const void *data, int data_len)
10564{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070010565 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010566 struct nlattr *spec[SAR_LIMITS_MAX + 1];
10567 struct nlattr *tb[SAR_LIMITS_MAX + 1];
10568 struct nlattr *spec_list;
10569 struct sar_limit_cmd_params *sar_limit_cmd;
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010570 int ret = -EINVAL, i = 0, rem = 0;
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010571 QDF_STATUS status;
10572 uint32_t num_limit_rows = 0;
10573 struct sar_limit_cmd_row *row;
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010574
Dustin Brown491d54b2018-03-14 12:39:11 -070010575 hdd_enter();
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010576
10577 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
10578 hdd_err("Command not allowed in FTM mode");
10579 return -EPERM;
10580 }
10581
10582 if (wlan_hdd_validate_context(hdd_ctx))
10583 return -EINVAL;
10584
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010585 if (wlan_cfg80211_nla_parse(tb, SAR_LIMITS_MAX, data, data_len,
10586 sar_limits_policy)) {
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010587 hdd_err("Invalid SAR attributes");
10588 return -EINVAL;
10589 }
10590
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010591 sar_limit_cmd = qdf_mem_malloc(sizeof(struct sar_limit_cmd_params));
10592 if (!sar_limit_cmd)
10593 return -ENOMEM;
10594
Jeff Johnson354c20b2018-07-17 20:15:56 -070010595 /* is special SAR V1 => SAR V2 logic enabled and applicable? */
Ashish Kumar Dhanotiya95498182019-04-29 13:59:20 +053010596 if (hdd_ctx->config->sar_version == 2 &&
10597 (hdd_convert_sarv1_to_sarv2(hdd_ctx, tb, sar_limit_cmd)))
Jeff Johnson354c20b2018-07-17 20:15:56 -070010598 goto send_sar_limits;
10599
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010600 /* Vendor command manadates all SAR Specs in single call */
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010601 sar_limit_cmd->commit_limits = 1;
10602 sar_limit_cmd->sar_enable = WMI_SAR_FEATURE_NO_CHANGE;
10603 if (tb[SAR_LIMITS_SAR_ENABLE]) {
10604 uint32_t sar_enable = nla_get_u32(tb[SAR_LIMITS_SAR_ENABLE]);
10605 uint32_t *sar_ptr = &sar_limit_cmd->sar_enable;
10606
10607 ret = wlan_hdd_cfg80211_sar_convert_limit_set(sar_enable,
10608 sar_ptr);
10609 if (ret) {
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010610 hdd_err("Invalid SAR Enable attr");
10611 goto fail;
10612 }
10613 }
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010614
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010615 hdd_debug("attr sar sar_enable %d", sar_limit_cmd->sar_enable);
10616
10617 if (tb[SAR_LIMITS_NUM_SPECS]) {
10618 num_limit_rows = nla_get_u32(tb[SAR_LIMITS_NUM_SPECS]);
10619 hdd_debug("attr sar num_limit_rows %u", num_limit_rows);
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010620 }
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010621
10622 if (num_limit_rows > MAX_SAR_LIMIT_ROWS_SUPPORTED) {
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010623 hdd_err("SAR Spec list exceed supported size");
10624 goto fail;
10625 }
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010626
10627 if (num_limit_rows == 0)
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010628 goto send_sar_limits;
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010629
10630 row = qdf_mem_malloc(sizeof(*row) * num_limit_rows);
10631 if (!row) {
10632 hdd_err("Failed to allocate memory for sar_limit_row_list");
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010633 goto fail;
10634 }
10635
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010636 sar_limit_cmd->num_limit_rows = num_limit_rows;
10637 sar_limit_cmd->sar_limit_row_list = row;
10638
10639 if (!tb[SAR_LIMITS_SPEC]) {
10640 hdd_err("Invalid SAR specification list");
10641 goto fail;
10642 }
10643
10644 nla_for_each_nested(spec_list, tb[SAR_LIMITS_SPEC], rem) {
10645 if (i == num_limit_rows) {
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010646 hdd_warn("SAR Cmd has excess SPECs in list");
10647 break;
10648 }
10649
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010650 if (wlan_cfg80211_nla_parse(spec,
10651 SAR_LIMITS_MAX,
10652 nla_data(spec_list),
10653 nla_len(spec_list),
Dustin Brown4ea21db2018-01-05 14:13:17 -080010654 sar_limits_policy)) {
10655 hdd_err("nla_parse failed for SAR Spec list");
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010656 goto fail;
10657 }
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010658
10659 ret = hdd_extract_sar_nested_attrs(spec, row);
10660 if (ret) {
10661 hdd_err("Failed to extract SAR nested attrs");
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010662 goto fail;
10663 }
10664
Srinivas Girigowda13d39252017-03-06 16:12:15 -080010665 hdd_debug("Spec_ID: %d, Band: %d Chain: %d Mod: %d POW_Limit: %d Validity_Bitmap: %d",
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010666 i, row->band_id, row->chain_id, row->mod_id,
10667 row->limit_value, row->validity_bitmap);
10668
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010669 i++;
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010670 row++;
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010671 }
10672
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010673 if (i < sar_limit_cmd->num_limit_rows) {
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010674 hdd_warn("SAR Cmd has less SPECs in list");
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010675 sar_limit_cmd->num_limit_rows = i;
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010676 }
10677
10678send_sar_limits:
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010679 status = sme_set_sar_power_limits(hdd_ctx->mac_handle, sar_limit_cmd);
10680 if (QDF_IS_STATUS_ERROR(status)) {
10681 hdd_err("Failed to set sar power limits");
10682 goto fail;
10683 }
10684
10685 /* After SSR, the SAR configuration is lost. As SSR is hidden from
10686 * userland, this command will not come from userspace after a SSR. To
10687 * restore this configuration, save this in hdd context and restore
10688 * after re-init.
10689 */
10690 hdd_store_sar_config(hdd_ctx, sar_limit_cmd);
10691 return 0;
10692
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010693fail:
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010694 if (sar_limit_cmd) {
10695 qdf_mem_free(sar_limit_cmd->sar_limit_row_list);
10696 qdf_mem_free(sar_limit_cmd);
10697 }
10698
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010699 return ret;
10700}
10701
Sourav Mohapatra9036f652019-04-02 15:02:59 +053010702#undef SAR_LIMITS_SAR_ENABLE
10703#undef SAR_LIMITS_NUM_SPECS
10704#undef SAR_LIMITS_SPEC
10705#undef SAR_LIMITS_SPEC_BAND
10706#undef SAR_LIMITS_SPEC_CHAIN
10707#undef SAR_LIMITS_SPEC_MODULATION
10708#undef SAR_LIMITS_SPEC_POWER_LIMIT
10709#undef SAR_LIMITS_SPEC_POWER_LIMIT_INDEX
10710#undef SAR_LIMITS_MAX
10711
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010712/**
10713 * wlan_hdd_cfg80211_set_sar_power_limits() - Set SAR power limits
10714 * @wiphy: Pointer to wireless phy
10715 * @wdev: Pointer to wireless device
10716 * @data: Pointer to data
10717 * @data_len: Length of @data
10718 *
10719 * Wrapper function of __wlan_hdd_cfg80211_set_sar_power_limits()
10720 *
10721 * Return: 0 on success, negative errno on failure
10722 */
10723static int wlan_hdd_cfg80211_set_sar_power_limits(struct wiphy *wiphy,
10724 struct wireless_dev *wdev,
10725 const void *data,
10726 int data_len)
10727{
Dustin Brown363b4792019-02-05 16:11:55 -080010728 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -080010729 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +053010730
Dustin Brown363b4792019-02-05 16:11:55 -080010731 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -080010732 if (errno)
10733 return errno;
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010734
Dustin Brownf0f00612019-01-31 16:02:24 -080010735 errno = __wlan_hdd_set_sar_power_limits(wiphy, wdev, data, data_len);
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010736
Dustin Brown363b4792019-02-05 16:11:55 -080010737 osif_psoc_sync_op_stop(psoc_sync);
Arunk Khandavalli99716d12018-11-14 15:02:02 +053010738
Dustin Brownf0f00612019-01-31 16:02:24 -080010739 return errno;
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080010740}
10741
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010742static const struct
10743nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
10744 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = {.type = NLA_U32},
10745 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {.type = NLA_BINARY,
10746 .len = QDF_MAC_ADDR_SIZE},
10747};
10748
Jeff Johnson43975142018-07-04 15:33:47 -070010749void wlan_hdd_rso_cmd_status_cb(hdd_handle_t hdd_handle,
10750 struct rso_cmd_status *rso_status)
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +053010751{
Jeff Johnson43975142018-07-04 15:33:47 -070010752 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Jeff Johnsone5006672017-08-29 14:39:02 -070010753 struct hdd_adapter *adapter;
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +053010754
10755 adapter = hdd_get_adapter_by_vdev(hdd_ctx, rso_status->vdev_id);
10756 if (!adapter) {
10757 hdd_err("adapter NULL");
10758 return;
10759 }
10760
10761 adapter->lfr_fw_status.is_disabled = rso_status->status;
10762 complete(&adapter->lfr_fw_status.disable_lfr_event);
10763}
10764
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010765/**
10766 * __wlan_hdd_cfg80211_set_fast_roaming() - enable/disable roaming
10767 * @wiphy: Pointer to wireless phy
10768 * @wdev: Pointer to wireless device
10769 * @data: Pointer to data
10770 * @data_len: Length of @data
10771 *
10772 * This function is used to enable/disable roaming using vendor commands
10773 *
10774 * Return: 0 on success, negative errno on failure
10775 */
10776static int __wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
10777 struct wireless_dev *wdev,
10778 const void *data, int data_len)
10779{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070010780 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010781 struct net_device *dev = wdev->netdev;
Jeff Johnsone5006672017-08-29 14:39:02 -070010782 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010783 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
Abhishek Singh1f217ec2017-12-22 11:48:27 +053010784 uint32_t is_fast_roam_enabled;
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010785 int ret;
Selvaraj, Sridhard753e7c2017-01-12 20:19:27 +053010786 QDF_STATUS qdf_status;
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +053010787 unsigned long rc;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070010788 struct hdd_station_ctx *hdd_sta_ctx =
10789 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
10790 mac_handle_t mac_handle;
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010791
Dustin Brownfdf17c12018-03-14 12:55:34 -070010792 hdd_enter_dev(dev);
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010793
10794 ret = wlan_hdd_validate_context(hdd_ctx);
10795 if (0 != ret)
10796 return ret;
10797
10798 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
10799 hdd_err("Command not allowed in FTM mode");
10800 return -EINVAL;
10801 }
10802
Dustin Brown4ea21db2018-01-05 14:13:17 -080010803 ret = wlan_cfg80211_nla_parse(tb,
10804 QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
10805 qca_wlan_vendor_attr);
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010806 if (ret) {
10807 hdd_err("Invalid ATTR");
10808 return -EINVAL;
10809 }
10810
10811 /* Parse and fetch Enable flag */
10812 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
10813 hdd_err("attr enable failed");
10814 return -EINVAL;
10815 }
10816
10817 is_fast_roam_enabled = nla_get_u32(
10818 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
Abhishek Singh1f217ec2017-12-22 11:48:27 +053010819 hdd_debug("isFastRoamEnabled %d", is_fast_roam_enabled);
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010820
10821 /* Update roaming */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070010822 mac_handle = hdd_ctx->mac_handle;
Jeff Johnsoncf07c312019-02-04 13:53:29 -080010823 qdf_status = sme_config_fast_roaming(mac_handle, adapter->vdev_id,
Abhishek Singh1f217ec2017-12-22 11:48:27 +053010824 is_fast_roam_enabled);
Selvaraj, Sridhard753e7c2017-01-12 20:19:27 +053010825 if (qdf_status != QDF_STATUS_SUCCESS)
10826 hdd_err("sme_config_fast_roaming failed with status=%d",
10827 qdf_status);
10828 ret = qdf_status_to_os_return(qdf_status);
10829
Jeff Johnsone7951512019-02-27 10:02:51 -080010830 if (eConnectionState_Associated == hdd_sta_ctx->conn_info.conn_state &&
Abhishek Singh1f217ec2017-12-22 11:48:27 +053010831 QDF_IS_STATUS_SUCCESS(qdf_status) && !is_fast_roam_enabled) {
Selvaraj, Sridhar4c7411e2017-05-04 12:58:41 +053010832
10833 INIT_COMPLETION(adapter->lfr_fw_status.disable_lfr_event);
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +053010834 /*
10835 * wait only for LFR disable in fw as LFR enable
10836 * is always success
10837 */
10838 rc = wait_for_completion_timeout(
10839 &adapter->lfr_fw_status.disable_lfr_event,
10840 msecs_to_jiffies(WAIT_TIME_RSO_CMD_STATUS));
10841 if (!rc) {
10842 hdd_err("Timed out waiting for RSO CMD status");
10843 return -ETIMEDOUT;
10844 }
10845
10846 if (!adapter->lfr_fw_status.is_disabled) {
10847 hdd_err("Roam disable attempt in FW fails");
10848 return -EBUSY;
10849 }
10850 }
10851
Dustin Browne74003f2018-03-14 12:51:58 -070010852 hdd_exit();
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010853 return ret;
10854}
10855
10856/**
10857 * wlan_hdd_cfg80211_set_fast_roaming() - enable/disable roaming
10858 * @wiphy: Pointer to wireless phy
10859 * @wdev: Pointer to wireless device
10860 * @data: Pointer to data
10861 * @data_len: Length of @data
10862 *
10863 * Wrapper function of __wlan_hdd_cfg80211_set_fast_roaming()
10864 *
10865 * Return: 0 on success, negative errno on failure
10866 */
10867static int wlan_hdd_cfg80211_set_fast_roaming(struct wiphy *wiphy,
10868 struct wireless_dev *wdev,
10869 const void *data, int data_len)
10870{
Dustin Browna09acf42018-11-08 12:32:26 +053010871 int errno;
10872 struct osif_vdev_sync *vdev_sync;
10873
10874 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
10875 if (errno)
10876 return errno;
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010877
Dustin Browna09acf42018-11-08 12:32:26 +053010878 errno = __wlan_hdd_cfg80211_set_fast_roaming(wiphy, wdev,
10879 data, data_len);
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010880
Dustin Browna09acf42018-11-08 12:32:26 +053010881 osif_vdev_sync_op_stop(vdev_sync);
10882
10883 return errno;
Mukul Sharma69c44cd2016-09-12 18:33:57 +053010884}
10885
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053010886/*
10887 * define short names for the global vendor params
10888 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
10889 */
10890#define STATS_SET_INVALID \
10891 QCA_ATTR_NUD_STATS_SET_INVALID
10892#define STATS_SET_START \
10893 QCA_ATTR_NUD_STATS_SET_START
10894#define STATS_GW_IPV4 \
10895 QCA_ATTR_NUD_STATS_GW_IPV4
10896#define STATS_SET_DATA_PKT_INFO \
10897 QCA_ATTR_NUD_STATS_SET_DATA_PKT_INFO
10898#define STATS_SET_MAX \
10899 QCA_ATTR_NUD_STATS_SET_MAX
10900
10901const struct nla_policy
10902qca_wlan_vendor_set_nud_stats[STATS_SET_MAX + 1] = {
10903 [STATS_SET_START] = {.type = NLA_FLAG },
10904 [STATS_GW_IPV4] = {.type = NLA_U32 },
10905 [STATS_SET_DATA_PKT_INFO] = {.type = NLA_U32 },
10906};
10907
10908/* define short names for the global vendor params */
10909#define CONNECTIVITY_STATS_SET_INVALID \
10910 QCA_ATTR_CONNECTIVITY_CHECK_STATS_SET_INVALID
10911#define STATS_PKT_INFO_TYPE \
10912 QCA_ATTR_CONNECTIVITY_CHECK_STATS_STATS_PKT_INFO_TYPE
10913#define STATS_DNS_DOMAIN_NAME \
10914 QCA_ATTR_CONNECTIVITY_CHECK_STATS_DNS_DOMAIN_NAME
10915#define STATS_SRC_PORT \
10916 QCA_ATTR_CONNECTIVITY_CHECK_STATS_SRC_PORT
10917#define STATS_DEST_PORT \
10918 QCA_ATTR_CONNECTIVITY_CHECK_STATS_DEST_PORT
10919#define STATS_DEST_IPV4 \
10920 QCA_ATTR_CONNECTIVITY_CHECK_STATS_DEST_IPV4
10921#define STATS_DEST_IPV6 \
10922 QCA_ATTR_CONNECTIVITY_CHECK_STATS_DEST_IPV6
10923#define CONNECTIVITY_STATS_SET_MAX \
10924 QCA_ATTR_CONNECTIVITY_CHECK_STATS_SET_MAX
10925
10926const struct nla_policy
10927qca_wlan_vendor_set_connectivity_check_stats[CONNECTIVITY_STATS_SET_MAX + 1] = {
10928 [STATS_PKT_INFO_TYPE] = {.type = NLA_U32 },
Sourav Mohapatraaaa0f882019-03-07 09:28:40 +053010929 [STATS_DNS_DOMAIN_NAME] = {.type = NLA_NUL_STRING,
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053010930 .len = DNS_DOMAIN_NAME_MAX_LEN },
10931 [STATS_SRC_PORT] = {.type = NLA_U32 },
10932 [STATS_DEST_PORT] = {.type = NLA_U32 },
10933 [STATS_DEST_IPV4] = {.type = NLA_U32 },
10934 [STATS_DEST_IPV6] = {.type = NLA_BINARY,
10935 .len = ICMPv6_ADDR_LEN },
10936};
10937
10938/**
10939 * hdd_dns_unmake_name_query() - Convert an uncompressed DNS name to a
10940 * NUL-terminated string
10941 * @name: DNS name
10942 *
10943 * Return: Produce a printable version of a DNS name.
10944 */
10945static inline uint8_t *hdd_dns_unmake_name_query(uint8_t *name)
10946{
10947 uint8_t *p;
10948 unsigned int len;
10949
10950 p = name;
10951 while ((len = *p)) {
10952 *(p++) = '.';
10953 p += len;
10954 }
10955
10956 return name + 1;
10957}
10958
10959/**
10960 * hdd_dns_make_name_query() - Convert a standard NUL-terminated string
10961 * to DNS name
10962 * @string: Name as a NUL-terminated string
10963 * @buf: Buffer in which to place DNS name
10964 *
10965 * DNS names consist of "<length>element" pairs.
10966 *
10967 * Return: Byte following constructed DNS name
10968 */
Sourav Mohapatra47710c32018-11-30 16:27:05 +053010969static uint8_t *hdd_dns_make_name_query(const uint8_t *string,
10970 uint8_t *buf, uint8_t len)
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053010971{
10972 uint8_t *length_byte = buf++;
10973 uint8_t c;
10974
Sourav Mohapatra47710c32018-11-30 16:27:05 +053010975 if (string[len - 1]) {
10976 hdd_debug("DNS name is not null terminated");
10977 return NULL;
10978 }
10979
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053010980 while ((c = *(string++))) {
10981 if (c == '.') {
10982 *length_byte = buf - length_byte - 1;
10983 length_byte = buf;
10984 }
10985 *(buf++) = c;
10986 }
10987 *length_byte = buf - length_byte - 1;
10988 *(buf++) = '\0';
10989 return buf;
10990}
10991
10992/**
10993 * hdd_set_clear_connectivity_check_stats_info() - set/clear stats info
10994 * @adapter: Pointer to hdd adapter
10995 * @arp_stats_params: arp stats structure to be sent to FW
10996 * @tb: nl attribute
10997 * @is_set_stats: set/clear stats
10998 *
10999 *
11000 * Return: 0 on success, negative errno on failure
11001 */
11002static int hdd_set_clear_connectivity_check_stats_info(
11003 struct hdd_adapter *adapter,
11004 struct set_arp_stats_params *arp_stats_params,
11005 struct nlattr **tb, bool is_set_stats)
11006{
11007 struct nlattr *tb2[CONNECTIVITY_STATS_SET_MAX + 1];
11008 struct nlattr *curr_attr = NULL;
11009 int err = 0;
11010 uint32_t pkt_bitmap;
11011 int rem;
11012
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011013 /* Set NUD command for start tracking is received. */
11014 nla_for_each_nested(curr_attr,
11015 tb[STATS_SET_DATA_PKT_INFO],
11016 rem) {
11017
11018 if (wlan_cfg80211_nla_parse(tb2,
11019 CONNECTIVITY_STATS_SET_MAX,
11020 nla_data(curr_attr), nla_len(curr_attr),
11021 qca_wlan_vendor_set_connectivity_check_stats)) {
11022 hdd_err("nla_parse failed");
11023 err = -EINVAL;
11024 goto end;
11025 }
11026
11027 if (tb2[STATS_PKT_INFO_TYPE]) {
11028 pkt_bitmap = nla_get_u32(tb2[STATS_PKT_INFO_TYPE]);
11029 if (!pkt_bitmap) {
11030 hdd_err("pkt tracking bitmap is empty");
11031 err = -EINVAL;
11032 goto end;
11033 }
Poddar, Siddarth9c2cd262018-01-18 19:03:39 +053011034
11035 if (is_set_stats) {
11036 arp_stats_params->pkt_type_bitmap = pkt_bitmap;
11037 arp_stats_params->flag = true;
11038 adapter->pkt_type_bitmap |=
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011039 arp_stats_params->pkt_type_bitmap;
11040
Poddar, Siddarth9c2cd262018-01-18 19:03:39 +053011041 if (pkt_bitmap & CONNECTIVITY_CHECK_SET_ARP) {
Srinivas Girigowda683726a2018-09-07 15:10:40 -070011042 if (!tb[STATS_GW_IPV4]) {
11043 hdd_err("GW ipv4 address is not present");
11044 err = -EINVAL;
11045 goto end;
11046 }
11047 arp_stats_params->ip_addr =
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011048 nla_get_u32(tb[STATS_GW_IPV4]);
Srinivas Girigowda683726a2018-09-07 15:10:40 -070011049 arp_stats_params->pkt_type =
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011050 WLAN_NUD_STATS_ARP_PKT_TYPE;
Srinivas Girigowda683726a2018-09-07 15:10:40 -070011051 adapter->track_arp_ip =
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011052 arp_stats_params->ip_addr;
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011053 }
Poddar, Siddarth9c2cd262018-01-18 19:03:39 +053011054
11055 if (pkt_bitmap & CONNECTIVITY_CHECK_SET_DNS) {
11056 uint8_t *domain_name;
11057
11058 if (!tb2[STATS_DNS_DOMAIN_NAME]) {
11059 hdd_err("DNS domain id is not present");
11060 err = -EINVAL;
11061 goto end;
11062 }
11063 domain_name = nla_data(
11064 tb2[STATS_DNS_DOMAIN_NAME]);
11065 adapter->track_dns_domain_len =
11066 nla_len(tb2[
11067 STATS_DNS_DOMAIN_NAME]);
Sourav Mohapatra47710c32018-11-30 16:27:05 +053011068 if (!hdd_dns_make_name_query(
11069 domain_name,
11070 adapter->dns_payload,
11071 adapter->track_dns_domain_len))
11072 adapter->track_dns_domain_len =
11073 0;
Poddar, Siddarth9c2cd262018-01-18 19:03:39 +053011074 /* DNStracking isn't supported in FW. */
11075 arp_stats_params->pkt_type_bitmap &=
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011076 ~CONNECTIVITY_CHECK_SET_DNS;
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011077 }
Poddar, Siddarth9c2cd262018-01-18 19:03:39 +053011078
11079 if (pkt_bitmap &
11080 CONNECTIVITY_CHECK_SET_TCP_HANDSHAKE) {
11081 if (!tb2[STATS_SRC_PORT] ||
11082 !tb2[STATS_DEST_PORT]) {
11083 hdd_err("Source/Dest port is not present");
11084 err = -EINVAL;
11085 goto end;
11086 }
11087 arp_stats_params->tcp_src_port =
11088 nla_get_u32(
11089 tb2[STATS_SRC_PORT]);
11090 arp_stats_params->tcp_dst_port =
11091 nla_get_u32(
11092 tb2[STATS_DEST_PORT]);
11093 adapter->track_src_port =
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011094 arp_stats_params->tcp_src_port;
Poddar, Siddarth9c2cd262018-01-18 19:03:39 +053011095 adapter->track_dest_port =
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011096 arp_stats_params->tcp_dst_port;
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011097 }
Poddar, Siddarth9c2cd262018-01-18 19:03:39 +053011098
11099 if (pkt_bitmap &
11100 CONNECTIVITY_CHECK_SET_ICMPV4) {
11101 if (!tb2[STATS_DEST_IPV4]) {
11102 hdd_err("destination ipv4 address to track ping packets is not present");
11103 err = -EINVAL;
11104 goto end;
11105 }
11106 arp_stats_params->icmp_ipv4 =
11107 nla_get_u32(
11108 tb2[STATS_DEST_IPV4]);
11109 adapter->track_dest_ipv4 =
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011110 arp_stats_params->icmp_ipv4;
Poddar, Siddarth9c2cd262018-01-18 19:03:39 +053011111 }
11112 } else {
11113 /* clear stats command received */
11114 arp_stats_params->pkt_type_bitmap = pkt_bitmap;
11115 arp_stats_params->flag = false;
11116 adapter->pkt_type_bitmap &=
11117 (~arp_stats_params->pkt_type_bitmap);
11118
11119 if (pkt_bitmap & CONNECTIVITY_CHECK_SET_ARP) {
11120 arp_stats_params->pkt_type =
11121 WLAN_NUD_STATS_ARP_PKT_TYPE;
11122 qdf_mem_zero(&adapter->hdd_stats.
11123 hdd_arp_stats,
11124 sizeof(adapter->hdd_stats.
11125 hdd_arp_stats));
11126 adapter->track_arp_ip = 0;
11127 }
11128
11129 if (pkt_bitmap & CONNECTIVITY_CHECK_SET_DNS) {
11130 /* DNStracking isn't supported in FW. */
11131 arp_stats_params->pkt_type_bitmap &=
11132 ~CONNECTIVITY_CHECK_SET_DNS;
11133 qdf_mem_zero(&adapter->hdd_stats.
11134 hdd_dns_stats,
11135 sizeof(adapter->hdd_stats.
11136 hdd_dns_stats));
11137 qdf_mem_zero(adapter->dns_payload,
11138 adapter->track_dns_domain_len);
11139 adapter->track_dns_domain_len = 0;
11140 }
11141
11142 if (pkt_bitmap &
11143 CONNECTIVITY_CHECK_SET_TCP_HANDSHAKE) {
11144 qdf_mem_zero(&adapter->hdd_stats.
11145 hdd_tcp_stats,
11146 sizeof(adapter->hdd_stats.
11147 hdd_tcp_stats));
11148 adapter->track_src_port = 0;
11149 adapter->track_dest_port = 0;
11150 }
11151
11152 if (pkt_bitmap &
11153 CONNECTIVITY_CHECK_SET_ICMPV4) {
11154 qdf_mem_zero(&adapter->hdd_stats.
11155 hdd_icmpv4_stats,
11156 sizeof(adapter->hdd_stats.
11157 hdd_icmpv4_stats));
11158 adapter->track_dest_ipv4 = 0;
11159 }
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011160 }
11161 } else {
11162 hdd_err("stats list empty");
11163 err = -EINVAL;
11164 goto end;
11165 }
11166 }
11167
11168end:
11169 return err;
11170}
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +053011171
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +053011172static const struct nla_policy qca_wlan_vendor_set_trace_level_policy[
11173 QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX + 1] = {
11174 [QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM] = {.type = NLA_NESTED },
11175 [QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MODULE_ID] = {.type = NLA_U32 },
11176 [QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_TRACE_MASK] = {.type = NLA_U32 },
11177};
11178
11179/**
11180 * __wlan_hdd_cfg80211_set_trace_level() - Set the trace level
11181 * @wiphy: Pointer to wireless phy
11182 * @wdev: Pointer to wireless device
11183 * @data: Pointer to data
11184 * @data_len: Length of @data
11185 *
11186 * Return: 0 on success, negative errno on failure
11187 */
11188static int
11189__wlan_hdd_cfg80211_set_trace_level(struct wiphy *wiphy,
11190 struct wireless_dev *wdev,
11191 const void *data,
11192 int data_len)
11193{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070011194 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +053011195 struct nlattr *tb1[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX + 1];
11196 struct nlattr *tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX + 1];
11197 struct nlattr *apth;
11198 int rem;
11199 int ret = 1;
11200 int print_idx = -1;
11201 int module_id = -1;
11202 int bit_mask = -1;
11203 int status;
11204
Dustin Brown491d54b2018-03-14 12:39:11 -070011205 hdd_enter();
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +053011206
11207 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
11208 hdd_err("Command not allowed in FTM mode");
11209 return -EINVAL;
11210 }
11211
11212 ret = wlan_hdd_validate_context(hdd_ctx);
11213 if (ret != 0)
11214 return -EINVAL;
11215
11216 print_idx = qdf_get_pidx();
11217 if (print_idx < 0 || print_idx >= MAX_PRINT_CONFIG_SUPPORTED) {
11218 hdd_err("Invalid print controle object index");
11219 return -EINVAL;
11220 }
11221
Dustin Brown4ea21db2018-01-05 14:13:17 -080011222 if (wlan_cfg80211_nla_parse(tb1,
11223 QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX,
11224 data, data_len,
11225 qca_wlan_vendor_set_trace_level_policy)) {
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +053011226 hdd_err("Invalid attr");
11227 return -EINVAL;
11228 }
11229
11230 if (!tb1[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM]) {
11231 hdd_err("attr trace level param failed");
11232 return -EINVAL;
11233 }
11234
11235 nla_for_each_nested(apth,
11236 tb1[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_PARAM], rem) {
Dustin Brown4ea21db2018-01-05 14:13:17 -080011237 if (wlan_cfg80211_nla_parse(tb2,
Ashish Kumar Dhanotiya69903252019-03-18 20:23:47 +053011238 QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MAX,
11239 nla_data(apth), nla_len(apth),
11240 qca_wlan_vendor_set_trace_level_policy)) {
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +053011241 hdd_err("Invalid attr");
11242 return -EINVAL;
11243 }
11244
11245 if (!tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MODULE_ID]) {
11246 hdd_err("attr Module ID failed");
11247 return -EINVAL;
11248 }
11249 module_id = nla_get_u32
11250 (tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_MODULE_ID]);
11251
11252 if (!tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_TRACE_MASK]) {
11253 hdd_err("attr Verbose mask failed");
11254 return -EINVAL;
11255 }
11256 bit_mask = nla_get_u32
11257 (tb2[QCA_WLAN_VENDOR_ATTR_SET_TRACE_LEVEL_TRACE_MASK]);
11258
11259 status = hdd_qdf_trace_enable(module_id, bit_mask);
11260
11261 if (status != 0)
11262 hdd_err("can not set verbose mask %d for the category %d",
11263 bit_mask, module_id);
11264 }
11265
Dustin Browne74003f2018-03-14 12:51:58 -070011266 hdd_exit();
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +053011267 return ret;
11268}
11269
11270/**
Ashish Kumar Dhanotiyaeb4fe4b2017-02-20 16:04:00 +053011271 * wlan_hdd_cfg80211_set_trace_level() - Set the trace level
11272 * @wiphy: Pointer to wireless phy
11273 * @wdev: Pointer to wireless device
11274 * @data: Pointer to data
11275 * @data_len: Length of @data
11276 *
11277 * Wrapper function of __wlan_hdd_cfg80211_set_trace_level()
11278 *
11279 * Return: 0 on success, negative errno on failure
11280 */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +053011281
11282static int wlan_hdd_cfg80211_set_trace_level(struct wiphy *wiphy,
11283 struct wireless_dev *wdev,
11284 const void *data,
11285 int data_len)
11286{
Dustin Brown363b4792019-02-05 16:11:55 -080011287 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -080011288 int errno;
Arunk Khandavalli99716d12018-11-14 15:02:02 +053011289
Dustin Brown363b4792019-02-05 16:11:55 -080011290 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -080011291 if (errno)
11292 return errno;
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +053011293
Dustin Brownf0f00612019-01-31 16:02:24 -080011294 errno = __wlan_hdd_cfg80211_set_trace_level(wiphy, wdev,
11295 data, data_len);
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +053011296
Dustin Brown363b4792019-02-05 16:11:55 -080011297 osif_psoc_sync_op_stop(psoc_sync);
Arunk Khandavalli99716d12018-11-14 15:02:02 +053011298
Dustin Brownf0f00612019-01-31 16:02:24 -080011299 return errno;
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +053011300}
11301
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011302/**
11303 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
11304 * @wiphy: pointer to wireless wiphy structure.
11305 * @wdev: pointer to wireless_dev structure.
11306 * @data: pointer to apfind configuration data.
11307 * @data_len: the length in byte of apfind data.
11308 *
11309 * This is called when wlan driver needs to send arp stats to
11310 * firmware.
11311 *
11312 * Return: An error code or 0 on success.
11313 */
11314static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
11315 struct wireless_dev *wdev,
11316 const void *data, int data_len)
11317{
11318 struct nlattr *tb[STATS_SET_MAX + 1];
11319 struct net_device *dev = wdev->netdev;
11320 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
11321 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011322 struct set_arp_stats_params arp_stats_params = {0};
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011323 int err = 0;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070011324 mac_handle_t mac_handle;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011325
Dustin Brown491d54b2018-03-14 12:39:11 -070011326 hdd_enter();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011327
Anurag Chouhan9fb2bd52018-01-04 12:25:48 +053011328 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
11329 hdd_err("Command not allowed in FTM mode");
11330 return -EINVAL;
11331 }
11332
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011333 err = wlan_hdd_validate_context(hdd_ctx);
11334 if (0 != err)
11335 return err;
11336
Jeff Johnson912b1bb2019-03-06 10:12:36 -080011337 if (adapter->vdev_id == WLAN_UMAC_VDEV_ID_MAX) {
11338 hdd_err("Invalid vdev id");
Yeshwanth Sriram Guntukad5aae7f2017-11-27 14:33:51 +053011339 return -EINVAL;
11340 }
11341
Poddar, Siddarthdf076672018-02-26 14:21:45 +053011342 if (adapter->device_mode != QDF_STA_MODE) {
Dustin Browna2868622018-03-20 11:38:14 -070011343 hdd_err("STATS supported in only STA mode!");
Poddar, Siddarthdf076672018-02-26 14:21:45 +053011344 return -EINVAL;
11345 }
11346
Jeff Johnson912b1bb2019-03-06 10:12:36 -080011347 err = wlan_cfg80211_nla_parse(tb, STATS_SET_MAX, data, data_len,
11348 qca_wlan_vendor_set_nud_stats);
11349 if (err) {
11350 hdd_err("STATS_SET_START ATTR");
11351 return err;
11352 }
11353
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011354 if (tb[STATS_SET_START]) {
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011355 /* tracking is enabled for stats other than arp. */
11356 if (tb[STATS_SET_DATA_PKT_INFO]) {
11357 err = hdd_set_clear_connectivity_check_stats_info(
11358 adapter,
11359 &arp_stats_params, tb, true);
11360 if (err)
11361 return -EINVAL;
11362
11363 /*
11364 * if only tracking dns, then don't send
11365 * wmi command to FW.
11366 */
11367 if (!arp_stats_params.pkt_type_bitmap)
11368 return err;
11369 } else {
11370 if (!tb[STATS_GW_IPV4]) {
Dustin Browna2868622018-03-20 11:38:14 -070011371 hdd_err("STATS_SET_START CMD");
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011372 return -EINVAL;
11373 }
Poddar, Siddarth9c2cd262018-01-18 19:03:39 +053011374
11375 arp_stats_params.pkt_type_bitmap =
11376 CONNECTIVITY_CHECK_SET_ARP;
11377 adapter->pkt_type_bitmap |=
11378 arp_stats_params.pkt_type_bitmap;
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011379 arp_stats_params.flag = true;
11380 arp_stats_params.ip_addr =
11381 nla_get_u32(tb[STATS_GW_IPV4]);
11382 adapter->track_arp_ip = arp_stats_params.ip_addr;
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011383 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011384 }
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011385 } else {
Poddar, Siddarth9c2cd262018-01-18 19:03:39 +053011386 /* clear stats command received. */
11387 if (tb[STATS_SET_DATA_PKT_INFO]) {
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011388 err = hdd_set_clear_connectivity_check_stats_info(
11389 adapter,
11390 &arp_stats_params, tb, false);
11391 if (err)
11392 return -EINVAL;
11393
11394 /*
11395 * if only tracking dns, then don't send
11396 * wmi command to FW.
11397 */
11398 if (!arp_stats_params.pkt_type_bitmap)
11399 return err;
11400 } else {
Poddar, Siddarth9c2cd262018-01-18 19:03:39 +053011401 arp_stats_params.pkt_type_bitmap =
11402 CONNECTIVITY_CHECK_SET_ARP;
11403 adapter->pkt_type_bitmap &=
11404 (~arp_stats_params.pkt_type_bitmap);
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011405 arp_stats_params.flag = false;
11406 qdf_mem_zero(&adapter->hdd_stats.hdd_arp_stats,
11407 sizeof(adapter->hdd_stats.hdd_arp_stats));
11408 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
11409 }
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011410 }
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011411
Abhinav Kumar50d4dc72018-06-15 16:35:50 +053011412 hdd_debug("STATS_SET_START Received flag %d!", arp_stats_params.flag);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011413
Jeff Johnsoncf07c312019-02-04 13:53:29 -080011414 arp_stats_params.vdev_id = adapter->vdev_id;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011415
Jeff Johnson34fc63a2018-06-14 10:10:02 -070011416 mac_handle = hdd_ctx->mac_handle;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011417 if (QDF_STATUS_SUCCESS !=
Jeff Johnson34fc63a2018-06-14 10:10:02 -070011418 sme_set_nud_debug_stats(mac_handle, &arp_stats_params)) {
Dustin Browna2868622018-03-20 11:38:14 -070011419 hdd_err("STATS_SET_START CMD Failed!");
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011420 return -EINVAL;
11421 }
11422
Dustin Browne74003f2018-03-14 12:51:58 -070011423 hdd_exit();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011424
11425 return err;
11426}
11427
11428/**
11429 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
11430 * @wiphy: pointer to wireless wiphy structure.
11431 * @wdev: pointer to wireless_dev structure.
11432 * @data: pointer to apfind configuration data.
11433 * @data_len: the length in byte of apfind data.
11434 *
11435 * This is called when wlan driver needs to send arp stats to
11436 * firmware.
11437 *
11438 * Return: An error code or 0 on success.
11439 */
11440static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
11441 struct wireless_dev *wdev,
11442 const void *data, int data_len)
11443{
Dustin Browna09acf42018-11-08 12:32:26 +053011444 int errno;
11445 struct osif_vdev_sync *vdev_sync;
11446
11447 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
11448 if (errno)
11449 return errno;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011450
Dustin Browna09acf42018-11-08 12:32:26 +053011451 errno = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011452
Dustin Browna09acf42018-11-08 12:32:26 +053011453 osif_vdev_sync_op_stop(vdev_sync);
11454
11455 return errno;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011456}
11457
11458#undef STATS_SET_INVALID
11459#undef STATS_SET_START
11460#undef STATS_GW_IPV4
11461#undef STATS_SET_MAX
11462
11463/*
11464 * define short names for the global vendor params
11465 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
11466 */
11467#define STATS_GET_INVALID \
11468 QCA_ATTR_NUD_STATS_SET_INVALID
11469#define COUNT_FROM_NETDEV \
11470 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
11471#define COUNT_TO_LOWER_MAC \
11472 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
11473#define RX_COUNT_BY_LOWER_MAC \
11474 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
11475#define COUNT_TX_SUCCESS \
11476 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
11477#define RSP_RX_COUNT_BY_LOWER_MAC \
11478 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
11479#define RSP_RX_COUNT_BY_UPPER_MAC \
11480 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
11481#define RSP_COUNT_TO_NETDEV \
11482 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
11483#define RSP_COUNT_OUT_OF_ORDER_DROP \
11484 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
11485#define AP_LINK_ACTIVE \
11486 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
11487#define AP_LINK_DAD \
11488 QCA_ATTR_NUD_STATS_IS_DAD
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011489#define DATA_PKT_STATS \
11490 QCA_ATTR_NUD_STATS_DATA_PKT_STATS
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011491#define STATS_GET_MAX \
11492 QCA_ATTR_NUD_STATS_GET_MAX
11493
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011494#define CHECK_STATS_INVALID \
11495 QCA_ATTR_CONNECTIVITY_CHECK_STATS_INVALID
11496#define CHECK_STATS_PKT_TYPE \
11497 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_TYPE
11498#define CHECK_STATS_PKT_DNS_DOMAIN_NAME \
11499 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_DNS_DOMAIN_NAME
11500#define CHECK_STATS_PKT_SRC_PORT \
11501 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_SRC_PORT
11502#define CHECK_STATS_PKT_DEST_PORT \
11503 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_DEST_PORT
11504#define CHECK_STATS_PKT_DEST_IPV4 \
11505 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_DEST_IPV4
11506#define CHECK_STATS_PKT_DEST_IPV6 \
11507 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_DEST_IPV6
11508#define CHECK_STATS_PKT_REQ_COUNT_FROM_NETDEV \
11509 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_REQ_COUNT_FROM_NETDEV
11510#define CHECK_STATS_PKT_REQ_COUNT_TO_LOWER_MAC \
11511 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_REQ_COUNT_TO_LOWER_MAC
11512#define CHECK_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC \
11513 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC
11514#define CHECK_STATS_PKT_REQ_COUNT_TX_SUCCESS \
11515 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_REQ_COUNT_TX_SUCCESS
11516#define CHECK_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC \
11517 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC
11518#define CHECK_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC \
11519 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC
11520#define CHECK_STATS_PKT_RSP_COUNT_TO_NETDEV \
11521 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_RSP_COUNT_TO_NETDEV
11522#define CHECK_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP \
11523 QCA_ATTR_CONNECTIVITY_CHECK_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP
11524#define CHECK_DATA_STATS_MAX \
11525 QCA_ATTR_CONNECTIVITY_CHECK_DATA_STATS_MAX
11526
11527
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011528const struct nla_policy
11529qca_wlan_vendor_get_nud_stats[STATS_GET_MAX + 1] = {
11530 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
11531 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
11532 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
11533 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
11534 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
11535 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
11536 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
11537 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
11538 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
11539 [AP_LINK_DAD] = {.type = NLA_FLAG },
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011540 [DATA_PKT_STATS] = {.type = NLA_U16 },
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011541};
11542
11543/**
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011544 * hdd_populate_dns_stats_info() - send dns stats info to network stack
11545 * @adapter: pointer to adapter context
11546 * @skb: pointer to skb
11547 *
11548 *
11549 * Return: An error code or 0 on success.
11550 */
11551static int hdd_populate_dns_stats_info(struct hdd_adapter *adapter,
11552 struct sk_buff *skb)
11553{
11554 uint8_t *dns_query;
11555
11556 dns_query = qdf_mem_malloc(adapter->track_dns_domain_len + 1);
Min Liu74a1a502018-10-10 19:59:07 +080011557 if (!dns_query)
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011558 return -EINVAL;
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011559
11560 qdf_mem_copy(dns_query, adapter->dns_payload,
11561 adapter->track_dns_domain_len);
11562
11563 if (nla_put_u16(skb, CHECK_STATS_PKT_TYPE,
11564 CONNECTIVITY_CHECK_SET_DNS) ||
11565 nla_put(skb, CHECK_STATS_PKT_DNS_DOMAIN_NAME,
11566 adapter->track_dns_domain_len,
11567 hdd_dns_unmake_name_query(dns_query)) ||
11568 nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_FROM_NETDEV,
11569 adapter->hdd_stats.hdd_dns_stats.tx_dns_req_count) ||
11570 nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TO_LOWER_MAC,
11571 adapter->hdd_stats.hdd_dns_stats.tx_host_fw_sent) ||
11572 nla_put_u16(skb, CHECK_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC,
11573 adapter->hdd_stats.hdd_dns_stats.tx_host_fw_sent) ||
11574 nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TX_SUCCESS,
11575 adapter->hdd_stats.hdd_dns_stats.tx_ack_cnt) ||
11576 nla_put_u16(skb, CHECK_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC,
11577 adapter->hdd_stats.hdd_dns_stats.rx_dns_rsp_count) ||
11578 nla_put_u16(skb, CHECK_STATS_PKT_RSP_COUNT_TO_NETDEV,
11579 adapter->hdd_stats.hdd_dns_stats.rx_delivered) ||
11580 nla_put_u16(skb, CHECK_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP,
11581 adapter->hdd_stats.hdd_dns_stats.rx_host_drop)) {
11582 hdd_err("nla put fail");
11583 qdf_mem_free(dns_query);
11584 kfree_skb(skb);
11585 return -EINVAL;
11586 }
11587 qdf_mem_free(dns_query);
11588 return 0;
11589}
11590
11591/**
11592 * hdd_populate_tcp_stats_info() - send tcp stats info to network stack
11593 * @adapter: pointer to adapter context
11594 * @skb: pointer to skb
11595 * @pkt_type: tcp pkt type
11596 *
11597 * Return: An error code or 0 on success.
11598 */
11599static int hdd_populate_tcp_stats_info(struct hdd_adapter *adapter,
11600 struct sk_buff *skb,
11601 uint8_t pkt_type)
11602{
11603 switch (pkt_type) {
11604 case CONNECTIVITY_CHECK_SET_TCP_SYN:
11605 /* Fill info for tcp syn packets (tx packet) */
11606 if (nla_put_u16(skb, CHECK_STATS_PKT_TYPE,
11607 CONNECTIVITY_CHECK_SET_TCP_SYN) ||
11608 nla_put_u16(skb, CHECK_STATS_PKT_SRC_PORT,
11609 adapter->track_src_port) ||
11610 nla_put_u16(skb, CHECK_STATS_PKT_DEST_PORT,
11611 adapter->track_dest_port) ||
11612 nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_FROM_NETDEV,
11613 adapter->hdd_stats.hdd_tcp_stats.tx_tcp_syn_count) ||
11614 nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TO_LOWER_MAC,
11615 adapter->hdd_stats.hdd_tcp_stats.
11616 tx_tcp_syn_host_fw_sent) ||
11617 nla_put_u16(skb, CHECK_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC,
11618 adapter->hdd_stats.hdd_tcp_stats.
11619 tx_tcp_syn_host_fw_sent) ||
11620 nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TX_SUCCESS,
11621 adapter->hdd_stats.hdd_tcp_stats.tx_tcp_syn_ack_cnt)) {
11622 hdd_err("nla put fail");
11623 kfree_skb(skb);
11624 return -EINVAL;
11625 }
11626 break;
11627 case CONNECTIVITY_CHECK_SET_TCP_SYN_ACK:
11628 /* Fill info for tcp syn-ack packets (rx packet) */
11629 if (nla_put_u16(skb, CHECK_STATS_PKT_TYPE,
11630 CONNECTIVITY_CHECK_SET_TCP_SYN_ACK) ||
11631 nla_put_u16(skb, CHECK_STATS_PKT_SRC_PORT,
11632 adapter->track_src_port) ||
11633 nla_put_u16(skb, CHECK_STATS_PKT_DEST_PORT,
11634 adapter->track_dest_port) ||
11635 nla_put_u16(skb, CHECK_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC,
11636 adapter->hdd_stats.hdd_tcp_stats.rx_fw_cnt) ||
11637 nla_put_u16(skb, CHECK_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC,
11638 adapter->hdd_stats.hdd_tcp_stats.
11639 rx_tcp_syn_ack_count) ||
11640 nla_put_u16(skb, CHECK_STATS_PKT_RSP_COUNT_TO_NETDEV,
11641 adapter->hdd_stats.hdd_tcp_stats.rx_delivered) ||
11642 nla_put_u16(skb,
11643 CHECK_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP,
11644 adapter->hdd_stats.hdd_tcp_stats.rx_host_drop)) {
11645 hdd_err("nla put fail");
11646 kfree_skb(skb);
11647 return -EINVAL;
11648 }
11649 break;
11650 case CONNECTIVITY_CHECK_SET_TCP_ACK:
11651 /* Fill info for tcp ack packets (tx packet) */
11652 if (nla_put_u16(skb, CHECK_STATS_PKT_TYPE,
11653 CONNECTIVITY_CHECK_SET_TCP_ACK) ||
11654 nla_put_u16(skb, CHECK_STATS_PKT_SRC_PORT,
11655 adapter->track_src_port) ||
11656 nla_put_u16(skb, CHECK_STATS_PKT_DEST_PORT,
11657 adapter->track_dest_port) ||
11658 nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_FROM_NETDEV,
11659 adapter->hdd_stats.hdd_tcp_stats.tx_tcp_ack_count) ||
11660 nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TO_LOWER_MAC,
11661 adapter->hdd_stats.hdd_tcp_stats.
11662 tx_tcp_ack_host_fw_sent) ||
11663 nla_put_u16(skb, CHECK_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC,
11664 adapter->hdd_stats.hdd_tcp_stats.
11665 tx_tcp_ack_host_fw_sent) ||
11666 nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TX_SUCCESS,
11667 adapter->hdd_stats.hdd_tcp_stats.tx_tcp_ack_ack_cnt)) {
11668 hdd_err("nla put fail");
11669 kfree_skb(skb);
11670 return -EINVAL;
11671 }
11672 break;
11673 default:
11674 break;
11675 }
11676 return 0;
11677}
11678
11679/**
11680 * hdd_populate_icmpv4_stats_info() - send icmpv4 stats info to network stack
11681 * @adapter: pointer to adapter context
11682 * @skb: pointer to skb
11683 *
11684 *
11685 * Return: An error code or 0 on success.
11686 */
11687static int hdd_populate_icmpv4_stats_info(struct hdd_adapter *adapter,
11688 struct sk_buff *skb)
11689{
11690 if (nla_put_u16(skb, CHECK_STATS_PKT_TYPE,
11691 CONNECTIVITY_CHECK_SET_ICMPV4) ||
11692 nla_put_u32(skb, CHECK_STATS_PKT_DEST_IPV4,
11693 adapter->track_dest_ipv4) ||
11694 nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_FROM_NETDEV,
11695 adapter->hdd_stats.hdd_icmpv4_stats.tx_icmpv4_req_count) ||
11696 nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TO_LOWER_MAC,
11697 adapter->hdd_stats.hdd_icmpv4_stats.tx_host_fw_sent) ||
11698 nla_put_u16(skb, CHECK_STATS_PKT_REQ_RX_COUNT_BY_LOWER_MAC,
11699 adapter->hdd_stats.hdd_icmpv4_stats.tx_host_fw_sent) ||
11700 nla_put_u16(skb, CHECK_STATS_PKT_REQ_COUNT_TX_SUCCESS,
11701 adapter->hdd_stats.hdd_icmpv4_stats.tx_ack_cnt) ||
11702 nla_put_u16(skb, CHECK_STATS_PKT_RSP_RX_COUNT_BY_LOWER_MAC,
11703 adapter->hdd_stats.hdd_icmpv4_stats.rx_fw_cnt) ||
11704 nla_put_u16(skb, CHECK_STATS_PKT_RSP_RX_COUNT_BY_UPPER_MAC,
11705 adapter->hdd_stats.hdd_icmpv4_stats.rx_icmpv4_rsp_count) ||
11706 nla_put_u16(skb, CHECK_STATS_PKT_RSP_COUNT_TO_NETDEV,
11707 adapter->hdd_stats.hdd_icmpv4_stats.rx_delivered) ||
11708 nla_put_u16(skb, CHECK_STATS_PKT_RSP_COUNT_OUT_OF_ORDER_DROP,
11709 adapter->hdd_stats.hdd_icmpv4_stats.rx_host_drop)) {
11710 hdd_err("nla put fail");
11711 kfree_skb(skb);
11712 return -EINVAL;
11713 }
11714 return 0;
11715}
11716
11717/**
11718 * hdd_populate_connectivity_check_stats_info() - send connectivity stats info
11719 * to network stack
11720 * @adapter: pointer to adapter context
11721 * @skb: pointer to skb
11722 *
11723 *
11724 * Return: An error code or 0 on success.
11725 */
11726
11727static int hdd_populate_connectivity_check_stats_info(
11728 struct hdd_adapter *adapter, struct sk_buff *skb)
11729{
11730 struct nlattr *connect_stats, *connect_info;
11731 uint32_t count = 0;
11732
11733 connect_stats = nla_nest_start(skb, DATA_PKT_STATS);
Jeff Johnsond36fa332019-03-18 13:42:25 -070011734 if (!connect_stats) {
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011735 hdd_err("nla_nest_start failed");
11736 return -EINVAL;
11737 }
11738
11739 if (adapter->pkt_type_bitmap & CONNECTIVITY_CHECK_SET_DNS) {
11740 connect_info = nla_nest_start(skb, count);
Jeff Johnsond36fa332019-03-18 13:42:25 -070011741 if (!connect_info) {
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011742 hdd_err("nla_nest_start failed count %u", count);
11743 return -EINVAL;
11744 }
11745
11746 if (hdd_populate_dns_stats_info(adapter, skb))
11747 goto put_attr_fail;
11748 nla_nest_end(skb, connect_info);
11749 count++;
11750 }
11751
11752 if (adapter->pkt_type_bitmap & CONNECTIVITY_CHECK_SET_TCP_HANDSHAKE) {
11753 connect_info = nla_nest_start(skb, count);
Jeff Johnsond36fa332019-03-18 13:42:25 -070011754 if (!connect_info) {
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011755 hdd_err("nla_nest_start failed count %u", count);
11756 return -EINVAL;
11757 }
11758 if (hdd_populate_tcp_stats_info(adapter, skb,
11759 CONNECTIVITY_CHECK_SET_TCP_SYN))
11760 goto put_attr_fail;
11761 nla_nest_end(skb, connect_info);
11762 count++;
11763
11764 connect_info = nla_nest_start(skb, count);
Jeff Johnsond36fa332019-03-18 13:42:25 -070011765 if (!connect_info) {
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011766 hdd_err("nla_nest_start failed count %u", count);
11767 return -EINVAL;
11768 }
11769 if (hdd_populate_tcp_stats_info(adapter, skb,
11770 CONNECTIVITY_CHECK_SET_TCP_SYN_ACK))
11771 goto put_attr_fail;
11772 nla_nest_end(skb, connect_info);
11773 count++;
11774
11775 connect_info = nla_nest_start(skb, count);
Jeff Johnsond36fa332019-03-18 13:42:25 -070011776 if (!connect_info) {
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011777 hdd_err("nla_nest_start failed count %u", count);
11778 return -EINVAL;
11779 }
11780 if (hdd_populate_tcp_stats_info(adapter, skb,
11781 CONNECTIVITY_CHECK_SET_TCP_ACK))
11782 goto put_attr_fail;
11783 nla_nest_end(skb, connect_info);
11784 count++;
11785 }
11786
11787 if (adapter->pkt_type_bitmap & CONNECTIVITY_CHECK_SET_ICMPV4) {
11788 connect_info = nla_nest_start(skb, count);
Jeff Johnsond36fa332019-03-18 13:42:25 -070011789 if (!connect_info) {
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011790 hdd_err("nla_nest_start failed count %u", count);
11791 return -EINVAL;
11792 }
11793
11794 if (hdd_populate_icmpv4_stats_info(adapter, skb))
11795 goto put_attr_fail;
11796 nla_nest_end(skb, connect_info);
11797 count++;
11798 }
11799
11800 nla_nest_end(skb, connect_stats);
11801 return 0;
11802
11803put_attr_fail:
11804 hdd_err("QCA_WLAN_VENDOR_ATTR put fail. count %u", count);
11805 return -EINVAL;
11806}
11807
11808
11809/**
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011810 * __wlan_hdd_cfg80211_get_nud_stats() - get arp stats command to firmware
11811 * @wiphy: pointer to wireless wiphy structure.
11812 * @wdev: pointer to wireless_dev structure.
11813 * @data: pointer to apfind configuration data.
11814 * @data_len: the length in byte of apfind data.
11815 *
11816 * This is called when wlan driver needs to get arp stats to
11817 * firmware.
11818 *
11819 * Return: An error code or 0 on success.
11820 */
11821static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
11822 struct wireless_dev *wdev,
11823 const void *data, int data_len)
11824{
11825 int err = 0;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011826 struct net_device *dev = wdev->netdev;
11827 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
11828 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
11829 struct get_arp_stats_params arp_stats_params;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070011830 mac_handle_t mac_handle;
Poddar, Siddarthdb568162017-07-27 18:16:38 +053011831 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011832 uint32_t pkt_type_bitmap;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011833 struct sk_buff *skb;
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011834 struct osif_request *request = NULL;
11835 static const struct osif_request_params params = {
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011836 .priv_size = 0,
11837 .timeout_ms = WLAN_WAIT_TIME_NUD_STATS,
11838 };
11839 void *cookie = NULL;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011840
Dustin Brown491d54b2018-03-14 12:39:11 -070011841 hdd_enter();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011842
Anurag Chouhan9fb2bd52018-01-04 12:25:48 +053011843 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
11844 hdd_err("Command not allowed in FTM mode");
11845 return -EINVAL;
11846 }
11847
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011848 err = wlan_hdd_validate_context(hdd_ctx);
11849 if (0 != err)
11850 return err;
11851
Rajeev Kumar7f28e8a32017-08-23 15:41:30 -070011852 err = hdd_validate_adapter(adapter);
11853 if (err)
11854 return err;
11855
Poddar, Siddarthdf076672018-02-26 14:21:45 +053011856 if (adapter->device_mode != QDF_STA_MODE) {
Dustin Browna2868622018-03-20 11:38:14 -070011857 hdd_err("STATS supported in only STA mode!");
Poddar, Siddarthdf076672018-02-26 14:21:45 +053011858 return -EINVAL;
11859 }
11860
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011861 request = osif_request_alloc(&params);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011862 if (!request) {
11863 hdd_err("Request allocation failure");
11864 return -ENOMEM;
11865 }
11866
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011867 cookie = osif_request_cookie(request);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011868
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011869 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
Jeff Johnsoncf07c312019-02-04 13:53:29 -080011870 arp_stats_params.vdev_id = adapter->vdev_id;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011871
Poddar, Siddarth762c5472018-03-20 14:55:35 +053011872 pkt_type_bitmap = adapter->pkt_type_bitmap;
11873
11874 /* send NUD failure event only when ARP tracking is enabled. */
jitiphil377bcc12018-10-05 19:46:08 +053011875 if (cdp_cfg_get(soc, cfg_dp_enable_data_stall) &&
Poddar, Siddarth762c5472018-03-20 14:55:35 +053011876 (pkt_type_bitmap & CONNECTIVITY_CHECK_SET_ARP))
Poddar, Siddarth37033032017-10-11 15:47:40 +053011877 cdp_post_data_stall_event(soc,
11878 DATA_STALL_LOG_INDICATOR_FRAMEWORK,
Poddar, Siddarthdb568162017-07-27 18:16:38 +053011879 DATA_STALL_LOG_NUD_FAILURE,
11880 0xFF, 0XFF,
11881 DATA_STALL_LOG_RECOVERY_TRIGGER_PDR);
11882
Jeff Johnson34fc63a2018-06-14 10:10:02 -070011883 mac_handle = hdd_ctx->mac_handle;
11884 if (sme_set_nud_debug_stats_cb(mac_handle, hdd_get_nud_stats_cb,
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011885 cookie) != QDF_STATUS_SUCCESS) {
11886 hdd_err("Setting NUD debug stats callback failure");
11887 err = -EINVAL;
11888 goto exit;
11889 }
11890
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011891 if (QDF_STATUS_SUCCESS !=
Jeff Johnson34fc63a2018-06-14 10:10:02 -070011892 sme_get_nud_debug_stats(mac_handle, &arp_stats_params)) {
Dustin Browna2868622018-03-20 11:38:14 -070011893 hdd_err("STATS_SET_START CMD Failed!");
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011894 err = -EINVAL;
11895 goto exit;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011896 }
11897
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011898 err = osif_request_wait_for_response(request);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011899 if (err) {
11900 hdd_err("SME timedout while retrieving NUD stats");
11901 err = -ETIMEDOUT;
11902 goto exit;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011903 }
11904
11905 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
11906 WLAN_NUD_STATS_LEN);
11907 if (!skb) {
11908 hdd_err("%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
11909 __func__);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011910 err = -ENOMEM;
11911 goto exit;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011912 }
11913
11914 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
Sravan Kumar Kairamc1ae71c2017-02-24 12:27:27 +053011915 adapter->hdd_stats.hdd_arp_stats.tx_arp_req_count) ||
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011916 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
11917 adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent) ||
11918 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
Sravan Kumar Kairamc1ae71c2017-02-24 12:27:27 +053011919 adapter->hdd_stats.hdd_arp_stats.tx_host_fw_sent) ||
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011920 nla_put_u16(skb, COUNT_TX_SUCCESS,
11921 adapter->hdd_stats.hdd_arp_stats.tx_ack_cnt) ||
11922 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
11923 adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt) ||
11924 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
Sravan Kumar Kairamc1ae71c2017-02-24 12:27:27 +053011925 adapter->hdd_stats.hdd_arp_stats.rx_arp_rsp_count) ||
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011926 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
11927 adapter->hdd_stats.hdd_arp_stats.rx_delivered) ||
11928 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
11929 adapter->hdd_stats.hdd_arp_stats.
11930 rx_host_drop_reorder)) {
11931 hdd_err("nla put fail");
11932 kfree_skb(skb);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011933 err = -EINVAL;
11934 goto exit;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011935 }
11936 if (adapter->con_status)
11937 nla_put_flag(skb, AP_LINK_ACTIVE);
11938 if (adapter->dad)
11939 nla_put_flag(skb, AP_LINK_DAD);
11940
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011941 /* ARP tracking is done above. */
11942 pkt_type_bitmap &= ~CONNECTIVITY_CHECK_SET_ARP;
11943
11944 if (pkt_type_bitmap) {
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011945 if (hdd_populate_connectivity_check_stats_info(adapter, skb)) {
11946 err = -EINVAL;
11947 goto exit;
11948 }
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011949 }
11950
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011951 cfg80211_vendor_cmd_reply(skb);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011952exit:
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011953 osif_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011954 return err;
11955}
11956
11957/**
11958 * wlan_hdd_cfg80211_get_nud_stats() - get arp stats command to firmware
11959 * @wiphy: pointer to wireless wiphy structure.
11960 * @wdev: pointer to wireless_dev structure.
11961 * @data: pointer to apfind configuration data.
11962 * @data_len: the length in byte of apfind data.
11963 *
11964 * This is called when wlan driver needs to get arp stats to
11965 * firmware.
11966 *
11967 * Return: An error code or 0 on success.
11968 */
11969static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
11970 struct wireless_dev *wdev,
11971 const void *data, int data_len)
11972{
Dustin Browna09acf42018-11-08 12:32:26 +053011973 int errno;
11974 struct osif_vdev_sync *vdev_sync;
11975
11976 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
11977 if (errno)
11978 return errno;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011979
Dustin Browna09acf42018-11-08 12:32:26 +053011980 errno = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011981
Dustin Browna09acf42018-11-08 12:32:26 +053011982 osif_vdev_sync_op_stop(vdev_sync);
11983
11984 return errno;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011985}
11986
11987#undef QCA_ATTR_NUD_STATS_SET_INVALID
11988#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
11989#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
11990#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
11991#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
11992#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
11993#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
11994#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
11995#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
11996#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
11997#undef QCA_ATTR_NUD_STATS_GET_MAX
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053011998
Jeff Johnsond0b6c7e2018-07-04 14:53:06 -070011999void hdd_bt_activity_cb(hdd_handle_t hdd_handle, uint32_t bt_activity)
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053012000{
Jeff Johnsond0b6c7e2018-07-04 14:53:06 -070012001 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053012002 int status;
12003
12004 status = wlan_hdd_validate_context(hdd_ctx);
12005 if (0 != status)
12006 return;
12007
12008 if (bt_activity == WLAN_COEX_EVENT_BT_A2DP_PROFILE_ADD)
12009 hdd_ctx->bt_a2dp_active = 1;
12010 else if (bt_activity == WLAN_COEX_EVENT_BT_A2DP_PROFILE_REMOVE)
12011 hdd_ctx->bt_a2dp_active = 0;
12012 else if (bt_activity == WLAN_COEX_EVENT_BT_VOICE_PROFILE_ADD)
12013 hdd_ctx->bt_vo_active = 1;
12014 else if (bt_activity == WLAN_COEX_EVENT_BT_VOICE_PROFILE_REMOVE)
12015 hdd_ctx->bt_vo_active = 0;
12016 else
12017 return;
12018
Dustin Brown76cd2932018-09-11 16:03:05 -070012019 ucfg_scan_set_bt_activity(hdd_ctx->psoc, hdd_ctx->bt_a2dp_active);
Srinivas Girigowda6598eea2017-07-06 19:26:19 -070012020 hdd_debug("a2dp_active: %d vo_active: %d", hdd_ctx->bt_a2dp_active,
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053012021 hdd_ctx->bt_vo_active);
12022}
12023
lifengd217d192017-05-09 19:44:16 +080012024struct chain_rssi_priv {
12025 struct chain_rssi_result chain_rssi;
12026};
12027
12028/**
12029 * hdd_get_chain_rssi_cb() - Callback function to get chain rssi
12030 * @context: opaque context originally passed to SME. HDD always passes
12031 * a cookie for the request context
12032 * @data: struct for get chain rssi
12033 *
12034 * This function receives the response/data from the lower layer and
12035 * checks to see if the thread is still waiting then post the results to
12036 * upper layer, if the request has timed out then ignore.
12037 *
12038 * Return: None
12039 */
12040static void hdd_get_chain_rssi_cb(void *context,
12041 struct chain_rssi_result *data)
12042{
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012043 struct osif_request *request;
lifengd217d192017-05-09 19:44:16 +080012044 struct chain_rssi_priv *priv;
12045
Dustin Brown491d54b2018-03-14 12:39:11 -070012046 hdd_enter();
lifengd217d192017-05-09 19:44:16 +080012047
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012048 request = osif_request_get(context);
lifengd217d192017-05-09 19:44:16 +080012049 if (!request) {
12050 hdd_err("Obsolete request");
12051 return;
12052 }
12053
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012054 priv = osif_request_priv(request);
lifengd217d192017-05-09 19:44:16 +080012055 priv->chain_rssi = *data;
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012056 osif_request_complete(request);
12057 osif_request_put(request);
lifengd217d192017-05-09 19:44:16 +080012058}
12059
12060/**
12061 * hdd_post_get_chain_rssi_rsp - send rsp to user space
12062 * @hdd_ctx: pointer to hdd context
12063 * @result: chain rssi result
12064 *
12065 * Return: 0 for success, non-zero for failure
12066 */
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070012067static int hdd_post_get_chain_rssi_rsp(struct hdd_context *hdd_ctx,
lifengd217d192017-05-09 19:44:16 +080012068 struct chain_rssi_result *result)
12069{
12070 struct sk_buff *skb;
lifengd217d192017-05-09 19:44:16 +080012071
12072 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
lifengfe6c3e22018-04-03 12:10:04 +080012073 (sizeof(result->chain_rssi) + NLA_HDRLEN) +
stonez396a9732019-01-16 12:29:16 +080012074 (sizeof(result->chain_evm) + NLA_HDRLEN) +
lifengfe6c3e22018-04-03 12:10:04 +080012075 (sizeof(result->ant_id) + NLA_HDRLEN) +
12076 NLMSG_HDRLEN);
lifengd217d192017-05-09 19:44:16 +080012077
12078 if (!skb) {
12079 hdd_err("cfg80211_vendor_event_alloc failed");
12080 return -ENOMEM;
12081 }
12082
lifengfe6c3e22018-04-03 12:10:04 +080012083 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_CHAIN_RSSI,
stonez396a9732019-01-16 12:29:16 +080012084 sizeof(result->chain_rssi),
12085 result->chain_rssi)) {
12086 hdd_err("put fail");
12087 goto nla_put_failure;
12088 }
12089
12090 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_CHAIN_EVM,
12091 sizeof(result->chain_evm),
12092 result->chain_evm)) {
lifengd217d192017-05-09 19:44:16 +080012093 hdd_err("put fail");
12094 goto nla_put_failure;
12095 }
12096
lifengfe6c3e22018-04-03 12:10:04 +080012097 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_ANTENNA_INFO,
stonez396a9732019-01-16 12:29:16 +080012098 sizeof(result->ant_id),
12099 result->ant_id)) {
lifengfe6c3e22018-04-03 12:10:04 +080012100 hdd_err("put fail");
12101 goto nla_put_failure;
12102 }
12103
lifengd217d192017-05-09 19:44:16 +080012104 cfg80211_vendor_cmd_reply(skb);
12105 return 0;
12106
12107nla_put_failure:
12108 kfree_skb(skb);
12109 return -EINVAL;
12110}
12111
12112/**
12113 * __wlan_hdd_cfg80211_get_chain_rssi() - get chain rssi
12114 * @wiphy: wiphy pointer
12115 * @wdev: pointer to struct wireless_dev
12116 * @data: pointer to incoming NL vendor data
12117 * @data_len: length of @data
12118 *
12119 * Return: 0 on success; error number otherwise.
12120 */
12121static int __wlan_hdd_cfg80211_get_chain_rssi(struct wiphy *wiphy,
12122 struct wireless_dev *wdev,
12123 const void *data,
12124 int data_len)
12125{
Jeff Johnsone5006672017-08-29 14:39:02 -070012126 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(wdev->netdev);
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070012127 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Jeff Johnson34fc63a2018-06-14 10:10:02 -070012128 mac_handle_t mac_handle;
lifengd217d192017-05-09 19:44:16 +080012129 struct get_chain_rssi_req_params req_msg;
12130 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
12131 QDF_STATUS status;
12132 int retval;
12133 void *cookie;
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012134 struct osif_request *request;
lifengd217d192017-05-09 19:44:16 +080012135 struct chain_rssi_priv *priv;
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012136 static const struct osif_request_params params = {
lifengd217d192017-05-09 19:44:16 +080012137 .priv_size = sizeof(*priv),
12138 .timeout_ms = WLAN_WAIT_TIME_STATS,
12139 };
12140
Dustin Brown491d54b2018-03-14 12:39:11 -070012141 hdd_enter();
lifengd217d192017-05-09 19:44:16 +080012142
12143 retval = wlan_hdd_validate_context(hdd_ctx);
12144 if (0 != retval)
12145 return retval;
12146
Dustin Brown4ea21db2018-01-05 14:13:17 -080012147 if (wlan_cfg80211_nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
12148 data, data_len, NULL)) {
lifengd217d192017-05-09 19:44:16 +080012149 hdd_err("Invalid ATTR");
12150 return -EINVAL;
12151 }
12152
12153 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
12154 hdd_err("attr mac addr failed");
12155 return -EINVAL;
12156 }
12157 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) !=
12158 QDF_MAC_ADDR_SIZE) {
12159 hdd_err("incorrect mac size");
12160 return -EINVAL;
12161 }
12162 memcpy(&req_msg.peer_macaddr,
12163 nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
12164 QDF_MAC_ADDR_SIZE);
Jeff Johnsoncf07c312019-02-04 13:53:29 -080012165 req_msg.session_id = adapter->vdev_id;
lifengd217d192017-05-09 19:44:16 +080012166
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012167 request = osif_request_alloc(&params);
lifengd217d192017-05-09 19:44:16 +080012168 if (!request) {
12169 hdd_err("Request allocation failure");
12170 return -ENOMEM;
12171 }
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012172 cookie = osif_request_cookie(request);
lifengd217d192017-05-09 19:44:16 +080012173
Jeff Johnson34fc63a2018-06-14 10:10:02 -070012174 mac_handle = hdd_ctx->mac_handle;
12175 status = sme_get_chain_rssi(mac_handle,
12176 &req_msg,
12177 hdd_get_chain_rssi_cb,
12178 cookie);
lifengd217d192017-05-09 19:44:16 +080012179 if (QDF_STATUS_SUCCESS != status) {
12180 hdd_err("Unable to get chain rssi");
12181 retval = qdf_status_to_os_return(status);
12182 } else {
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012183 retval = osif_request_wait_for_response(request);
lifengd217d192017-05-09 19:44:16 +080012184 if (retval) {
12185 hdd_err("Target response timed out");
12186 } else {
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012187 priv = osif_request_priv(request);
lifengd217d192017-05-09 19:44:16 +080012188 retval = hdd_post_get_chain_rssi_rsp(hdd_ctx,
12189 &priv->chain_rssi);
12190 if (retval)
12191 hdd_err("Failed to post chain rssi");
12192 }
12193 }
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012194 osif_request_put(request);
lifengd217d192017-05-09 19:44:16 +080012195
Dustin Browne74003f2018-03-14 12:51:58 -070012196 hdd_exit();
lifengd217d192017-05-09 19:44:16 +080012197 return retval;
12198}
12199
12200/**
12201 * wlan_hdd_cfg80211_get_chain_rssi() - get chain rssi
12202 * @wiphy: wiphy pointer
12203 * @wdev: pointer to struct wireless_dev
12204 * @data: pointer to incoming NL vendor data
12205 * @data_len: length of @data
12206 *
12207 * Return: 0 on success; error number otherwise.
12208 */
12209static int wlan_hdd_cfg80211_get_chain_rssi(struct wiphy *wiphy,
12210 struct wireless_dev *wdev,
12211 const void *data,
12212 int data_len)
12213{
Dustin Browna09acf42018-11-08 12:32:26 +053012214 int errno;
12215 struct osif_vdev_sync *vdev_sync;
12216
12217 errno = osif_vdev_sync_op_start(wdev->netdev, &vdev_sync);
12218 if (errno)
12219 return errno;
lifengd217d192017-05-09 19:44:16 +080012220
Dustin Browna09acf42018-11-08 12:32:26 +053012221 errno = __wlan_hdd_cfg80211_get_chain_rssi(wiphy, wdev, data, data_len);
lifengd217d192017-05-09 19:44:16 +080012222
Dustin Browna09acf42018-11-08 12:32:26 +053012223 osif_vdev_sync_op_stop(vdev_sync);
12224
12225 return errno;
lifengd217d192017-05-09 19:44:16 +080012226}
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053012227
Ganesh Kondabattinib1960e72017-09-01 09:09:50 +053012228/**
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053012229 * wlan_hdd_fill_intf_info() - Fill skb buffer with interface info
12230 * @skb: Pointer to skb
12231 * @info: mac mode info
12232 * @index: attribute type index for nla_nest_start()
12233 *
12234 * Return : 0 on success and errno on failure
12235 */
12236static int wlan_hdd_fill_intf_info(struct sk_buff *skb,
12237 struct connection_info *info, int index)
12238{
12239 struct nlattr *attr;
12240 uint32_t freq;
12241 struct hdd_context *hdd_ctx;
12242 struct hdd_adapter *hdd_adapter;
12243
12244 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12245 if (!hdd_ctx)
12246 goto error;
12247
12248 hdd_adapter = hdd_get_adapter_by_vdev(hdd_ctx, info->vdev_id);
12249 if (!hdd_adapter)
12250 goto error;
12251
12252 attr = nla_nest_start(skb, index);
12253 if (!attr)
12254 goto error;
12255
12256 freq = sme_chn_to_freq(info->channel);
12257
12258 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_IFINDEX,
12259 hdd_adapter->dev->ifindex) ||
12260 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO_FREQ, freq))
12261 goto error;
12262
12263 nla_nest_end(skb, attr);
12264
12265 return 0;
12266error:
12267 hdd_err("Fill buffer with interface info failed");
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053012268 return -EINVAL;
12269}
12270
12271/**
12272 * wlan_hdd_fill_mac_info() - Fill skb buffer with mac info
12273 * @skb: Pointer to skb
12274 * @info: mac mode info
12275 * @mac_id: MAC id
12276 * @conn_count: number of current connections
12277 *
12278 * Return : 0 on success and errno on failure
12279 */
12280static int wlan_hdd_fill_mac_info(struct sk_buff *skb,
12281 struct connection_info *info, uint32_t mac_id,
12282 uint32_t conn_count)
12283{
12284 struct nlattr *attr, *intf_attr;
12285 uint32_t band = 0, i = 0, j = 0;
12286 bool present = false;
12287
12288 while (i < conn_count) {
12289 if (info[i].mac_id == mac_id) {
12290 present = true;
12291 if (info[i].channel <= SIR_11B_CHANNEL_END)
12292 band |= 1 << NL80211_BAND_2GHZ;
12293 else if (info[i].channel <= SIR_11A_CHANNEL_END)
12294 band |= 1 << NL80211_BAND_5GHZ;
12295 }
12296 i++;
12297 }
12298
12299 if (!present)
12300 return 0;
12301
12302 i = 0;
12303 attr = nla_nest_start(skb, mac_id);
12304 if (!attr)
12305 goto error;
12306
12307 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_MAC_INFO_MAC_ID, mac_id) ||
12308 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_MAC_INFO_BAND, band))
12309 goto error;
12310
12311 intf_attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_MAC_IFACE_INFO);
12312 if (!intf_attr)
12313 goto error;
12314
12315 while (i < conn_count) {
12316 if (info[i].mac_id == mac_id) {
12317 if (wlan_hdd_fill_intf_info(skb, &info[i], j))
12318 return -EINVAL;
12319 j++;
12320 }
12321 i++;
12322 }
12323
12324 nla_nest_end(skb, intf_attr);
12325
12326 nla_nest_end(skb, attr);
12327
12328 return 0;
12329error:
12330 hdd_err("Fill buffer with mac info failed");
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053012331 return -EINVAL;
12332}
12333
12334
12335int wlan_hdd_send_mode_change_event(void)
12336{
12337 int err;
12338 struct hdd_context *hdd_ctx;
12339 struct sk_buff *skb;
12340 struct nlattr *attr;
12341 struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS];
12342 uint32_t conn_count, mac_id;
12343
Dustin Brown491d54b2018-03-14 12:39:11 -070012344 hdd_enter();
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053012345 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12346 if (!hdd_ctx) {
12347 hdd_err("HDD context is NULL");
12348 return -EINVAL;
12349 }
12350
12351 err = wlan_hdd_validate_context(hdd_ctx);
12352 if (0 != err)
12353 return err;
12354
Dustin Brown76cd2932018-09-11 16:03:05 -070012355 conn_count = policy_mgr_get_connection_info(hdd_ctx->psoc, info);
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053012356 if (!conn_count)
12357 return -EINVAL;
12358
12359 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL,
12360 (sizeof(uint32_t) * 4) *
12361 MAX_NUMBER_OF_CONC_CONNECTIONS + NLMSG_HDRLEN,
12362 QCA_NL80211_VENDOR_SUBCMD_WLAN_MAC_INFO_INDEX,
12363 GFP_KERNEL);
12364 if (!skb) {
12365 hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
12366 return -ENOMEM;
12367 }
12368
12369 attr = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_MAC_INFO);
12370 if (!attr) {
12371 hdd_err("nla_nest_start failed");
12372 kfree_skb(skb);
12373 return -EINVAL;
12374 }
12375
12376 for (mac_id = 0; mac_id < MAX_MAC; mac_id++) {
Lin Baifac77972018-07-05 19:51:49 +080012377 if (wlan_hdd_fill_mac_info(skb, info, mac_id, conn_count)) {
12378 kfree_skb(skb);
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053012379 return -EINVAL;
Lin Baifac77972018-07-05 19:51:49 +080012380 }
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053012381 }
12382
12383 nla_nest_end(skb, attr);
12384
12385 cfg80211_vendor_event(skb, GFP_KERNEL);
Dustin Browne74003f2018-03-14 12:51:58 -070012386 hdd_exit();
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053012387
12388 return err;
12389}
12390
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012391const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
12392 {
12393 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12394 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY,
12395 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Srinivas Dasari947abd72016-09-02 12:11:33 +053012396 WIPHY_VENDOR_CMD_NEED_NETDEV,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012397 .doit = is_driver_dfs_capable
12398 },
12399
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012400#ifdef WLAN_FEATURE_STATS_EXT
12401 {
12402 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12403 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_STATS_EXT,
12404 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12405 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
12406 .doit = wlan_hdd_cfg80211_stats_ext_request
12407 },
12408#endif
12409#ifdef FEATURE_WLAN_EXTSCAN
12410 {
12411 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12412 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
12413 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12414 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
12415 .doit = wlan_hdd_cfg80211_extscan_start
12416 },
12417 {
12418 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12419 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
12420 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12421 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
12422 .doit = wlan_hdd_cfg80211_extscan_stop
12423 },
12424 {
12425 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12426 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
Manjeet Singh3abd7302017-01-11 16:07:42 +053012427 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12428 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012429 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
12430 },
12431 {
12432 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12433 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
12434 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12435 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
12436 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
12437 },
12438 {
12439 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12440 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
12441 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12442 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
12443 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
12444 },
12445 {
12446 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12447 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
12448 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12449 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
12450 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
12451 },
12452 {
12453 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12454 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
12455 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12456 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
12457 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
12458 },
12459 {
12460 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12461 .info.subcmd =
12462 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
12463 .flags =
12464 WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV |
12465 WIPHY_VENDOR_CMD_NEED_RUNNING,
12466 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
12467 },
12468 {
12469 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12470 .info.subcmd =
12471 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
12472 .flags =
12473 WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV |
12474 WIPHY_VENDOR_CMD_NEED_RUNNING,
12475 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
12476 },
12477 {
12478 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12479 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_SET_LIST,
12480 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12481 WIPHY_VENDOR_CMD_NEED_NETDEV |
12482 WIPHY_VENDOR_CMD_NEED_RUNNING,
12483 .doit = wlan_hdd_cfg80211_set_epno_list
12484 },
12485#endif /* FEATURE_WLAN_EXTSCAN */
12486
12487#ifdef WLAN_FEATURE_LINK_LAYER_STATS
12488 {
12489 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12490 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
12491 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12492 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
12493 .doit = wlan_hdd_cfg80211_ll_stats_clear
12494 },
12495
12496 {
12497 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12498 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
12499 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12500 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
12501 .doit = wlan_hdd_cfg80211_ll_stats_set
12502 },
12503
12504 {
12505 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12506 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
12507 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12508 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
12509 .doit = wlan_hdd_cfg80211_ll_stats_get
12510 },
12511#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
12512#ifdef FEATURE_WLAN_TDLS
12513 {
12514 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12515 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
12516 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12517 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
12518 .doit = wlan_hdd_cfg80211_exttdls_enable
12519 },
12520 {
12521 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12522 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
12523 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12524 WIPHY_VENDOR_CMD_NEED_NETDEV | WIPHY_VENDOR_CMD_NEED_RUNNING,
12525 .doit = wlan_hdd_cfg80211_exttdls_disable
12526 },
12527 {
12528 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12529 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
12530 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
12531 .doit = wlan_hdd_cfg80211_exttdls_get_status
12532 },
12533#endif
12534 {
12535 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12536 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
12537 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
12538 .doit = wlan_hdd_cfg80211_get_supported_features
12539 },
12540 {
12541 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12542 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SCANNING_MAC_OUI,
SaidiReddy Yenuga76047d02017-04-26 19:17:42 +053012543 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12544 WIPHY_VENDOR_CMD_NEED_NETDEV |
12545 WIPHY_VENDOR_CMD_NEED_RUNNING,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012546 .doit = wlan_hdd_cfg80211_set_scanning_mac_oui
12547 },
Qiwei Caie689a262018-07-26 15:50:22 +080012548
12549 FEATURE_CONCURRENCY_MATRIX_VENDOR_COMMANDS
12550
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012551 {
12552 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12553 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
12554 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
SaidiReddy Yenuga76047d02017-04-26 19:17:42 +053012555 WIPHY_VENDOR_CMD_NEED_NETDEV |
12556 WIPHY_VENDOR_CMD_NEED_RUNNING,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012557 .doit = wlan_hdd_cfg80211_disable_dfs_chan_scan
12558 },
Manikandan Mohan80dea792016-04-28 16:36:48 -070012559 {
12560 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12561 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WISA,
12562 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
SaidiReddy Yenuga76047d02017-04-26 19:17:42 +053012563 WIPHY_VENDOR_CMD_NEED_NETDEV |
12564 WIPHY_VENDOR_CMD_NEED_RUNNING,
Manikandan Mohan80dea792016-04-28 16:36:48 -070012565 .doit = wlan_hdd_cfg80211_handle_wisa_cmd
12566 },
Qiwei Caie689a262018-07-26 15:50:22 +080012567
12568 FEATURE_STATION_INFO_VENDOR_COMMANDS
12569
Anurag Chouhan96919482016-07-13 16:36:57 +053012570 {
12571 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012572 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DO_ACS,
12573 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12574 WIPHY_VENDOR_CMD_NEED_NETDEV |
12575 WIPHY_VENDOR_CMD_NEED_RUNNING,
12576 .doit = wlan_hdd_cfg80211_do_acs
12577 },
12578
12579 {
12580 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12581 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES,
12582 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12583 WIPHY_VENDOR_CMD_NEED_NETDEV,
12584 .doit = wlan_hdd_cfg80211_get_features
12585 },
12586#ifdef WLAN_FEATURE_ROAM_OFFLOAD
12587 {
12588 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12589 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY,
12590 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12591 WIPHY_VENDOR_CMD_NEED_NETDEV |
12592 WIPHY_VENDOR_CMD_NEED_RUNNING,
12593 .doit = wlan_hdd_cfg80211_keymgmt_set_key
12594 },
12595#endif
12596#ifdef FEATURE_WLAN_EXTSCAN
12597 {
12598 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12599 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_SET_PASSPOINT_LIST,
12600 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12601 WIPHY_VENDOR_CMD_NEED_NETDEV |
12602 WIPHY_VENDOR_CMD_NEED_RUNNING,
12603 .doit = wlan_hdd_cfg80211_set_passpoint_list
12604 },
12605 {
12606 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12607 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_PNO_RESET_PASSPOINT_LIST,
12608 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12609 WIPHY_VENDOR_CMD_NEED_NETDEV |
12610 WIPHY_VENDOR_CMD_NEED_RUNNING,
12611 .doit = wlan_hdd_cfg80211_reset_passpoint_list
12612 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012613#endif /* FEATURE_WLAN_EXTSCAN */
12614 {
12615 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12616 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
12617 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12618 WIPHY_VENDOR_CMD_NEED_NETDEV,
12619 .doit = wlan_hdd_cfg80211_get_wifi_info
12620 },
12621 {
12622 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12623 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
12624 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12625 WIPHY_VENDOR_CMD_NEED_NETDEV |
12626 WIPHY_VENDOR_CMD_NEED_RUNNING,
12627 .doit = wlan_hdd_cfg80211_wifi_configuration_set
12628 },
12629 {
12630 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Kiran Kumar Lokere08195ef2018-01-17 19:25:15 -080012631 .info.subcmd =
12632 QCA_NL80211_VENDOR_SUBCMD_WIFI_TEST_CONFIGURATION,
12633 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12634 WIPHY_VENDOR_CMD_NEED_NETDEV |
12635 WIPHY_VENDOR_CMD_NEED_RUNNING,
12636 .doit = wlan_hdd_cfg80211_set_wifi_test_config
12637 },
12638
12639 {
12640 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012641 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAM,
12642 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
SaidiReddy Yenuga76047d02017-04-26 19:17:42 +053012643 WIPHY_VENDOR_CMD_NEED_NETDEV |
12644 WIPHY_VENDOR_CMD_NEED_RUNNING,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012645 .doit = wlan_hdd_cfg80211_set_ext_roam_params
12646 },
12647 {
12648 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12649 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
12650 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
SaidiReddy Yenuga76047d02017-04-26 19:17:42 +053012651 WIPHY_VENDOR_CMD_NEED_NETDEV |
12652 WIPHY_VENDOR_CMD_NEED_RUNNING,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012653 .doit = wlan_hdd_cfg80211_wifi_logger_start
12654 },
12655 {
12656 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12657 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
12658 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
SaidiReddy Yenuga76047d02017-04-26 19:17:42 +053012659 WIPHY_VENDOR_CMD_NEED_NETDEV |
12660 WIPHY_VENDOR_CMD_NEED_RUNNING,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012661 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
12662 },
12663 {
12664 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12665 .info.subcmd =
12666 QCA_NL80211_VENDOR_SUBCMD_GET_PREFERRED_FREQ_LIST,
12667 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12668 WIPHY_VENDOR_CMD_NEED_NETDEV |
12669 WIPHY_VENDOR_CMD_NEED_RUNNING,
12670 .doit = wlan_hdd_cfg80211_get_preferred_freq_list
12671 },
12672 {
12673 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12674 .info.subcmd =
12675 QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL,
12676 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12677 WIPHY_VENDOR_CMD_NEED_NETDEV |
12678 WIPHY_VENDOR_CMD_NEED_RUNNING,
12679 .doit = wlan_hdd_cfg80211_set_probable_oper_channel
12680 },
Manikandan Mohan5356c2b2016-04-03 15:51:35 -070012681#ifdef WLAN_FEATURE_TSF
12682 {
12683 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12684 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TSF,
12685 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12686 WIPHY_VENDOR_CMD_NEED_NETDEV |
12687 WIPHY_VENDOR_CMD_NEED_RUNNING,
12688 .doit = wlan_hdd_cfg80211_handle_tsf_cmd
12689 },
12690#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012691#ifdef FEATURE_WLAN_TDLS
12692 {
12693 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12694 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_CAPABILITIES,
12695 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12696 WIPHY_VENDOR_CMD_NEED_NETDEV |
12697 WIPHY_VENDOR_CMD_NEED_RUNNING,
12698 .doit = wlan_hdd_cfg80211_get_tdls_capabilities
12699 },
12700#endif
12701#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
12702 {
12703 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12704 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
12705 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12706 WIPHY_VENDOR_CMD_NEED_NETDEV |
12707 WIPHY_VENDOR_CMD_NEED_RUNNING,
12708 .doit = wlan_hdd_cfg80211_offloaded_packets
12709 },
12710#endif
Qiwei Caie689a262018-07-26 15:50:22 +080012711 FEATURE_RSSI_MONITOR_VENDOR_COMMANDS
Paul Zhangda2970b2019-06-23 18:16:38 +080012712 FEATURE_OEM_DATA_VENDOR_COMMANDS
Paul Zhang37185672019-05-14 11:20:14 +080012713 FEATURE_INTEROP_ISSUES_AP_VENDOR_COMMANDS
Qiwei Caie689a262018-07-26 15:50:22 +080012714
Qiwei Cai1083f5b2018-07-02 19:10:11 +080012715#ifdef WLAN_NS_OFFLOAD
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012716 {
12717 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +053012718 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ND_OFFLOAD,
12719 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12720 WIPHY_VENDOR_CMD_NEED_NETDEV |
12721 WIPHY_VENDOR_CMD_NEED_RUNNING,
12722 .doit = wlan_hdd_cfg80211_set_ns_offload
12723 },
Qiwei Cai1083f5b2018-07-02 19:10:11 +080012724#endif /* WLAN_NS_OFFLOAD */
Sravan Kumar Kairamfece87f2016-07-26 14:58:28 +053012725 {
12726 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012727 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_LOGGER_FEATURE_SET,
12728 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
Sourav Mohapatra412ceb92018-03-07 18:41:16 +053012729 WIPHY_VENDOR_CMD_NEED_NETDEV,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012730 .doit = wlan_hdd_cfg80211_get_logger_supp_feature
12731 },
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012732 {
12733 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12734 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TRIGGER_SCAN,
12735 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12736 WIPHY_VENDOR_CMD_NEED_NETDEV |
12737 WIPHY_VENDOR_CMD_NEED_RUNNING,
12738 .doit = wlan_hdd_cfg80211_vendor_scan
12739 },
12740
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +053012741 /* Vendor abort scan */
12742 {
12743 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12744 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ABORT_SCAN,
12745 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12746 WIPHY_VENDOR_CMD_NEED_NETDEV |
12747 WIPHY_VENDOR_CMD_NEED_RUNNING,
12748 .doit = wlan_hdd_vendor_abort_scan
12749 },
12750
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012751 /* OCB commands */
12752 {
12753 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12754 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_SET_CONFIG,
12755 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12756 WIPHY_VENDOR_CMD_NEED_NETDEV |
12757 WIPHY_VENDOR_CMD_NEED_RUNNING,
12758 .doit = wlan_hdd_cfg80211_ocb_set_config
12759 },
12760 {
12761 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12762 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_SET_UTC_TIME,
12763 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12764 WIPHY_VENDOR_CMD_NEED_NETDEV |
12765 WIPHY_VENDOR_CMD_NEED_RUNNING,
12766 .doit = wlan_hdd_cfg80211_ocb_set_utc_time
12767 },
12768 {
12769 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12770 .info.subcmd =
12771 QCA_NL80211_VENDOR_SUBCMD_OCB_START_TIMING_ADVERT,
12772 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12773 WIPHY_VENDOR_CMD_NEED_NETDEV |
12774 WIPHY_VENDOR_CMD_NEED_RUNNING,
12775 .doit = wlan_hdd_cfg80211_ocb_start_timing_advert
12776 },
12777 {
12778 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12779 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_STOP_TIMING_ADVERT,
12780 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12781 WIPHY_VENDOR_CMD_NEED_NETDEV |
12782 WIPHY_VENDOR_CMD_NEED_RUNNING,
12783 .doit = wlan_hdd_cfg80211_ocb_stop_timing_advert
12784 },
12785 {
12786 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12787 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OCB_GET_TSF_TIMER,
12788 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12789 WIPHY_VENDOR_CMD_NEED_NETDEV |
12790 WIPHY_VENDOR_CMD_NEED_RUNNING,
12791 .doit = wlan_hdd_cfg80211_ocb_get_tsf_timer
12792 },
12793 {
12794 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12795 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_GET_STATS,
12796 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12797 WIPHY_VENDOR_CMD_NEED_NETDEV |
12798 WIPHY_VENDOR_CMD_NEED_RUNNING,
12799 .doit = wlan_hdd_cfg80211_dcc_get_stats
12800 },
12801 {
12802 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12803 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_CLEAR_STATS,
12804 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12805 WIPHY_VENDOR_CMD_NEED_NETDEV |
12806 WIPHY_VENDOR_CMD_NEED_RUNNING,
12807 .doit = wlan_hdd_cfg80211_dcc_clear_stats
12808 },
12809 {
12810 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12811 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_UPDATE_NDL,
12812 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12813 WIPHY_VENDOR_CMD_NEED_NETDEV |
12814 WIPHY_VENDOR_CMD_NEED_RUNNING,
12815 .doit = wlan_hdd_cfg80211_dcc_update_ndl
12816 },
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +053012817 {
12818 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12819 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
12820 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12821 WIPHY_VENDOR_CMD_NEED_NETDEV |
12822 WIPHY_VENDOR_CMD_NEED_RUNNING,
12823 .doit = wlan_hdd_cfg80211_get_link_properties
12824 },
Qiwei Caie689a262018-07-26 15:50:22 +080012825
12826 FEATURE_OTA_TEST_VENDOR_COMMANDS
12827
Ravi Joshideb5a8d2015-11-09 19:11:43 -080012828#ifdef FEATURE_LFR_SUBNET_DETECTION
12829 {
12830 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12831 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GW_PARAM_CONFIG,
12832 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12833 WIPHY_VENDOR_CMD_NEED_NETDEV |
12834 WIPHY_VENDOR_CMD_NEED_RUNNING,
12835 .doit = wlan_hdd_cfg80211_set_gateway_params
12836 },
12837#endif /* FEATURE_LFR_SUBNET_DETECTION */
Qiwei Caie689a262018-07-26 15:50:22 +080012838
12839 FEATURE_TX_POWER_VENDOR_COMMANDS
12840
Nachiket Kukaded0dd62e2018-05-21 18:39:22 +053012841#ifdef FEATURE_WLAN_APF
Arun Khandavalli2476ef52016-04-26 20:19:43 +053012842 {
12843 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12844 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_PACKET_FILTER,
12845 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12846 WIPHY_VENDOR_CMD_NEED_NETDEV |
12847 WIPHY_VENDOR_CMD_NEED_RUNNING,
Nachiket Kukadee547a482018-05-22 16:43:30 +053012848 .doit = wlan_hdd_cfg80211_apf_offload
Arun Khandavalli2476ef52016-04-26 20:19:43 +053012849 },
Nachiket Kukaded0dd62e2018-05-21 18:39:22 +053012850#endif /* FEATURE_WLAN_APF */
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +053012851 {
12852 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Agrawal Ashish65634612016-08-18 13:24:32 +053012853 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY,
12854 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12855 WIPHY_VENDOR_CMD_NEED_NETDEV |
12856 WIPHY_VENDOR_CMD_NEED_RUNNING,
12857 .doit = wlan_hdd_cfg80211_acs_dfs_mode
12858 },
12859 {
12860 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Agrawal Ashish21ba2572016-09-03 16:40:10 +053012861 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_STA_CONNECT_ROAM_POLICY,
12862 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12863 WIPHY_VENDOR_CMD_NEED_NETDEV |
12864 WIPHY_VENDOR_CMD_NEED_RUNNING,
12865 .doit = wlan_hdd_cfg80211_sta_roam_policy
12866 },
Agrawal Ashish467dde42016-09-08 18:44:22 +053012867#ifdef FEATURE_WLAN_CH_AVOID
12868 {
12869 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12870 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY,
12871 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12872 WIPHY_VENDOR_CMD_NEED_NETDEV |
12873 WIPHY_VENDOR_CMD_NEED_RUNNING,
12874 .doit = wlan_hdd_cfg80211_avoid_freq
12875 },
12876#endif
Agrawal Ashish21ba2572016-09-03 16:40:10 +053012877 {
12878 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Agrawal Ashishc9ddbab2016-05-25 12:04:47 +053012879 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_SAP_CONFIG,
12880 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12881 WIPHY_VENDOR_CMD_NEED_NETDEV |
12882 WIPHY_VENDOR_CMD_NEED_RUNNING,
12883 .doit = wlan_hdd_cfg80211_sap_configuration_set
12884 },
Qiwei Caie689a262018-07-26 15:50:22 +080012885
12886 FEATURE_P2P_LISTEN_OFFLOAD_VENDOR_COMMANDS
12887
12888 FEATURE_SAP_COND_CHAN_SWITCH_VENDOR_COMMANDS
Padma, Santhosh Kumar5e33beb2016-08-08 19:07:06 +053012889 {
12890 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12891 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS,
12892 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12893 WIPHY_VENDOR_CMD_NEED_NETDEV |
12894 WIPHY_VENDOR_CMD_NEED_RUNNING,
12895 .doit = wlan_hdd_cfg80211_get_wakelock_stats
12896 },
Srinivas Dasari510e7fe2016-04-28 11:51:30 +053012897 {
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +053012898 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12899 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_BUS_SIZE,
12900 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12901 WIPHY_VENDOR_CMD_NEED_NETDEV |
12902 WIPHY_VENDOR_CMD_NEED_RUNNING,
12903 .doit = wlan_hdd_cfg80211_get_bus_size
12904 },
12905 {
Kapil Gupta8878ad92017-02-13 11:56:04 +053012906 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12907 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTERNAL_ACS,
12908 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12909 WIPHY_VENDOR_CMD_NEED_NETDEV |
12910 WIPHY_VENDOR_CMD_NEED_RUNNING,
12911 .doit = wlan_hdd_cfg80211_update_vendor_channel
12912 },
12913 {
bingsd09dea32017-03-17 10:08:26 +080012914 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari510e7fe2016-04-28 11:51:30 +053012915 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
12916 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12917 WIPHY_VENDOR_CMD_NEED_NETDEV |
12918 WIPHY_VENDOR_CMD_NEED_RUNNING,
12919 .doit = wlan_hdd_cfg80211_setband
Mukul Sharma69c44cd2016-09-12 18:33:57 +053012920 },
12921 {
12922 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12923 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
12924 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12925 WIPHY_VENDOR_CMD_NEED_NETDEV |
12926 WIPHY_VENDOR_CMD_NEED_RUNNING,
12927 .doit = wlan_hdd_cfg80211_set_fast_roaming
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +053012928 },
12929#ifdef WLAN_FEATURE_DISA
12930 {
12931 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12932 .info.subcmd =
12933 QCA_NL80211_VENDOR_SUBCMD_ENCRYPTION_TEST,
12934 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12935 WIPHY_VENDOR_CMD_NEED_NETDEV |
12936 WIPHY_VENDOR_CMD_NEED_RUNNING,
12937 .doit = wlan_hdd_cfg80211_encrypt_decrypt_msg
12938 },
12939#endif
Kabilan Kannand053aaf2016-10-26 02:06:14 -070012940#ifdef FEATURE_WLAN_TDLS
12941 {
12942 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12943 .info.subcmd =
12944 QCA_NL80211_VENDOR_SUBCMD_CONFIGURE_TDLS,
12945 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12946 WIPHY_VENDOR_CMD_NEED_NETDEV |
12947 WIPHY_VENDOR_CMD_NEED_RUNNING,
12948 .doit = wlan_hdd_cfg80211_configure_tdls_mode
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080012949 },
Kabilan Kannand053aaf2016-10-26 02:06:14 -070012950#endif
Qiwei Caie689a262018-07-26 15:50:22 +080012951 FEATURE_SAR_LIMITS_VENDOR_COMMANDS
Abhinav Kumardbbfd2c2019-05-07 12:22:06 +053012952 BCN_RECV_FEATURE_VENDOR_COMMANDS
Qiwei Caie689a262018-07-26 15:50:22 +080012953
Jeff Johnson8c83f132017-12-18 16:41:37 -080012954 {
12955 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Kabilan Kannan3c0a7352016-12-02 18:49:38 -080012956 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_SAR_LIMITS,
12957 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12958 WIPHY_VENDOR_CMD_NEED_RUNNING,
12959 .doit = wlan_hdd_cfg80211_set_sar_power_limits
12960 },
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +053012961 {
12962 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12963 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_TRACE_LEVEL,
12964 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12965 WIPHY_VENDOR_CMD_NEED_NETDEV |
12966 WIPHY_VENDOR_CMD_NEED_RUNNING,
12967 .doit = wlan_hdd_cfg80211_set_trace_level
12968 },
Zhang Qian4ead8f02017-03-27 14:21:47 +080012969 {
12970 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12971 .info.subcmd =
12972 QCA_NL80211_VENDOR_SUBCMD_LL_STATS_EXT,
12973 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12974 WIPHY_VENDOR_CMD_NEED_NETDEV |
12975 WIPHY_VENDOR_CMD_NEED_RUNNING,
12976 .doit = wlan_hdd_cfg80211_ll_stats_ext_set_param
12977 },
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012978 {
12979 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12980 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
12981 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12982 WIPHY_VENDOR_CMD_NEED_NETDEV |
12983 WIPHY_VENDOR_CMD_NEED_RUNNING,
12984 .doit = wlan_hdd_cfg80211_set_nud_stats
12985 },
12986 {
12987 .info.vendor_id = QCA_NL80211_VENDOR_ID,
12988 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
12989 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
12990 WIPHY_VENDOR_CMD_NEED_NETDEV |
12991 WIPHY_VENDOR_CMD_NEED_RUNNING,
12992 .doit = wlan_hdd_cfg80211_get_nud_stats
12993 },
Qiwei Caie689a262018-07-26 15:50:22 +080012994
12995 FEATURE_BSS_TRANSITION_VENDOR_COMMANDS
Sandeep Puligilla063a4342018-01-10 02:50:14 -080012996 FEATURE_SPECTRAL_SCAN_VENDOR_COMMANDS
Krishna Kumaar Natarajanf5676502017-03-06 10:28:44 -080012997 FEATURE_11AX_VENDOR_COMMANDS
lifengd217d192017-05-09 19:44:16 +080012998
12999 {
13000 .info.vendor_id = QCA_NL80211_VENDOR_ID,
13001 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CHAIN_RSSI,
13002 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
13003 WIPHY_VENDOR_CMD_NEED_NETDEV |
13004 WIPHY_VENDOR_CMD_NEED_RUNNING,
13005 .doit = wlan_hdd_cfg80211_get_chain_rssi
13006 },
Qiwei Caie689a262018-07-26 15:50:22 +080013007
13008 FEATURE_ACTIVE_TOS_VENDOR_COMMANDS
Nachiket Kukadea6a70a92018-10-09 20:07:21 +053013009 FEATURE_NAN_VENDOR_COMMANDS
Qun Zhangef655622019-02-25 10:48:10 +080013010 FEATURE_FW_STATE_COMMANDS
Jiani Liua5f17222019-03-04 16:22:33 +080013011 FEATURE_COEX_CONFIG_COMMANDS
stonez2d686482019-03-12 14:54:26 +080013012 FEATURE_MPTA_HELPER_COMMANDS
guangde4853c402019-05-06 15:54:04 +080013013 FEATURE_HW_CAPABILITY_COMMANDS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013014};
13015
Dustin Brown92bd8382018-10-31 15:49:46 -070013016struct hdd_context *hdd_cfg80211_wiphy_alloc(void)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013017{
13018 struct wiphy *wiphy;
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070013019 struct hdd_context *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080013020
Dustin Brown491d54b2018-03-14 12:39:11 -070013021 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013022
Dustin Brown92bd8382018-10-31 15:49:46 -070013023 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, sizeof(*hdd_ctx));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013024 if (!wiphy) {
Dustin Brown92bd8382018-10-31 15:49:46 -070013025 hdd_err("failed to allocate wiphy!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013026 return NULL;
13027 }
13028
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080013029 hdd_ctx = wiphy_priv(wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080013030 hdd_ctx->wiphy = wiphy;
13031
13032 return hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013033}
13034
Jeff Johnson459d2732019-03-02 10:13:25 -080013035int wlan_hdd_cfg80211_update_band(struct hdd_context *hdd_ctx,
13036 struct wiphy *wiphy,
13037 enum band_info new_band)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013038{
13039 int i, j;
Jeff Johnson9cb757b2019-03-11 15:29:02 -070013040 enum channel_state channel_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013041
Dustin Brown491d54b2018-03-14 12:39:11 -070013042 hdd_enter();
Srinivas Girigowda5da651b2017-08-04 11:22:54 -070013043
13044 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013045
Jeff Johnsond36fa332019-03-18 13:42:25 -070013046 if (!wiphy->bands[i])
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013047 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013048
13049 for (j = 0; j < wiphy->bands[i]->n_channels; j++) {
13050 struct ieee80211_supported_band *band = wiphy->bands[i];
13051
Jeff Johnson9cb757b2019-03-11 15:29:02 -070013052 channel_state = wlan_reg_get_channel_state(
Dustin Brown07901ec2018-09-07 11:02:41 -070013053 hdd_ctx->pdev,
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070013054 band->channels[j].hw_value);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013055
Srinivas Girigowda11c28e02017-06-27 20:06:21 -070013056 if (HDD_NL80211_BAND_2GHZ == i &&
Jeff Johnson459d2732019-03-02 10:13:25 -080013057 BAND_5G == new_band) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013058 /* 5G only */
13059#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
13060 /* Enable Social channels for P2P */
13061 if (WLAN_HDD_IS_SOCIAL_CHANNEL
13062 (band->channels[j].center_freq)
13063 && CHANNEL_STATE_ENABLE ==
Jeff Johnson9cb757b2019-03-11 15:29:02 -070013064 channel_state)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013065 band->channels[j].flags &=
13066 ~IEEE80211_CHAN_DISABLED;
13067 else
13068#endif
13069 band->channels[j].flags |=
13070 IEEE80211_CHAN_DISABLED;
13071 continue;
Srinivas Girigowda11c28e02017-06-27 20:06:21 -070013072 } else if (HDD_NL80211_BAND_5GHZ == i &&
Jeff Johnson459d2732019-03-02 10:13:25 -080013073 BAND_2G == new_band) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013074 /* 2G only */
13075 band->channels[j].flags |=
13076 IEEE80211_CHAN_DISABLED;
13077 continue;
13078 }
13079
Jeff Johnson9cb757b2019-03-11 15:29:02 -070013080 if (CHANNEL_STATE_DISABLE != channel_state)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013081 band->channels[j].flags &=
13082 ~IEEE80211_CHAN_DISABLED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013083 }
13084 }
13085 return 0;
13086}
13087
Rajeev Kumar Sirasanagandla686abd92017-06-08 18:09:01 +053013088#if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \
13089 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
13090static void wlan_hdd_cfg80211_scan_randomization_init(struct wiphy *wiphy)
13091{
Pragaspathi Thilagarajf37f3932019-01-11 00:25:43 +053013092 wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
13093 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
Rajeev Kumar Sirasanagandla686abd92017-06-08 18:09:01 +053013094}
13095#else
13096static void wlan_hdd_cfg80211_scan_randomization_init(struct wiphy *wiphy)
13097{
13098}
13099#endif
13100
Peng Xuacfdda12017-02-06 16:15:38 -080013101#define WLAN_HDD_MAX_NUM_CSA_COUNTERS 2
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +053013102
Liangwei Dong3abfe8f2018-09-20 02:25:44 -040013103#if defined(CFG80211_RAND_TA_FOR_PUBLIC_ACTION_FRAME) || \
13104 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
13105/**
13106 * wlan_hdd_cfg80211_action_frame_randomization_init() - Randomize SA of MA
13107 * frames
13108 * @wiphy: Pointer to wiphy
13109 *
13110 * This function is used to indicate the support of source mac address
13111 * randomization of management action frames
13112 *
13113 * Return: None
13114 */
13115static void
13116wlan_hdd_cfg80211_action_frame_randomization_init(struct wiphy *wiphy)
13117{
13118 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA);
13119}
13120#else
13121static void
13122wlan_hdd_cfg80211_action_frame_randomization_init(struct wiphy *wiphy)
13123{
13124}
13125#endif
13126
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +053013127#if defined(WLAN_FEATURE_FILS_SK) && \
13128 (defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
13129 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)))
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053013130static void wlan_hdd_cfg80211_set_wiphy_fils_feature(struct wiphy *wiphy)
13131{
13132 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_SK_OFFLOAD);
13133}
13134#else
13135static void wlan_hdd_cfg80211_set_wiphy_fils_feature(struct wiphy *wiphy)
13136{
13137}
13138#endif
13139
gaurank kathpaliaa398d5f2018-02-27 16:42:22 +053013140#if defined (CFG80211_SCAN_DBS_CONTROL_SUPPORT) || \
13141 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0))
13142static void wlan_hdd_cfg80211_set_wiphy_scan_flags(struct wiphy *wiphy)
13143{
13144 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_LOW_SPAN_SCAN);
13145 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_LOW_POWER_SCAN);
13146 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_HIGH_ACCURACY_SCAN);
13147}
13148#else
13149static void wlan_hdd_cfg80211_set_wiphy_scan_flags(struct wiphy *wiphy)
13150{
13151}
13152#endif
13153
Veerendranath Jakkam62fedb92019-03-20 16:32:17 +053013154#if defined(CFG80211_SCAN_OCE_CAPABILITY_SUPPORT) || \
13155 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
13156static void wlan_hdd_cfg80211_set_wiphy_oce_scan_flags(struct wiphy *wiphy)
13157{
13158 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME);
13159 wiphy_ext_feature_set(wiphy,
13160 NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP);
13161 wiphy_ext_feature_set(wiphy,
13162 NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE);
13163 wiphy_ext_feature_set(
13164 wiphy, NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION);
13165}
13166#else
13167static void wlan_hdd_cfg80211_set_wiphy_oce_scan_flags(struct wiphy *wiphy)
13168{
13169}
13170#endif
13171
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053013172#if defined(WLAN_FEATURE_SAE) && \
13173 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
Padma, Santhosh Kumar3e47c632017-09-01 20:15:27 +053013174/**
13175 * wlan_hdd_cfg80211_set_wiphy_sae_feature() - Indicates support of SAE feature
13176 * @wiphy: Pointer to wiphy
Padma, Santhosh Kumar3e47c632017-09-01 20:15:27 +053013177 *
13178 * This function is used to indicate the support of SAE
13179 *
13180 * Return: None
13181 */
Manikandan Mohan66df7fc2019-01-08 17:57:05 -080013182static void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy)
Padma, Santhosh Kumar3e47c632017-09-01 20:15:27 +053013183{
Manikandan Mohand350c192018-11-29 14:01:12 -080013184 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Manikandan Mohand350c192018-11-29 14:01:12 -080013185
Manikandan Mohan66df7fc2019-01-08 17:57:05 -080013186 if (ucfg_fwol_get_sae_enable(hdd_ctx->psoc))
Manikandan Mohan5dba1c72019-01-07 16:57:03 -080013187 wiphy->features |= NL80211_FEATURE_SAE;
Padma, Santhosh Kumar3e47c632017-09-01 20:15:27 +053013188}
13189#else
Manikandan Mohan66df7fc2019-01-08 17:57:05 -080013190static void wlan_hdd_cfg80211_set_wiphy_sae_feature(struct wiphy *wiphy)
Padma, Santhosh Kumar3e47c632017-09-01 20:15:27 +053013191{
13192}
13193#endif
13194
Peng Xu8e8b0392018-04-30 11:32:34 -070013195#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)) || \
13196 defined(CFG80211_DFS_OFFLOAD_BACKPORT)
13197static void wlan_hdd_cfg80211_set_dfs_offload_feature(struct wiphy *wiphy)
13198{
13199 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD);
13200}
13201#else
13202static void wlan_hdd_cfg80211_set_dfs_offload_feature(struct wiphy *wiphy)
13203{
13204 wiphy->flags |= WIPHY_FLAG_DFS_OFFLOAD;
13205}
13206#endif
13207
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070013208#ifdef WLAN_FEATURE_DSRC
13209static void wlan_hdd_get_num_dsrc_ch_and_len(struct hdd_config *hdd_cfg,
13210 int *num_ch, int *ch_len)
13211{
13212 *num_ch = QDF_ARRAY_SIZE(hdd_channels_dot11p);
13213 *ch_len = sizeof(hdd_channels_dot11p);
13214}
13215
13216static void wlan_hdd_copy_dsrc_ch(char *ch_ptr, int ch_arr_len)
13217{
13218 if (!ch_arr_len)
13219 return;
13220 qdf_mem_copy(ch_ptr, &hdd_channels_dot11p[0], ch_arr_len);
13221}
13222
13223static void wlan_hdd_get_num_srd_ch_and_len(struct hdd_config *hdd_cfg,
13224 int *num_ch, int *ch_len)
13225{
13226 *num_ch = 0;
13227 *ch_len = 0;
13228}
13229
13230static void wlan_hdd_copy_srd_ch(char *ch_ptr, int ch_arr_len)
13231{
13232}
13233
Rajeev Kumar Sirasanagandla9770bba2018-09-24 20:12:28 +053013234/**
13235 * wlan_hdd_populate_srd_chan_info() - Populate SRD chan info in hdd context
13236 * @hdd_ctx: pointer to hdd context
13237 * @index: SRD channel beginning index in chan_info of @hdd_ctx
13238 *
13239 * Return: Number of SRD channels populated
13240 */
13241static uint32_t
13242wlan_hdd_populate_srd_chan_info(struct hdd_context *hdd_ctx, uint32_t index)
13243{
13244 return 0;
13245}
13246
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070013247#else
13248
13249static void wlan_hdd_get_num_dsrc_ch_and_len(struct hdd_config *hdd_cfg,
13250 int *num_ch, int *ch_len)
13251{
13252 *num_ch = 0;
13253 *ch_len = 0;
13254}
13255
13256static void wlan_hdd_copy_dsrc_ch(char *ch_ptr, int ch_arr_len)
13257{
13258}
13259
13260static void wlan_hdd_get_num_srd_ch_and_len(struct hdd_config *hdd_cfg,
13261 int *num_ch, int *ch_len)
13262{
13263 *num_ch = QDF_ARRAY_SIZE(hdd_etsi13_srd_ch);
13264 *ch_len = sizeof(hdd_etsi13_srd_ch);
13265}
13266
13267static void wlan_hdd_copy_srd_ch(char *ch_ptr, int ch_arr_len)
13268{
13269 if (!ch_arr_len)
13270 return;
13271 qdf_mem_copy(ch_ptr, &hdd_etsi13_srd_ch[0], ch_arr_len);
13272}
Rajeev Kumar Sirasanagandla9770bba2018-09-24 20:12:28 +053013273
13274/**
13275 * wlan_hdd_populate_srd_chan_info() - Populate SRD chan info in hdd context
13276 * @hdd_ctx: pointer to hdd context
13277 * @index: SRD channel beginning index in chan_info of @hdd_ctx
13278 *
13279 * Return: Number of SRD channels populated
13280 */
13281static uint32_t
13282wlan_hdd_populate_srd_chan_info(struct hdd_context *hdd_ctx, uint32_t index)
13283{
13284 uint32_t num_srd_ch, i;
13285 struct scan_chan_info *chan_info;
13286
13287 num_srd_ch = QDF_ARRAY_SIZE(hdd_etsi13_srd_ch);
13288 chan_info = hdd_ctx->chan_info;
13289
13290 for (i = 0; i < num_srd_ch; i++)
13291 chan_info[index + i].freq = hdd_etsi13_srd_ch[i].center_freq;
13292
13293 return num_srd_ch;
13294}
13295
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070013296#endif
13297
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013298/*
13299 * FUNCTION: wlan_hdd_cfg80211_init
13300 * This function is called by hdd_wlan_startup()
13301 * during initialization.
13302 * This function is used to initialize and register wiphy structure.
13303 */
13304int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson30f5bba2019-03-08 11:58:08 -080013305 struct wiphy *wiphy, struct hdd_config *config)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013306{
Jeff Johnsonb8944722017-09-03 09:03:19 -070013307 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053013308 uint32_t *cipher_suites;
Dustin Brown491d54b2018-03-14 12:39:11 -070013309 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013310
13311 /* Now bind the underlying wlan device with wiphy */
13312 set_wiphy_dev(wiphy, dev);
13313
13314 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
13315
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013316 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
13317 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
13318 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
13319#ifdef FEATURE_WLAN_STA_4ADDR_SCHEME
13320 | WIPHY_FLAG_4ADDR_STATION
13321#endif
13322 | WIPHY_FLAG_OFFCHAN_TX;
13323
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013324#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
13325 wiphy->wowlan = &wowlan_support_cfg80211_init;
13326#else
13327 wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT;
13328 wiphy->wowlan.n_patterns = WOWL_MAX_PTRNS_ALLOWED;
13329 wiphy->wowlan.pattern_min_len = 1;
13330 wiphy->wowlan.pattern_max_len = WOWL_PTRN_MAX_SIZE;
13331#endif
13332
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013333#ifdef FEATURE_WLAN_TDLS
13334 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
13335 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
13336#endif
13337
13338 wiphy->features |= NL80211_FEATURE_HT_IBSS;
13339
Naveen Rawatc77e6e72016-08-05 15:19:03 -070013340#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
13341 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
13342#endif
13343
gaurank kathpaliaa398d5f2018-02-27 16:42:22 +053013344 wlan_hdd_cfg80211_set_wiphy_scan_flags(wiphy);
13345
Pragaspathi Thilagaraj24789d32018-12-10 22:28:03 +053013346 wlan_scan_cfg80211_add_connected_pno_support(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013347
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013348 wiphy->max_scan_ssids = MAX_SCAN_SSID;
13349
13350 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
13351
13352 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
13353
Arun Khandavallifae92942016-08-01 13:31:08 +053013354 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
13355 | BIT(NL80211_IFTYPE_ADHOC)
13356 | BIT(NL80211_IFTYPE_P2P_CLIENT)
13357 | BIT(NL80211_IFTYPE_P2P_GO)
13358 | BIT(NL80211_IFTYPE_AP)
13359 | BIT(NL80211_IFTYPE_MONITOR);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013360
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013361
Abhishek Singhf512bf32016-05-04 16:47:46 +053013362 /*
13363 * In case of static linked driver at the time of driver unload,
13364 * module exit doesn't happens. Module cleanup helps in cleaning
13365 * of static memory.
13366 * If driver load happens statically, at the time of driver unload,
13367 * wiphy flags don't get reset because of static memory.
13368 * It's better not to store channel in static memory.
Qun Zhang043635a2019-02-27 15:19:29 +080013369 * The memory is for channels of struct wiphy and shouldn't be
13370 * released during stop modules. So if it's allocated in active
13371 * domain, the memory leak detector would catch the leak during
13372 * stop modules. To avoid this,alloc in init domain in advance.
Abhishek Singhf512bf32016-05-04 16:47:46 +053013373 */
Qun Zhang043635a2019-02-27 15:19:29 +080013374 hdd_ctx->channels_2ghz = qdf_mem_malloc(band_2_ghz_channels_size);
13375 if (!hdd_ctx->channels_2ghz) {
13376 hdd_err("Not enough memory to allocate channels");
Abhishek Singhf512bf32016-05-04 16:47:46 +053013377 return -ENOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013378 }
Qun Zhang043635a2019-02-27 15:19:29 +080013379 hdd_ctx->channels_5ghz = qdf_mem_malloc(band_5_ghz_chanenls_size);
13380 if (!hdd_ctx->channels_5ghz)
13381 goto mem_fail;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013382
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013383 /*Initialise the supported cipher suite details */
Manikandan Mohan66df7fc2019-01-08 17:57:05 -080013384 if (ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc)) {
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053013385 cipher_suites = qdf_mem_malloc(sizeof(hdd_cipher_suites) +
13386 sizeof(hdd_gcmp_cipher_suits));
Min Liu74a1a502018-10-10 19:59:07 +080013387 if (!cipher_suites)
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053013388 return -ENOMEM;
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053013389 wiphy->n_cipher_suites = QDF_ARRAY_SIZE(hdd_cipher_suites) +
13390 QDF_ARRAY_SIZE(hdd_gcmp_cipher_suits);
13391 qdf_mem_copy(cipher_suites, &hdd_cipher_suites,
13392 sizeof(hdd_cipher_suites));
13393 qdf_mem_copy(cipher_suites + QDF_ARRAY_SIZE(hdd_cipher_suites),
13394 &hdd_gcmp_cipher_suits,
13395 sizeof(hdd_gcmp_cipher_suits));
13396 } else {
13397 cipher_suites = qdf_mem_malloc(sizeof(hdd_cipher_suites));
Min Liu74a1a502018-10-10 19:59:07 +080013398 if (!cipher_suites)
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053013399 return -ENOMEM;
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053013400 wiphy->n_cipher_suites = QDF_ARRAY_SIZE(hdd_cipher_suites);
13401 qdf_mem_copy(cipher_suites, &hdd_cipher_suites,
13402 sizeof(hdd_cipher_suites));
13403 }
13404 wiphy->cipher_suites = cipher_suites;
13405 cipher_suites = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013406 /*signal strength in mBm (100*dBm) */
13407 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
13408 wiphy->max_remain_on_channel_duration = MAX_REMAIN_ON_CHANNEL_DURATION;
13409
Anurag Chouhan6d760662016-02-20 16:05:43 +053013410 if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013411 wiphy->n_vendor_commands =
13412 ARRAY_SIZE(hdd_wiphy_vendor_commands);
13413 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
13414
13415 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
13416 wiphy->n_vendor_events =
13417 ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
13418 }
13419
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013420#ifdef QCA_HT_2040_COEX
13421 wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
13422#endif
Agrawal, Ashish4e5fa1c2016-09-21 19:03:43 +053013423 wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
wadesonga75734c2017-02-07 16:03:25 +080013424
hangtian821d12d2019-06-11 11:53:50 +080013425 wiphy->features |= NL80211_FEATURE_VIF_TXPOWER;
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +053013426#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)) || \
wadesonga75734c2017-02-07 16:03:25 +080013427 defined(CFG80211_BEACON_TX_RATE_CUSTOM_BACKPORT)
13428 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_LEGACY);
13429 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_HT);
13430 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_BEACON_RATE_VHT);
13431#endif
13432
Abhishek Singh1bdb1572015-10-16 16:24:19 +053013433 hdd_add_channel_switch_support(&wiphy->flags);
Peng Xuacfdda12017-02-06 16:15:38 -080013434 wiphy->max_num_csa_counters = WLAN_HDD_MAX_NUM_CSA_COUNTERS;
Liangwei Dong3abfe8f2018-09-20 02:25:44 -040013435 wlan_hdd_cfg80211_action_frame_randomization_init(wiphy);
Abhishek Singh1bdb1572015-10-16 16:24:19 +053013436
Dustin Browne74003f2018-03-14 12:51:58 -070013437 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013438 return 0;
Ashish Kumar Dhanotiyacc2e0d32017-08-24 20:13:08 +053013439
13440mem_fail:
13441 hdd_err("Not enough memory to allocate channels");
Qun Zhang043635a2019-02-27 15:19:29 +080013442 if (hdd_ctx->channels_2ghz) {
13443 qdf_mem_free(hdd_ctx->channels_2ghz);
13444 hdd_ctx->channels_2ghz = NULL;
Ashish Kumar Dhanotiyacc2e0d32017-08-24 20:13:08 +053013445 }
13446 return -ENOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013447}
13448
Abhishek Singhf512bf32016-05-04 16:47:46 +053013449/**
Yingying Tang80e15f32016-09-27 18:23:01 +080013450 * wlan_hdd_cfg80211_deinit() - Deinit cfg80211
13451 * @wiphy: the wiphy to validate against
Abhishek Singhf512bf32016-05-04 16:47:46 +053013452 *
13453 * this function deinit cfg80211 and cleanup the
Abhishek Singh3e6172f2016-05-04 16:56:48 +053013454 * memory allocated in wlan_hdd_cfg80211_init also
13455 * reset the global reg params.
Abhishek Singhf512bf32016-05-04 16:47:46 +053013456 *
13457 * Return: void
13458 */
13459void wlan_hdd_cfg80211_deinit(struct wiphy *wiphy)
13460{
13461 int i;
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053013462 const uint32_t *cipher_suites;
Qun Zhang043635a2019-02-27 15:19:29 +080013463 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Abhishek Singhf512bf32016-05-04 16:47:46 +053013464
Srinivas Girigowda5da651b2017-08-04 11:22:54 -070013465 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++) {
Jeff Johnsond36fa332019-03-18 13:42:25 -070013466 if (wiphy->bands[i] &&
Qun Zhang043635a2019-02-27 15:19:29 +080013467 (wiphy->bands[i]->channels))
Abhishek Singhf512bf32016-05-04 16:47:46 +053013468 wiphy->bands[i]->channels = NULL;
Abhishek Singhf512bf32016-05-04 16:47:46 +053013469 }
Qun Zhang043635a2019-02-27 15:19:29 +080013470 qdf_mem_free(hdd_ctx->channels_2ghz);
13471 qdf_mem_free(hdd_ctx->channels_5ghz);
13472 hdd_ctx->channels_2ghz = NULL;
13473 hdd_ctx->channels_5ghz = NULL;
Amar Singhal5cccafe2017-02-15 12:42:58 -080013474
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053013475 cipher_suites = wiphy->cipher_suites;
13476 wiphy->cipher_suites = NULL;
13477 wiphy->n_cipher_suites = 0;
13478 qdf_mem_free((uint32_t *)cipher_suites);
13479 cipher_suites = NULL;
Abhishek Singh3e6172f2016-05-04 16:56:48 +053013480 hdd_reset_global_reg_params();
Abhishek Singhf512bf32016-05-04 16:47:46 +053013481}
13482
Yingying Tang80e15f32016-09-27 18:23:01 +080013483/**
13484 * wlan_hdd_update_band_cap() - update capabilities for supported bands
13485 * @hdd_ctx: HDD context
13486 *
13487 * this function will update capabilities for supported bands
13488 *
13489 * Return: void
13490 */
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013491static void wlan_hdd_update_ht_cap(struct hdd_context *hdd_ctx)
Yingying Tang80e15f32016-09-27 18:23:01 +080013492{
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013493 struct mlme_ht_capabilities_info ht_cap_info = {0};
Yingying Tang80e15f32016-09-27 18:23:01 +080013494 QDF_STATUS status;
Wu Gaoed616a12019-01-16 15:19:21 +080013495 uint32_t channel_bonding_mode;
Yingying Tang80e15f32016-09-27 18:23:01 +080013496
Dustin Brown76cd2932018-09-11 16:03:05 -070013497 status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013498 if (QDF_STATUS_SUCCESS != status)
Yingying Tang80e15f32016-09-27 18:23:01 +080013499 hdd_err("could not get HT capability info");
Yingying Tang80e15f32016-09-27 18:23:01 +080013500
Vignesh Viswanathan78182502018-08-06 15:13:30 +053013501 if (ht_cap_info.tx_stbc) {
Jeff Johnsond36fa332019-03-18 13:42:25 -070013502 if (hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ])
Srinivas Girigowda11c28e02017-06-27 20:06:21 -070013503 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]->ht_cap.cap |=
Yingying Tang80e15f32016-09-27 18:23:01 +080013504 IEEE80211_HT_CAP_TX_STBC;
Jeff Johnsond36fa332019-03-18 13:42:25 -070013505 if (hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ])
Srinivas Girigowda11c28e02017-06-27 20:06:21 -070013506 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->ht_cap.cap |=
Yingying Tang80e15f32016-09-27 18:23:01 +080013507 IEEE80211_HT_CAP_TX_STBC;
13508 }
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080013509
13510 if (!sme_is_feature_supported_by_fw(DOT11AC)) {
Srinivas Girigowda11c28e02017-06-27 20:06:21 -070013511 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]->
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080013512 vht_cap.vht_supported = 0;
Srinivas Girigowda11c28e02017-06-27 20:06:21 -070013513 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ]->vht_cap.cap = 0;
13514 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080013515 vht_cap.vht_supported = 0;
Srinivas Girigowda11c28e02017-06-27 20:06:21 -070013516 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ]->vht_cap.cap = 0;
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080013517 }
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013518
Vignesh Viswanathan78182502018-08-06 15:13:30 +053013519 if (!ht_cap_info.short_gi_20_mhz) {
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013520 wlan_hdd_band_2_4_ghz.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
13521 wlan_hdd_band_5_ghz.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
13522 }
13523
Vignesh Viswanathan78182502018-08-06 15:13:30 +053013524 if (!ht_cap_info.short_gi_40_mhz)
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013525 wlan_hdd_band_5_ghz.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
Wu Gaoed616a12019-01-16 15:19:21 +080013526
13527 ucfg_mlme_get_channel_bonding_5ghz(hdd_ctx->psoc, &channel_bonding_mode);
13528 if (!channel_bonding_mode)
13529 wlan_hdd_band_5_ghz.ht_cap.cap &=
13530 ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
Yingying Tang80e15f32016-09-27 18:23:01 +080013531}
13532
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053013533/**
13534 * wlan_hdd_update_band_cap_in_wiphy() - update channel flags based on band cap
13535 * @hdd_ctx: HDD context
13536 *
13537 * This function updates the channel flags based on the band capability set
13538 * in the MLME CFG
13539 *
13540 * Return: void
13541 */
13542static void wlan_hdd_update_band_cap_in_wiphy(struct hdd_context *hdd_ctx)
13543{
13544 int i, j;
13545 uint8_t band_capability;
13546 QDF_STATUS status;
13547 struct ieee80211_supported_band *band;
13548
13549 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
13550 if (QDF_IS_STATUS_ERROR(status)) {
13551 hdd_err("Failed to get MLME Band Capability");
13552 return;
13553 }
13554
13555 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++) {
Jeff Johnsond36fa332019-03-18 13:42:25 -070013556 if (!hdd_ctx->wiphy->bands[i])
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053013557 continue;
13558
13559 for (j = 0; j < hdd_ctx->wiphy->bands[i]->n_channels; j++) {
13560 band = hdd_ctx->wiphy->bands[i];
13561
13562 if (HDD_NL80211_BAND_2GHZ == i &&
13563 BAND_5G == band_capability) {
13564 /* 5G only */
13565#ifdef WLAN_ENABLE_SOCIAL_CHANNELS_5G_ONLY
13566 /* Enable social channels for P2P */
13567 if (WLAN_HDD_IS_SOCIAL_CHANNEL
13568 (band->channels[j].center_freq))
13569 band->channels[j].flags &=
13570 ~IEEE80211_CHAN_DISABLED;
13571 else
13572#endif
13573 band->channels[j].flags |=
13574 IEEE80211_CHAN_DISABLED;
13575 continue;
13576 } else if (HDD_NL80211_BAND_5GHZ == i &&
13577 BAND_2G == band_capability) {
13578 /* 2G only */
13579 band->channels[j].flags |=
13580 IEEE80211_CHAN_DISABLED;
13581 continue;
13582 }
13583 }
13584 }
13585}
13586
Wu Gao1ab05582018-11-08 16:22:49 +080013587#ifdef FEATURE_WLAN_ESE
13588/**
13589 * wlan_hdd_update_lfr_wiphy() - update LFR flag based on configures
13590 * @hdd_ctx: HDD context
13591 *
13592 * This function updates the LFR flag based on LFR configures
13593 *
13594 * Return: void
13595 */
13596static void wlan_hdd_update_lfr_wiphy(struct hdd_context *hdd_ctx)
13597{
13598 bool fast_transition_enabled;
13599 bool lfr_enabled;
13600 bool ese_enabled;
13601
13602 ucfg_mlme_is_fast_transition_enabled(hdd_ctx->psoc,
13603 &fast_transition_enabled);
13604 ucfg_mlme_is_lfr_enabled(hdd_ctx->psoc, &lfr_enabled);
13605 ucfg_mlme_is_ese_enabled(hdd_ctx->psoc, &ese_enabled);
13606 if (fast_transition_enabled || lfr_enabled || ese_enabled)
13607 hdd_ctx->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
13608}
13609#else
13610static void wlan_hdd_update_lfr_wiphy(struct hdd_context *hdd_ctx)
13611{
13612 bool fast_transition_enabled;
13613 bool lfr_enabled;
13614
13615 ucfg_mlme_is_fast_transition_enabled(hdd_ctx->psoc,
13616 &fast_transition_enabled);
13617 ucfg_mlme_is_lfr_enabled(hdd_ctx->psoc, &lfr_enabled);
13618 if (fast_transition_enabled || lfr_enabled)
13619 hdd_ctx->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
13620}
13621#endif
13622
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013623/*
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053013624 * In this function, wiphy structure is updated after QDF
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013625 * initialization. In wlan_hdd_cfg80211_init, only the
13626 * default values will be initialized. The final initialization
13627 * of all required members can be done here.
13628 */
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070013629void wlan_hdd_update_wiphy(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013630{
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053013631 int value;
Ashish Kumar Dhanotiya53d8bb62019-05-29 20:55:13 +053013632 bool fils_enabled, mac_spoofing_enabled;
Srinivas Dasarib264fec2019-05-21 18:56:25 +053013633 bool dfs_master_capable = true, is_oce_sta_enabled = false;
Karthik Kantamneni2231a232018-09-11 15:45:55 +053013634 QDF_STATUS status;
Ashish Kumar Dhanotiya53d8bb62019-05-29 20:55:13 +053013635 struct wiphy *wiphy = hdd_ctx->wiphy;
13636 uint8_t allow_mcc_go_diff_bi = 0, enable_mcc = 0;
Yingying Tang80e15f32016-09-27 18:23:01 +080013637
Ashish Kumar Dhanotiya53d8bb62019-05-29 20:55:13 +053013638 if (!wiphy) {
13639 hdd_err("Invalid wiphy");
13640 return;
13641 }
Dustin Brown05d81302018-09-11 16:49:22 -070013642 ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053013643 hdd_ctx->wiphy->max_ap_assoc_sta = value;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013644 wlan_hdd_update_ht_cap(hdd_ctx);
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053013645 wlan_hdd_update_band_cap_in_wiphy(hdd_ctx);
Wu Gao1ab05582018-11-08 16:22:49 +080013646 wlan_hdd_update_lfr_wiphy(hdd_ctx);
Karthik Kantamneni2231a232018-09-11 15:45:55 +053013647
13648 fils_enabled = 0;
Dustin Brown05d81302018-09-11 16:49:22 -070013649 status = ucfg_mlme_get_fils_enabled_info(hdd_ctx->psoc,
Karthik Kantamneni2231a232018-09-11 15:45:55 +053013650 &fils_enabled);
13651 if (QDF_IS_STATUS_ERROR(status))
13652 hdd_err("could not get fils enabled info");
13653 if (fils_enabled)
Ashish Kumar Dhanotiya53d8bb62019-05-29 20:55:13 +053013654 wlan_hdd_cfg80211_set_wiphy_fils_feature(wiphy);
Arif Hussain88d1fdd2018-09-26 16:12:24 -070013655
13656 status = ucfg_mlme_get_dfs_master_capability(hdd_ctx->psoc,
13657 &dfs_master_capable);
13658 if (QDF_IS_STATUS_SUCCESS(status) && dfs_master_capable)
Ashish Kumar Dhanotiya53d8bb62019-05-29 20:55:13 +053013659 wlan_hdd_cfg80211_set_dfs_offload_feature(wiphy);
Srinivas Dasarib264fec2019-05-21 18:56:25 +053013660
13661 status = ucfg_mlme_get_oce_sta_enabled_info(hdd_ctx->psoc,
13662 &is_oce_sta_enabled);
13663 if (QDF_IS_STATUS_ERROR(status))
13664 hdd_err("could not get OCE STA enable info");
13665 if (is_oce_sta_enabled)
Ashish Kumar Dhanotiya53d8bb62019-05-29 20:55:13 +053013666 wlan_hdd_cfg80211_set_wiphy_oce_scan_flags(wiphy);
13667
13668 wlan_hdd_cfg80211_set_wiphy_sae_feature(wiphy);
13669
13670 if (QDF_STATUS_SUCCESS !=
13671 ucfg_policy_mgr_get_allow_mcc_go_diff_bi(hdd_ctx->psoc,
13672 &allow_mcc_go_diff_bi))
13673 hdd_err("can't get mcc_go_diff_bi value, use default");
13674
13675 if (QDF_STATUS_SUCCESS !=
13676 ucfg_mlme_get_mcc_feature(hdd_ctx->psoc, &enable_mcc))
13677 hdd_err("can't get enable_mcc value, use default");
13678
13679 if (hdd_ctx->config->advertise_concurrent_operation) {
13680 if (enable_mcc) {
13681 int i;
13682
13683 for (i = 0;
13684 i < ARRAY_SIZE(wlan_hdd_iface_combination);
13685 i++) {
13686 if (!allow_mcc_go_diff_bi)
13687 wlan_hdd_iface_combination[i].
13688 beacon_int_infra_match = true;
13689 }
13690 }
13691 wiphy->n_iface_combinations =
13692 ARRAY_SIZE(wlan_hdd_iface_combination);
13693 wiphy->iface_combinations = wlan_hdd_iface_combination;
13694 }
13695
13696 mac_spoofing_enabled = ucfg_scan_is_mac_spoofing_enabled(hdd_ctx->psoc);
13697 if (mac_spoofing_enabled)
13698 wlan_hdd_cfg80211_scan_randomization_init(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013699}
13700
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080013701/**
13702 * wlan_hdd_update_11n_mode - update 11n mode in hdd cfg
13703 * @cfg: hdd cfg
13704 *
13705 * this function update 11n mode in hdd cfg
13706 *
13707 * Return: void
13708 */
Sandeep Puligilla34618782019-01-04 17:42:42 -080013709void wlan_hdd_update_11n_mode(struct hdd_context *hdd_ctx)
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080013710{
Sandeep Puligilla34618782019-01-04 17:42:42 -080013711 struct hdd_config *cfg = hdd_ctx->config;
13712
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080013713 if (sme_is_feature_supported_by_fw(DOT11AC)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080013714 hdd_debug("support 11ac");
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080013715 } else {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080013716 hdd_debug("not support 11ac");
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080013717 if ((cfg->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) ||
13718 (cfg->dot11Mode == eHDD_DOT11_MODE_11ac)) {
13719 cfg->dot11Mode = eHDD_DOT11_MODE_11n;
Sandeep Puligilla34618782019-01-04 17:42:42 -080013720 ucfg_mlme_set_sap_11ac_override(hdd_ctx->psoc, 0);
13721 ucfg_mlme_set_go_11ac_override(hdd_ctx->psoc, 0);
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080013722 }
13723 }
13724}
13725
Qun Zhang043635a2019-02-27 15:19:29 +080013726QDF_STATUS wlan_hdd_update_wiphy_supported_band(struct hdd_context *hdd_ctx)
13727{
13728 int len_5g_ch, num_ch;
13729 int num_dsrc_ch, len_dsrc_ch, num_srd_ch, len_srd_ch;
13730 struct hdd_config *cfg = hdd_ctx->config;
13731 struct wiphy *wiphy = hdd_ctx->wiphy;
13732
tinlin5d3721d2019-06-03 16:13:20 +080013733 if (wiphy->registered)
13734 return QDF_STATUS_SUCCESS;
13735
Ashish Kumar Dhanotiya34507e02019-06-12 12:53:59 +053013736 if (hdd_is_2g_supported(hdd_ctx)) {
13737 if (!hdd_ctx->channels_2ghz)
13738 return QDF_STATUS_E_NOMEM;
13739 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_ghz;
13740 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
13741 hdd_ctx->channels_2ghz;
13742 qdf_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
13743 &hdd_channels_2_4_ghz[0],
13744 sizeof(hdd_channels_2_4_ghz));
13745 }
Qun Zhang043635a2019-02-27 15:19:29 +080013746 if (!hdd_is_5g_supported(hdd_ctx) ||
13747 (eHDD_DOT11_MODE_11b == cfg->dot11Mode) ||
13748 (eHDD_DOT11_MODE_11g == cfg->dot11Mode) ||
13749 (eHDD_DOT11_MODE_11b_ONLY == cfg->dot11Mode) ||
13750 (eHDD_DOT11_MODE_11g_ONLY == cfg->dot11Mode))
13751 return QDF_STATUS_SUCCESS;
13752
13753 if (!hdd_ctx->channels_5ghz)
13754 return QDF_STATUS_E_NOMEM;
13755 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_ghz;
13756 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels = hdd_ctx->channels_5ghz;
13757 wlan_hdd_get_num_dsrc_ch_and_len(cfg, &num_dsrc_ch, &len_dsrc_ch);
13758 wlan_hdd_get_num_srd_ch_and_len(cfg, &num_srd_ch, &len_srd_ch);
13759 num_ch = QDF_ARRAY_SIZE(hdd_channels_5_ghz) + num_dsrc_ch + num_srd_ch;
13760 len_5g_ch = sizeof(hdd_channels_5_ghz);
13761
13762 wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels = num_ch;
13763 qdf_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
13764 &hdd_channels_5_ghz[0], len_5g_ch);
13765 if (num_dsrc_ch)
13766 wlan_hdd_copy_dsrc_ch((char *)wiphy->bands[
13767 HDD_NL80211_BAND_5GHZ]->channels +
13768 len_5g_ch, len_dsrc_ch);
13769 if (num_srd_ch)
13770 wlan_hdd_copy_srd_ch((char *)wiphy->bands[
13771 HDD_NL80211_BAND_5GHZ]->channels +
13772 len_5g_ch, len_srd_ch);
13773
13774 return QDF_STATUS_SUCCESS;
13775}
13776
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013777/* In this function we are registering wiphy. */
13778int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
13779{
Dustin Brown491d54b2018-03-14 12:39:11 -070013780 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013781 /* Register our wiphy dev with cfg80211 */
13782 if (0 > wiphy_register(wiphy)) {
Jeff Johnson77848112016-06-29 14:52:06 -070013783 hdd_err("wiphy register failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013784 return -EIO;
13785 }
13786
Dustin Browne74003f2018-03-14 12:51:58 -070013787 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013788 return 0;
13789}
13790
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013791/* This function registers for all frame which supplicant is interested in */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070013792int wlan_hdd_cfg80211_register_frames(struct hdd_adapter *adapter)
Wu Gao84d120c2017-03-24 18:46:00 +080013793{
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013794 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
Wu Gao84d120c2017-03-24 18:46:00 +080013795 /* Register for all P2P action, public action etc frames */
13796 uint16_t type = (SIR_MAC_MGMT_FRAME << 2) | (SIR_MAC_MGMT_ACTION << 4);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013797 QDF_STATUS status;
Wu Gao84d120c2017-03-24 18:46:00 +080013798
Dustin Brown491d54b2018-03-14 12:39:11 -070013799 hdd_enter();
Sourav Mohapatraa0943922018-11-21 21:26:29 +053013800 if (adapter->device_mode == QDF_FTM_MODE) {
13801 hdd_info("No need to register frames in FTM mode");
13802 return 0;
13803 }
Wu Gao84d120c2017-03-24 18:46:00 +080013804
13805 /* Register frame indication call back */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013806 status = sme_register_mgmt_frame_ind_callback(mac_handle,
13807 hdd_indicate_mgmt_frame);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013808 if (status != QDF_STATUS_SUCCESS) {
13809 hdd_err("Failed to register hdd_indicate_mgmt_frame");
13810 goto ret_status;
13811 }
Wu Gao84d120c2017-03-24 18:46:00 +080013812
Wu Gao84d120c2017-03-24 18:46:00 +080013813 /* Right now we are registering these frame when driver is getting
13814 * initialized. Once we will move to 2.6.37 kernel, in which we have
13815 * frame register ops, we will move this code as a part of that
13816 */
13817
13818 /* GAS Initial Request */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013819 status = sme_register_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
13820 (uint8_t *) GAS_INITIAL_REQ,
13821 GAS_INITIAL_REQ_SIZE);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013822 if (status != QDF_STATUS_SUCCESS) {
13823 hdd_err("Failed to register GAS_INITIAL_REQ");
13824 goto ret_status;
13825 }
Wu Gao84d120c2017-03-24 18:46:00 +080013826
13827 /* GAS Initial Response */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013828 status = sme_register_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
13829 (uint8_t *) GAS_INITIAL_RSP,
13830 GAS_INITIAL_RSP_SIZE);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013831 if (status != QDF_STATUS_SUCCESS) {
13832 hdd_err("Failed to register GAS_INITIAL_RSP");
13833 goto dereg_gas_initial_req;
13834 }
Wu Gao84d120c2017-03-24 18:46:00 +080013835
13836 /* GAS Comeback Request */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013837 status = sme_register_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
13838 (uint8_t *) GAS_COMEBACK_REQ,
13839 GAS_COMEBACK_REQ_SIZE);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013840 if (status != QDF_STATUS_SUCCESS) {
13841 hdd_err("Failed to register GAS_COMEBACK_REQ");
13842 goto dereg_gas_initial_rsp;
13843 }
Wu Gao84d120c2017-03-24 18:46:00 +080013844
13845 /* GAS Comeback Response */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013846 status = sme_register_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
13847 (uint8_t *) GAS_COMEBACK_RSP,
13848 GAS_COMEBACK_RSP_SIZE);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013849 if (status != QDF_STATUS_SUCCESS) {
13850 hdd_err("Failed to register GAS_COMEBACK_RSP");
13851 goto dereg_gas_comeback_req;
13852 }
Wu Gao84d120c2017-03-24 18:46:00 +080013853
13854 /* WNM BSS Transition Request frame */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013855 status = sme_register_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
13856 (uint8_t *) WNM_BSS_ACTION_FRAME,
13857 WNM_BSS_ACTION_FRAME_SIZE);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013858 if (status != QDF_STATUS_SUCCESS) {
13859 hdd_err("Failed to register WNM_BSS_ACTION_FRAME");
13860 goto dereg_gas_comeback_rsp;
13861 }
Wu Gao84d120c2017-03-24 18:46:00 +080013862
13863 /* WNM-Notification */
Jeff Johnsoncf07c312019-02-04 13:53:29 -080013864 status = sme_register_mgmt_frame(mac_handle, adapter->vdev_id, type,
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013865 (uint8_t *) WNM_NOTIFICATION_FRAME,
13866 WNM_NOTIFICATION_FRAME_SIZE);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013867 if (status != QDF_STATUS_SUCCESS) {
13868 hdd_err("Failed to register WNM_NOTIFICATION_FRAME");
13869 goto dereg_wnm_bss_action_frm;
13870 }
13871
Dustin Brown237baee2018-05-10 13:22:18 -070013872 return 0;
13873
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013874dereg_wnm_bss_action_frm:
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013875 sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
13876 (uint8_t *) WNM_BSS_ACTION_FRAME,
13877 WNM_BSS_ACTION_FRAME_SIZE);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013878dereg_gas_comeback_rsp:
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013879 sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
13880 (uint8_t *) GAS_COMEBACK_RSP,
13881 GAS_COMEBACK_RSP_SIZE);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013882dereg_gas_comeback_req:
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013883 sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
13884 (uint8_t *) GAS_COMEBACK_REQ,
13885 GAS_COMEBACK_REQ_SIZE);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013886dereg_gas_initial_rsp:
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013887 sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
13888 (uint8_t *) GAS_INITIAL_RSP,
13889 GAS_INITIAL_RSP_SIZE);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013890dereg_gas_initial_req:
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013891 sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
13892 (uint8_t *) GAS_INITIAL_REQ,
13893 GAS_INITIAL_REQ_SIZE);
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +053013894ret_status:
13895 return qdf_status_to_os_return(status);
Wu Gao84d120c2017-03-24 18:46:00 +080013896}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013897
Jeff Johnsonce2ba702017-10-02 13:30:24 -070013898void wlan_hdd_cfg80211_deregister_frames(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013899{
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013900 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
13901 /* Deregister for all P2P action, public action etc frames */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013902 uint16_t type = (SIR_MAC_MGMT_FRAME << 2) | (SIR_MAC_MGMT_ACTION << 4);
13903
Dustin Brown491d54b2018-03-14 12:39:11 -070013904 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013905
13906 /* Right now we are registering these frame when driver is getting
Jeff Johnsonf3826e12017-01-12 09:49:40 -080013907 * initialized. Once we will move to 2.6.37 kernel, in which we have
13908 * frame register ops, we will move this code as a part of that
13909 */
13910
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013911 /* GAS Initial Request */
13912
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013913 sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013914 (uint8_t *) GAS_INITIAL_REQ,
13915 GAS_INITIAL_REQ_SIZE);
13916
13917 /* GAS Initial Response */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013918 sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013919 (uint8_t *) GAS_INITIAL_RSP,
13920 GAS_INITIAL_RSP_SIZE);
13921
13922 /* GAS Comeback Request */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013923 sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013924 (uint8_t *) GAS_COMEBACK_REQ,
13925 GAS_COMEBACK_REQ_SIZE);
13926
13927 /* GAS Comeback Response */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013928 sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013929 (uint8_t *) GAS_COMEBACK_RSP,
13930 GAS_COMEBACK_RSP_SIZE);
13931
13932 /* P2P Public Action */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013933 sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013934 (uint8_t *) P2P_PUBLIC_ACTION_FRAME,
13935 P2P_PUBLIC_ACTION_FRAME_SIZE);
13936
13937 /* P2P Action */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013938 sme_deregister_mgmt_frame(mac_handle, SME_SESSION_ID_ANY, type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013939 (uint8_t *) P2P_ACTION_FRAME,
13940 P2P_ACTION_FRAME_SIZE);
13941
13942 /* WNM-Notification */
Jeff Johnsoncf07c312019-02-04 13:53:29 -080013943 sme_deregister_mgmt_frame(mac_handle, adapter->vdev_id, type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013944 (uint8_t *) WNM_NOTIFICATION_FRAME,
13945 WNM_NOTIFICATION_FRAME_SIZE);
13946}
13947
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070013948#if defined(FEATURE_WLAN_WAPI) && !defined(CRYPTO_SET_KEY_CONVERGED)
Sourav Mohapatrad21fc6b2018-06-01 11:31:14 +053013949static void wlan_hdd_cfg80211_set_key_wapi(struct hdd_adapter *adapter,
13950 uint8_t key_index,
13951 const uint8_t *mac_addr,
13952 const uint8_t *key,
Jeff Johnson7d70e4f2019-03-23 11:18:59 -070013953 int key_len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013954{
Jeff Johnson89515092019-03-23 10:52:04 -070013955 tCsrRoamSetKey set_key;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013956 QDF_STATUS status;
Jeff Johnson29c78672019-02-26 21:05:53 -080013957 uint32_t roam_id = INVALID_ROAM_ID;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070013958 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013959
Srinivas Girigowda13d39252017-03-06 16:12:15 -080013960 hdd_debug("Device_mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -070013961 qdf_opmode_str(adapter->device_mode), adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013962
Jeff Johnson7d70e4f2019-03-23 11:18:59 -070013963 qdf_mem_zero(&set_key, sizeof(set_key));
13964 set_key.keyId = key_index;
13965 set_key.encType = eCSR_ENCRYPT_TYPE_WPI;
13966 set_key.keyDirection = eSIR_TX_RX;
13967 set_key.paeRole = 0;
Srinivas Girigowda576b2352017-08-25 14:44:26 -070013968 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson89515092019-03-23 10:52:04 -070013969 qdf_set_macaddr_broadcast(&set_key.peerMac);
Srinivas Girigowda576b2352017-08-25 14:44:26 -070013970 else
Jeff Johnson7d70e4f2019-03-23 11:18:59 -070013971 qdf_mem_copy(set_key.peerMac.bytes, mac_addr,
13972 QDF_MAC_ADDR_SIZE);
Srinivas Girigowda576b2352017-08-25 14:44:26 -070013973
Jeff Johnson7d70e4f2019-03-23 11:18:59 -070013974 set_key.keyLength = key_len;
13975 memcpy(set_key.Key, key, key_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013976
Jeff Johnson7d70e4f2019-03-23 11:18:59 -070013977 hdd_debug("WAPI KEY LENGTH:0x%04x", key_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013978
Jeff Johnson7d70e4f2019-03-23 11:18:59 -070013979 mac_handle = hdd_adapter_get_mac_handle(adapter);
13980 status = sme_roam_set_key(mac_handle, adapter->vdev_id,
13981 &set_key, &roam_id);
13982 if (status != QDF_STATUS_SUCCESS)
13983 hdd_err("sme_roam_set_key failed status: %d", status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013984}
13985#endif /* FEATURE_WLAN_WAPI */
13986
Krunal Soni364e0872017-05-10 21:24:34 -070013987bool wlan_hdd_is_ap_supports_immediate_power_save(uint8_t *ies, int length)
13988{
Naveen Rawat08db88f2017-09-08 15:07:48 -070013989 const uint8_t *vendor_ie;
Krunal Soni364e0872017-05-10 21:24:34 -070013990
13991 if (length < 2) {
13992 hdd_debug("bss size is less than expected");
13993 return true;
13994 }
13995 if (!ies) {
13996 hdd_debug("invalid IE pointer");
13997 return true;
13998 }
Naveen Rawat08db88f2017-09-08 15:07:48 -070013999 vendor_ie = wlan_get_vendor_ie_ptr_from_oui(VENDOR1_AP_OUI_TYPE,
Krunal Soni364e0872017-05-10 21:24:34 -070014000 VENDOR1_AP_OUI_TYPE_SIZE, ies, length);
14001 if (vendor_ie) {
14002 hdd_debug("AP can't support immediate powersave. defer it");
14003 return false;
14004 }
14005 return true;
14006}
14007
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014008/*
14009 * FUNCTION: wlan_hdd_validate_operation_channel
14010 * called by wlan_hdd_cfg80211_start_bss() and
14011 * wlan_hdd_set_channel()
14012 * This function validates whether given channel is part of valid
14013 * channel list.
14014 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014015QDF_STATUS wlan_hdd_validate_operation_channel(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014016 int channel)
14017{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014018 uint32_t num_ch = 0;
Wu Gao0821b0d2019-01-11 17:31:11 +080014019 u8 valid_ch[CFG_VALID_CHANNEL_LIST_LEN];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014020 u32 indx = 0;
Jeff Johnson603ef852019-03-11 15:23:30 -070014021 bool is_valid_channel = false;
14022 uint8_t count;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053014023 QDF_STATUS status;
14024 bool value;
14025 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014026
Wu Gao0821b0d2019-01-11 17:31:11 +080014027 num_ch = CFG_VALID_CHANNEL_LIST_LEN;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053014028 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Dustin Brown05d81302018-09-11 16:49:22 -070014029 status = ucfg_mlme_get_sap_allow_all_channels(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053014030 if (status != QDF_STATUS_SUCCESS)
14031 hdd_err("Unable to fetch sap allow all channels");
14032 if (value) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014033 /* Validate the channel */
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070014034 for (count = CHAN_ENUM_1; count <= CHAN_ENUM_173; count++) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070014035 if (channel == WLAN_REG_CH_NUM(count)) {
Jeff Johnson603ef852019-03-11 15:23:30 -070014036 is_valid_channel = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014037 break;
14038 }
14039 }
Jeff Johnson603ef852019-03-11 15:23:30 -070014040 if (!is_valid_channel) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080014041 hdd_err("Invalid Channel: %d", channel);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053014042 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014043 }
14044 } else {
Wu Gaof3cbeaf2019-01-15 18:26:25 +080014045 ucfg_mlme_get_valid_channel_list(hdd_ctx->psoc, valid_ch,
14046 &num_ch);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014047 for (indx = 0; indx < num_ch; indx++) {
Srinivas Girigowda576b2352017-08-25 14:44:26 -070014048 if (channel == valid_ch[indx])
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014049 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014050 }
14051
14052 if (indx >= num_ch) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080014053 hdd_err("Invalid Channel: %d", channel);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053014054 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014055 }
14056 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053014057 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014058
14059}
14060
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014061static int __wlan_hdd_cfg80211_change_bss(struct wiphy *wiphy,
14062 struct net_device *dev,
14063 struct bss_parameters *params)
14064{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014065 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
14066 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014067 int ret = 0;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053014068 QDF_STATUS qdf_ret_status;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070014069 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014070
Dustin Brown491d54b2018-03-14 12:39:11 -070014071 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014072
Anurag Chouhan6d760662016-02-20 16:05:43 +053014073 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson77848112016-06-29 14:52:06 -070014074 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014075 return -EINVAL;
14076 }
14077
Jeff Johnson48363022019-02-24 16:26:51 -080014078 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053014079 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053014080
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053014081 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
14082 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080014083 adapter->vdev_id, params->ap_isolate);
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053014084
Srinivas Girigowda13d39252017-03-06 16:12:15 -080014085 hdd_debug("Device_mode %s(%d), ap_isolate = %d",
Dustin Brown458027c2018-10-19 12:26:27 -070014086 qdf_opmode_str(adapter->device_mode),
14087 adapter->device_mode, params->ap_isolate);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014088
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014089 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnsonb8944722017-09-03 09:03:19 -070014090 ret = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053014091 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014092 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014093
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014094 if (!(adapter->device_mode == QDF_SAP_MODE ||
14095 adapter->device_mode == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014096 return -EOPNOTSUPP;
14097 }
14098
14099 /* ap_isolate == -1 means that in change bss, upper layer doesn't
Jeff Johnsonf3826e12017-01-12 09:49:40 -080014100 * want to update this parameter
14101 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014102 if (-1 != params->ap_isolate) {
Jeff Johnsonb9424862017-10-30 08:49:35 -070014103 adapter->session.ap.disable_intrabss_fwd =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014104 !!params->ap_isolate;
14105
Jeff Johnson34fc63a2018-06-14 10:10:02 -070014106 mac_handle = hdd_ctx->mac_handle;
14107 qdf_ret_status = sme_ap_disable_intra_bss_fwd(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080014108 adapter->vdev_id,
Jeff Johnsonb9424862017-10-30 08:49:35 -070014109 adapter->session.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014110 ap.
Jeff Johnson82ceb082017-10-27 14:52:42 -070014111 disable_intrabss_fwd);
Srinivas Girigowda576b2352017-08-25 14:44:26 -070014112 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014113 ret = -EINVAL;
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +053014114
Dustin Brown07901ec2018-09-07 11:02:41 -070014115 ucfg_ipa_set_ap_ibss_fwd(hdd_ctx->pdev,
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +053014116 adapter->session.ap.
14117 disable_intrabss_fwd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014118 }
14119
Dustin Browne74003f2018-03-14 12:51:58 -070014120 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014121 return ret;
14122}
14123
Krunal Soni8c37e322016-02-03 16:08:37 -080014124/**
Dustin Brown56377e12018-10-10 17:04:04 -070014125 * hdd_change_adapter_mode() - change @adapter's operating mode to @new_mode
14126 * @adapter: the adapter to change modes on
14127 * @new_mode: the new operating mode to change to
Krunal Soni8c37e322016-02-03 16:08:37 -080014128 *
Dustin Brown56377e12018-10-10 17:04:04 -070014129 * Return: Errno
Krunal Soni8c37e322016-02-03 16:08:37 -080014130 */
Dustin Brown56377e12018-10-10 17:04:04 -070014131static int hdd_change_adapter_mode(struct hdd_adapter *adapter,
14132 enum QDF_OPMODE new_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014133{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070014134 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Dustin Brown56377e12018-10-10 17:04:04 -070014135 struct net_device *netdev = adapter->dev;
Krunal Soni8c37e322016-02-03 16:08:37 -080014136 struct hdd_config *config = hdd_ctx->config;
Jeff Johnson20227a92018-03-13 09:41:05 -070014137 struct csr_roam_profile *roam_profile;
Arun Khandavallib2f6c262016-08-18 19:07:19 +053014138 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014139
Dustin Brown491d54b2018-03-14 12:39:11 -070014140 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014141
Krunal Soni8c37e322016-02-03 16:08:37 -080014142 if (test_bit(ACS_IN_PROGRESS, &hdd_ctx->g_event_flags)) {
Dustin Brown56377e12018-10-10 17:04:04 -070014143 hdd_warn("Can't change interface: ACS in progress");
Sandeep Puligilla1e6da362017-04-07 14:16:03 -070014144 return -EBUSY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014145 }
14146
Dustin Browndb2a8be2017-12-20 11:49:56 -080014147 hdd_stop_adapter(hdd_ctx, adapter);
Krunal Soni8c37e322016-02-03 16:08:37 -080014148 hdd_deinit_adapter(hdd_ctx, adapter, true);
Dustin Brown194aeca2018-10-12 15:37:36 -070014149 adapter->device_mode = new_mode;
Jeff Johnsonb9424862017-10-30 08:49:35 -070014150 memset(&adapter->session, 0, sizeof(adapter->session));
Dustin Brown56377e12018-10-10 17:04:04 -070014151 hdd_set_station_ops(netdev);
Jeff Johnson20227a92018-03-13 09:41:05 -070014152
14153 roam_profile = hdd_roam_profile(adapter);
14154 roam_profile->pAddIEScan = adapter->scan_info.scan_add_ie.addIEdata;
Dustin Brown56377e12018-10-10 17:04:04 -070014155 roam_profile->nAddIEScanLength = adapter->scan_info.scan_add_ie.length;
14156
14157 if (new_mode == QDF_IBSS_MODE) {
Krunal Sonib51eec72017-11-20 21:53:01 -080014158 status = hdd_start_station_adapter(adapter);
Jeff Johnson20227a92018-03-13 09:41:05 -070014159 roam_profile->BSSType = eCSR_BSS_TYPE_START_IBSS;
14160 roam_profile->phyMode =
Krunal Soni8c37e322016-02-03 16:08:37 -080014161 hdd_cfg_xlate_to_csr_phy_mode(config->dot11Mode);
14162 }
Dustin Brown56377e12018-10-10 17:04:04 -070014163
Dustin Browne74003f2018-03-14 12:51:58 -070014164 hdd_exit();
Sandeep Puligilla1e6da362017-04-07 14:16:03 -070014165
14166 return qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014167}
14168
14169static int wlan_hdd_cfg80211_change_bss(struct wiphy *wiphy,
14170 struct net_device *dev,
14171 struct bss_parameters *params)
14172{
Dustin Brown1d31b082018-11-22 14:41:20 +053014173 int errno;
14174 struct osif_vdev_sync *vdev_sync;
14175
14176 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
14177 if (errno)
14178 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014179
Dustin Brown1d31b082018-11-22 14:41:20 +053014180 errno = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014181
Dustin Brown1d31b082018-11-22 14:41:20 +053014182 osif_vdev_sync_op_stop(vdev_sync);
14183
14184 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014185}
14186
Dustin Brown63fe4922018-10-12 15:02:26 -070014187static bool hdd_is_client_mode(enum QDF_OPMODE mode)
14188{
14189 switch (mode) {
14190 case QDF_STA_MODE:
14191 case QDF_P2P_CLIENT_MODE:
14192 case QDF_P2P_DEVICE_MODE:
14193 case QDF_IBSS_MODE:
14194 return true;
14195 default:
14196 return false;
14197 }
14198}
14199
14200static bool hdd_is_ap_mode(enum QDF_OPMODE mode)
14201{
14202 switch (mode) {
14203 case QDF_SAP_MODE:
14204 case QDF_P2P_GO_MODE:
14205 return true;
14206 default:
14207 return false;
14208 }
14209}
14210
14211/**
Rajeev Kumar98edb772016-01-19 12:42:19 -080014212 * __wlan_hdd_cfg80211_change_iface() - change interface cfg80211 op
14213 * @wiphy: Pointer to the wiphy structure
14214 * @ndev: Pointer to the net device
14215 * @type: Interface type
14216 * @flags: Flags for change interface
14217 * @params: Pointer to change interface parameters
14218 *
14219 * Return: 0 for success, error number on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014220 */
14221static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
14222 struct net_device *ndev,
14223 enum nl80211_iftype type,
14224 u32 *flags,
14225 struct vif_params *params)
14226{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014227 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Jeff Johnsonb8944722017-09-03 09:03:19 -070014228 struct hdd_context *hdd_ctx;
Dustin Brown56377e12018-10-10 17:04:04 -070014229 bool iff_up = ndev->flags & IFF_UP;
14230 enum QDF_OPMODE new_mode;
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +053014231 bool ap_random_bssid_enabled;
Dustin Brown56377e12018-10-10 17:04:04 -070014232 QDF_STATUS status;
Dustin Brown63fe4922018-10-12 15:02:26 -070014233 int errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014234
Dustin Brown491d54b2018-03-14 12:39:11 -070014235 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014236
Dustin Brown63fe4922018-10-12 15:02:26 -070014237 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
Jeff Johnson77848112016-06-29 14:52:06 -070014238 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014239 return -EINVAL;
14240 }
14241
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014242 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Dustin Brown2ab5a972018-10-09 17:19:37 -070014243 errno = wlan_hdd_validate_context(hdd_ctx);
14244 if (errno)
14245 return errno;
Nachiket Kukade08b9f292017-11-17 18:27:37 +053014246
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053014247 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
14248 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080014249 adapter->vdev_id, type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014250
Dustin Brown56377e12018-10-10 17:04:04 -070014251 status = hdd_nl_to_qdf_iface_type(type, &new_mode);
14252 if (QDF_IS_STATUS_ERROR(status))
14253 return qdf_status_to_os_return(status);
14254
Dustin Brown194aeca2018-10-12 15:37:36 -070014255 /* A userspace issue leads to it sending a 'change to station mode'
14256 * request on a "p2p" device, expecting the driver do execute a 'change
14257 * to p2p-device mode' request instead. The (unfortunate) work around
14258 * here is implemented by overriding the new mode if the net_device name
14259 * starts with "p2p" and the requested mode was station.
14260 */
14261 if (strnstr(ndev->name, "p2p", 3) && new_mode == QDF_STA_MODE)
14262 new_mode = QDF_P2P_DEVICE_MODE;
14263
Dustin Brown56377e12018-10-10 17:04:04 -070014264 hdd_debug("Changing mode for '%s' from %s to %s",
14265 ndev->name,
14266 qdf_opmode_str(adapter->device_mode),
14267 qdf_opmode_str(new_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014268
Rajeev Kumar473f9af2019-04-05 14:25:56 -070014269 errno = hdd_trigger_psoc_idle_restart(hdd_ctx);
Dustin Brown2ab5a972018-10-09 17:19:37 -070014270 if (errno) {
Dustin Brown3ecc8782018-09-19 16:37:13 -070014271 hdd_err("Failed to restart psoc; errno:%d", errno);
Arun Khandavallifae92942016-08-01 13:31:08 +053014272 return -EINVAL;
14273 }
14274
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014275 /* Reset the current device mode bit mask */
Dustin Brown2ab5a972018-10-09 17:19:37 -070014276 policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014277
Dustin Brown63fe4922018-10-12 15:02:26 -070014278 if (hdd_is_client_mode(adapter->device_mode)) {
14279 if (hdd_is_client_mode(new_mode)) {
Visweswara Tanukub5a61242019-03-26 12:24:13 +053014280 if (new_mode == QDF_IBSS_MODE) {
14281 hdd_deregister_hl_netdev_fc_timer(adapter);
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014282 hdd_deregister_tx_flow_control(adapter);
Visweswara Tanukub5a61242019-03-26 12:24:13 +053014283 }
Dustin Brown56377e12018-10-10 17:04:04 -070014284
14285 errno = hdd_change_adapter_mode(adapter, new_mode);
Liangwei Dong4d35cad2018-11-02 02:38:50 -040014286 if (errno) {
14287 hdd_err("change intf mode fail %d", errno);
14288 goto err;
14289 }
Dustin Brown63fe4922018-10-12 15:02:26 -070014290 } else if (hdd_is_ap_mode(new_mode)) {
14291 if (new_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014292 wlan_hdd_cancel_existing_remain_on_channel
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014293 (adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014294
Dustin Browndb2a8be2017-12-20 11:49:56 -080014295 hdd_stop_adapter(hdd_ctx, adapter);
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014296 hdd_deinit_adapter(hdd_ctx, adapter, true);
Dustin Brown2ab5a972018-10-09 17:19:37 -070014297 memset(&adapter->session, 0, sizeof(adapter->session));
Dustin Brown56377e12018-10-10 17:04:04 -070014298 adapter->device_mode = new_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014299
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +053014300 status = ucfg_mlme_get_ap_random_bssid_enable(
14301 hdd_ctx->psoc,
14302 &ap_random_bssid_enabled);
14303 if (QDF_IS_STATUS_ERROR(status))
14304 return qdf_status_to_os_return(status);
14305
Dustin Brown2ab5a972018-10-09 17:19:37 -070014306 if (adapter->device_mode == QDF_SAP_MODE &&
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +053014307 ap_random_bssid_enabled) {
Jeff Johnsonf3826e12017-01-12 09:49:40 -080014308 /* To meet Android requirements create
14309 * a randomized MAC address of the
14310 * form 02:1A:11:Fx:xx:xx
14311 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014312 get_random_bytes(&ndev->dev_addr[3], 3);
14313 ndev->dev_addr[0] = 0x02;
14314 ndev->dev_addr[1] = 0x1A;
14315 ndev->dev_addr[2] = 0x11;
14316 ndev->dev_addr[3] |= 0xF0;
Dustin Brown2ab5a972018-10-09 17:19:37 -070014317 memcpy(adapter->mac_addr.bytes, ndev->dev_addr,
Anurag Chouhan6d760662016-02-20 16:05:43 +053014318 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014319 pr_info("wlan: Generated HotSpot BSSID "
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070014320 QDF_MAC_ADDR_STR "\n",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070014321 QDF_MAC_ADDR_ARRAY(ndev->dev_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014322 }
14323
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014324 hdd_set_ap_ops(adapter->dev);
Dustin Brown63fe4922018-10-12 15:02:26 -070014325 } else {
Dustin Brown56377e12018-10-10 17:04:04 -070014326 hdd_err("Changing to device mode '%s' is not supported",
14327 qdf_opmode_str(new_mode));
Liangwei Dong4d35cad2018-11-02 02:38:50 -040014328 errno = -EOPNOTSUPP;
14329 goto err;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014330 }
Dustin Brown63fe4922018-10-12 15:02:26 -070014331 } else if (hdd_is_ap_mode(adapter->device_mode)) {
14332 if (hdd_is_client_mode(new_mode)) {
Dustin Brown56377e12018-10-10 17:04:04 -070014333 errno = hdd_change_adapter_mode(adapter, new_mode);
Liangwei Dong4d35cad2018-11-02 02:38:50 -040014334 if (errno) {
14335 hdd_err("change mode fail %d", errno);
14336 goto err;
14337 }
Dustin Brown63fe4922018-10-12 15:02:26 -070014338 } else if (hdd_is_ap_mode(new_mode)) {
Dustin Brown56377e12018-10-10 17:04:04 -070014339 adapter->device_mode = new_mode;
14340
Dustin Brown63fe4922018-10-12 15:02:26 -070014341 /* avoid starting the adapter, since it never stopped */
14342 iff_up = false;
14343 } else {
Dustin Brown56377e12018-10-10 17:04:04 -070014344 hdd_err("Changing to device mode '%s' is not supported",
14345 qdf_opmode_str(new_mode));
Liangwei Dong4d35cad2018-11-02 02:38:50 -040014346 errno = -EOPNOTSUPP;
14347 goto err;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014348 }
14349 } else {
Dustin Brown56377e12018-10-10 17:04:04 -070014350 hdd_err("Changing from device mode '%s' is not supported",
14351 qdf_opmode_str(adapter->device_mode));
Liangwei Dong4d35cad2018-11-02 02:38:50 -040014352 errno = -EOPNOTSUPP;
14353 goto err;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014354 }
Dustin Brown56377e12018-10-10 17:04:04 -070014355
Dustin Brown63fe4922018-10-12 15:02:26 -070014356 /* restart the adapter if it was up before the change iface request */
14357 if (iff_up) {
14358 errno = hdd_start_adapter(adapter);
14359 if (errno) {
14360 hdd_err("Failed to start adapter");
Liangwei Dong4d35cad2018-11-02 02:38:50 -040014361 errno = -EINVAL;
14362 goto err;
Dustin Brown63fe4922018-10-12 15:02:26 -070014363 }
14364 }
14365
14366 ndev->ieee80211_ptr->iftype = type;
Liangwei Dong4d35cad2018-11-02 02:38:50 -040014367 hdd_lpass_notify_mode_change(adapter);
14368err:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014369 /* Set bitmask based on updated value */
Dustin Brown2ab5a972018-10-09 17:19:37 -070014370 policy_mgr_set_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014371
Dustin Browne74003f2018-03-14 12:51:58 -070014372 hdd_exit();
Dustin Brown2ab5a972018-10-09 17:19:37 -070014373
Liangwei Dong4d35cad2018-11-02 02:38:50 -040014374 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014375}
14376
Dustin Brown0e1e1622019-01-17 11:00:22 -080014377static int _wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
14378 struct net_device *net_dev,
14379 enum nl80211_iftype type,
14380 u32 *flags,
14381 struct vif_params *params)
14382{
14383 int errno;
14384 struct osif_vdev_sync *vdev_sync;
14385
14386 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
14387 if (errno)
14388 return errno;
14389
Dustin Brown0e1e1622019-01-17 11:00:22 -080014390 errno = __wlan_hdd_cfg80211_change_iface(wiphy, net_dev, type,
14391 flags, params);
Dustin Brown0e1e1622019-01-17 11:00:22 -080014392
14393 osif_vdev_sync_trans_stop(vdev_sync);
14394
14395 return errno;
14396}
14397
Dustin Brown9ed30a52017-08-16 13:59:38 -070014398#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
Rajeev Kumar98edb772016-01-19 12:42:19 -080014399/**
14400 * wlan_hdd_cfg80211_change_iface() - change interface cfg80211 op
14401 * @wiphy: Pointer to the wiphy structure
14402 * @ndev: Pointer to the net device
14403 * @type: Interface type
14404 * @flags: Flags for change interface
14405 * @params: Pointer to change interface parameters
14406 *
14407 * Return: 0 for success, error number on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014408 */
14409static int wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
14410 struct net_device *ndev,
14411 enum nl80211_iftype type,
14412 u32 *flags,
14413 struct vif_params *params)
14414{
Dustin Brown0e1e1622019-01-17 11:00:22 -080014415 return _wlan_hdd_cfg80211_change_iface(wiphy, ndev, type,
14416 flags, params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014417}
Dustin Brown9ed30a52017-08-16 13:59:38 -070014418#else
14419static int wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy,
14420 struct net_device *ndev,
14421 enum nl80211_iftype type,
14422 struct vif_params *params)
14423{
Dustin Brown0e1e1622019-01-17 11:00:22 -080014424 return _wlan_hdd_cfg80211_change_iface(wiphy, ndev, type,
Dustin Brown9ed30a52017-08-16 13:59:38 -070014425 &params->flags, params);
Dustin Brown9ed30a52017-08-16 13:59:38 -070014426}
14427#endif /* KERNEL_VERSION(4, 12, 0) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014428
Ashish Kumar Dhanotiya42b03782018-01-16 10:55:16 +053014429QDF_STATUS wlan_hdd_send_sta_authorized_event(
14430 struct hdd_adapter *adapter,
14431 struct hdd_context *hdd_ctx,
14432 const struct qdf_mac_addr *mac_addr)
14433{
14434 struct sk_buff *vendor_event;
14435 QDF_STATUS status;
14436 struct nl80211_sta_flag_update sta_flags;
14437
14438 hdd_enter();
14439 if (!hdd_ctx) {
14440 hdd_err("HDD context is null");
14441 return QDF_STATUS_E_INVAL;
14442 }
14443
14444 vendor_event =
14445 cfg80211_vendor_event_alloc(
14446 hdd_ctx->wiphy, &adapter->wdev, sizeof(sta_flags) +
14447 QDF_MAC_ADDR_SIZE + NLMSG_HDRLEN,
14448 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
14449 GFP_KERNEL);
14450 if (!vendor_event) {
14451 hdd_err("cfg80211_vendor_event_alloc failed");
14452 return QDF_STATUS_E_FAILURE;
14453 }
14454
Ashish Kumar Dhanotiya0dd9b8b2019-06-04 20:21:06 +053014455 qdf_mem_zero(&sta_flags, sizeof(sta_flags));
14456
Ashish Kumar Dhanotiya42b03782018-01-16 10:55:16 +053014457 sta_flags.mask |= BIT(NL80211_STA_FLAG_AUTHORIZED);
14458 sta_flags.set = true;
14459
14460 status = nla_put(vendor_event,
14461 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
14462 sizeof(struct nl80211_sta_flag_update),
14463 &sta_flags);
14464 if (status) {
14465 hdd_err("STA flag put fails");
14466 kfree_skb(vendor_event);
14467 return QDF_STATUS_E_FAILURE;
14468 }
14469 status = nla_put(vendor_event,
14470 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_MAC_ADDR,
14471 QDF_MAC_ADDR_SIZE, mac_addr->bytes);
14472 if (status) {
14473 hdd_err("STA MAC put fails");
14474 kfree_skb(vendor_event);
14475 return QDF_STATUS_E_FAILURE;
14476 }
14477
14478 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
14479
14480 hdd_exit();
14481 return QDF_STATUS_SUCCESS;
14482}
14483
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014484/**
14485 * __wlan_hdd_change_station() - change station
14486 * @wiphy: Pointer to the wiphy structure
14487 * @dev: Pointer to the net device.
14488 * @mac: bssid
14489 * @params: Pointer to station parameters
14490 *
14491 * Return: 0 for success, error number on failure.
14492 */
14493#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
14494static int __wlan_hdd_change_station(struct wiphy *wiphy,
14495 struct net_device *dev,
14496 const uint8_t *mac,
14497 struct station_parameters *params)
14498#else
14499static int __wlan_hdd_change_station(struct wiphy *wiphy,
14500 struct net_device *dev,
14501 uint8_t *mac,
14502 struct station_parameters *params)
14503#endif
14504{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053014505 QDF_STATUS status = QDF_STATUS_SUCCESS;
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014506 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsonb8944722017-09-03 09:03:19 -070014507 struct hdd_context *hdd_ctx;
Jeff Johnsond377dce2017-10-04 10:32:42 -070014508 struct hdd_station_ctx *sta_ctx;
Vignesh Viswanathan597d9012018-07-06 15:26:08 +053014509 struct hdd_ap_ctx *ap_ctx;
Jeff Johnsonf31df632019-03-23 11:53:28 -070014510 struct qdf_mac_addr sta_macaddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014511 int ret;
14512
Dustin Brown491d54b2018-03-14 12:39:11 -070014513 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014514
Anurag Chouhan6d760662016-02-20 16:05:43 +053014515 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070014516 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014517 return -EINVAL;
14518 }
14519
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053014520 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
14521 TRACE_CODE_HDD_CHANGE_STATION,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080014522 adapter->vdev_id, params->listen_interval);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014523
Jeff Johnson48363022019-02-24 16:26:51 -080014524 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053014525 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053014526
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014527 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnsonb8944722017-09-03 09:03:19 -070014528 ret = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053014529 if (0 != ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014530 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014531
Jeff Johnsond377dce2017-10-04 10:32:42 -070014532 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014533
Jeff Johnsonf31df632019-03-23 11:53:28 -070014534 qdf_mem_copy(sta_macaddr.bytes, mac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014535
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014536 if ((adapter->device_mode == QDF_SAP_MODE) ||
14537 (adapter->device_mode == QDF_P2P_GO_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014538 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
Vignesh Viswanathan597d9012018-07-06 15:26:08 +053014539 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
14540 /*
14541 * For Encrypted SAP session, this will be done as
14542 * part of eSAP_STA_SET_KEY_EVENT
14543 */
14544 if (ap_ctx->encryption_type !=
14545 eCSR_ENCRYPT_TYPE_NONE) {
14546 hdd_debug("Encrypt type %d, not setting peer authorized now",
14547 ap_ctx->encryption_type);
14548 return 0;
14549 }
14550
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014551 status =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014552 hdd_softap_change_sta_state(adapter,
Jeff Johnsonf31df632019-03-23 11:53:28 -070014553 &sta_macaddr,
Dhanashri Atreb08959a2016-03-01 17:28:03 -080014554 OL_TXRX_PEER_STATE_AUTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014555
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053014556 if (status != QDF_STATUS_SUCCESS) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080014557 hdd_debug("Not able to change TL state to AUTHENTICATED");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014558 return -EINVAL;
14559 }
Ashish Kumar Dhanotiya42b03782018-01-16 10:55:16 +053014560 status = wlan_hdd_send_sta_authorized_event(
14561 adapter,
14562 hdd_ctx,
Jeff Johnsonf31df632019-03-23 11:53:28 -070014563 &sta_macaddr);
Ashish Kumar Dhanotiya42b03782018-01-16 10:55:16 +053014564 if (status != QDF_STATUS_SUCCESS) {
14565 return -EINVAL;
14566 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014567 }
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014568 } else if ((adapter->device_mode == QDF_STA_MODE) ||
14569 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014570 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Frank Liud1a28462017-09-06 22:55:48 +080014571#if defined(FEATURE_WLAN_TDLS)
Min Liu8c5d99e2018-09-10 17:18:44 +080014572 struct wlan_objmgr_vdev *vdev;
14573
14574 vdev = hdd_objmgr_get_vdev(adapter);
14575 if (!vdev)
14576 return -EINVAL;
14577 ret = wlan_cfg80211_tdls_update_peer(vdev, mac, params);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +053014578 hdd_objmgr_put_vdev(vdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014579#endif
Frank Liud4b2fa02017-03-29 11:46:48 +080014580 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014581 }
Dustin Browne74003f2018-03-14 12:51:58 -070014582 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014583 return ret;
14584}
14585
14586/**
14587 * wlan_hdd_change_station() - cfg80211 change station handler function
14588 * @wiphy: Pointer to the wiphy structure
14589 * @dev: Pointer to the net device.
14590 * @mac: bssid
14591 * @params: Pointer to station parameters
14592 *
14593 * This is the cfg80211 change station handler function which invokes
14594 * the internal function @__wlan_hdd_change_station with
14595 * SSR protection.
14596 *
14597 * Return: 0 for success, error number on failure.
14598 */
14599#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0)) || defined(WITH_BACKPORTS)
14600static int wlan_hdd_change_station(struct wiphy *wiphy,
14601 struct net_device *dev,
14602 const u8 *mac,
14603 struct station_parameters *params)
14604#else
14605static int wlan_hdd_change_station(struct wiphy *wiphy,
14606 struct net_device *dev,
14607 u8 *mac,
14608 struct station_parameters *params)
14609#endif
14610{
Dustin Brown1d31b082018-11-22 14:41:20 +053014611 int errno;
14612 struct osif_vdev_sync *vdev_sync;
14613
14614 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
14615 if (errno)
14616 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014617
Dustin Brown1d31b082018-11-22 14:41:20 +053014618 errno = __wlan_hdd_change_station(wiphy, dev, mac, params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014619
Dustin Brown1d31b082018-11-22 14:41:20 +053014620 osif_vdev_sync_op_stop(vdev_sync);
14621
14622 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014623}
14624
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014625#ifdef CRYPTO_SET_KEY_CONVERGED
14626#ifdef FEATURE_WLAN_ESE
14627static bool hdd_is_krk_enc_type(uint32_t cipher_type)
14628{
14629 if (cipher_type == WLAN_CIPHER_SUITE_KRK)
14630 return true;
14631
14632 return false;
14633}
14634#else
14635static bool hdd_is_krk_enc_type(uint32_t cipher_type)
14636{
14637 return false;
14638}
14639#endif
14640
14641#if defined(FEATURE_WLAN_ESE) && defined(WLAN_FEATURE_ROAM_OFFLOAD)
14642static bool hdd_is_btk_enc_type(uint32_t cipher_type)
14643{
14644 if (cipher_type == WLAN_CIPHER_SUITE_BTK)
14645 return true;
14646
14647 return false;
14648}
14649#else
14650static bool hdd_is_btk_enc_type(uint32_t cipher_type)
14651{
14652 return false;
14653}
14654#endif
14655#endif
14656
14657#ifdef CRYPTO_SET_KEY_CONVERGED
14658static int wlan_hdd_add_key_ibss(struct hdd_adapter *adapter,
14659 bool pairwise, u8 key_index,
14660 const u8 *mac_addr, struct key_params *params,
14661 bool *key_already_installed)
14662{
14663 struct wlan_objmgr_vdev *vdev;
14664 int errno;
14665
14666 if (pairwise)
14667 return 0;
14668 /* if a key is already installed, block all subsequent ones */
14669 if (adapter->session.station.ibss_enc_key_installed) {
14670 hdd_debug("IBSS key installed already");
14671 *key_already_installed = true;
14672 return 0;
14673 }
14674 /*Set the group key */
14675 vdev = hdd_objmgr_get_vdev(adapter);
14676 if (!vdev)
14677 return -EINVAL;
Kiran Kumar Lokere47d0dac2019-01-24 18:38:33 -080014678 errno = wlan_cfg80211_crypto_add_key(vdev, WLAN_CRYPTO_KEY_TYPE_GROUP,
14679 key_index);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014680 if (errno) {
14681 hdd_err("add_ibss_key failed, errno: %d", errno);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +053014682 hdd_objmgr_put_vdev(vdev);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014683 return errno;
14684 }
14685 /* Save the keys here and call set_key for setting
14686 * the PTK after peer joins the IBSS network
14687 */
Kiran Kumar Lokere47d0dac2019-01-24 18:38:33 -080014688 wlan_cfg80211_store_key(vdev, key_index, WLAN_CRYPTO_KEY_TYPE_UNICAST,
14689 mac_addr, params);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +053014690 hdd_objmgr_put_vdev(vdev);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014691 adapter->session.station.ibss_enc_key_installed = 1;
14692
14693 return 0;
14694}
14695
14696static int wlan_hdd_add_key_sap(struct hdd_adapter *adapter,
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080014697 bool pairwise, u8 key_index,
14698 enum wlan_crypto_cipher_type cipher)
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014699{
14700 struct wlan_objmgr_vdev *vdev;
14701 int errno = 0;
14702 struct hdd_hostapd_state *hostapd_state =
14703 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
14704
14705 vdev = hdd_objmgr_get_vdev(adapter);
14706 if (!vdev)
14707 return -EINVAL;
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080014708 if (hostapd_state->bss_state == BSS_START) {
Kiran Kumar Lokere47d0dac2019-01-24 18:38:33 -080014709 errno =
14710 wlan_cfg80211_crypto_add_key(vdev, (pairwise ?
14711 WLAN_CRYPTO_KEY_TYPE_UNICAST :
14712 WLAN_CRYPTO_KEY_TYPE_GROUP),
14713 key_index);
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080014714 if (!errno)
14715 wma_update_set_key(adapter->vdev_id, pairwise,
14716 key_index, cipher);
14717 }
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +053014718 hdd_objmgr_put_vdev(vdev);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014719
14720 return errno;
14721}
14722
14723static int wlan_hdd_add_key_sta(struct hdd_adapter *adapter,
14724 bool pairwise, u8 key_index,
14725 mac_handle_t mac_handle, bool *ft_mode)
14726{
14727 struct wlan_objmgr_vdev *vdev;
14728 struct hdd_station_ctx *sta_ctx =
14729 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
14730 int errno;
14731 QDF_STATUS status;
14732
14733 if (!pairwise) {
14734 /* set group key */
14735 if (sta_ctx->roam_info.defer_key_complete) {
14736 hdd_debug("Perform Set key Complete");
14737 hdd_perform_roam_set_key_complete(adapter);
14738 }
14739 }
14740 /* The supplicant may attempt to set the PTK once
14741 * pre-authentication is done. Save the key in the
14742 * UMAC and include it in the ADD BSS request
14743 */
Jeff Johnsoncf07c312019-02-04 13:53:29 -080014744 status = sme_check_ft_status(mac_handle, adapter->vdev_id);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014745 if (status == QDF_STATUS_SUCCESS) {
14746 *ft_mode = true;
14747 return 0;
14748 }
14749 vdev = hdd_objmgr_get_vdev(adapter);
14750 if (!vdev)
14751 return -EINVAL;
Kiran Kumar Lokere47d0dac2019-01-24 18:38:33 -080014752 errno = wlan_cfg80211_crypto_add_key(vdev, (pairwise ?
14753 WLAN_CRYPTO_KEY_TYPE_UNICAST :
14754 WLAN_CRYPTO_KEY_TYPE_GROUP),
14755 key_index);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +053014756 hdd_objmgr_put_vdev(vdev);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014757 if (!errno && adapter->send_mode_change) {
14758 wlan_hdd_send_mode_change_event();
14759 adapter->send_mode_change = false;
14760 }
14761
14762 return errno;
14763}
14764
14765static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
14766 struct net_device *ndev,
14767 u8 key_index, bool pairwise,
14768 const u8 *mac_addr,
14769 struct key_params *params)
14770{
14771 struct hdd_context *hdd_ctx;
14772 mac_handle_t mac_handle;
14773 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
14774 struct wlan_objmgr_vdev *vdev;
14775 bool key_already_installed = false, ft_mode = false;
14776 enum wlan_crypto_cipher_type cipher;
14777 int errno;
Kiran Kumar Lokere47d0dac2019-01-24 18:38:33 -080014778 struct qdf_mac_addr mac_address;
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014779
14780 hdd_enter();
14781
14782 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
14783 hdd_err("Command not allowed in FTM mode");
14784 return -EINVAL;
14785 }
14786
Jeff Johnson48363022019-02-24 16:26:51 -080014787 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014788 return -EINVAL;
14789
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053014790 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
14791 TRACE_CODE_HDD_CFG80211_ADD_KEY,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080014792 adapter->vdev_id, params->key_len);
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053014793
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014794 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14795 errno = wlan_hdd_validate_context(hdd_ctx);
14796 if (errno)
14797 return errno;
14798
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080014799 hdd_debug("converged Device_mode %s(%d) index %d, pairwise %d",
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014800 qdf_opmode_str(adapter->device_mode),
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080014801 adapter->device_mode, key_index, pairwise);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014802 mac_handle = hdd_ctx->mac_handle;
14803
14804 if (hdd_is_btk_enc_type(params->cipher))
Jeff Johnsoncf07c312019-02-04 13:53:29 -080014805 return sme_add_key_btk(mac_handle, adapter->vdev_id,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014806 params->key, params->key_len);
14807 if (hdd_is_krk_enc_type(params->cipher))
Jeff Johnsoncf07c312019-02-04 13:53:29 -080014808 return sme_add_key_krk(mac_handle, adapter->vdev_id,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014809 params->key, params->key_len);
14810
14811 vdev = hdd_objmgr_get_vdev(adapter);
14812 if (!vdev)
14813 return -EINVAL;
Kiran Kumar Lokere47d0dac2019-01-24 18:38:33 -080014814 if (!pairwise && ((adapter->device_mode == QDF_STA_MODE) ||
14815 (adapter->device_mode == QDF_P2P_CLIENT_MODE))) {
14816 qdf_mem_copy(mac_address.bytes,
Jeff Johnsone04b6992019-02-27 14:06:55 -080014817 adapter->session.station.conn_info.bssid.bytes,
Kiran Kumar Lokere47d0dac2019-01-24 18:38:33 -080014818 QDF_MAC_ADDR_SIZE);
14819 } else {
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080014820 if (mac_addr)
14821 qdf_mem_copy(mac_address.bytes, mac_addr,
14822 QDF_MAC_ADDR_SIZE);
Kiran Kumar Lokere47d0dac2019-01-24 18:38:33 -080014823 }
14824 errno = wlan_cfg80211_store_key(vdev, key_index,
14825 (pairwise ?
14826 WLAN_CRYPTO_KEY_TYPE_UNICAST :
14827 WLAN_CRYPTO_KEY_TYPE_GROUP),
14828 mac_address.bytes, params);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +053014829 hdd_objmgr_put_vdev(vdev);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014830 if (errno)
14831 return errno;
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080014832 cipher = osif_nl_to_crypto_cipher_type(params->cipher);
Abhishek Singhf880a7d2019-04-29 14:51:11 +053014833 if (pairwise)
14834 wma_set_peer_ucast_cipher(mac_address.bytes, cipher);
14835
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014836 switch (adapter->device_mode) {
14837 case QDF_IBSS_MODE:
14838 errno = wlan_hdd_add_key_ibss(adapter, pairwise, key_index,
14839 mac_addr, params,
14840 &key_already_installed);
14841 if (key_already_installed)
14842 return 0;
14843 break;
14844 case QDF_SAP_MODE:
14845 case QDF_P2P_GO_MODE:
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080014846 errno = wlan_hdd_add_key_sap(adapter, pairwise,
14847 key_index, cipher);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014848 break;
14849 case QDF_STA_MODE:
14850 case QDF_P2P_CLIENT_MODE:
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080014851 errno = wlan_hdd_add_key_sta(adapter, pairwise, key_index,
14852 mac_handle, &ft_mode);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014853 if (ft_mode)
14854 return 0;
14855 break;
14856 default:
14857 break;
14858 }
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080014859 if (!errno && (adapter->device_mode != QDF_SAP_MODE))
Jeff Johnsoncf07c312019-02-04 13:53:29 -080014860 wma_update_set_key(adapter->vdev_id, pairwise, key_index,
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014861 cipher);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014862 hdd_exit();
14863
14864 return errno;
14865}
14866#else /* !CRYPTO_SET_KEY_CONVERGED */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014867/*
14868 * FUNCTION: __wlan_hdd_cfg80211_add_key
14869 * This function is used to initialize the key information
14870 */
14871static int __wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
14872 struct net_device *ndev,
14873 u8 key_index, bool pairwise,
14874 const u8 *mac_addr,
14875 struct key_params *params)
14876{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014877 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Jeff Johnson89515092019-03-23 10:52:04 -070014878 tCsrRoamSetKey set_key;
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014879 int errno;
Jeff Johnson29c78672019-02-26 21:05:53 -080014880 uint32_t roam_id = INVALID_ROAM_ID;
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014881 QDF_STATUS status;
Jeff Johnsonb8944722017-09-03 09:03:19 -070014882 struct hdd_context *hdd_ctx;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070014883 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014884
Dustin Brown491d54b2018-03-14 12:39:11 -070014885 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014886
Anurag Chouhan6d760662016-02-20 16:05:43 +053014887 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070014888 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014889 return -EINVAL;
14890 }
14891
Jeff Johnson48363022019-02-24 16:26:51 -080014892 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053014893 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053014894
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053014895 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
14896 TRACE_CODE_HDD_CFG80211_ADD_KEY,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080014897 adapter->vdev_id, params->key_len);
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053014898
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014899 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014900 errno = wlan_hdd_validate_context(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014901
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070014902 if (errno)
14903 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014904
Srinivas Girigowda13d39252017-03-06 16:12:15 -080014905 hdd_debug("Device_mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -070014906 qdf_opmode_str(adapter->device_mode), adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014907
14908 if (CSR_MAX_NUM_KEY <= key_index) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070014909 hdd_err("Invalid key index %d", key_index);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014910
14911 return -EINVAL;
14912 }
14913
14914 if (CSR_MAX_KEY_LEN < params->key_len) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070014915 hdd_err("Invalid key length %d", params->key_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014916
14917 return -EINVAL;
14918 }
14919
Srinivas Girigowdacf161402019-03-14 11:37:33 -070014920 if (WLAN_CRYPTO_RSC_SIZE < params->seq_len) {
Jeff Johnsonb05f4fd2017-10-18 15:08:21 -070014921 hdd_err("Invalid seq length %d", params->seq_len);
14922
14923 return -EINVAL;
14924 }
14925
14926 hdd_debug("key index %d, key length %d, seq length %d",
14927 key_index, params->key_len, params->seq_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014928
14929 /*extract key idx, key len and key */
Jeff Johnson89515092019-03-23 10:52:04 -070014930 qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey));
14931 set_key.keyId = key_index;
14932 set_key.keyLength = params->key_len;
14933 qdf_mem_copy(&set_key.Key[0], params->key, params->key_len);
14934 qdf_mem_copy(&set_key.keyRsc[0], params->seq, params->seq_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014935
Jeff Johnson34fc63a2018-06-14 10:10:02 -070014936 mac_handle = hdd_ctx->mac_handle;
14937
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014938 switch (params->cipher) {
14939 case WLAN_CIPHER_SUITE_WEP40:
Jeff Johnson89515092019-03-23 10:52:04 -070014940 set_key.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014941 break;
14942
14943 case WLAN_CIPHER_SUITE_WEP104:
Jeff Johnson89515092019-03-23 10:52:04 -070014944 set_key.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014945 break;
14946
14947 case WLAN_CIPHER_SUITE_TKIP:
14948 {
Jeff Johnson675072b2019-03-23 11:47:35 -070014949 u8 *key = &set_key.Key[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014950
Jeff Johnson89515092019-03-23 10:52:04 -070014951 set_key.encType = eCSR_ENCRYPT_TYPE_TKIP;
Jeff Johnson675072b2019-03-23 11:47:35 -070014952 qdf_mem_zero(key, CSR_MAX_KEY_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014953
Jeff Johnsonf3826e12017-01-12 09:49:40 -080014954 /* Supplicant sends the 32bytes key in this order
14955 *
14956 * |--------------|----------|----------|
14957 * | Tk1 |TX-MIC | RX Mic |
14958 * |--------------|----------|----------|
14959 * <---16bytes---><--8bytes--><--8bytes-->
14960 *
14961 * Sme expects the 32 bytes key to be in the below order
14962 *
14963 * |--------------|----------|----------|
14964 * | Tk1 |RX-MIC | TX Mic |
14965 * |--------------|----------|----------|
14966 * <---16bytes---><--8bytes--><--8bytes-->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014967 */
14968 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnson675072b2019-03-23 11:47:35 -070014969 qdf_mem_copy(key, params->key, 16);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014970
14971 /*Copy the rx mic first */
Jeff Johnson675072b2019-03-23 11:47:35 -070014972 qdf_mem_copy(&key[16], &params->key[24], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014973
14974 /*Copy the tx mic */
Jeff Johnson675072b2019-03-23 11:47:35 -070014975 qdf_mem_copy(&key[24], &params->key[16], 8);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014976
14977 break;
14978 }
14979
14980 case WLAN_CIPHER_SUITE_CCMP:
Jeff Johnson89515092019-03-23 10:52:04 -070014981 set_key.encType = eCSR_ENCRYPT_TYPE_AES;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014982 break;
14983
14984#ifdef FEATURE_WLAN_WAPI
14985 case WLAN_CIPHER_SUITE_SMS4:
14986 {
Jeff Johnson89515092019-03-23 10:52:04 -070014987 qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey));
Jeff Johnsonce2ba702017-10-02 13:30:24 -070014988 wlan_hdd_cfg80211_set_key_wapi(adapter, key_index,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014989 mac_addr, params->key,
14990 params->key_len);
14991 return 0;
14992 }
14993#endif
14994
14995#ifdef FEATURE_WLAN_ESE
14996 case WLAN_CIPHER_SUITE_KRK:
Jeff Johnson89515092019-03-23 10:52:04 -070014997 set_key.encType = eCSR_ENCRYPT_TYPE_KRK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080014998 break;
14999#ifdef WLAN_FEATURE_ROAM_OFFLOAD
15000 case WLAN_CIPHER_SUITE_BTK:
Jeff Johnson89515092019-03-23 10:52:04 -070015001 set_key.encType = eCSR_ENCRYPT_TYPE_BTK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015002 break;
15003#endif
15004#endif
15005
15006#ifdef WLAN_FEATURE_11W
15007 case WLAN_CIPHER_SUITE_AES_CMAC:
Jeff Johnson89515092019-03-23 10:52:04 -070015008 set_key.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015009 break;
Padma, Santhosh Kumar4117d7a2017-12-20 17:39:33 +053015010#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
15011 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
Jeff Johnson89515092019-03-23 10:52:04 -070015012 set_key.encType = eCSR_ENCRYPT_TYPE_AES_GMAC_128;
Padma, Santhosh Kumar4117d7a2017-12-20 17:39:33 +053015013 break;
15014 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
Jeff Johnson89515092019-03-23 10:52:04 -070015015 set_key.encType = eCSR_ENCRYPT_TYPE_AES_GMAC_256;
Padma, Santhosh Kumar4117d7a2017-12-20 17:39:33 +053015016 break;
15017#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015018#endif
Mukul Sharma05504ac2017-06-08 12:35:53 +053015019 case WLAN_CIPHER_SUITE_GCMP:
Jeff Johnson89515092019-03-23 10:52:04 -070015020 set_key.encType = eCSR_ENCRYPT_TYPE_AES_GCMP;
Mukul Sharma05504ac2017-06-08 12:35:53 +053015021 break;
15022 case WLAN_CIPHER_SUITE_GCMP_256:
Jeff Johnson89515092019-03-23 10:52:04 -070015023 set_key.encType = eCSR_ENCRYPT_TYPE_AES_GCMP_256;
Mukul Sharma05504ac2017-06-08 12:35:53 +053015024 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015025
15026 default:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015027 hdd_err("Unsupported cipher type: %u", params->cipher);
Jeff Johnson89515092019-03-23 10:52:04 -070015028 qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015029 return -EOPNOTSUPP;
15030 }
15031
Jeff Johnson89515092019-03-23 10:52:04 -070015032 hdd_debug("encryption type %d", set_key.encType);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015033
15034 if (!pairwise) {
15035 /* set group key */
Jeff Johnson96aa2ac2017-10-18 15:55:36 -070015036 hdd_debug("setting Broadcast key");
Jeff Johnson89515092019-03-23 10:52:04 -070015037 set_key.keyDirection = eSIR_RX_ONLY;
15038 qdf_set_macaddr_broadcast(&set_key.peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015039 } else {
15040 /* set pairwise key */
Jeff Johnson96aa2ac2017-10-18 15:55:36 -070015041 hdd_debug("setting pairwise key");
Jeff Johnson89515092019-03-23 10:52:04 -070015042 set_key.keyDirection = eSIR_TX_RX;
15043 qdf_mem_copy(set_key.peerMac.bytes, mac_addr, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015044 }
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015045 if ((QDF_IBSS_MODE == adapter->device_mode) && !pairwise) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015046 /* if a key is already installed, block all subsequent ones */
Jeff Johnsonb9424862017-10-30 08:49:35 -070015047 if (adapter->session.station.ibss_enc_key_installed) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015048 hdd_debug("IBSS key installed already");
Jeff Johnson89515092019-03-23 10:52:04 -070015049 qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015050 return 0;
15051 }
15052
Jeff Johnson89515092019-03-23 10:52:04 -070015053 set_key.keyDirection = eSIR_TX_RX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015054 /*Set the group key */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070015055 status = sme_roam_set_key(mac_handle,
Jeff Johnson89515092019-03-23 10:52:04 -070015056 adapter->vdev_id, &set_key, &roam_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015057
15058 if (0 != status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015059 hdd_err("sme_roam_set_key failed, status: %d", status);
Jeff Johnson89515092019-03-23 10:52:04 -070015060 qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015061 return -EINVAL;
15062 }
Jeff Johnsonf3826e12017-01-12 09:49:40 -080015063 /* Save the keys here and call sme_roam_set_key for setting
15064 * the PTK after peer joins the IBSS network
15065 */
Jeff Johnsonb9424862017-10-30 08:49:35 -070015066 qdf_mem_copy(&adapter->session.station.ibss_enc_key,
Jeff Johnson89515092019-03-23 10:52:04 -070015067 &set_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015068
Jeff Johnsonb9424862017-10-30 08:49:35 -070015069 adapter->session.station.ibss_enc_key_installed = 1;
Jeff Johnson89515092019-03-23 10:52:04 -070015070 qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey));
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015071 return qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015072 }
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015073 if ((adapter->device_mode == QDF_SAP_MODE) ||
15074 (adapter->device_mode == QDF_P2P_GO_MODE)) {
Nachiket Kukaded9152832017-10-16 16:18:22 +053015075 struct hdd_hostapd_state *hostapd_state =
15076 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
15077 struct hdd_ap_ctx *ap_ctx =
15078 WLAN_HDD_GET_AP_CTX_PTR(adapter);
15079
Jeff Johnson0f9f87b2017-10-28 09:21:06 -070015080 if (hostapd_state->bss_state == BSS_START) {
Dustin Brown6ba30a12016-09-13 13:59:43 -070015081 status = wlansap_set_key_sta(
Jeff Johnson89515092019-03-23 10:52:04 -070015082 WLAN_HDD_GET_SAP_CTX_PTR(adapter), &set_key);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053015083 if (status != QDF_STATUS_SUCCESS) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015084 hdd_err("wlansap_set_key_sta failed status: %d",
15085 status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015086 }
15087 }
15088
Jeff Johnson413c15f2017-10-27 18:56:35 -070015089 /* Save the key in ap ctx for use on START_BSS and restart */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015090 if (pairwise ||
Jeff Johnson89515092019-03-23 10:52:04 -070015091 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == set_key.encType ||
15092 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == set_key.encType)
15093 qdf_mem_copy(&ap_ctx->wep_key[key_index], &set_key,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015094 sizeof(tCsrRoamSetKey));
15095 else
Jeff Johnson89515092019-03-23 10:52:04 -070015096 qdf_mem_copy(&ap_ctx->group_key, &set_key,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015097 sizeof(tCsrRoamSetKey));
15098
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015099 } else if ((adapter->device_mode == QDF_STA_MODE) ||
15100 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Jeff Johnsond377dce2017-10-04 10:32:42 -070015101 struct hdd_station_ctx *sta_ctx =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015102 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnson20227a92018-03-13 09:41:05 -070015103 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015104
15105 if (!pairwise) {
15106 /* set group key */
Jeff Johnsonaf2ae4b2017-11-01 11:38:50 -070015107 if (sta_ctx->roam_info.defer_key_complete) {
Jeff Johnson96aa2ac2017-10-18 15:55:36 -070015108 hdd_debug("Perform Set key Complete");
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015109 hdd_perform_roam_set_key_complete(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015110 }
15111 }
15112
Jeff Johnson20227a92018-03-13 09:41:05 -070015113 roam_profile = hdd_roam_profile(adapter);
15114 roam_profile->Keys.KeyLength[key_index] = params->key_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015115
Jeff Johnson20227a92018-03-13 09:41:05 -070015116 roam_profile->Keys.defaultIndex = key_index;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015117
Jeff Johnson20227a92018-03-13 09:41:05 -070015118 qdf_mem_copy(&roam_profile->Keys.KeyMaterial[key_index][0],
15119 params->key, params->key_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015120
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070015121 hdd_debug("Set key for peerMac "QDF_MAC_ADDR_STR" direction %d",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070015122 QDF_MAC_ADDR_ARRAY(set_key.peerMac.bytes),
15123 set_key.keyDirection);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015124
Jeff Johnsonf3826e12017-01-12 09:49:40 -080015125 /* The supplicant may attempt to set the PTK once
15126 * pre-authentication is done. Save the key in the
15127 * UMAC and include it in the ADD BSS request
15128 */
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015129 status = sme_ft_update_key(mac_handle,
Jeff Johnson89515092019-03-23 10:52:04 -070015130 adapter->vdev_id, &set_key);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015131 if (status == QDF_STATUS_FT_PREAUTH_KEY_SUCCESS) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015132 hdd_debug("Update PreAuth Key success");
Jeff Johnson89515092019-03-23 10:52:04 -070015133 qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015134 return 0;
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015135 } else if (status == QDF_STATUS_FT_PREAUTH_KEY_FAILED) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070015136 hdd_err("Update PreAuth Key failed");
Jeff Johnson89515092019-03-23 10:52:04 -070015137 qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015138 return -EINVAL;
15139 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015140
15141 /* issue set key request to SME */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070015142 status = sme_roam_set_key(mac_handle,
Jeff Johnson89515092019-03-23 10:52:04 -070015143 adapter->vdev_id, &set_key,
Jeff Johnson29c78672019-02-26 21:05:53 -080015144 &roam_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015145
15146 if (0 != status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015147 hdd_err("sme_roam_set_key failed, status: %d", status);
Jeff Johnson89515092019-03-23 10:52:04 -070015148 qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015149 return -EINVAL;
15150 }
15151
Yeshwanth Sriram Guntuka4fe30bd2018-06-13 11:41:42 +053015152 if (adapter->send_mode_change) {
15153 wlan_hdd_send_mode_change_event();
15154 adapter->send_mode_change = false;
15155 }
15156
Jeff Johnsonf3826e12017-01-12 09:49:40 -080015157 /* in case of IBSS as there was no information
15158 * available about WEP keys during IBSS join, group
Jeff Johnson5e19a942018-05-06 15:37:39 -070015159 * key initialized with NULL key, so re-initialize
Jeff Johnsonf3826e12017-01-12 09:49:40 -080015160 * group key with correct value
15161 */
Jeff Johnson20227a92018-03-13 09:41:05 -070015162 if ((eCSR_BSS_TYPE_START_IBSS == roam_profile->BSSType) &&
Jeff Johnson37ecea42018-03-18 17:54:40 -070015163 !((HDD_AUTH_KEY_MGMT_802_1X ==
15164 (sta_ctx->auth_key_mgmt & HDD_AUTH_KEY_MGMT_802_1X))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015165 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
Jeff Johnson96e33512019-02-27 15:10:21 -080015166 sta_ctx->conn_info.auth_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015167 )
15168 && ((WLAN_CIPHER_SUITE_WEP40 == params->cipher)
15169 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
15170 )
15171 ) {
Jeff Johnson89515092019-03-23 10:52:04 -070015172 set_key.keyDirection = eSIR_RX_ONLY;
15173 qdf_set_macaddr_broadcast(&set_key.peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015174
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070015175 hdd_debug("Set key peerMac "QDF_MAC_ADDR_STR" direction %d",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070015176 QDF_MAC_ADDR_ARRAY(set_key.peerMac.bytes),
Jeff Johnson89515092019-03-23 10:52:04 -070015177 set_key.keyDirection);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015178
Jeff Johnson34fc63a2018-06-14 10:10:02 -070015179 status = sme_roam_set_key(mac_handle,
Jeff Johnson89515092019-03-23 10:52:04 -070015180 adapter->vdev_id, &set_key,
Jeff Johnson29c78672019-02-26 21:05:53 -080015181 &roam_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015182
15183 if (0 != status) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070015184 hdd_err("sme_roam_set_key failed for group key (IBSS), returned %d", status);
Jeff Johnson89515092019-03-23 10:52:04 -070015185 qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015186 return -EINVAL;
15187 }
15188 }
15189 }
Jeff Johnson89515092019-03-23 10:52:04 -070015190 qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey));
Dustin Browne74003f2018-03-14 12:51:58 -070015191 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015192 return 0;
15193}
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015194#endif /* CRYPTO_SET_KEY_CONVERGED */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015195
15196static int wlan_hdd_cfg80211_add_key(struct wiphy *wiphy,
15197 struct net_device *ndev,
15198 u8 key_index, bool pairwise,
15199 const u8 *mac_addr,
15200 struct key_params *params)
15201{
Dustin Brown1d31b082018-11-22 14:41:20 +053015202 int errno;
15203 struct osif_vdev_sync *vdev_sync;
15204
15205 errno = osif_vdev_sync_op_start(ndev, &vdev_sync);
15206 if (errno)
15207 return errno;
Srinivas Girigowda576b2352017-08-25 14:44:26 -070015208
Dustin Brown1d31b082018-11-22 14:41:20 +053015209 errno = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
15210 mac_addr, params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015211
Dustin Brown1d31b082018-11-22 14:41:20 +053015212 osif_vdev_sync_op_stop(vdev_sync);
15213
15214 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015215}
15216
15217/*
15218 * FUNCTION: __wlan_hdd_cfg80211_get_key
15219 * This function is used to get the key information
15220 */
15221static int __wlan_hdd_cfg80211_get_key(struct wiphy *wiphy,
15222 struct net_device *ndev,
15223 u8 key_index, bool pairwise,
15224 const u8 *mac_addr, void *cookie,
15225 void (*callback)(void *cookie,
15226 struct key_params *)
15227 )
15228{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015229 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Jeff Johnson61b5e982018-03-15 11:33:31 -070015230 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015231 struct key_params params;
15232
Dustin Brown491d54b2018-03-14 12:39:11 -070015233 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015234
Anurag Chouhan6d760662016-02-20 16:05:43 +053015235 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070015236 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015237 return -EINVAL;
15238 }
15239
Jeff Johnson48363022019-02-24 16:26:51 -080015240 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Jiachao Wud58cfc92017-12-27 14:15:23 +080015241 return -EINVAL;
Jiachao Wud58cfc92017-12-27 14:15:23 +080015242
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015243 hdd_debug("Device_mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -070015244 qdf_opmode_str(adapter->device_mode), adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015245
15246 memset(&params, 0, sizeof(params));
15247
15248 if (CSR_MAX_NUM_KEY <= key_index) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015249 hdd_err("Invalid key index: %d", key_index);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015250 return -EINVAL;
15251 }
15252
Nachiket Kukaded9152832017-10-16 16:18:22 +053015253 if ((adapter->device_mode == QDF_SAP_MODE) ||
15254 (adapter->device_mode == QDF_P2P_GO_MODE)) {
15255 struct hdd_ap_ctx *ap_ctx =
15256 WLAN_HDD_GET_AP_CTX_PTR(adapter);
Jeff Johnson20227a92018-03-13 09:41:05 -070015257
Nachiket Kukaded9152832017-10-16 16:18:22 +053015258 roam_profile =
15259 wlan_sap_get_roam_profile(ap_ctx->sap_context);
15260 } else {
Jeff Johnson20227a92018-03-13 09:41:05 -070015261 roam_profile = hdd_roam_profile(adapter);
Nachiket Kukaded9152832017-10-16 16:18:22 +053015262 }
15263
Jeff Johnsond36fa332019-03-18 13:42:25 -070015264 if (!roam_profile) {
Jiachao Wud58cfc92017-12-27 14:15:23 +080015265 hdd_err("Get roam profile failed!");
15266 return -EINVAL;
15267 }
15268
Jeff Johnson5b34fce2017-10-13 13:24:51 -070015269 switch (roam_profile->EncryptionType.encryptionType[0]) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015270 case eCSR_ENCRYPT_TYPE_NONE:
15271 params.cipher = IW_AUTH_CIPHER_NONE;
15272 break;
15273
15274 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
15275 case eCSR_ENCRYPT_TYPE_WEP40:
15276 params.cipher = WLAN_CIPHER_SUITE_WEP40;
15277 break;
15278
15279 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
15280 case eCSR_ENCRYPT_TYPE_WEP104:
15281 params.cipher = WLAN_CIPHER_SUITE_WEP104;
15282 break;
15283
15284 case eCSR_ENCRYPT_TYPE_TKIP:
15285 params.cipher = WLAN_CIPHER_SUITE_TKIP;
15286 break;
15287
15288 case eCSR_ENCRYPT_TYPE_AES:
15289 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
15290 break;
Mukul Sharma05504ac2017-06-08 12:35:53 +053015291 case eCSR_ENCRYPT_TYPE_AES_GCMP:
15292 params.cipher = WLAN_CIPHER_SUITE_GCMP;
15293 break;
15294 case eCSR_ENCRYPT_TYPE_AES_GCMP_256:
15295 params.cipher = WLAN_CIPHER_SUITE_GCMP_256;
15296 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015297 default:
15298 params.cipher = IW_AUTH_CIPHER_NONE;
15299 break;
15300 }
15301
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053015302 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
15303 TRACE_CODE_HDD_CFG80211_GET_KEY,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080015304 adapter->vdev_id, params.cipher);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015305
Jeff Johnson5b34fce2017-10-13 13:24:51 -070015306 params.key_len = roam_profile->Keys.KeyLength[key_index];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015307 params.seq_len = 0;
15308 params.seq = NULL;
Jeff Johnson5b34fce2017-10-13 13:24:51 -070015309 params.key = &roam_profile->Keys.KeyMaterial[key_index][0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015310 callback(cookie, &params);
15311
Dustin Browne74003f2018-03-14 12:51:58 -070015312 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015313 return 0;
15314}
15315
15316static int wlan_hdd_cfg80211_get_key(struct wiphy *wiphy,
15317 struct net_device *ndev,
15318 u8 key_index, bool pairwise,
15319 const u8 *mac_addr, void *cookie,
15320 void (*callback)(void *cookie,
15321 struct key_params *)
15322 )
15323{
Dustin Brown1d31b082018-11-22 14:41:20 +053015324 int errno;
15325 struct osif_vdev_sync *vdev_sync;
15326
15327 errno = osif_vdev_sync_op_start(ndev, &vdev_sync);
15328 if (errno)
15329 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015330
Dustin Brown1d31b082018-11-22 14:41:20 +053015331 errno = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
15332 mac_addr, cookie, callback);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015333
Dustin Brown1d31b082018-11-22 14:41:20 +053015334 osif_vdev_sync_op_stop(vdev_sync);
15335
15336 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015337}
15338
15339/**
15340 * __wlan_hdd_cfg80211_del_key() - Delete the encryption key for station
15341 * @wiphy: wiphy interface context
15342 * @ndev: pointer to net device
15343 * @key_index: Key index used in 802.11 frames
15344 * @unicast: true if it is unicast key
15345 * @multicast: true if it is multicast key
15346 *
15347 * This function is required for cfg80211_ops API.
15348 * It is used to delete the key information
15349 * Underlying hardware implementation does not have API to delete the
15350 * encryption key. It is automatically deleted when the peer is
15351 * removed. Hence this function currently does nothing.
15352 * Future implementation may interprete delete key operation to
15353 * replacing the key with a random junk value, effectively making it
15354 * useless.
15355 *
15356 * Return: status code, always 0.
15357 */
15358
15359static int __wlan_hdd_cfg80211_del_key(struct wiphy *wiphy,
15360 struct net_device *ndev,
15361 u8 key_index,
15362 bool pairwise, const u8 *mac_addr)
15363{
Dustin Browne74003f2018-03-14 12:51:58 -070015364 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015365 return 0;
15366}
15367
15368/**
15369 * wlan_hdd_cfg80211_del_key() - cfg80211 delete key handler function
15370 * @wiphy: Pointer to wiphy structure.
15371 * @dev: Pointer to net_device structure.
15372 * @key_index: key index
15373 * @pairwise: pairwise
15374 * @mac_addr: mac address
15375 *
15376 * This is the cfg80211 delete key handler function which invokes
15377 * the internal function @__wlan_hdd_cfg80211_del_key with
15378 * SSR protection.
15379 *
15380 * Return: 0 for success, error number on failure.
15381 */
15382static int wlan_hdd_cfg80211_del_key(struct wiphy *wiphy,
15383 struct net_device *dev,
15384 u8 key_index,
15385 bool pairwise, const u8 *mac_addr)
15386{
Dustin Brown1d31b082018-11-22 14:41:20 +053015387 int errno;
15388 struct osif_vdev_sync *vdev_sync;
15389
15390 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
15391 if (errno)
15392 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015393
Dustin Brown1d31b082018-11-22 14:41:20 +053015394 errno = __wlan_hdd_cfg80211_del_key(wiphy, dev, key_index,
15395 pairwise, mac_addr);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015396
Dustin Brown1d31b082018-11-22 14:41:20 +053015397 osif_vdev_sync_op_stop(vdev_sync);
15398
15399 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015400}
15401
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015402#ifndef CRYPTO_SET_KEY_CONVERGED
Hu Wangc3148842017-06-20 19:03:29 +080015403#ifdef FEATURE_WLAN_WAPI
Jeff Johnsonb1959842019-02-27 13:04:04 -080015404static bool hdd_is_wapi_enc_type(eCsrEncryptionType encrypt_type)
Hu Wangc3148842017-06-20 19:03:29 +080015405{
Jeff Johnsonb1959842019-02-27 13:04:04 -080015406 if (encrypt_type == eCSR_ENCRYPT_TYPE_WPI)
Hu Wangc3148842017-06-20 19:03:29 +080015407 return true;
15408
15409 return false;
15410}
15411#else
Jeff Johnsonb1959842019-02-27 13:04:04 -080015412static bool hdd_is_wapi_enc_type(eCsrEncryptionType encrypt_type)
Hu Wangc3148842017-06-20 19:03:29 +080015413{
15414 return false;
15415}
15416#endif
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015417#endif
Hu Wangc3148842017-06-20 19:03:29 +080015418
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015419#ifdef CRYPTO_SET_KEY_CONVERGED
15420static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy,
15421 struct net_device *ndev,
15422 u8 key_index,
15423 bool unicast, bool multicast)
15424{
15425 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
15426 struct hdd_context *hdd_ctx;
15427 struct qdf_mac_addr bssid = QDF_MAC_ADDR_BCAST_INIT;
15428 struct hdd_station_ctx *sta_ctx;
15429 struct wlan_crypto_key *crypto_key;
15430 int ret;
15431 QDF_STATUS status;
15432
15433 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
15434 hdd_err("Command not allowed in FTM mode");
15435 return -EINVAL;
15436 }
15437
Jeff Johnson48363022019-02-24 16:26:51 -080015438 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015439 return -EINVAL;
15440
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053015441 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
15442 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080015443 adapter->vdev_id, key_index);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015444
15445 hdd_debug("Device_mode %s(%d) key_index = %d",
15446 qdf_opmode_str(adapter->device_mode),
15447 adapter->device_mode, key_index);
15448
15449 if (CSR_MAX_NUM_KEY <= key_index) {
15450 hdd_err("Invalid key index: %d", key_index);
15451 return -EINVAL;
15452 }
15453
15454 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
15455 ret = wlan_hdd_validate_context(hdd_ctx);
15456
15457 if (0 != ret)
15458 return ret;
15459 crypto_key = wlan_crypto_get_key(adapter->vdev, key_index);
15460 hdd_debug("unicast %d, cipher %d", unicast, crypto_key->cipher_type);
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080015461 if (!IS_WEP_CIPHER(crypto_key->cipher_type))
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015462 return 0;
15463 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
15464 if (unicast)
15465 status =
15466 wlan_cfg80211_set_default_key(adapter->vdev, key_index,
Jeff Johnsone04b6992019-02-27 14:06:55 -080015467 &sta_ctx->conn_info.bssid);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015468 else
15469 status = wlan_cfg80211_set_default_key(adapter->vdev, key_index,
15470 &bssid);
15471 if (QDF_STATUS_SUCCESS != status) {
15472 hdd_err("ret fail status %d", ret);
15473 return -EINVAL;
15474 }
15475 if ((adapter->device_mode == QDF_STA_MODE) ||
15476 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Kiran Kumar Lokere47d0dac2019-01-24 18:38:33 -080015477 ret =
15478 wlan_cfg80211_crypto_add_key(adapter->vdev, (unicast ?
15479 WLAN_CRYPTO_KEY_TYPE_UNICAST :
15480 WLAN_CRYPTO_KEY_TYPE_GROUP),
15481 key_index);
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080015482 wma_update_set_key(adapter->vdev_id, unicast, key_index,
15483 crypto_key->cipher_type);
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015484 }
15485
15486 return ret;
15487}
15488#else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015489/*
15490 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
15491 * This function is used to set the default tx key index
15492 */
15493static int __wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy,
15494 struct net_device *ndev,
15495 u8 key_index,
15496 bool unicast, bool multicast)
15497{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015498 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Jeff Johnsonb8944722017-09-03 09:03:19 -070015499 struct hdd_context *hdd_ctx;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070015500 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015501 int status;
15502
Dustin Brown491d54b2018-03-14 12:39:11 -070015503 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015504
Anurag Chouhan6d760662016-02-20 16:05:43 +053015505 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070015506 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015507 return -EINVAL;
15508 }
15509
Jeff Johnson48363022019-02-24 16:26:51 -080015510 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053015511 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053015512
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053015513 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
15514 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080015515 adapter->vdev_id, key_index);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015516
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015517 hdd_debug("Device_mode %s(%d) key_index = %d",
Dustin Brown458027c2018-10-19 12:26:27 -070015518 qdf_opmode_str(adapter->device_mode),
15519 adapter->device_mode, key_index);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015520
15521 if (CSR_MAX_NUM_KEY <= key_index) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015522 hdd_err("Invalid key index: %d", key_index);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015523 return -EINVAL;
15524 }
15525
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015526 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnsonb8944722017-09-03 09:03:19 -070015527 status = wlan_hdd_validate_context(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015528
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053015529 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015530 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015531
Jeff Johnson34fc63a2018-06-14 10:10:02 -070015532 mac_handle = hdd_ctx->mac_handle;
15533
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015534 if ((adapter->device_mode == QDF_STA_MODE) ||
15535 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Nachiket Kukaded9152832017-10-16 16:18:22 +053015536 struct hdd_station_ctx *sta_ctx =
15537 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnson20227a92018-03-13 09:41:05 -070015538 struct csr_roam_profile *roam_profile;
15539
15540 roam_profile = hdd_roam_profile(adapter);
Nachiket Kukaded9152832017-10-16 16:18:22 +053015541
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015542 if ((eCSR_ENCRYPT_TYPE_TKIP !=
Jeff Johnsonb1959842019-02-27 13:04:04 -080015543 sta_ctx->conn_info.uc_encrypt_type) &&
Hu Wangc3148842017-06-20 19:03:29 +080015544 !hdd_is_wapi_enc_type(
Jeff Johnsonb1959842019-02-27 13:04:04 -080015545 sta_ctx->conn_info.uc_encrypt_type) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015546 (eCSR_ENCRYPT_TYPE_AES !=
Jeff Johnsonb1959842019-02-27 13:04:04 -080015547 sta_ctx->conn_info.uc_encrypt_type) &&
Mukul Sharma05504ac2017-06-08 12:35:53 +053015548 (eCSR_ENCRYPT_TYPE_AES_GCMP !=
Jeff Johnsonb1959842019-02-27 13:04:04 -080015549 sta_ctx->conn_info.uc_encrypt_type) &&
Mukul Sharma05504ac2017-06-08 12:35:53 +053015550 (eCSR_ENCRYPT_TYPE_AES_GCMP_256 !=
Jeff Johnsonb1959842019-02-27 13:04:04 -080015551 sta_ctx->conn_info.uc_encrypt_type)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015552 /* If default key index is not same as previous one,
Jeff Johnsonf3826e12017-01-12 09:49:40 -080015553 * then update the default key index
15554 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015555
Jeff Johnson89515092019-03-23 10:52:04 -070015556 tCsrRoamSetKey set_key;
Jeff Johnson29c78672019-02-26 21:05:53 -080015557 uint32_t roam_id = INVALID_ROAM_ID;
Jeff Johnson25e452b2019-03-23 11:51:16 -070015558 tCsrKeys *keys = &roam_profile->Keys;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015559
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015560 hdd_debug("Default tx key index %d", key_index);
Jeff Johnson25e452b2019-03-23 11:51:16 -070015561 keys->defaultIndex = (u8) key_index;
Jeff Johnson89515092019-03-23 10:52:04 -070015562 qdf_mem_zero(&set_key, sizeof(tCsrRoamSetKey));
15563 set_key.keyId = key_index;
Jeff Johnson25e452b2019-03-23 11:51:16 -070015564 set_key.keyLength = keys->KeyLength[key_index];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015565
Jeff Johnson89515092019-03-23 10:52:04 -070015566 qdf_mem_copy(&set_key.Key[0],
Jeff Johnson25e452b2019-03-23 11:51:16 -070015567 &keys->KeyMaterial[key_index][0],
15568 keys->KeyLength[key_index]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015569
Jeff Johnson89515092019-03-23 10:52:04 -070015570 set_key.keyDirection = eSIR_TX_RX;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015571
Jeff Johnson89515092019-03-23 10:52:04 -070015572 qdf_copy_macaddr(&set_key.peerMac,
Jeff Johnsone04b6992019-02-27 14:06:55 -080015573 &sta_ctx->conn_info.bssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015574
Jeff Johnson25e452b2019-03-23 11:51:16 -070015575 if (keys->KeyLength[key_index] ==
Srinivas Girigowdacf161402019-03-14 11:37:33 -070015576 WLAN_CRYPTO_KEY_WEP40_LEN &&
Jeff Johnson20227a92018-03-13 09:41:05 -070015577 roam_profile->EncryptionType.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015578 encryptionType[0] == eCSR_ENCRYPT_TYPE_WEP104) {
Jeff Johnsonf3826e12017-01-12 09:49:40 -080015579 /* In the case of dynamic wep
15580 * supplicant hardcodes DWEP type to
15581 * eCSR_ENCRYPT_TYPE_WEP104 even
15582 * though ap is configured for WEP-40
15583 * encryption. In this canse the key
15584 * length is 5 but the encryption type
15585 * is 104 hence checking the key
Jeff Johnsonfe8e9492018-05-06 15:40:52 -070015586 * length(5) and encryption type(104)
Jeff Johnsonf3826e12017-01-12 09:49:40 -080015587 * and switching encryption type to 40
15588 */
Jeff Johnson20227a92018-03-13 09:41:05 -070015589 roam_profile->EncryptionType.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015590 encryptionType[0] = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson20227a92018-03-13 09:41:05 -070015591 roam_profile->mcEncryptionType.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015592 encryptionType[0] = eCSR_ENCRYPT_TYPE_WEP40;
15593 }
15594
Jeff Johnson89515092019-03-23 10:52:04 -070015595 set_key.encType =
Jeff Johnson20227a92018-03-13 09:41:05 -070015596 roam_profile->EncryptionType.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015597 encryptionType[0];
15598
15599 /* Issue set key request */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070015600 status = sme_roam_set_key(mac_handle,
Jeff Johnson89515092019-03-23 10:52:04 -070015601 adapter->vdev_id, &set_key,
Jeff Johnson29c78672019-02-26 21:05:53 -080015602 &roam_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015603
15604 if (0 != status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015605 hdd_err("sme_roam_set_key failed, status: %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015606 status);
15607 return -EINVAL;
15608 }
15609 }
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015610 } else if (QDF_SAP_MODE == adapter->device_mode) {
Nachiket Kukaded9152832017-10-16 16:18:22 +053015611 struct hdd_ap_ctx *ap_ctx =
15612 WLAN_HDD_GET_AP_CTX_PTR(adapter);
Jeff Johnson61b5e982018-03-15 11:33:31 -070015613 struct csr_roam_profile *profile =
Nachiket Kukaded9152832017-10-16 16:18:22 +053015614 wlan_sap_get_roam_profile(ap_ctx->sap_context);
15615
15616 if (!profile) {
15617 hdd_err("Failed to get SAP Roam Profile");
15618 return -EINVAL;
15619 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015620 /* In SoftAp mode setting key direction for default mode */
15621 if ((eCSR_ENCRYPT_TYPE_TKIP !=
Nachiket Kukaded9152832017-10-16 16:18:22 +053015622 profile->EncryptionType.encryptionType[0]) &&
Mukul Sharma05504ac2017-06-08 12:35:53 +053015623 (eCSR_ENCRYPT_TYPE_AES !=
Nachiket Kukaded9152832017-10-16 16:18:22 +053015624 profile->EncryptionType.encryptionType[0]) &&
Mukul Sharma05504ac2017-06-08 12:35:53 +053015625 (eCSR_ENCRYPT_TYPE_AES_GCMP !=
Nachiket Kukaded9152832017-10-16 16:18:22 +053015626 profile->EncryptionType.encryptionType[0]) &&
Mukul Sharma05504ac2017-06-08 12:35:53 +053015627 (eCSR_ENCRYPT_TYPE_AES_GCMP_256 !=
Nachiket Kukaded9152832017-10-16 16:18:22 +053015628 profile->EncryptionType.encryptionType[0])) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015629 /* Saving key direction for default key index to TX default */
Nachiket Kukaded9152832017-10-16 16:18:22 +053015630 ap_ctx->wep_key[key_index].keyDirection =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015631 eSIR_TX_DEFAULT;
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015632 hdd_debug("WEP default key index set to SAP context %d",
Masti, Narayanraddiab712a72016-08-04 11:59:11 +053015633 key_index);
Nachiket Kukaded9152832017-10-16 16:18:22 +053015634 ap_ctx->wep_def_key_idx = key_index;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015635 }
15636 }
15637
Dustin Browne74003f2018-03-14 12:51:58 -070015638 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015639 return status;
15640}
Kiran Kumar Lokere7d6e4c92018-09-19 13:45:47 -070015641#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015642
15643static int wlan_hdd_cfg80211_set_default_key(struct wiphy *wiphy,
15644 struct net_device *ndev,
15645 u8 key_index,
15646 bool unicast, bool multicast)
15647{
Dustin Brown1d31b082018-11-22 14:41:20 +053015648 int errno;
15649 struct osif_vdev_sync *vdev_sync;
15650
15651 errno = osif_vdev_sync_op_start(ndev, &vdev_sync);
15652 if (errno)
15653 return errno;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -070015654
Dustin Brown1d31b082018-11-22 14:41:20 +053015655 errno = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index,
15656 unicast, multicast);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015657
Dustin Brown1d31b082018-11-22 14:41:20 +053015658 osif_vdev_sync_op_stop(vdev_sync);
15659
15660 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015661}
15662
Abhishek Singh85283ae2019-03-08 12:00:51 +053015663void wlan_hdd_cfg80211_unlink_bss(struct hdd_adapter *adapter,
Ashish Kumar Dhanotiya3d8b0ae2019-07-10 20:55:56 +053015664 tSirMacAddr bssid, uint8_t *ssid,
15665 uint8_t ssid_len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015666{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015667 struct net_device *dev = adapter->dev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015668 struct wireless_dev *wdev = dev->ieee80211_ptr;
15669 struct wiphy *wiphy = wdev->wiphy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015670
Ashish Kumar Dhanotiya3d8b0ae2019-07-10 20:55:56 +053015671 __wlan_cfg80211_unlink_bss_list(wiphy, bssid, ssid, ssid_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015672}
15673
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015674#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015675static inline int
15676wlan_hdd_get_frame_len(struct bss_description *bss_desc)
15677{
15678 return GET_IE_LEN_IN_BSS(bss_desc->length) + sizeof(qcom_ie_age);
15679}
15680
15681static inline void wlan_hdd_add_age_ie(struct ieee80211_mgmt *mgmt,
Abhishek Singhf1c16762018-03-07 10:48:46 +053015682 uint32_t *ie_length, struct bss_description *bss_desc)
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015683{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015684 qcom_ie_age *qie_age = NULL;
Nachiket Kukade348ede72017-04-28 16:34:24 +053015685
15686 /*
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015687 * GPS Requirement: need age ie per entry. Using vendor specific.
15688 * Assuming this is the last IE, copy at the end
Nachiket Kukade348ede72017-04-28 16:34:24 +053015689 */
Abhishek Singhf1c16762018-03-07 10:48:46 +053015690 *ie_length -= sizeof(qcom_ie_age);
15691 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + *ie_length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015692 qie_age->element_id = QCOM_VENDOR_IE_ID;
15693 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
15694 qie_age->oui_1 = QCOM_OUI1;
15695 qie_age->oui_2 = QCOM_OUI2;
15696 qie_age->oui_3 = QCOM_OUI3;
15697 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Deepthi Gowri6acee342016-10-28 15:00:38 +053015698 /*
15699 * Lowi expects the timestamp of bss in units of 1/10 ms. In driver
15700 * all bss related timestamp is in units of ms. Due to this when scan
15701 * results are sent to lowi the scan age is high.To address this,
15702 * send age in units of 1/10 ms.
15703 */
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015704 qie_age->age = (uint32_t)(qdf_mc_timer_get_system_time() -
15705 bss_desc->received_time)/10;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015706 qie_age->tsf_delta = bss_desc->tsf_delta;
Krishna Kumaar Natarajana4e12242016-04-01 18:44:39 -070015707 memcpy(&qie_age->beacon_tsf, bss_desc->timeStamp,
15708 sizeof(qie_age->beacon_tsf));
Krishna Kumaar Natarajan89a99d42016-08-04 15:44:38 -070015709 memcpy(&qie_age->seq_ctrl, &bss_desc->seq_ctrl,
15710 sizeof(qie_age->seq_ctrl));
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015711}
15712#else
15713static inline int
15714wlan_hdd_get_frame_len(struct bss_description *bss_desc)
15715{
15716 return GET_IE_LEN_IN_BSS(bss_desc->length);
15717}
15718static inline void wlan_hdd_add_age_ie(struct ieee80211_mgmt *mgmt,
Abhishek Singhf1c16762018-03-07 10:48:46 +053015719 uint32_t *ie_length, struct bss_description *bss_desc)
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015720{
15721}
15722#endif /* WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015723
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015724
15725struct cfg80211_bss *
15726wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter,
15727 struct bss_description *bss_desc)
15728{
15729 struct wireless_dev *wdev = adapter->dev->ieee80211_ptr;
15730 struct wiphy *wiphy = wdev->wiphy;
Abhishek Singhf1c16762018-03-07 10:48:46 +053015731 uint32_t ie_length = wlan_hdd_get_frame_len(bss_desc);
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015732 const char *ie =
15733 ((ie_length != 0) ? (const char *)&bss_desc->ieFields : NULL);
Will Huang65d64252019-07-16 17:57:42 +080015734 uint32_t i;
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015735 struct cfg80211_bss *bss_status = NULL;
15736 struct hdd_context *hdd_ctx;
15737 struct timespec ts;
15738 struct hdd_config *cfg_param;
15739 struct wlan_cfg80211_inform_bss bss_data = {0};
15740
15741 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
15742 /*
15743 * wlan_hdd_validate_context should not be used here, In validate ctx
15744 * start_modules_in_progress or stop_modules_in_progress is validated,
15745 * If the start_modules_in_progress is set to true means the interface
15746 * is not UP yet if the stop_modules_in_progress means that interface
15747 * is already down. So in both the two scenario's driver should not be
15748 * informing bss to kernel. Hence removing the validate context.
15749 */
15750
15751 if (!hdd_ctx || !hdd_ctx->config) {
15752 hdd_debug("HDD context is Null");
15753 return NULL;
15754 }
15755
15756 if (cds_is_driver_recovering() ||
15757 cds_is_load_or_unload_in_progress()) {
15758 hdd_debug("Recovery or load/unload in progress. State: 0x%x",
15759 cds_get_driver_state());
15760 return NULL;
15761 }
15762
15763 cfg_param = hdd_ctx->config;
15764 bss_data.frame_len = ie_length + offsetof(struct ieee80211_mgmt,
15765 u.probe_resp.variable);
15766 bss_data.mgmt = qdf_mem_malloc(bss_data.frame_len);
Min Liu74a1a502018-10-10 19:59:07 +080015767 if (!bss_data.mgmt)
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015768 return NULL;
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015769
15770 memcpy(bss_data.mgmt->bssid, bss_desc->bssId, ETH_ALEN);
15771
15772 /* Android does not want the timestamp from the frame.
15773 * Instead it wants a monotonic increasing value
15774 */
15775 get_monotonic_boottime(&ts);
15776 bss_data.mgmt->u.probe_resp.timestamp =
15777 ((u64) ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
15778
15779 bss_data.mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
15780 bss_data.mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
15781
Abhishek Singhf1c16762018-03-07 10:48:46 +053015782 wlan_hdd_add_age_ie(bss_data.mgmt, &ie_length, bss_desc);
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015783
15784 memcpy(bss_data.mgmt->u.probe_resp.variable, ie, ie_length);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015785 if (bss_desc->fProbeRsp) {
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015786 bss_data.mgmt->frame_control |=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015787 (u16) (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
15788 } else {
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015789 bss_data.mgmt->frame_control |=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015790 (u16) (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
15791 }
15792
Will Huang65d64252019-07-16 17:57:42 +080015793 bss_data.chan = ieee80211_get_channel(wiphy, bss_desc->chan_freq);
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015794 if (!bss_data.chan) {
Will Huang65d64252019-07-16 17:57:42 +080015795 hdd_err("chan pointer is NULL, chan freq: %d",
15796 bss_desc->chan_freq);
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015797 qdf_mem_free(bss_data.mgmt);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015798 return NULL;
15799 }
15800
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015801 /*
15802 * Based on .ini configuration, raw rssi can be reported for bss.
Deepak Dhamdhere68929ec2015-08-05 15:16:35 -070015803 * Raw rssi is typically used for estimating power.
15804 */
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015805 bss_data.rssi = (cfg_param->inform_bss_rssi_raw) ? bss_desc->rssi_raw :
Deepak Dhamdhere68929ec2015-08-05 15:16:35 -070015806 bss_desc->rssi;
15807
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015808 /* Supplicant takes the signal strength in terms of mBm(100*dBm) */
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015809 bss_data.rssi = QDF_MIN(bss_data.rssi, 0) * 100;
15810
15811 bss_data.boottime_ns = bss_desc->scansystimensec;
15812
15813 /* Set all per chain rssi as invalid */
15814 for (i = 0; i < WLAN_MGMT_TXRX_HOST_MAX_ANTENNA; i++)
Yeshwanth Sriram Guntuka14ab04c2018-09-21 15:06:49 +053015815 bss_data.per_chain_rssi[i] = WLAN_INVALID_PER_CHAIN_RSSI;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015816
Ashish Kumar Dhanotiya3d8b0ae2019-07-10 20:55:56 +053015817 hdd_debug("BSSID: " QDF_MAC_ADDR_STR " Channel:%d RSSI:%d TSF %u seq %d is_prob_resp %d",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070015818 QDF_MAC_ADDR_ARRAY(bss_data.mgmt->bssid),
Abhishek Singhef6f38c2018-12-20 13:51:29 +053015819 bss_data.chan->center_freq, (int)(bss_data.rssi / 100),
15820 bss_desc->timeStamp[0], ((bss_desc->seq_ctrl.seqNumHi <<
Ashish Kumar Dhanotiya3d8b0ae2019-07-10 20:55:56 +053015821 HIGH_SEQ_NUM_OFFSET) | bss_desc->seq_ctrl.seqNumLo),
15822 bss_desc->fProbeRsp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015823
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015824 bss_status = wlan_cfg80211_inform_bss_frame_data(wiphy, &bss_data);
Jeff Johnsonb8944722017-09-03 09:03:19 -070015825 hdd_ctx->beacon_probe_rsp_cnt_per_scan++;
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015826 qdf_mem_free(bss_data.mgmt);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015827 return bss_status;
15828}
15829
15830/**
15831 * wlan_hdd_cfg80211_update_bss_db() - update bss database of CF80211
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015832 * @adapter: Pointer to adapter
Jeff Johnsonfd060852017-10-04 10:50:51 -070015833 * @roam_info: Pointer to roam info
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015834 *
15835 * This function is used to update the BSS data base of CFG8011
15836 *
15837 * Return: struct cfg80211_bss pointer
15838 */
Jeff Johnson172237b2017-11-07 15:32:59 -080015839struct cfg80211_bss *
15840wlan_hdd_cfg80211_update_bss_db(struct hdd_adapter *adapter,
15841 struct csr_roam_info *roam_info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015842{
15843 tCsrRoamConnectedProfile roamProfile;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070015844 mac_handle_t mac_handle = hdd_adapter_get_mac_handle(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015845 struct cfg80211_bss *bss = NULL;
15846
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015847 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
Jeff Johnsoncf07c312019-02-04 13:53:29 -080015848 sme_roam_get_connect_profile(mac_handle, adapter->vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -070015849 &roamProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015850
Pragaspathi Thilagaraj96742ae2019-05-29 00:49:33 +053015851 if (roamProfile.bss_desc) {
15852 bss = wlan_hdd_inform_bss_frame(adapter, roamProfile.bss_desc);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015853
Jeff Johnsond36fa332019-03-18 13:42:25 -070015854 if (!bss)
Abhishek Singhf05b0cb62018-02-20 18:06:13 +053015855 hdd_debug("wlan_hdd_inform_bss_frame returned NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015856
Naveen Rawatdf0a7e72016-01-06 18:35:53 -080015857 sme_roam_free_connect_profile(&roamProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015858 } else {
Pragaspathi Thilagaraj96742ae2019-05-29 00:49:33 +053015859 hdd_err("roamProfile.bss_desc is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015860 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015861 return bss;
15862}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015863
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015864/**
15865 * wlan_hdd_cfg80211_pmksa_candidate_notify() - notify a new PMSKA candidate
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015866 * @adapter: Pointer to adapter
Jeff Johnsonfd060852017-10-04 10:50:51 -070015867 * @roam_info: Pointer to roam info
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015868 * @index: Index
15869 * @preauth: Preauth flag
15870 *
15871 * This function is used to notify the supplicant of a new PMKSA candidate.
Deepak Dhamdhere828f1892017-02-09 11:51:19 -080015872 * PMK value is notified to supplicant whether PMK caching or OKC is enabled
15873 * in firmware or not. Supplicant needs this value becaue it uses PMK caching
15874 * by default.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015875 *
15876 * Return: 0 for success, non-zero for failure
15877 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015878int wlan_hdd_cfg80211_pmksa_candidate_notify(struct hdd_adapter *adapter,
Jeff Johnson172237b2017-11-07 15:32:59 -080015879 struct csr_roam_info *roam_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015880 int index, bool preauth)
15881{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015882 struct net_device *dev = adapter->dev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015883
Dustin Brown491d54b2018-03-14 12:39:11 -070015884 hdd_enter();
Srinivas Girigowda13d39252017-03-06 16:12:15 -080015885 hdd_debug("is going to notify supplicant of:");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015886
Jeff Johnsond36fa332019-03-18 13:42:25 -070015887 if (!roam_info) {
Jeff Johnsonfd060852017-10-04 10:50:51 -070015888 hdd_err("roam_info is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015889 return -EINVAL;
15890 }
15891
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070015892 hdd_info(QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(roam_info->bssid.bytes));
Deepak Dhamdhere828f1892017-02-09 11:51:19 -080015893 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnsonfd060852017-10-04 10:50:51 -070015894 roam_info->bssid.bytes,
Deepak Dhamdhere828f1892017-02-09 11:51:19 -080015895 preauth, GFP_KERNEL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015896 return 0;
15897}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015898
15899#ifdef FEATURE_WLAN_LFR_METRICS
15900/**
15901 * wlan_hdd_cfg80211_roam_metrics_preauth() - roam metrics preauth
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015902 * @adapter: Pointer to adapter
Jeff Johnsonfd060852017-10-04 10:50:51 -070015903 * @roam_info: Pointer to roam info
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015904 *
15905 * 802.11r/LFR metrics reporting function to report preauth initiation
15906 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053015907 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015908 */
15909#define MAX_LFR_METRICS_EVENT_LENGTH 100
Jeff Johnson172237b2017-11-07 15:32:59 -080015910QDF_STATUS
15911wlan_hdd_cfg80211_roam_metrics_preauth(struct hdd_adapter *adapter,
15912 struct csr_roam_info *roam_info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015913{
15914 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
15915 union iwreq_data wrqu;
15916
Dustin Brown491d54b2018-03-14 12:39:11 -070015917 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015918
Jeff Johnsond36fa332019-03-18 13:42:25 -070015919 if (!adapter) {
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015920 hdd_err("adapter is NULL!");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053015921 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015922 }
15923
15924 /* create the event */
15925 memset(&wrqu, 0, sizeof(wrqu));
15926 memset(metrics_notification, 0, sizeof(metrics_notification));
15927
15928 wrqu.data.pointer = metrics_notification;
15929 wrqu.data.length = scnprintf(metrics_notification,
15930 sizeof(metrics_notification),
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070015931 "QCOM: LFR_PREAUTH_INIT " QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070015932 QDF_MAC_ADDR_ARRAY(roam_info->bssid.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015933
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015934 wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015935 metrics_notification);
15936
Dustin Browne74003f2018-03-14 12:51:58 -070015937 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015938
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053015939 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015940}
15941
15942/**
15943 * wlan_hdd_cfg80211_roam_metrics_handover() - roam metrics hand over
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015944 * @adapter: Pointer to adapter
Jeff Johnsonfd060852017-10-04 10:50:51 -070015945 * @roam_info: Pointer to roam info
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015946 * @preauth_status: Preauth status
15947 *
15948 * 802.11r/LFR metrics reporting function to report handover initiation
15949 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053015950 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015951 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053015952QDF_STATUS
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015953wlan_hdd_cfg80211_roam_metrics_preauth_status(struct hdd_adapter *adapter,
Jeff Johnson172237b2017-11-07 15:32:59 -080015954 struct csr_roam_info *roam_info,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015955 bool preauth_status)
15956{
15957 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
15958 union iwreq_data wrqu;
15959
Dustin Brown491d54b2018-03-14 12:39:11 -070015960 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015961
Jeff Johnsond36fa332019-03-18 13:42:25 -070015962 if (!adapter) {
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015963 hdd_err("adapter is NULL!");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053015964 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015965 }
15966
15967 /* create the event */
15968 memset(&wrqu, 0, sizeof(wrqu));
15969 memset(metrics_notification, 0, sizeof(metrics_notification));
15970
15971 scnprintf(metrics_notification, sizeof(metrics_notification),
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070015972 "QCOM: LFR_PREAUTH_STATUS " QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070015973 QDF_MAC_ADDR_ARRAY(roam_info->bssid.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015974
15975 if (1 == preauth_status)
15976 strlcat(metrics_notification, " true",
15977 sizeof(metrics_notification));
15978 else
15979 strlcat(metrics_notification, " false",
15980 sizeof(metrics_notification));
15981
15982 wrqu.data.pointer = metrics_notification;
15983 wrqu.data.length = strlen(metrics_notification);
15984
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015985 wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015986 metrics_notification);
15987
Dustin Browne74003f2018-03-14 12:51:58 -070015988 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015989
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053015990 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015991}
15992
15993/**
15994 * wlan_hdd_cfg80211_roam_metrics_handover() - roam metrics hand over
Jeff Johnsonce2ba702017-10-02 13:30:24 -070015995 * @adapter: Pointer to adapter
Jeff Johnsonfd060852017-10-04 10:50:51 -070015996 * @roam_info: Pointer to roam info
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015997 *
15998 * 802.11r/LFR metrics reporting function to report handover initiation
15999 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053016000 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016001 */
Jeff Johnson172237b2017-11-07 15:32:59 -080016002QDF_STATUS
16003wlan_hdd_cfg80211_roam_metrics_handover(struct hdd_adapter *adapter,
16004 struct csr_roam_info *roam_info)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016005{
16006 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
16007 union iwreq_data wrqu;
16008
Dustin Brown491d54b2018-03-14 12:39:11 -070016009 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016010
Jeff Johnsond36fa332019-03-18 13:42:25 -070016011 if (!adapter) {
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016012 hdd_err("adapter is NULL!");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053016013 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016014 }
16015
16016 /* create the event */
16017 memset(&wrqu, 0, sizeof(wrqu));
16018 memset(metrics_notification, 0, sizeof(metrics_notification));
16019
16020 wrqu.data.pointer = metrics_notification;
16021 wrqu.data.length = scnprintf(metrics_notification,
16022 sizeof(metrics_notification),
16023 "QCOM: LFR_PREAUTH_HANDOVER "
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070016024 QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070016025 QDF_MAC_ADDR_ARRAY(roam_info->bssid.bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016026
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016027 wireless_send_event(adapter->dev, IWEVCUSTOM, &wrqu,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016028 metrics_notification);
16029
Dustin Browne74003f2018-03-14 12:51:58 -070016030 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016031
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053016032 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016033}
16034#endif
16035
Nirav Shah73713f72018-05-17 14:50:41 +053016036#ifdef FEATURE_MONITOR_MODE_SUPPORT
16037static
16038void hdd_mon_select_cbmode(struct hdd_adapter *adapter,
16039 uint8_t operationChannel,
16040 struct ch_params *ch_params)
16041{
16042 struct hdd_station_ctx *station_ctx =
16043 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
16044 struct hdd_mon_set_ch_info *ch_info = &station_ctx->ch_info;
16045 enum hdd_dot11_mode hdd_dot11_mode;
16046 uint8_t ini_dot11_mode =
16047 (WLAN_HDD_GET_CTX(adapter))->config->dot11Mode;
16048
16049 hdd_debug("Dot11Mode is %u", ini_dot11_mode);
16050 switch (ini_dot11_mode) {
16051 case eHDD_DOT11_MODE_AUTO:
16052 case eHDD_DOT11_MODE_11ax:
16053 case eHDD_DOT11_MODE_11ax_ONLY:
16054 if (sme_is_feature_supported_by_fw(DOT11AX))
16055 hdd_dot11_mode = eHDD_DOT11_MODE_11ax;
16056 else if (sme_is_feature_supported_by_fw(DOT11AC))
16057 hdd_dot11_mode = eHDD_DOT11_MODE_11ac;
16058 else
16059 hdd_dot11_mode = eHDD_DOT11_MODE_11n;
16060 break;
16061 case eHDD_DOT11_MODE_11ac:
16062 case eHDD_DOT11_MODE_11ac_ONLY:
16063 if (sme_is_feature_supported_by_fw(DOT11AC))
16064 hdd_dot11_mode = eHDD_DOT11_MODE_11ac;
16065 else
16066 hdd_dot11_mode = eHDD_DOT11_MODE_11n;
16067 break;
16068 case eHDD_DOT11_MODE_11n:
16069 case eHDD_DOT11_MODE_11n_ONLY:
16070 hdd_dot11_mode = eHDD_DOT11_MODE_11n;
16071 break;
16072 default:
16073 hdd_dot11_mode = ini_dot11_mode;
16074 break;
16075 }
16076 ch_info->channel_width = ch_params->ch_width;
16077 ch_info->phy_mode =
16078 hdd_cfg_xlate_to_csr_phy_mode(hdd_dot11_mode);
16079 ch_info->channel = operationChannel;
16080 ch_info->cb_mode = ch_params->ch_width;
16081 hdd_debug("ch_info width %d, phymode %d channel %d",
16082 ch_info->channel_width, ch_info->phy_mode,
16083 ch_info->channel);
16084}
16085#else
16086static
16087void hdd_mon_select_cbmode(struct hdd_adapter *adapter,
16088 uint8_t operationChannel,
16089 struct ch_params *ch_params)
16090{
16091}
16092#endif
16093
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016094/**
16095 * hdd_select_cbmode() - select channel bonding mode
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016096 * @adapter: Pointer to adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016097 * @operatingChannel: Operating channel
Naveen Rawatc77e6e72016-08-05 15:19:03 -070016098 * @ch_params: channel info struct to populate
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016099 *
16100 * Return: none
16101 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016102void hdd_select_cbmode(struct hdd_adapter *adapter, uint8_t operationChannel,
Amar Singhal5cccafe2017-02-15 12:42:58 -080016103 struct ch_params *ch_params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016104{
Sandeep Puligilla1cc23f62016-04-27 16:52:49 -070016105 uint8_t sec_ch = 0;
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016106 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Chaoli Zhou75b062f2018-06-11 12:36:54 +080016107 struct hdd_station_ctx *station_ctx =
16108 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
16109 eConnectionState connstate;
16110 bool cbmode_select = false;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070016111
Sandeep Puligilla1cc23f62016-04-27 16:52:49 -070016112 /*
16113 * CDS api expects secondary channel for calculating
16114 * the channel params
16115 */
Naveen Rawatc77e6e72016-08-05 15:19:03 -070016116 if ((ch_params->ch_width == CH_WIDTH_40MHZ) &&
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070016117 (WLAN_REG_IS_24GHZ_CH(operationChannel))) {
Sandeep Puligilla1cc23f62016-04-27 16:52:49 -070016118 if (operationChannel >= 1 && operationChannel <= 5)
16119 sec_ch = operationChannel + 4;
16120 else if (operationChannel >= 6 && operationChannel <= 13)
16121 sec_ch = operationChannel - 4;
16122 }
16123
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016124 /* This call decides required channel bonding mode */
Dustin Brown07901ec2018-09-07 11:02:41 -070016125 wlan_reg_set_channel_params(hdd_ctx->pdev, operationChannel,
16126 sec_ch, ch_params);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070016127
Chaoli Zhou75b062f2018-06-11 12:36:54 +080016128 if (adapter->device_mode == QDF_STA_MODE &&
Pragaspathi Thilagaraja8893752019-02-06 19:58:59 +053016129 ucfg_mlme_is_change_channel_bandwidth_enabled(hdd_ctx->psoc)) {
Jeff Johnsone7951512019-02-27 10:02:51 -080016130 connstate = station_ctx->conn_info.conn_state;
Chaoli Zhou75b062f2018-06-11 12:36:54 +080016131 if (!(eConnectionState_Associated == connstate ||
16132 eConnectionState_Connecting == connstate)) {
16133 cbmode_select = true;
16134 }
16135 }
16136
16137 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE || cbmode_select)
Nirav Shah73713f72018-05-17 14:50:41 +053016138 hdd_mon_select_cbmode(adapter, operationChannel, ch_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016139}
16140
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016141/**
16142 * wlan_hdd_handle_sap_sta_dfs_conc() - to handle SAP STA DFS conc
16143 * @adapter: STA adapter
16144 * @roam_profile: STA roam profile
16145 *
16146 * This routine will move SAP from dfs to non-dfs, if sta is coming up.
16147 *
16148 * Return: false if sta-sap conc is not allowed, else return true
16149 */
Jeff Johnson61b5e982018-03-15 11:33:31 -070016150static
16151bool wlan_hdd_handle_sap_sta_dfs_conc(struct hdd_adapter *adapter,
16152 struct csr_roam_profile *roam_profile)
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016153{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070016154 struct hdd_context *hdd_ctx;
Jeff Johnsone5006672017-08-29 14:39:02 -070016155 struct hdd_adapter *ap_adapter;
Jeff Johnson87251032017-08-29 13:31:11 -070016156 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070016157 struct hdd_hostapd_state *hostapd_state;
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016158 uint8_t channel = 0;
16159 QDF_STATUS status;
16160
16161 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
16162 if (!hdd_ctx) {
16163 hdd_err("HDD context is NULL");
16164 return true;
16165 }
16166
16167 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
16168 /* probably no sap running, no handling required */
Jeff Johnsond36fa332019-03-18 13:42:25 -070016169 if (!ap_adapter)
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016170 return true;
16171
16172 /*
16173 * sap is not in started state, so it is fine to go ahead with sta.
16174 * if sap is currently doing CAC then don't allow sta to go further.
16175 */
16176 if (!test_bit(SOFTAP_BSS_STARTED, &(ap_adapter)->event_flags) &&
16177 (hdd_ctx->dev_dfs_cac_status != DFS_CAC_IN_PROGRESS))
16178 return true;
16179
16180 if (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS) {
16181 hdd_err("Concurrent SAP is in CAC state, STA is not allowed");
16182 return false;
16183 }
16184
16185 /*
16186 * log and return error, if we allow STA to go through, we don't
16187 * know what is going to happen better stop sta connection
16188 */
16189 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
Jeff Johnsond36fa332019-03-18 13:42:25 -070016190 if (!hdd_ap_ctx) {
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016191 hdd_err("AP context not found");
16192 return false;
16193 }
16194
16195 /* sap is on non-dfs channel, nothing to handle */
Dustin Brown07901ec2018-09-07 11:02:41 -070016196 if (!wlan_reg_is_dfs_ch(hdd_ctx->pdev,
Jeff Johnson01206862017-10-27 20:55:59 -070016197 hdd_ap_ctx->operating_channel)) {
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070016198 hdd_info("sap is on non-dfs channel, sta is allowed");
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016199 return true;
16200 }
16201 /*
16202 * find out by looking in to scan cache where sta is going to
Nitesh Shah59774522016-09-16 15:14:21 +053016203 * connect by passing its roam_profile.
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016204 */
Dustin Brown76cd2932018-09-11 16:03:05 -070016205 status = policy_mgr_get_channel_from_scan_result(hdd_ctx->psoc,
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016206 roam_profile, &channel);
16207
Nitesh Shah59774522016-09-16 15:14:21 +053016208 /*
16209 * If the STA's channel is 2.4 GHz, then set pcl with only 2.4 GHz
16210 * channels for roaming case.
16211 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070016212 if (WLAN_REG_IS_24GHZ_CH(channel)) {
16213 hdd_info("sap is on dfs, new sta conn on 2.4 is allowed");
Nitesh Shah59774522016-09-16 15:14:21 +053016214 return true;
16215 }
16216
16217 /*
Jeff Johnsondcf84ce2017-10-05 09:26:24 -070016218 * If channel is 0 or DFS or LTE unsafe then better to call pcl and
Tushnim Bhattacharyya9a929992017-06-18 00:59:09 -070016219 * find out the best channel. If channel is non-dfs 5 GHz then
16220 * better move SAP to STA's channel to make scc, so we have room
16221 * for 3port MCC scenario.
Nitesh Shah59774522016-09-16 15:14:21 +053016222 */
Dustin Brown07901ec2018-09-07 11:02:41 -070016223 if (!channel || wlan_reg_is_dfs_ch(hdd_ctx->pdev, channel) ||
Dustin Brown76cd2932018-09-11 16:03:05 -070016224 !policy_mgr_is_safe_channel(hdd_ctx->psoc, channel))
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080016225 channel = policy_mgr_get_nondfs_preferred_channel(
Dustin Brown76cd2932018-09-11 16:03:05 -070016226 hdd_ctx->psoc, PM_SAP_MODE, true);
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016227
16228 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
16229 qdf_event_reset(&hostapd_state->qdf_event);
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +053016230 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, ap_adapter->vdev_id,
16231 CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS);
16232
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016233 status = wlansap_set_channel_change_with_csa(
16234 WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter), channel,
Jeff Johnson91df29d2017-10-27 19:29:50 -070016235 hdd_ap_ctx->sap_config.ch_width_orig, false);
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016236
16237 if (QDF_STATUS_SUCCESS != status) {
16238 hdd_err("Set channel with CSA IE failed, can't allow STA");
16239 return false;
16240 }
16241
16242 /*
16243 * wait here for SAP to finish the channel switch. When channel
16244 * switch happens, SAP sends few beacons with CSA_IE. After
16245 * successfully Transmission of those beacons, it will move its
16246 * state from started to disconnected and move to new channel.
16247 * once it moves to new channel, sap again moves its state
16248 * machine from disconnected to started and set this event.
16249 * wait for 10 secs to finish this.
16250 */
Nachiket Kukade0396b732017-11-14 16:35:16 +053016251 status = qdf_wait_for_event_completion(&hostapd_state->qdf_event, 10000);
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016252 if (!QDF_IS_STATUS_SUCCESS(status)) {
16253 hdd_err("wait for qdf_event failed, STA not allowed!!");
16254 return false;
16255 }
16256
16257 return true;
16258}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016259
Abhishek Singhcfb44482017-03-10 12:42:37 +053016260#ifdef WLAN_FEATURE_11W
16261/**
16262 * wlan_hdd_cfg80211_check_pmf_valid() - check if pmf status is ok
16263 * @roam_profile: pointer to roam profile
16264 *
16265 * if MFPEnabled is set but the peer AP is non-PMF i.e 80211w=2
16266 * or pmf=2 is an explicit configuration in the supplicant
16267 * configuration, drop the connection request.
16268 *
16269 * Return: 0 if check result is valid, otherwise return error code
16270 */
Jeff Johnson61b5e982018-03-15 11:33:31 -070016271static
16272int wlan_hdd_cfg80211_check_pmf_valid(struct csr_roam_profile *roam_profile)
Abhishek Singhcfb44482017-03-10 12:42:37 +053016273{
16274 if (roam_profile->MFPEnabled &&
Jeff Johnson20227a92018-03-13 09:41:05 -070016275 !(roam_profile->MFPRequired || roam_profile->MFPCapable)) {
Abhishek Singhcfb44482017-03-10 12:42:37 +053016276 hdd_err("Drop connect req as supplicant has indicated PMF required for the non-PMF peer. MFPEnabled %d MFPRequired %d MFPCapable %d",
16277 roam_profile->MFPEnabled,
16278 roam_profile->MFPRequired,
16279 roam_profile->MFPCapable);
16280 return -EINVAL;
16281 }
16282 return 0;
16283}
16284#else
16285static inline
Jeff Johnson61b5e982018-03-15 11:33:31 -070016286int wlan_hdd_cfg80211_check_pmf_valid(struct csr_roam_profile *roam_profile)
Abhishek Singhcfb44482017-03-10 12:42:37 +053016287{
16288 return 0;
16289}
16290#endif
16291
Krunal Soni31949422016-07-29 17:17:53 -070016292/**
16293 * wlan_hdd_cfg80211_connect_start() - to start the association process
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016294 * @adapter: Pointer to adapter
Krunal Soni31949422016-07-29 17:17:53 -070016295 * @ssid: Pointer to ssid
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016296 * @ssid_len: Length of ssid
16297 * @bssid: Pointer to bssid
Krunal Soni31949422016-07-29 17:17:53 -070016298 * @bssid_hint: Pointer to bssid hint
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016299 * @operatingChannel: Operating channel
Naveen Rawatc77e6e72016-08-05 15:19:03 -070016300 * @ch_width: channel width. this is needed only for IBSS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016301 *
16302 * This function is used to start the association process
16303 *
16304 * Return: 0 for success, non-zero for failure
16305 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016306static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016307 const u8 *ssid, size_t ssid_len,
Krunal Soni31949422016-07-29 17:17:53 -070016308 const u8 *bssid, const u8 *bssid_hint,
Naveen Rawatc77e6e72016-08-05 15:19:03 -070016309 u8 operatingChannel,
16310 enum nl80211_chan_width ch_width)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016311{
16312 int status = 0;
Rajeev Kumard31e1542017-01-13 14:37:42 -080016313 QDF_STATUS qdf_status;
Jeff Johnsonb8944722017-09-03 09:03:19 -070016314 struct hdd_context *hdd_ctx;
Jeff Johnson40dae4e2017-08-29 14:00:25 -070016315 struct hdd_station_ctx *hdd_sta_ctx;
Jeff Johnson29c78672019-02-26 21:05:53 -080016316 uint32_t roam_id = INVALID_ROAM_ID;
Jeff Johnson61b5e982018-03-15 11:33:31 -070016317 struct csr_roam_profile *roam_profile;
Pragaspathi Thilagaraj7a1a08e2019-05-29 01:20:29 +053016318 enum csr_akm_type rsn_auth_type;
Jeff Johnson46b4f0e2019-03-08 10:48:35 -080016319 struct sme_config_params *sme_config;
Nitesh Shah044fd672016-10-13 18:53:25 +053016320 uint8_t channel = 0;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070016321 mac_handle_t mac_handle;
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +053016322 uint8_t wmm_mode = 0;
16323 uint8_t value = 0;
Min Liu8c5d99e2018-09-10 17:18:44 +080016324 struct wlan_objmgr_vdev *vdev;
Wu Gaoed616a12019-01-16 15:19:21 +080016325 uint32_t channel_bonding_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016326
Dustin Brown491d54b2018-03-14 12:39:11 -070016327 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016328
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016329 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
16330 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016331
Jeff Johnsonb8944722017-09-03 09:03:19 -070016332 status = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053016333 if (status)
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016334 goto ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016335
Srinivas Girigowdab8fdc642019-03-19 15:33:03 -070016336 if (WLAN_SSID_MAX_LEN < ssid_len) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070016337 hdd_err("wrong SSID len");
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016338 status = -EINVAL;
16339 goto ret_status;
16340 }
16341
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080016342 if (true == hdd_is_connection_in_progress(NULL, NULL)) {
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016343 hdd_err("Connection refused: conn in progress");
16344 status = -EINVAL;
16345 goto ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016346 }
16347
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053016348 /* Disable roaming on all other adapters before connect start */
16349 wlan_hdd_disable_roaming(adapter);
16350
Bala Venkatesh9bb9c052019-05-27 14:16:40 +053016351 hdd_notify_teardown_tdls_links(hdd_ctx->psoc);
Nitesh Shah273e4e52017-04-03 12:53:36 +053016352
Anurag Chouhand939d3d2016-07-20 17:45:48 +053016353 qdf_mem_zero(&hdd_sta_ctx->conn_info.conn_flag,
16354 sizeof(hdd_sta_ctx->conn_info.conn_flag));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016355
Jeff Johnson20227a92018-03-13 09:41:05 -070016356 roam_profile = hdd_roam_profile(adapter);
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016357 if (roam_profile) {
Jeff Johnsond377dce2017-10-04 10:32:42 -070016358 struct hdd_station_ctx *sta_ctx;
Srinivas Girigowda576b2352017-08-25 14:44:26 -070016359
Jeff Johnsond377dce2017-10-04 10:32:42 -070016360 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016361
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016362 /* Restart the opportunistic timer
16363 *
16364 * If hw_mode_change_in_progress is true, then wait
16365 * till firmware sends the callback for hw_mode change.
16366 *
16367 * Else set connect_in_progress as true and proceed.
16368 */
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080016369 policy_mgr_restart_opportunistic_timer(
Dustin Brown76cd2932018-09-11 16:03:05 -070016370 hdd_ctx->psoc, false);
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080016371 if (policy_mgr_is_hw_mode_change_in_progress(
Dustin Brown76cd2932018-09-11 16:03:05 -070016372 hdd_ctx->psoc)) {
Abhishek Singh471652b2017-04-14 12:28:32 +053016373 qdf_status = policy_mgr_wait_for_connection_update(
Dustin Brown76cd2932018-09-11 16:03:05 -070016374 hdd_ctx->psoc);
Abhishek Singh471652b2017-04-14 12:28:32 +053016375 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016376 hdd_err("qdf wait for event failed!!");
16377 status = -EINVAL;
16378 goto ret_status;
16379 }
16380 }
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080016381 hdd_set_connection_in_progress(true);
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016382
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +053016383 status = ucfg_mlme_get_wmm_mode(hdd_ctx->psoc, &wmm_mode);
16384 if (!QDF_IS_STATUS_SUCCESS(status)) {
16385 hdd_err("Get wmm_mode failed");
16386 status = -EINVAL;
16387 goto ret_status;
16388 }
16389 if (HDD_WMM_USER_MODE_NO_QOS == wmm_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016390 /*QoS not enabled in cfg file */
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016391 roam_profile->uapsd_mask = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016392 } else {
16393 /*QoS enabled, update uapsd mask from cfg file */
Abhinav Kumar7d6f1ac2018-09-01 18:33:56 +053016394 status = ucfg_mlme_get_wmm_uapsd_mask(hdd_ctx->psoc,
16395 &value);
16396 if (!QDF_IS_STATUS_SUCCESS(status)) {
16397 hdd_err("Get uapsd_mask failed");
16398 status = -EINVAL;
16399 goto ret_status;
16400 }
16401 roam_profile->uapsd_mask = value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016402 }
16403
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016404 roam_profile->SSIDs.numOfSSIDs = 1;
16405 roam_profile->SSIDs.SSIDList->SSID.length = ssid_len;
16406 qdf_mem_zero(roam_profile->SSIDs.SSIDList->SSID.ssId,
16407 sizeof(roam_profile->SSIDs.SSIDList->SSID.ssId));
16408 qdf_mem_copy((void *)(roam_profile->SSIDs.SSIDList->SSID.ssId),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016409 ssid, ssid_len);
16410
Abhishek Singh3c9910e2017-01-06 17:56:47 +053016411 /* cleanup bssid hint */
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016412 qdf_mem_zero(roam_profile->bssid_hint.bytes,
Abhishek Singh3c9910e2017-01-06 17:56:47 +053016413 QDF_MAC_ADDR_SIZE);
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016414 qdf_mem_zero((void *)(roam_profile->BSSIDs.bssid),
Abhishek Singh3c9910e2017-01-06 17:56:47 +053016415 QDF_MAC_ADDR_SIZE);
16416
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016417 if (bssid) {
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016418 roam_profile->BSSIDs.numOfBSSIDs = 1;
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016419 qdf_mem_copy((void *)(roam_profile->BSSIDs.bssid),
Anurag Chouhan6d760662016-02-20 16:05:43 +053016420 bssid, QDF_MAC_ADDR_SIZE);
Krunal Soni31949422016-07-29 17:17:53 -070016421 /*
Jeff Johnsonfa7d9602018-05-06 11:25:31 -070016422 * Save BSSID in separate variable as
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016423 * roam_profile's BSSID is getting zeroed out in the
Krunal Soni31949422016-07-29 17:17:53 -070016424 * association process. In case of join failure
16425 * we should send valid BSSID to supplicant
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016426 */
Jeff Johnson731bc322017-10-14 19:53:44 -070016427 qdf_mem_copy(sta_ctx->requested_bssid.bytes,
16428 bssid, QDF_MAC_ADDR_SIZE);
Srinivas Girigowda13d39252017-03-06 16:12:15 -080016429 hdd_debug("bssid is given by upper layer %pM", bssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016430 } else if (bssid_hint) {
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016431 qdf_mem_copy(roam_profile->bssid_hint.bytes,
Abhishek Singh3c9910e2017-01-06 17:56:47 +053016432 bssid_hint, QDF_MAC_ADDR_SIZE);
Krunal Soni31949422016-07-29 17:17:53 -070016433 /*
16434 * Save BSSID in a separate variable as
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016435 * roam_profile's BSSID is getting zeroed out in the
Krunal Soni31949422016-07-29 17:17:53 -070016436 * association process. In case of join failure
16437 * we should send valid BSSID to supplicant
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016438 */
Jeff Johnson731bc322017-10-14 19:53:44 -070016439 qdf_mem_copy(sta_ctx->requested_bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +053016440 bssid_hint, QDF_MAC_ADDR_SIZE);
Srinivas Girigowda13d39252017-03-06 16:12:15 -080016441 hdd_debug("bssid_hint is given by upper layer %pM",
Krunal Soni35b404c2016-07-14 23:36:00 -070016442 bssid_hint);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016443 }
16444
Srinivas Girigowda13d39252017-03-06 16:12:15 -080016445 hdd_debug("Connect to SSID: %.*s operating Channel: %u",
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016446 roam_profile->SSIDs.SSIDList->SSID.length,
16447 roam_profile->SSIDs.SSIDList->SSID.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016448 operatingChannel);
16449
Jeff Johnsonce4a8342017-10-14 13:12:22 -070016450 if (hdd_sta_ctx->wpa_versions) {
Jeff Johnson784efe22019-03-09 18:31:13 -080016451 hdd_set_genie_to_csr(adapter, &rsn_auth_type);
16452 hdd_set_csr_auth_type(adapter, rsn_auth_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016453 }
16454#ifdef FEATURE_WLAN_WAPI
Jeff Johnson7d2f4c62017-11-02 09:25:45 -070016455 if (adapter->wapi_info.wapi_mode) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080016456 hdd_debug("Setting WAPI AUTH Type and Encryption Mode values");
Jeff Johnson7d2f4c62017-11-02 09:25:45 -070016457 switch (adapter->wapi_info.wapi_auth_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016458 case WAPI_AUTH_MODE_PSK:
16459 {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080016460 hdd_debug("WAPI AUTH TYPE: PSK: %d",
Jeff Johnson7d2f4c62017-11-02 09:25:45 -070016461 adapter->wapi_info.wapi_auth_mode);
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016462 roam_profile->AuthType.authType[0] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016463 eCSR_AUTH_TYPE_WAPI_WAI_PSK;
16464 break;
16465 }
16466 case WAPI_AUTH_MODE_CERT:
16467 {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080016468 hdd_debug("WAPI AUTH TYPE: CERT: %d",
Jeff Johnson7d2f4c62017-11-02 09:25:45 -070016469 adapter->wapi_info.wapi_auth_mode);
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016470 roam_profile->AuthType.authType[0] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016471 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
16472 break;
16473 }
Jeff Johnson7d2f4c62017-11-02 09:25:45 -070016474 default:
16475 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016476 } /* End of switch */
Jeff Johnson7d2f4c62017-11-02 09:25:45 -070016477 if (adapter->wapi_info.wapi_auth_mode ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016478 WAPI_AUTH_MODE_PSK
Jeff Johnson7d2f4c62017-11-02 09:25:45 -070016479 || adapter->wapi_info.wapi_auth_mode ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016480 WAPI_AUTH_MODE_CERT) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080016481 hdd_debug("WAPI PAIRWISE/GROUP ENCRYPTION: WPI");
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016482 roam_profile->AuthType.numEntries = 1;
16483 roam_profile->EncryptionType.numEntries = 1;
16484 roam_profile->EncryptionType.encryptionType[0] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016485 eCSR_ENCRYPT_TYPE_WPI;
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016486 roam_profile->mcEncryptionType.numEntries = 1;
16487 roam_profile->mcEncryptionType.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016488 encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
16489 }
16490 }
Krunal Soni31949422016-07-29 17:17:53 -070016491#endif
Min Liu8c5d99e2018-09-10 17:18:44 +080016492 vdev = hdd_objmgr_get_vdev(adapter);
16493 if (!vdev) {
16494 status = -EINVAL;
16495 goto conn_failure;
16496 }
16497 ucfg_pmo_flush_gtk_offload_req(vdev);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +053016498 hdd_objmgr_put_vdev(vdev);
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016499 roam_profile->csrPersona = adapter->device_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016500
16501 if (operatingChannel) {
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016502 roam_profile->ChannelInfo.ChannelList =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016503 &operatingChannel;
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016504 roam_profile->ChannelInfo.numOfChannels = 1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016505 } else {
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016506 roam_profile->ChannelInfo.ChannelList = NULL;
16507 roam_profile->ChannelInfo.numOfChannels = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016508 }
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016509 if ((QDF_IBSS_MODE == adapter->device_mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016510 && operatingChannel) {
16511 /*
16512 * Need to post the IBSS power save parameters
16513 * to WMA. WMA will configure this parameters
16514 * to firmware if power save is enabled by the
16515 * firmware.
16516 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016517 qdf_status = hdd_set_ibss_power_save_params(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016518
Abhishek Singh471652b2017-04-14 12:28:32 +053016519 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070016520 hdd_err("Set IBSS Power Save Params Failed");
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016521 status = -EINVAL;
16522 goto conn_failure;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016523 }
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016524 roam_profile->ch_params.ch_width =
Naveen Rawatc77e6e72016-08-05 15:19:03 -070016525 hdd_map_nl_chan_width(ch_width);
Nitesh Shah87335a52016-09-05 15:47:32 +053016526 /*
16527 * In IBSS mode while operating in 2.4 GHz,
16528 * the device supports only 20 MHz.
16529 */
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070016530 if (WLAN_REG_IS_24GHZ_CH(operatingChannel))
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016531 roam_profile->ch_params.ch_width =
Nitesh Shah87335a52016-09-05 15:47:32 +053016532 CH_WIDTH_20MHZ;
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016533 hdd_select_cbmode(adapter, operatingChannel,
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016534 &roam_profile->ch_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016535 }
16536
Jeff Johnson20227a92018-03-13 09:41:05 -070016537 if (wlan_hdd_cfg80211_check_pmf_valid(roam_profile)) {
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016538 status = -EINVAL;
16539 goto conn_failure;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016540 }
16541
Krunal Soni31949422016-07-29 17:17:53 -070016542 /*
16543 * After 8-way handshake supplicant should give the scan command
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016544 * in that it update the additional IEs, But because of scan
Krunal Soni31949422016-07-29 17:17:53 -070016545 * enhancements, the supplicant is not issuing the scan command
16546 * now. So the unicast frames which are sent from the host are
16547 * not having the additional IEs. If it is P2P CLIENT and there
16548 * is no additional IE present in roamProfile, then use the
16549 * addtional IE form scan_info
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016550 */
16551
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016552 if ((adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016553 (!roam_profile->pAddIEScan)) {
16554 roam_profile->pAddIEScan =
Jeff Johnson37fa0402017-10-28 12:42:29 -070016555 &adapter->scan_info.scan_add_ie.addIEdata[0];
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016556 roam_profile->nAddIEScanLength =
Jeff Johnson37fa0402017-10-28 12:42:29 -070016557 adapter->scan_info.scan_add_ie.length;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016558 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016559
Dustin Brown76cd2932018-09-11 16:03:05 -070016560 if ((policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc) == true)
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016561 && (false == wlan_hdd_handle_sap_sta_dfs_conc(adapter,
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016562 roam_profile))) {
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016563 hdd_err("sap-sta conc will fail, can't allow sta");
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016564 hdd_conn_set_connection_state(adapter,
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016565 eConnectionState_NotConnected);
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016566 status = -ENOMEM;
16567 goto conn_failure;
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016568 }
16569
Anurag Chouhan600c3a02016-03-01 10:33:54 +053016570 sme_config = qdf_mem_malloc(sizeof(*sme_config));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016571 if (!sme_config) {
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016572 hdd_conn_set_connection_state(adapter,
Rajeev Kumar249ea8d2016-04-15 16:57:46 -070016573 eConnectionState_NotConnected);
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016574 status = -ENOMEM;
16575 goto conn_failure;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016576 }
Jeff Johnson34fc63a2018-06-14 10:10:02 -070016577
16578 mac_handle = hdd_ctx->mac_handle;
16579 sme_get_config_param(mac_handle, sme_config);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016580 /* These values are not sessionized. So, any change in these SME
16581 * configs on an older or parallel interface will affect the
16582 * cb mode. So, restoring the default INI params before starting
16583 * interfaces such as sta, cli etc.,
16584 */
Wu Gaoed616a12019-01-16 15:19:21 +080016585 ucfg_mlme_get_channel_bonding_5ghz(hdd_ctx->psoc,
16586 &channel_bonding_mode);
Jeff Johnsone94ccd02019-04-02 15:02:56 -070016587 sme_config->csr_config.channelBondingMode5GHz =
Wu Gaoed616a12019-01-16 15:19:21 +080016588 channel_bonding_mode;
16589 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
16590 &channel_bonding_mode);
Jeff Johnsone94ccd02019-04-02 15:02:56 -070016591 sme_config->csr_config.channelBondingMode24GHz =
Wu Gaoed616a12019-01-16 15:19:21 +080016592 channel_bonding_mode;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070016593 sme_update_config(mac_handle, sme_config);
Anurag Chouhan600c3a02016-03-01 10:33:54 +053016594 qdf_mem_free(sme_config);
Agrawal Ashish6b015762016-05-05 11:22:18 +053016595 /*
16596 * Change conn_state to connecting before sme_roam_connect(),
16597 * because sme_roam_connect() has a direct path to call
16598 * hdd_sme_roam_callback(), which will change the conn_state
16599 * If direct path, conn_state will be accordingly changed to
16600 * NotConnected or Associated by either
16601 * hdd_association_completion_handler() or
16602 * hdd_dis_connect_handler() in sme_RoamCallback()if
16603 * sme_RomConnect is to be queued,
16604 * Connecting state will remain until it is completed.
16605 *
16606 * If connection state is not changed, connection state will
16607 * remain in eConnectionState_NotConnected state.
16608 * In hdd_association_completion_handler, "hddDisconInProgress"
16609 * is set to true if conn state is
16610 * eConnectionState_NotConnected.
16611 * If "hddDisconInProgress" is set to true then cfg80211 layer
16612 * is not informed of connect result indication which
16613 * is an issue.
16614 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016615 if (QDF_STA_MODE == adapter->device_mode ||
16616 QDF_P2P_CLIENT_MODE == adapter->device_mode)
16617 hdd_conn_set_connection_state(adapter,
Agrawal Ashish6b015762016-05-05 11:22:18 +053016618 eConnectionState_Connecting);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016619
Alok Kumarb64650c2018-03-23 17:05:11 +053016620 hdd_set_disconnect_status(adapter, false);
16621
Jingxiang Geb49aa302018-01-17 20:54:15 +080016622 qdf_runtime_pm_prevent_suspend(
16623 &hdd_ctx->runtime_context.connect);
Padma, Santhosh Kumarc88de482018-04-09 16:17:04 +053016624 hdd_prevent_suspend_timeout(HDD_WAKELOCK_CONNECT_COMPLETE,
Dustin Brownceed67e2017-05-26 11:57:31 -070016625 WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Jeff Johnson34fc63a2018-06-14 10:10:02 -070016626 qdf_status = sme_roam_connect(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080016627 adapter->vdev_id, roam_profile,
Jeff Johnson29c78672019-02-26 21:05:53 -080016628 &roam_id);
Abhishek Singh471652b2017-04-14 12:28:32 +053016629 if (QDF_IS_STATUS_ERROR(qdf_status))
16630 status = qdf_status_to_os_return(qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016631
Rajeev Kumard31e1542017-01-13 14:37:42 -080016632 if ((QDF_STATUS_SUCCESS != qdf_status) &&
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016633 (QDF_STA_MODE == adapter->device_mode ||
16634 QDF_P2P_CLIENT_MODE == adapter->device_mode)) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070016635 hdd_err("sme_roam_connect (session %d) failed with "
Rajeev Kumard31e1542017-01-13 14:37:42 -080016636 "qdf_status %d. -> NotConnected",
Jeff Johnsoncf07c312019-02-04 13:53:29 -080016637 adapter->vdev_id, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016638 /* change back to NotAssociated */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016639 hdd_conn_set_connection_state(adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016640 eConnectionState_NotConnected);
Jingxiang Geb49aa302018-01-17 20:54:15 +080016641 qdf_runtime_pm_allow_suspend(
16642 &hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -070016643 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016644 }
16645
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016646 /* Reset connect_in_progress */
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080016647 hdd_set_connection_in_progress(false);
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016648
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016649 roam_profile->ChannelInfo.ChannelList = NULL;
16650 roam_profile->ChannelInfo.numOfChannels = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016651
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016652 if ((QDF_STA_MODE == adapter->device_mode)
Dustin Brown76cd2932018-09-11 16:03:05 -070016653 && policy_mgr_is_current_hwmode_dbs(hdd_ctx->psoc)
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080016654 && !policy_mgr_is_hw_dbs_2x2_capable(
Dustin Brown76cd2932018-09-11 16:03:05 -070016655 hdd_ctx->psoc)) {
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080016656 policy_mgr_get_channel_from_scan_result(
Dustin Brown76cd2932018-09-11 16:03:05 -070016657 hdd_ctx->psoc,
Jeff Johnson5b34fce2017-10-13 13:24:51 -070016658 roam_profile, &channel);
Archana Ramachandrancc0ffb12017-02-17 18:30:43 -080016659 hdd_info("Move to single MAC mode(optimization) if applicable");
Nitesh Shah044fd672016-10-13 18:53:25 +053016660 if (channel)
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080016661 policy_mgr_checkn_update_hw_mode_single_mac_mode(
Dustin Brown76cd2932018-09-11 16:03:05 -070016662 hdd_ctx->psoc, channel);
Nitesh Shah044fd672016-10-13 18:53:25 +053016663 }
16664
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016665 } else {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070016666 hdd_err("No valid Roam profile");
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016667 status = -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016668 }
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016669 goto ret_status;
16670
16671conn_failure:
16672 /* Reset connect_in_progress */
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080016673 hdd_set_connection_in_progress(false);
Nitesh Shaha3dfea32017-02-09 19:18:57 +053016674
16675ret_status:
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053016676 /*
16677 * Enable roaming on other STA adapter for failure case.
16678 * For success case, it is enabled in assoc completion handler
16679 */
16680 if (status)
16681 wlan_hdd_enable_roaming(adapter);
16682
Dustin Browne74003f2018-03-14 12:51:58 -070016683 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016684 return status;
16685}
16686
16687/**
16688 * wlan_hdd_cfg80211_set_auth_type() - set auth type
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016689 * @adapter: Pointer to adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016690 * @auth_type: Auth type
16691 *
16692 * This function is used to set the authentication type (OPEN/SHARED).
16693 *
16694 * Return: 0 for success, non-zero for failure
16695 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016696static int wlan_hdd_cfg80211_set_auth_type(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016697 enum nl80211_auth_type auth_type)
16698{
Jeff Johnsond377dce2017-10-04 10:32:42 -070016699 struct hdd_station_ctx *sta_ctx =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016700 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnson20227a92018-03-13 09:41:05 -070016701 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016702
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016703 /*set authentication type */
16704 switch (auth_type) {
16705 case NL80211_AUTHTYPE_AUTOMATIC:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080016706 hdd_debug("set authentication type to AUTOSWITCH");
Jeff Johnson96e33512019-02-27 15:10:21 -080016707 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_AUTOSWITCH;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016708 break;
16709
16710 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016711 case NL80211_AUTHTYPE_FT:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080016712 hdd_debug("set authentication type to OPEN");
Jeff Johnson96e33512019-02-27 15:10:21 -080016713 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016714 break;
16715
16716 case NL80211_AUTHTYPE_SHARED_KEY:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080016717 hdd_debug("set authentication type to SHARED");
Jeff Johnson96e33512019-02-27 15:10:21 -080016718 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_SHARED_KEY;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016719 break;
16720#ifdef FEATURE_WLAN_ESE
16721 case NL80211_AUTHTYPE_NETWORK_EAP:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080016722 hdd_debug("set authentication type to CCKM WPA");
Jeff Johnson96e33512019-02-27 15:10:21 -080016723 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016724 break;
16725#endif
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +053016726#if defined(WLAN_FEATURE_FILS_SK) && \
16727 (defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
16728 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)))
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053016729 case NL80211_AUTHTYPE_FILS_SK:
Dustin Brown5e89ef82018-03-14 11:50:23 -070016730 hdd_debug("set authentication type to FILS SHARED");
Jeff Johnson96e33512019-02-27 15:10:21 -080016731 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053016732 break;
16733#endif
Padma, Santhosh Kumar07eb80b2017-07-05 16:10:06 +053016734 case NL80211_AUTHTYPE_SAE:
16735 hdd_debug("set authentication type to SAE");
Jeff Johnson96e33512019-02-27 15:10:21 -080016736 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_SAE;
Padma, Santhosh Kumar07eb80b2017-07-05 16:10:06 +053016737 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016738 default:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080016739 hdd_err("Unsupported authentication type: %d", auth_type);
Jeff Johnson96e33512019-02-27 15:10:21 -080016740 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_UNKNOWN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016741 return -EINVAL;
16742 }
16743
Jeff Johnson20227a92018-03-13 09:41:05 -070016744 roam_profile = hdd_roam_profile(adapter);
Jeff Johnson96e33512019-02-27 15:10:21 -080016745 roam_profile->AuthType.authType[0] = sta_ctx->conn_info.auth_type;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016746 return 0;
16747}
16748
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +053016749#if defined(WLAN_FEATURE_FILS_SK) && \
16750 (defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
16751 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)))
Jeff Johnson20227a92018-03-13 09:41:05 -070016752static bool hdd_validate_fils_info_ptr(struct csr_roam_profile *roam_profile)
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053016753{
16754 struct cds_fils_connection_info *fils_con_info;
16755
Jeff Johnson20227a92018-03-13 09:41:05 -070016756 fils_con_info = roam_profile->fils_con_info;
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053016757 if (!fils_con_info) {
Varun Reddy Yeturu625a6412017-10-23 10:20:01 -070016758 hdd_err("No valid Roam profile");
16759 return false;
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053016760 }
16761
Varun Reddy Yeturu625a6412017-10-23 10:20:01 -070016762 return true;
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053016763}
Varun Reddy Yeturu625a6412017-10-23 10:20:01 -070016764
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016765static enum eAniAuthType wlan_hdd_get_fils_auth_type(
16766 enum nl80211_auth_type auth)
16767{
16768 switch (auth) {
16769 case NL80211_AUTHTYPE_FILS_SK:
16770 return SIR_FILS_SK_WITHOUT_PFS;
16771 case NL80211_AUTHTYPE_FILS_SK_PFS:
16772 return SIR_FILS_SK_WITH_PFS;
16773 case NL80211_AUTHTYPE_FILS_PK:
16774 return SIR_FILS_PK_AUTH;
16775 default:
16776 return eSIR_DONOT_USE_AUTH_TYPE;
16777 }
16778}
16779
Varun Reddy Yeturu448cb9d2017-11-20 20:36:31 -080016780static bool wlan_hdd_fils_data_in_limits(struct cfg80211_connect_params *req)
16781{
16782 hdd_debug("seq=%d auth=%d lengths: user=%zu rrk=%zu realm=%zu",
16783 req->fils_erp_next_seq_num, req->auth_type,
16784 req->fils_erp_username_len, req->fils_erp_rrk_len,
16785 req->fils_erp_realm_len);
16786 if (!req->fils_erp_rrk_len || !req->fils_erp_realm_len ||
16787 !req->fils_erp_username_len ||
16788 req->fils_erp_rrk_len > FILS_MAX_RRK_LENGTH ||
16789 req->fils_erp_realm_len > FILS_MAX_REALM_LEN ||
16790 req->fils_erp_username_len > FILS_MAX_KEYNAME_NAI_LENGTH) {
16791 hdd_err("length incorrect, user=%zu rrk=%zu realm=%zu",
16792 req->fils_erp_username_len, req->fils_erp_rrk_len,
16793 req->fils_erp_realm_len);
16794 return false;
16795 }
16796
bings77a35ac2018-06-01 15:10:44 +080016797 if (!req->fils_erp_rrk || !req->fils_erp_realm ||
16798 !req->fils_erp_username) {
16799 hdd_err("buffer incorrect, user=%pK rrk=%pK realm=%pK",
16800 req->fils_erp_username, req->fils_erp_rrk,
16801 req->fils_erp_realm);
16802 return false;
16803 }
16804
Varun Reddy Yeturu448cb9d2017-11-20 20:36:31 -080016805 return true;
16806}
16807
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016808/**
16809 * wlan_hdd_cfg80211_set_fils_config() - set fils config params during connect
16810 * @adapter: Pointer to adapter
16811 * @req: Pointer to fils parameters
16812 *
16813 * Return: 0 for success, non-zero for failure
16814 */
16815static int wlan_hdd_cfg80211_set_fils_config(struct hdd_adapter *adapter,
16816 struct cfg80211_connect_params *req)
16817{
Jeff Johnson61b5e982018-03-15 11:33:31 -070016818 struct csr_roam_profile *roam_profile;
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016819 enum eAniAuthType auth_type;
16820 uint8_t *buf;
Karthik Kantamneni2231a232018-09-11 15:45:55 +053016821 bool value;
16822 QDF_STATUS status;
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016823 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
16824
Jeff Johnson20227a92018-03-13 09:41:05 -070016825 roam_profile = hdd_roam_profile(adapter);
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016826
Karthik Kantamneni2231a232018-09-11 15:45:55 +053016827 value = 0;
Dustin Brown05d81302018-09-11 16:49:22 -070016828 status = ucfg_mlme_get_fils_enabled_info(hdd_ctx->psoc, &value);
Karthik Kantamneni2231a232018-09-11 15:45:55 +053016829 if (QDF_IS_STATUS_ERROR(status) || !value) {
16830 hdd_err("get_fils_enabled status: %d fils_enabled: %d",
16831 status, value);
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016832 return -EINVAL;
16833 }
Karthik Kantamneni2231a232018-09-11 15:45:55 +053016834
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016835 hdd_clear_fils_connection_info(adapter);
16836 roam_profile->fils_con_info =
16837 qdf_mem_malloc(sizeof(*roam_profile->fils_con_info));
16838
Min Liu74a1a502018-10-10 19:59:07 +080016839 if (!roam_profile->fils_con_info)
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016840 return -EINVAL;
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016841 /*
16842 * The initial connection for FILS may happen with an OPEN
16843 * auth type. Hence we need to allow the connection to go
16844 * through in that case as well. Below is_fils_connection
16845 * flag is propagated down to CSR and PE sessions through
Varun Reddy Yeturu448cb9d2017-11-20 20:36:31 -080016846 * the JOIN request. As the flag is used, do not free the
16847 * memory allocated to fils_con_info and return success.
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016848 */
16849 if (req->auth_type != NL80211_AUTHTYPE_FILS_SK) {
16850 roam_profile->fils_con_info->is_fils_connection = false;
16851 return 0;
16852 }
16853
16854 /*
16855 * Once above check is done, then we can check for valid FILS
16856 * auth types. Currently only NL80211_AUTHTYPE_FILS_SK is
16857 * supported. Once all auth types are supported, then we can
16858 * merge these 2 conditions into one.
16859 */
16860 auth_type = wlan_hdd_get_fils_auth_type(req->auth_type);
16861 if (auth_type == eSIR_DONOT_USE_AUTH_TYPE) {
16862 hdd_err("invalid auth type for fils %d", req->auth_type);
Varun Reddy Yeturu82e39cd2017-10-16 12:04:05 -070016863 goto fils_conn_fail;
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016864 }
Varun Reddy Yeturu448cb9d2017-11-20 20:36:31 -080016865 if (!wlan_hdd_fils_data_in_limits(req))
Jeff Johnsonb8adae42018-02-27 16:12:00 -080016866 goto fils_conn_fail;
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016867
16868 roam_profile->fils_con_info->is_fils_connection = true;
16869 roam_profile->fils_con_info->sequence_number =
Pragaspathi Thilagaraj87a60af2019-02-20 20:42:47 +053016870 (req->fils_erp_next_seq_num + 1);
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016871 roam_profile->fils_con_info->auth_type = auth_type;
16872
16873 roam_profile->fils_con_info->r_rk_length =
16874 req->fils_erp_rrk_len;
16875 if (req->fils_erp_rrk_len)
16876 qdf_mem_copy(roam_profile->fils_con_info->r_rk,
16877 req->fils_erp_rrk,
16878 roam_profile->fils_con_info->r_rk_length);
16879
16880 roam_profile->fils_con_info->realm_len = req->fils_erp_realm_len;
16881 if (req->fils_erp_realm_len)
16882 qdf_mem_copy(roam_profile->fils_con_info->realm,
16883 req->fils_erp_realm,
16884 roam_profile->fils_con_info->realm_len);
16885
16886 roam_profile->fils_con_info->key_nai_length =
16887 req->fils_erp_username_len + sizeof(char) +
16888 req->fils_erp_realm_len;
16889 hdd_debug("key_nai_length = %d",
16890 roam_profile->fils_con_info->key_nai_length);
Varun Reddy Yeturu82e39cd2017-10-16 12:04:05 -070016891 if (roam_profile->fils_con_info->key_nai_length >
16892 FILS_MAX_KEYNAME_NAI_LENGTH) {
16893 hdd_err("Do not allow FILS conn due to excess NAI Length %d",
16894 roam_profile->fils_con_info->key_nai_length);
16895 goto fils_conn_fail;
16896 }
Varun Reddy Yeturu448cb9d2017-11-20 20:36:31 -080016897 buf = roam_profile->fils_con_info->keyname_nai;
16898 qdf_mem_copy(buf, req->fils_erp_username, req->fils_erp_username_len);
16899 buf += req->fils_erp_username_len;
16900 *buf++ = '@';
16901 qdf_mem_copy(buf, req->fils_erp_realm, req->fils_erp_realm_len);
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016902
16903 return 0;
Varun Reddy Yeturu82e39cd2017-10-16 12:04:05 -070016904
16905fils_conn_fail:
16906 if (roam_profile->fils_con_info) {
16907 qdf_mem_free(roam_profile->fils_con_info);
16908 roam_profile->fils_con_info = NULL;
16909 }
16910 return -EINVAL;
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016911}
16912
Varun Reddy Yeturu625a6412017-10-23 10:20:01 -070016913static bool wlan_hdd_is_akm_suite_fils(uint32_t key_mgmt)
16914{
16915 switch (key_mgmt) {
16916 case WLAN_AKM_SUITE_FILS_SHA256:
16917 case WLAN_AKM_SUITE_FILS_SHA384:
16918 case WLAN_AKM_SUITE_FT_FILS_SHA256:
16919 case WLAN_AKM_SUITE_FT_FILS_SHA384:
16920 return true;
16921 default:
16922 return false;
16923 }
16924}
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016925
16926static bool wlan_hdd_is_conn_type_fils(struct cfg80211_connect_params *req)
16927{
16928 enum nl80211_auth_type auth_type = req->auth_type;
16929 /*
16930 * Below n_akm_suites is defined as int in the kernel, even though it
16931 * is supposed to be unsigned.
16932 */
16933 int num_akm_suites = req->crypto.n_akm_suites;
16934 uint32_t key_mgmt = req->crypto.akm_suites[0];
16935 enum eAniAuthType fils_auth_type =
16936 wlan_hdd_get_fils_auth_type(req->auth_type);
16937
16938 hdd_debug("Num of AKM suites = %d", num_akm_suites);
16939 if (num_akm_suites <= 0)
16940 return false;
16941
16942 /*
16943 * Auth type will be either be OPEN or FILS type for a FILS connection
16944 */
16945 if ((auth_type != NL80211_AUTHTYPE_OPEN_SYSTEM) &&
16946 (fils_auth_type == eSIR_DONOT_USE_AUTH_TYPE)) {
16947 hdd_debug("Not a FILS auth type, auth = %d, fils auth = %d",
16948 auth_type, fils_auth_type);
16949 return false;
16950 }
16951
16952 if (!wlan_hdd_is_akm_suite_fils(key_mgmt)) {
16953 hdd_debug("Not a FILS AKM SUITE %d", key_mgmt);
16954 return false;
16955 }
16956
16957 return true;
16958}
16959
Varun Reddy Yeturu625a6412017-10-23 10:20:01 -070016960#else
Jeff Johnson20227a92018-03-13 09:41:05 -070016961static bool hdd_validate_fils_info_ptr(struct csr_roam_profile *roam_profile)
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016962{
16963 return true;
16964}
16965
16966static int wlan_hdd_cfg80211_set_fils_config(struct hdd_adapter *adapter,
16967 struct cfg80211_connect_params *req)
16968{
16969 return 0;
16970}
16971
Varun Reddy Yeturu625a6412017-10-23 10:20:01 -070016972static bool wlan_hdd_is_akm_suite_fils(uint32_t key_mgmt)
16973{
16974 return false;
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053016975}
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070016976
16977static bool wlan_hdd_is_conn_type_fils(struct cfg80211_connect_params *req)
16978{
16979 return false;
16980}
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053016981#endif
16982
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016983/**
16984 * wlan_hdd_set_akm_suite() - set key management type
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016985 * @adapter: Pointer to adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016986 * @key_mgmt: Key management type
16987 *
16988 * This function is used to set the key mgmt type(PSK/8021x).
16989 *
16990 * Return: 0 for success, non-zero for failure
16991 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070016992static int wlan_hdd_set_akm_suite(struct hdd_adapter *adapter, u32 key_mgmt)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016993{
Jeff Johnson37ecea42018-03-18 17:54:40 -070016994 struct hdd_station_ctx *sta_ctx;
Jeff Johnson61b5e982018-03-15 11:33:31 -070016995 struct csr_roam_profile *roam_profile;
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053016996
Jeff Johnson20227a92018-03-13 09:41:05 -070016997 roam_profile = hdd_roam_profile(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016998
Varun Reddy Yeturu625a6412017-10-23 10:20:01 -070016999 if (wlan_hdd_is_akm_suite_fils(key_mgmt) &&
Jeff Johnson20227a92018-03-13 09:41:05 -070017000 !hdd_validate_fils_info_ptr(roam_profile))
Varun Reddy Yeturu625a6412017-10-23 10:20:01 -070017001 return -EINVAL;
Vidyullatha Kanchanapally7b5bee02017-04-13 14:00:56 +053017002#ifndef WLAN_AKM_SUITE_8021X_SHA256
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017003#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally7b5bee02017-04-13 14:00:56 +053017004#endif
17005#ifndef WLAN_AKM_SUITE_PSK_SHA256
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017006#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally7b5bee02017-04-13 14:00:56 +053017007#endif
Jeff Johnson37ecea42018-03-18 17:54:40 -070017008
17009 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
17010
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017011 /*set key mgmt type */
17012 switch (key_mgmt) {
17013 case WLAN_AKM_SUITE_PSK:
17014 case WLAN_AKM_SUITE_PSK_SHA256:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017015 case WLAN_AKM_SUITE_FT_PSK:
Abhishek Singh02cb9e02017-08-30 17:39:50 +053017016 case WLAN_AKM_SUITE_DPP_RSN:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017017 hdd_debug("setting key mgmt type to PSK");
Jeff Johnson37ecea42018-03-18 17:54:40 -070017018 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_PSK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017019 break;
17020
17021 case WLAN_AKM_SUITE_8021X_SHA256:
17022 case WLAN_AKM_SUITE_8021X:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017023 case WLAN_AKM_SUITE_FT_8021X:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017024 hdd_debug("setting key mgmt type to 8021x");
Jeff Johnson37ecea42018-03-18 17:54:40 -070017025 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017026 break;
17027#ifdef FEATURE_WLAN_ESE
17028#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017029 case WLAN_AKM_SUITE_CCKM:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017030 hdd_debug("setting key mgmt type to CCKM");
Jeff Johnson37ecea42018-03-18 17:54:40 -070017031 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_CCKM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017032 break;
17033#endif
17034#ifndef WLAN_AKM_SUITE_OSEN
17035#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
17036#endif
17037 case WLAN_AKM_SUITE_OSEN:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017038 hdd_debug("setting key mgmt type to OSEN");
Jeff Johnson37ecea42018-03-18 17:54:40 -070017039 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017040 break;
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +053017041#if defined(WLAN_FEATURE_FILS_SK) && \
17042 (defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
17043 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)))
Sridhar Selvaraj6cf642f2017-08-21 14:28:10 +053017044 case WLAN_AKM_SUITE_FILS_SHA256:
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053017045 hdd_debug("setting key mgmt type to FILS SHA256");
Jeff Johnson37ecea42018-03-18 17:54:40 -070017046 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053017047 roam_profile->fils_con_info->akm_type =
17048 eCSR_AUTH_TYPE_FILS_SHA256;
17049 break;
17050
17051 case WLAN_AKM_SUITE_FILS_SHA384:
Varun Reddy Yeturu625a6412017-10-23 10:20:01 -070017052 hdd_debug("setting key mgmt type to FILS SHA384");
Jeff Johnson37ecea42018-03-18 17:54:40 -070017053 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053017054 roam_profile->fils_con_info->akm_type =
17055 eCSR_AUTH_TYPE_FILS_SHA384;
17056 break;
17057
17058 case WLAN_AKM_SUITE_FT_FILS_SHA256:
Varun Reddy Yeturu625a6412017-10-23 10:20:01 -070017059 hdd_debug("setting key mgmt type to FILS FT SHA256");
Jeff Johnson37ecea42018-03-18 17:54:40 -070017060 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053017061 roam_profile->fils_con_info->akm_type =
17062 eCSR_AUTH_TYPE_FT_FILS_SHA256;
17063 break;
17064
17065 case WLAN_AKM_SUITE_FT_FILS_SHA384:
Varun Reddy Yeturu625a6412017-10-23 10:20:01 -070017066 hdd_debug("setting key mgmt type to FILS FT SHA384");
Jeff Johnson37ecea42018-03-18 17:54:40 -070017067 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053017068 roam_profile->fils_con_info->akm_type =
17069 eCSR_AUTH_TYPE_FT_FILS_SHA384;
Sridhar Selvaraj6cf642f2017-08-21 14:28:10 +053017070 break;
17071#endif
Padma, Santhosh Kumarc69ce072017-11-06 18:21:05 +053017072
17073 case WLAN_AKM_SUITE_OWE:
17074 hdd_debug("setting key mgmt type to OWE");
Jeff Johnson37ecea42018-03-18 17:54:40 -070017075 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
Padma, Santhosh Kumarc69ce072017-11-06 18:21:05 +053017076 break;
17077
Padma, Santhosh Kumare587a5c2017-12-21 12:44:46 +053017078 case WLAN_AKM_SUITE_EAP_SHA256:
17079 hdd_debug("setting key mgmt type to EAP_SHA256");
Jeff Johnson37ecea42018-03-18 17:54:40 -070017080 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
Padma, Santhosh Kumare587a5c2017-12-21 12:44:46 +053017081 break;
17082 case WLAN_AKM_SUITE_EAP_SHA384:
17083 hdd_debug("setting key mgmt type to EAP_SHA384");
Jeff Johnson37ecea42018-03-18 17:54:40 -070017084 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
Padma, Santhosh Kumare587a5c2017-12-21 12:44:46 +053017085 break;
17086
Padma, Santhosh Kumar07eb80b2017-07-05 16:10:06 +053017087 case WLAN_AKM_SUITE_SAE:
17088 hdd_debug("setting key mgmt type to SAE");
Jeff Johnson37ecea42018-03-18 17:54:40 -070017089 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
Padma, Santhosh Kumar07eb80b2017-07-05 16:10:06 +053017090 break;
17091
Pragaspathi Thilagarajeb367282019-02-19 00:42:28 +053017092 case WLAN_AKM_SUITE_FT_SAE:
17093 hdd_debug("setting key mgmt type to FT-SAE");
17094 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
17095 break;
17096
17097 case WLAN_AKM_SUITE_FT_EAP_SHA_384:
17098 hdd_debug("setting key mgmt type to FT-EAP-SHA384");
17099 sta_ctx->auth_key_mgmt |= HDD_AUTH_KEY_MGMT_802_1X;
17100 break;
17101
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017102 default:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017103 hdd_err("Unsupported key mgmt type: %d", key_mgmt);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017104 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017105 }
17106 return 0;
17107}
17108
17109/**
17110 * wlan_hdd_cfg80211_set_cipher() - set encryption type
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017111 * @adapter: Pointer to adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017112 * @cipher: Cipher type
17113 * @ucast: Unicast flag
17114 *
17115 * This function is used to set the encryption type
17116 * (NONE/WEP40/WEP104/TKIP/CCMP).
17117 *
17118 * Return: 0 for success, non-zero for failure
17119 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017120static int wlan_hdd_cfg80211_set_cipher(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017121 u32 cipher, bool ucast)
17122{
17123 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Jeff Johnsond377dce2017-10-04 10:32:42 -070017124 struct hdd_station_ctx *sta_ctx =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017125 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnson20227a92018-03-13 09:41:05 -070017126 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017127
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017128 if (!cipher) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017129 hdd_debug("received cipher %d - considering none", cipher);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017130 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17131 } else {
17132
17133 /*set encryption method */
17134 switch (cipher) {
17135 case IW_AUTH_CIPHER_NONE:
17136 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17137 break;
17138
17139 case WLAN_CIPHER_SUITE_WEP40:
17140 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
17141 break;
17142
17143 case WLAN_CIPHER_SUITE_WEP104:
17144 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
17145 break;
17146
17147 case WLAN_CIPHER_SUITE_TKIP:
17148 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
17149 break;
17150
17151 case WLAN_CIPHER_SUITE_CCMP:
17152 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17153 break;
17154#ifdef FEATURE_WLAN_WAPI
17155 case WLAN_CIPHER_SUITE_SMS4:
17156 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
17157 break;
17158#endif
17159
17160#ifdef FEATURE_WLAN_ESE
17161 case WLAN_CIPHER_SUITE_KRK:
17162 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
17163 break;
17164#ifdef WLAN_FEATURE_ROAM_OFFLOAD
17165 case WLAN_CIPHER_SUITE_BTK:
17166 encryptionType = eCSR_ENCRYPT_TYPE_BTK;
17167 break;
17168#endif
17169#endif
Mukul Sharma05504ac2017-06-08 12:35:53 +053017170 case WLAN_CIPHER_SUITE_GCMP:
17171 encryptionType = eCSR_ENCRYPT_TYPE_AES_GCMP;
17172 break;
17173 case WLAN_CIPHER_SUITE_GCMP_256:
17174 encryptionType = eCSR_ENCRYPT_TYPE_AES_GCMP_256;
17175 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017176 default:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017177 hdd_err("Unsupported cipher type: %d", cipher);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017178 return -EOPNOTSUPP;
17179 }
17180 }
17181
Jeff Johnson20227a92018-03-13 09:41:05 -070017182 roam_profile = hdd_roam_profile(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017183 if (ucast) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017184 hdd_debug("setting unicast cipher type to %d", encryptionType);
Jeff Johnsonb1959842019-02-27 13:04:04 -080017185 sta_ctx->conn_info.uc_encrypt_type = encryptionType;
Jeff Johnson20227a92018-03-13 09:41:05 -070017186 roam_profile->EncryptionType.numEntries = 1;
17187 roam_profile->EncryptionType.encryptionType[0] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017188 encryptionType;
17189 } else {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017190 hdd_debug("setting mcast cipher type to %d", encryptionType);
Jeff Johnsonb1959842019-02-27 13:04:04 -080017191 sta_ctx->conn_info.mc_encrypt_type = encryptionType;
Jeff Johnson20227a92018-03-13 09:41:05 -070017192 roam_profile->mcEncryptionType.numEntries = 1;
17193 roam_profile->mcEncryptionType.encryptionType[0] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017194 encryptionType;
17195 }
17196
17197 return 0;
17198}
17199
17200/**
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017201 * wlan_hdd_add_assoc_ie() - Add Assoc IE to roamProfile
Jeff Johnson20227a92018-03-13 09:41:05 -070017202 * @adapter: Pointer to adapter
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017203 * @gen_ie: Pointer to IE data
17204 * @len: length of IE data
17205 *
17206 * Return: 0 for success, non-zero for failure
17207 */
Jeff Johnson20227a92018-03-13 09:41:05 -070017208static int wlan_hdd_add_assoc_ie(struct hdd_adapter *adapter,
17209 const uint8_t *gen_ie, uint16_t len)
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017210{
Jeff Johnson20227a92018-03-13 09:41:05 -070017211 struct csr_roam_profile *roam_profile;
17212 tSirAddie *assoc_add_ie;
17213 uint16_t cur_add_ie_len;
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017214
Jeff Johnson20227a92018-03-13 09:41:05 -070017215 assoc_add_ie = hdd_assoc_additional_ie(adapter);
17216 cur_add_ie_len = assoc_add_ie->length;
17217 if (SIR_MAC_MAX_ADD_IE_LENGTH < (cur_add_ie_len + len)) {
17218 hdd_err("current len %u, new ie of len %u will overflow",
17219 cur_add_ie_len, len);
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017220 return -ENOMEM;
17221 }
Jeff Johnson20227a92018-03-13 09:41:05 -070017222 memcpy(assoc_add_ie->addIEdata + cur_add_ie_len, gen_ie, len);
17223 assoc_add_ie->length += len;
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017224
Jeff Johnson20227a92018-03-13 09:41:05 -070017225 roam_profile = hdd_roam_profile(adapter);
17226 roam_profile->pAddIEAssoc = assoc_add_ie->addIEdata;
17227 roam_profile->nAddIEAssocLength = assoc_add_ie->length;
17228
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017229 return 0;
17230}
17231
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053017232#ifdef WLAN_FEATURE_FILS_SK
17233/**
17234 * wlan_hdd_save_hlp_ie - API to save HLP IE
17235 * @roam_profile: Pointer to roam profile
17236 * @gen_ie: IE buffer to store
17237 * @len: length of the IE buffer @gen_ie
17238 * @flush: Flush the older saved HLP if any
17239 *
17240 * Return: None
17241 */
Jeff Johnson61b5e982018-03-15 11:33:31 -070017242static void wlan_hdd_save_hlp_ie(struct csr_roam_profile *roam_profile,
Jeff Johnson20227a92018-03-13 09:41:05 -070017243 const uint8_t *gen_ie, uint16_t len,
17244 bool flush)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053017245{
17246 uint8_t *hlp_ie = roam_profile->hlp_ie;
17247
17248 if (flush) {
17249 roam_profile->hlp_ie_len = 0;
17250 if (hlp_ie) {
17251 qdf_mem_free(hlp_ie);
17252 roam_profile->hlp_ie = NULL;
17253 }
17254 }
17255
17256 if ((roam_profile->hlp_ie_len +
17257 len) > FILS_MAX_HLP_DATA_LEN) {
17258 hdd_err("HLP len exceeds: hlp_ie_len %d len %d",
17259 roam_profile->hlp_ie_len, len);
17260 return;
17261 }
17262
17263 if (!roam_profile->hlp_ie) {
17264 roam_profile->hlp_ie =
17265 qdf_mem_malloc(FILS_MAX_HLP_DATA_LEN);
17266 hlp_ie = roam_profile->hlp_ie;
Min Liu74a1a502018-10-10 19:59:07 +080017267 if (!hlp_ie)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053017268 return;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053017269 }
17270
17271 qdf_mem_copy(hlp_ie + roam_profile->hlp_ie_len, gen_ie, len);
17272 roam_profile->hlp_ie_len += len;
17273}
17274#else
Jeff Johnson61b5e982018-03-15 11:33:31 -070017275static inline void wlan_hdd_save_hlp_ie(struct csr_roam_profile *roam_profile,
Jeff Johnson20227a92018-03-13 09:41:05 -070017276 const uint8_t *gen_ie, uint16_t len,
17277 bool flush)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053017278{}
17279#endif
Arif Hussainf8f6b3b2019-01-10 19:42:09 -080017280
17281#ifdef WLAN_CONV_CRYPTO_SUPPORTED
17282/**
17283 * hdd_populate_crypto_auth_type() - populate auth type for crypto
17284 * @vdev: pointed to vdev obmgr
17285 * @auth_type: legacy auth_type
17286 *
17287 * set the crypto auth type for corresponding auth type received
17288 * from NL
17289 *
17290 * Return: None
17291 */
17292static void hdd_populate_crypto_auth_type(struct wlan_objmgr_vdev *vdev,
17293 enum nl80211_auth_type auth_type)
17294{
17295 QDF_STATUS status;
17296 uint32_t set_val = 0;
17297 wlan_crypto_auth_mode crypto_auth_type =
17298 osif_nl_to_crypto_auth_type(auth_type);
17299
17300 hdd_debug("set auth type %d to crypto component", crypto_auth_type);
17301 HDD_SET_BIT(set_val, crypto_auth_type);
17302 status = wlan_crypto_set_vdev_param(vdev,
17303 WLAN_CRYPTO_PARAM_AUTH_MODE,
17304 set_val);
17305 if (QDF_IS_STATUS_ERROR(status))
17306 hdd_err("Failed to set auth type %0X to crypto component",
17307 set_val);
17308}
17309
17310/**
17311 * hdd_populate_crypto_akm_type() - populate akm type for crypto
17312 * @vdev: pointed to vdev obmgr
17313 * @akm_type: legacy akm_type
17314 *
17315 * set the crypto akm type for corresponding akm type received
17316 * from NL
17317 *
17318 * Return: None
17319 */
17320static void hdd_populate_crypto_akm_type(struct wlan_objmgr_vdev *vdev,
17321 u32 key_mgmt)
17322{
17323 QDF_STATUS status;
17324 uint32_t set_val = 0;
17325 wlan_crypto_key_mgmt crypto_akm_type =
17326 osif_nl_to_crypto_akm_type(key_mgmt);
17327
17328 hdd_debug("set akm type %d to crypto component", crypto_akm_type);
17329 HDD_SET_BIT(set_val, crypto_akm_type);
17330
17331 status = wlan_crypto_set_vdev_param(vdev,
17332 WLAN_CRYPTO_PARAM_KEY_MGMT,
17333 set_val);
17334 if (QDF_IS_STATUS_ERROR(status))
17335 hdd_err("Failed to set akm type %0x to crypto component",
17336 set_val);
17337}
17338
17339/**
17340 * hdd_populate_crypto_cipher_type() - populate cipher type for crypto
17341 * @cipher: legacy cipher type
17342 * @vdev: pointed to vdev obmgr
17343 * @cipher_param_type: param type, UCST/MCAST
17344 *
17345 * set the crypto cipher type for corresponding cipher type received
17346 * from NL
17347 *
17348 * Return: None
17349 */
17350static void hdd_populate_crypto_cipher_type(u32 cipher,
17351 struct wlan_objmgr_vdev *vdev,
17352 wlan_crypto_param_type
17353 cipher_param_type)
17354{
17355 QDF_STATUS status;
17356 uint32_t set_val = 0;
17357 wlan_crypto_cipher_type crypto_cipher_type =
17358 osif_nl_to_crypto_cipher_type(cipher);
17359
17360 hdd_debug("set cipher params %d type %d to crypto",
17361 cipher_param_type, crypto_cipher_type);
17362 HDD_SET_BIT(set_val, crypto_cipher_type);
17363 status = wlan_crypto_set_vdev_param(vdev, cipher_param_type, set_val);
17364 if (QDF_IS_STATUS_ERROR(status))
17365 hdd_err("Failed to set cipher params %d type %0x to crypto",
17366 cipher_param_type, set_val);
17367}
17368
17369/**
17370 * hdd_populate_crypto_params() - set crypto params
17371 * @vdev: Pointer to vdev obh mgr
17372 * @req: Pointer to security parameters
17373 *
17374 * Set Auth, Akm and Cipher type for crypto
17375 *
17376 * Return: None
17377 */
17378static void hdd_populate_crypto_params(struct wlan_objmgr_vdev *vdev,
17379 struct cfg80211_connect_params *req)
17380{
17381 hdd_populate_crypto_auth_type(vdev, req->auth_type);
17382
17383 if (req->crypto.n_akm_suites)
17384 hdd_populate_crypto_akm_type(vdev, req->crypto.akm_suites[0]);
17385
17386 if (req->crypto.n_ciphers_pairwise) {
17387 hdd_populate_crypto_cipher_type(req->crypto.ciphers_pairwise[0],
17388 vdev,
17389 WLAN_CRYPTO_PARAM_UCAST_CIPHER);
17390 } else {
17391 /* Reset previous cipher suite to none */
17392 hdd_populate_crypto_cipher_type(0, vdev,
17393 WLAN_CRYPTO_PARAM_UCAST_CIPHER);
17394 }
17395
17396 hdd_populate_crypto_cipher_type(req->crypto.cipher_group,
17397 vdev,
17398 WLAN_CRYPTO_PARAM_MCAST_CIPHER);
17399}
17400
17401/**
17402 * hdd_set_crypto_key_mgmt_param() - Set key mgmt param.
17403 * @adapter: Pointer to adapter.
17404 *
17405 * Return: None
17406 */
17407static void hdd_set_crypto_key_mgmt_param(struct hdd_adapter *adapter)
17408{
17409 uint32_t key_mgmt = 0;
17410 struct wlan_objmgr_vdev *vdev;
17411
17412 if (!adapter) {
17413 hdd_err("adapter is null");
17414 return;
17415 }
17416
17417 vdev = hdd_objmgr_get_vdev(adapter);
17418 if (!vdev)
17419 return;
17420
17421 if (adapter->wapi_info.wapi_auth_mode == WAPI_AUTH_MODE_PSK)
17422 HDD_SET_BIT(key_mgmt, WLAN_CRYPTO_KEY_MGMT_WAPI_PSK);
17423 if (adapter->wapi_info.wapi_auth_mode == WAPI_AUTH_MODE_CERT)
17424 HDD_SET_BIT(key_mgmt, WLAN_CRYPTO_KEY_MGMT_WAPI_CERT);
17425
17426 wlan_crypto_set_vdev_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT, key_mgmt);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +053017427 hdd_objmgr_put_vdev(vdev);
Arif Hussainf8f6b3b2019-01-10 19:42:09 -080017428}
17429
17430#else
17431
17432static inline
17433void hdd_populate_crypto_auth_type(struct wlan_objmgr_vdev *vdev,
17434 enum nl80211_auth_type auth_type)
17435{
17436}
17437
17438static inline
17439void hdd_populate_crypto_akm_type(struct wlan_objmgr_vdev *vdev,
17440 u32 key_mgmt)
17441{
17442}
17443
17444static inline
17445void hdd_populate_crypto_cipher_type(u32 cipher,
17446 struct wlan_objmgr_vdev *vdev,
17447 wlan_crypto_param_type
17448 cipher_param_type)
17449{
17450}
17451
17452static inline
17453void hdd_populate_crypto_params(struct wlan_objmgr_vdev *vdev,
17454 struct cfg80211_connect_params *req)
17455{
17456}
17457
17458static inline void hdd_set_crypto_key_mgmt_param(struct hdd_adapter *adapter)
17459{
17460}
17461
17462#endif
17463
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017464/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017465 * wlan_hdd_cfg80211_set_ie() - set IEs
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017466 * @adapter: Pointer to adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017467 * @ie: Pointer ot ie
17468 * @ie: IE length
17469 *
17470 * Return: 0 for success, non-zero for failure
17471 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017472static int wlan_hdd_cfg80211_set_ie(struct hdd_adapter *adapter,
Jeff Johnson2a722002017-09-30 20:02:35 -070017473 const uint8_t *ie,
17474 size_t ie_len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017475{
Jeff Johnson20227a92018-03-13 09:41:05 -070017476 struct csr_roam_profile *roam_profile;
17477 tSirAddie *assoc_add_ie;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017478 const uint8_t *genie = ie;
17479 uint16_t remLen = ie_len;
17480#ifdef FEATURE_WLAN_WAPI
17481 uint32_t akmsuite[MAX_NUM_AKM_SUITES];
tinlin8a44b642018-04-25 13:56:06 +080017482 uint8_t *tmp;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017483 uint16_t akmsuiteCount;
tinlin8a44b642018-04-25 13:56:06 +080017484 uint32_t *akmlist;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017485#endif
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017486 int status;
Jeff Johnson20227a92018-03-13 09:41:05 -070017487 uint8_t *security_ie;
17488
17489 roam_profile = hdd_roam_profile(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017490
17491 /* clear previous assocAddIE */
Jeff Johnson20227a92018-03-13 09:41:05 -070017492 assoc_add_ie = hdd_assoc_additional_ie(adapter);
17493 assoc_add_ie->length = 0;
17494 roam_profile->bWPSAssociation = false;
17495 roam_profile->bOSENAssociation = false;
17496 security_ie = hdd_security_ie(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017497
17498 while (remLen >= 2) {
17499 uint16_t eLen = 0;
17500 uint8_t elementId;
Srinivas Girigowda576b2352017-08-25 14:44:26 -070017501
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017502 elementId = *genie++;
17503 eLen = *genie++;
17504 remLen -= 2;
17505
Nachiket Kukade4bea8b42017-06-13 11:53:19 +053017506 /* Sanity check on eLen */
17507 if (eLen > remLen) {
17508 hdd_err("%s: Invalid IE length[%d] for IE[0x%X]",
17509 __func__, eLen, elementId);
17510 QDF_ASSERT(0);
17511 return -EINVAL;
17512 }
17513
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017514 hdd_debug("IE[0x%X], LEN[%d]", elementId, eLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017515
17516 switch (elementId) {
17517 case DOT11F_EID_WPA:
17518 if (4 > eLen) { /* should have at least OUI which is 4 bytes so extra 2 bytes not needed */
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070017519 hdd_err("Invalid WPA IE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017520 return -EINVAL;
17521 } else if (0 ==
17522 memcmp(&genie[0], "\x00\x50\xf2\x04", 4)) {
Jeff Johnson20227a92018-03-13 09:41:05 -070017523 uint16_t curAddIELen = assoc_add_ie->length;
17524
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017525 hdd_debug("Set WPS IE(len %d)", eLen + 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017526
17527 if (SIR_MAC_MAX_ADD_IE_LENGTH <
Jeff Johnson20227a92018-03-13 09:41:05 -070017528 (assoc_add_ie->length + eLen)) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070017529 hdd_err("Cannot accommodate assocAddIE. Need bigger buffer space");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053017530 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017531 return -ENOMEM;
17532 }
17533 /* WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE */
Jeff Johnson20227a92018-03-13 09:41:05 -070017534 memcpy(assoc_add_ie->addIEdata +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017535 curAddIELen, genie - 2, eLen + 2);
Jeff Johnson20227a92018-03-13 09:41:05 -070017536 assoc_add_ie->length += eLen + 2;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017537
Jeff Johnson20227a92018-03-13 09:41:05 -070017538 roam_profile->bWPSAssociation = true;
17539 roam_profile->pAddIEAssoc =
17540 assoc_add_ie->addIEdata;
17541 roam_profile->nAddIEAssocLength =
17542 assoc_add_ie->length;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017543 } else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3)) {
Srinivas Girigowdacf161402019-03-14 11:37:33 -070017544 if (eLen > (WLAN_MAX_IE_LEN - 2)) {
Nachiket Kukade2f6509f2017-06-13 17:45:46 +053017545 hdd_err("%s: Invalid WPA IE length[%d]",
17546 __func__, eLen);
17547 QDF_ASSERT(0);
17548 return -EINVAL;
17549 }
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017550 hdd_debug("Set WPA IE (len %d)", eLen + 2);
Srinivas Girigowdacf161402019-03-14 11:37:33 -070017551 memset(security_ie, 0, WLAN_MAX_IE_LEN);
Jeff Johnson20227a92018-03-13 09:41:05 -070017552 memcpy(security_ie, genie - 2, (eLen + 2));
17553 roam_profile->pWPAReqIE = security_ie;
17554 roam_profile->nWPAReqIELength = eLen + 2; /* ie_len; */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017555 } else if ((0 == memcmp(&genie[0], P2P_OUI_TYPE,
17556 P2P_OUI_TYPE_SIZE))) {
17557 uint16_t curAddIELen =
Jeff Johnson20227a92018-03-13 09:41:05 -070017558 assoc_add_ie->length;
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017559 hdd_debug("Set P2P IE(len %d)", eLen + 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017560
17561 if (SIR_MAC_MAX_ADD_IE_LENGTH <
Jeff Johnson20227a92018-03-13 09:41:05 -070017562 (assoc_add_ie->length + eLen)) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070017563 hdd_err("Cannot accommodate assocAddIE Need bigger buffer space");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053017564 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017565 return -ENOMEM;
17566 }
17567 /* P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE */
Jeff Johnson20227a92018-03-13 09:41:05 -070017568 memcpy(assoc_add_ie->addIEdata +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017569 curAddIELen, genie - 2, eLen + 2);
Jeff Johnson20227a92018-03-13 09:41:05 -070017570 assoc_add_ie->length += eLen + 2;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017571
Jeff Johnson20227a92018-03-13 09:41:05 -070017572 roam_profile->pAddIEAssoc =
17573 assoc_add_ie->addIEdata;
17574 roam_profile->nAddIEAssocLength =
17575 assoc_add_ie->length;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017576 }
17577#ifdef WLAN_FEATURE_WFD
17578 else if ((0 == memcmp(&genie[0], WFD_OUI_TYPE,
17579 WFD_OUI_TYPE_SIZE)) &&
17580 /* Consider WFD IE, only for P2P Client */
Krunal Sonib4326f22016-03-10 13:05:51 -080017581 (QDF_P2P_CLIENT_MODE ==
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017582 adapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017583 uint16_t curAddIELen =
Jeff Johnson20227a92018-03-13 09:41:05 -070017584 assoc_add_ie->length;
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017585 hdd_debug("Set WFD IE(len %d)", eLen + 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017586
17587 if (SIR_MAC_MAX_ADD_IE_LENGTH <
Jeff Johnson20227a92018-03-13 09:41:05 -070017588 (assoc_add_ie->length + eLen)) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070017589 hdd_err("Cannot accommodate assocAddIE Need bigger buffer space");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053017590 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017591 return -ENOMEM;
17592 }
17593 /* WFD IE is saved to Additional IE ; it should
17594 * be accumulated to handle WPS IE + P2P IE +
Jeff Johnsonf3826e12017-01-12 09:49:40 -080017595 * WFD IE
17596 */
Jeff Johnson20227a92018-03-13 09:41:05 -070017597 memcpy(assoc_add_ie->addIEdata +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017598 curAddIELen, genie - 2, eLen + 2);
Jeff Johnson20227a92018-03-13 09:41:05 -070017599 assoc_add_ie->length += eLen + 2;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017600
Jeff Johnson20227a92018-03-13 09:41:05 -070017601 roam_profile->pAddIEAssoc =
17602 assoc_add_ie->addIEdata;
17603 roam_profile->nAddIEAssocLength =
17604 assoc_add_ie->length;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017605 }
17606#endif
17607 /* Appending HS 2.0 Indication Element in Assiciation Request */
17608 else if ((0 == memcmp(&genie[0], HS20_OUI_TYPE,
17609 HS20_OUI_TYPE_SIZE))) {
17610 uint16_t curAddIELen =
Jeff Johnson20227a92018-03-13 09:41:05 -070017611 assoc_add_ie->length;
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017612 hdd_debug("Set HS20 IE(len %d)", eLen + 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017613
17614 if (SIR_MAC_MAX_ADD_IE_LENGTH <
Jeff Johnson20227a92018-03-13 09:41:05 -070017615 (assoc_add_ie->length + eLen)) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070017616 hdd_err("Cannot accommodate assocAddIE Need bigger buffer space");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053017617 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017618 return -ENOMEM;
17619 }
Jeff Johnson20227a92018-03-13 09:41:05 -070017620 memcpy(assoc_add_ie->addIEdata +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017621 curAddIELen, genie - 2, eLen + 2);
Jeff Johnson20227a92018-03-13 09:41:05 -070017622 assoc_add_ie->length += eLen + 2;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017623
Jeff Johnson20227a92018-03-13 09:41:05 -070017624 roam_profile->pAddIEAssoc =
17625 assoc_add_ie->addIEdata;
17626 roam_profile->nAddIEAssocLength =
17627 assoc_add_ie->length;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017628 }
17629 /* Appending OSEN Information Element in Assiciation Request */
17630 else if ((0 == memcmp(&genie[0], OSEN_OUI_TYPE,
17631 OSEN_OUI_TYPE_SIZE))) {
17632 uint16_t curAddIELen =
Jeff Johnson20227a92018-03-13 09:41:05 -070017633 assoc_add_ie->length;
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017634 hdd_debug("Set OSEN IE(len %d)", eLen + 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017635
17636 if (SIR_MAC_MAX_ADD_IE_LENGTH <
Jeff Johnson20227a92018-03-13 09:41:05 -070017637 (assoc_add_ie->length + eLen)) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070017638 hdd_err("Cannot accommodate assocAddIE Need bigger buffer space");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053017639 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017640 return -ENOMEM;
17641 }
Jeff Johnson20227a92018-03-13 09:41:05 -070017642 memcpy(assoc_add_ie->addIEdata +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017643 curAddIELen, genie - 2, eLen + 2);
Jeff Johnson20227a92018-03-13 09:41:05 -070017644 assoc_add_ie->length += eLen + 2;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017645
Jeff Johnson20227a92018-03-13 09:41:05 -070017646 roam_profile->bOSENAssociation = true;
17647 roam_profile->pAddIEAssoc =
17648 assoc_add_ie->addIEdata;
17649 roam_profile->nAddIEAssocLength =
17650 assoc_add_ie->length;
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017651 } else if ((0 == memcmp(&genie[0], MBO_OUI_TYPE,
17652 MBO_OUI_TYPE_SIZE))){
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017653 hdd_debug("Set MBO IE(len %d)", eLen + 2);
Jeff Johnson20227a92018-03-13 09:41:05 -070017654 status = wlan_hdd_add_assoc_ie(adapter,
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017655 genie - 2, eLen + 2);
17656 if (status)
17657 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017658 } else {
17659 uint16_t add_ie_len =
Jeff Johnson20227a92018-03-13 09:41:05 -070017660 assoc_add_ie->length;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017661
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017662 hdd_debug("Set OSEN IE(len %d)", eLen + 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017663
17664 if (SIR_MAC_MAX_ADD_IE_LENGTH <
Jeff Johnson20227a92018-03-13 09:41:05 -070017665 (assoc_add_ie->length + eLen)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017666 hdd_err("Cannot accommodate assocAddIE Need bigger buffer space");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053017667 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017668 return -ENOMEM;
17669 }
17670
Jeff Johnson20227a92018-03-13 09:41:05 -070017671 memcpy(assoc_add_ie->addIEdata +
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017672 add_ie_len, genie - 2, eLen + 2);
Jeff Johnson20227a92018-03-13 09:41:05 -070017673 assoc_add_ie->length += eLen + 2;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017674
Jeff Johnson20227a92018-03-13 09:41:05 -070017675 roam_profile->pAddIEAssoc =
17676 assoc_add_ie->addIEdata;
17677 roam_profile->nAddIEAssocLength =
17678 assoc_add_ie->length;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017679 }
17680 break;
17681 case DOT11F_EID_RSN:
tinlin8a44b642018-04-25 13:56:06 +080017682 if (eLen > DOT11F_IE_RSN_MAX_LEN) {
Vignesh Viswanathan96e0e702017-12-05 19:42:46 +053017683 hdd_err("%s: Invalid WPA RSN IE length[%d]",
tinlin8a44b642018-04-25 13:56:06 +080017684 __func__, eLen);
Vignesh Viswanathan96e0e702017-12-05 19:42:46 +053017685 return -EINVAL;
17686 }
Srinivas Girigowdacf161402019-03-14 11:37:33 -070017687 memset(security_ie, 0, WLAN_MAX_IE_LEN);
Jeff Johnson20227a92018-03-13 09:41:05 -070017688 memcpy(security_ie, genie - 2, (eLen + 2));
17689 roam_profile->pRSNReqIE = security_ie;
17690 roam_profile->nRSNReqIELength = eLen + 2; /* ie_len; */
tinlin8a44b642018-04-25 13:56:06 +080017691 hdd_debug("Set RSN IE(len %d)", eLen + 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017692 break;
17693 /*
17694 * Appending Extended Capabilities with Interworking bit set
17695 * in Assoc Req.
17696 *
17697 * In assoc req this EXT Cap will only be taken into account if
17698 * interworkingService bit is set to 1. Currently
17699 * driver is only interested in interworkingService capability
17700 * from supplicant. If in future any other EXT Cap info is
17701 * required from supplicat, it needs to be handled while
17702 * sending Assoc Req in LIM.
17703 */
17704 case DOT11F_EID_EXTCAP:
17705 {
17706 uint16_t curAddIELen =
Jeff Johnson20227a92018-03-13 09:41:05 -070017707 assoc_add_ie->length;
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017708 hdd_debug("Set Extended CAPS IE(len %d)", eLen + 2);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017709
17710 if (SIR_MAC_MAX_ADD_IE_LENGTH <
Jeff Johnson20227a92018-03-13 09:41:05 -070017711 (assoc_add_ie->length + eLen)) {
Jeff Johnsonff5b9aa2016-06-29 15:10:30 -070017712 hdd_err("Cannot accommodate assocAddIE Need bigger buffer space");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053017713 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017714 return -ENOMEM;
17715 }
Jeff Johnson20227a92018-03-13 09:41:05 -070017716 memcpy(assoc_add_ie->addIEdata + curAddIELen, genie - 2, eLen + 2);
17717 assoc_add_ie->length += eLen + 2;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017718
Jeff Johnson20227a92018-03-13 09:41:05 -070017719 roam_profile->pAddIEAssoc = assoc_add_ie->addIEdata;
17720 roam_profile->nAddIEAssocLength = assoc_add_ie->length;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017721 break;
17722 }
17723#ifdef FEATURE_WLAN_WAPI
Srinivas Girigowda61771262019-04-01 11:55:19 -070017724 case WLAN_ELEMID_WAPI:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017725 /* Setting WAPI Mode to ON=1 */
tinlin8a44b642018-04-25 13:56:06 +080017726 adapter->wapi_info.wapi_mode = 1;
Jeff Johnson7d2f4c62017-11-02 09:25:45 -070017727 hdd_debug("WAPI MODE IS %u", adapter->wapi_info.wapi_mode);
Abhinav Kumarf56c81f2018-06-06 16:07:01 +053017728 /* genie is pointing to data field of WAPI IE's buffer */
17729 tmp = (uint8_t *)genie;
17730 /* Validate length for Version(2 bytes) and Number
17731 * of AKM suite (2 bytes) in WAPI IE buffer, coming from
17732 * supplicant*/
17733 if (eLen < 4) {
17734 hdd_err("Invalid IE Len: %u", eLen);
17735 return -EINVAL;
17736 }
17737 tmp = tmp + 2; /* Skip Version */
tinlin8a44b642018-04-25 13:56:06 +080017738 /* Get the number of AKM suite */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017739 akmsuiteCount = WPA_GET_LE16(tmp);
tinlin8a44b642018-04-25 13:56:06 +080017740 /* Skip the number of AKM suite */
17741 tmp = tmp + 2;
Abhinav Kumarf56c81f2018-06-06 16:07:01 +053017742 /* Validate total length for WAPI IE's buffer */
17743 if (eLen < (4 + (akmsuiteCount * sizeof(uint32_t)))) {
17744 hdd_err("Invalid IE Len: %u", eLen);
17745 return -EINVAL;
17746 }
tinlin8a44b642018-04-25 13:56:06 +080017747 /* AKM suite list, each OUI contains 4 bytes */
17748 akmlist = (uint32_t *)(tmp);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017749 if (akmsuiteCount <= MAX_NUM_AKM_SUITES) {
Vignesh Viswanathan845bd472018-06-11 18:45:45 +053017750 qdf_mem_copy(akmsuite, akmlist,
17751 sizeof(uint32_t) * akmsuiteCount);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017752 } else {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017753 hdd_err("Invalid akmSuite count: %u",
17754 akmsuiteCount);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053017755 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017756 return -EINVAL;
17757 }
17758
17759 if (WAPI_PSK_AKM_SUITE == akmsuite[0]) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017760 hdd_debug("WAPI AUTH MODE SET TO PSK");
Jeff Johnson7d2f4c62017-11-02 09:25:45 -070017761 adapter->wapi_info.wapi_auth_mode =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017762 WAPI_AUTH_MODE_PSK;
17763 }
17764 if (WAPI_CERT_AKM_SUITE == akmsuite[0]) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017765 hdd_debug("WAPI AUTH MODE SET TO CERTIFICATE");
Jeff Johnson7d2f4c62017-11-02 09:25:45 -070017766 adapter->wapi_info.wapi_auth_mode =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017767 WAPI_AUTH_MODE_CERT;
17768 }
Arif Hussainf8f6b3b2019-01-10 19:42:09 -080017769
17770 hdd_set_crypto_key_mgmt_param(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017771 break;
17772#endif
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017773 case DOT11F_EID_SUPPOPERATINGCLASSES:
17774 {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017775 hdd_debug("Set Supported Operating Classes IE(len %d)", eLen + 2);
Jeff Johnson20227a92018-03-13 09:41:05 -070017776 status = wlan_hdd_add_assoc_ie(adapter,
Selvaraj, Sridhara7fc7632016-09-04 13:13:38 +053017777 genie - 2, eLen + 2);
17778 if (status)
17779 return status;
17780 break;
17781 }
Srinivas Girigowda61771262019-04-01 11:55:19 -070017782 case WLAN_REQUEST_IE_MAX_LEN:
Sridhar Selvaraj6d3e0d72017-08-17 17:32:37 +053017783 {
17784 if (genie[0] == SIR_FILS_HLP_EXT_EID) {
17785 hdd_debug("Set HLP EXT IE(len %d)",
17786 eLen + 2);
Jeff Johnson20227a92018-03-13 09:41:05 -070017787 wlan_hdd_save_hlp_ie(roam_profile,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053017788 genie - 2, eLen + 2,
17789 true);
Sridhar Selvaraj6d3e0d72017-08-17 17:32:37 +053017790 status = wlan_hdd_add_assoc_ie(
Jeff Johnson20227a92018-03-13 09:41:05 -070017791 adapter, genie - 2,
Sridhar Selvaraj6d3e0d72017-08-17 17:32:37 +053017792 eLen + 2);
17793 if (status)
17794 return status;
Padma, Santhosh Kumarc69ce072017-11-06 18:21:05 +053017795 } else if (genie[0] ==
17796 SIR_DH_PARAMETER_ELEMENT_EXT_EID) {
17797 hdd_debug("Set DH EXT IE(len %d)",
17798 eLen + 2);
17799 status = wlan_hdd_add_assoc_ie(
Jeff Johnson20227a92018-03-13 09:41:05 -070017800 adapter, genie - 2,
Padma, Santhosh Kumarc69ce072017-11-06 18:21:05 +053017801 eLen + 2);
17802 if (status)
17803 return status;
Sridhar Selvaraj6d3e0d72017-08-17 17:32:37 +053017804 } else {
17805 hdd_err("UNKNOWN EID: %X", genie[0]);
17806 }
17807 break;
17808 }
17809 case DOT11F_EID_FRAGMENT_IE:
17810 {
17811 hdd_debug("Set Fragment IE(len %d)", eLen + 2);
Jeff Johnson20227a92018-03-13 09:41:05 -070017812 wlan_hdd_save_hlp_ie(roam_profile,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053017813 genie - 2, eLen + 2,
17814 false);
Jeff Johnson20227a92018-03-13 09:41:05 -070017815 status = wlan_hdd_add_assoc_ie(adapter,
Sridhar Selvaraj6d3e0d72017-08-17 17:32:37 +053017816 genie - 2, eLen + 2);
17817 if (status)
17818 return status;
17819 break;
17820 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017821 default:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017822 hdd_err("Set UNKNOWN IE: %X", elementId);
Jeff Johnsonf3826e12017-01-12 09:49:40 -080017823 /* when Unknown IE is received we break
17824 * and continue to the next IE in the buffer
17825 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017826 break;
17827 }
17828 genie += eLen;
17829 remLen -= eLen;
17830 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017831 return 0;
17832}
17833
17834/**
17835 * hdd_is_wpaie_present() - check for WPA ie
17836 * @ie: Pointer to ie
17837 * @ie_len: Ie length
17838 *
17839 * Parse the received IE to find the WPA IE
17840 *
17841 * Return: true if wpa ie is found else false
17842 */
17843static bool hdd_is_wpaie_present(const uint8_t *ie, uint8_t ie_len)
17844{
17845 uint8_t eLen = 0;
17846 uint16_t remLen = ie_len;
17847 uint8_t elementId = 0;
17848
17849 while (remLen >= 2) {
17850 elementId = *ie++;
17851 eLen = *ie++;
17852 remLen -= 2;
17853 if (eLen > remLen) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017854 hdd_err("Invalid IE length: %d", eLen);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017855 return false;
17856 }
17857 if ((elementId == DOT11F_EID_WPA) && (remLen > 5)) {
17858 /* OUI - 0x00 0X50 0XF2
17859 * WPA Information Element - 0x01
17860 * WPA version - 0x01
17861 */
17862 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
17863 return true;
17864 }
17865 ie += eLen;
17866 remLen -= eLen;
17867 }
17868 return false;
17869}
17870
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080017871#ifdef CRYPTO_SET_KEY_CONVERGED
17872static void wlan_hdd_cfg80211_store_wep_key(struct hdd_adapter *adapter,
17873 struct wlan_objmgr_vdev *vdev,
17874 struct cfg80211_connect_params *req)
17875{
17876 struct key_params params;
17877
17878 qdf_mem_zero(&params, sizeof(params));
17879 params.cipher = req->crypto.ciphers_pairwise[0];
17880 params.key_len = req->key_len;
17881 params.key = req->key;
17882 wlan_cfg80211_store_key(vdev, req->key_idx,
17883 WLAN_CRYPTO_KEY_TYPE_UNICAST,
17884 NULL, &params);
17885}
17886#else
17887static void wlan_hdd_cfg80211_store_wep_key(struct hdd_adapter *adapter,
17888 struct wlan_objmgr_vdev *vdev,
17889 struct cfg80211_connect_params *req)
17890{
17891 struct csr_roam_profile *roam_profile;
17892
17893 roam_profile = hdd_roam_profile(adapter);
17894 hdd_debug("setting default wep key, key_idx = %hu key_len %hu",
17895 req->key_idx, req->key_len);
17896 qdf_mem_copy(&roam_profile->Keys.KeyMaterial[req->key_idx][0],
17897 req->key, req->key_len);
17898 roam_profile->Keys.KeyLength[req->key_idx] = req->key_len;
17899 roam_profile->Keys.defaultIndex = req->key_idx;
17900}
17901#endif /* !CRYPTO_SET_KEY_CONVERGED */
17902
Harprit Chhabada6c641ba2018-06-28 14:45:10 -070017903/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017904 * wlan_hdd_cfg80211_set_privacy() - set security parameters during connection
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017905 * @adapter: Pointer to adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017906 * @req: Pointer to security parameters
17907 *
17908 * Return: 0 for success, non-zero for failure
17909 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017910static int wlan_hdd_cfg80211_set_privacy(struct hdd_adapter *adapter,
Jeff Johnson8b8a04b2016-10-05 15:49:43 -070017911 struct cfg80211_connect_params *req)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017912{
17913 int status = 0;
Jeff Johnsonce4a8342017-10-14 13:12:22 -070017914 struct hdd_station_ctx *sta_ctx;
Jeff Johnson20227a92018-03-13 09:41:05 -070017915 struct csr_roam_profile *roam_profile;
Min Liu8c5d99e2018-09-10 17:18:44 +080017916 struct wlan_objmgr_vdev *vdev;
Srinivas Girigowda576b2352017-08-25 14:44:26 -070017917
Dustin Brown491d54b2018-03-14 12:39:11 -070017918 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017919
Jeff Johnsonce4a8342017-10-14 13:12:22 -070017920 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
17921 sta_ctx->wpa_versions = req->crypto.wpa_versions;
17922 hdd_debug("set wpa version to %d", sta_ctx->wpa_versions);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017923
Jeff Johnson20227a92018-03-13 09:41:05 -070017924 roam_profile = hdd_roam_profile(adapter);
17925
Harprit Chhabada6c641ba2018-06-28 14:45:10 -070017926 /* populate auth,akm and cipher params for crypto */
Min Liu8c5d99e2018-09-10 17:18:44 +080017927 vdev = hdd_objmgr_get_vdev(adapter);
17928 if (!vdev)
17929 return -EINVAL;
17930 hdd_populate_crypto_params(vdev, req);
Harprit Chhabada6c641ba2018-06-28 14:45:10 -070017931
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017932 /*set authentication type */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017933 status = wlan_hdd_cfg80211_set_auth_type(adapter, req->auth_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017934
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070017935 if (wlan_hdd_is_conn_type_fils(req)) {
17936 status = wlan_hdd_cfg80211_set_fils_config(adapter, req);
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053017937
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070017938 if (0 > status) {
17939 hdd_err("Failed to set fils config");
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080017940 goto release_vdev_ref;
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070017941 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017942 }
17943
17944 /*set key mgmt type */
17945 if (req->crypto.n_akm_suites) {
17946 status =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017947 wlan_hdd_set_akm_suite(adapter, req->crypto.akm_suites[0]);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017948 if (0 > status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017949 hdd_err("Failed to set akm suite");
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080017950 goto release_vdev_ref;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017951 }
17952 }
17953
17954 /*set pairwise cipher type */
17955 if (req->crypto.n_ciphers_pairwise) {
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017956 status = wlan_hdd_cfg80211_set_cipher(adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017957 req->crypto.
17958 ciphers_pairwise[0],
17959 true);
17960 if (0 > status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017961 hdd_err("Failed to set unicast cipher type");
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080017962 goto release_vdev_ref;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017963 }
17964 } else {
17965 /*Reset previous cipher suite to none */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017966 status = wlan_hdd_cfg80211_set_cipher(adapter, 0, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017967 if (0 > status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017968 hdd_err("Failed to set unicast cipher type");
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080017969 goto release_vdev_ref;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017970 }
17971 }
17972
17973 /*set group cipher type */
17974 status =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017975 wlan_hdd_cfg80211_set_cipher(adapter, req->crypto.cipher_group,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017976 false);
17977
17978 if (0 > status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017979 hdd_err("Failed to set mcast cipher type");
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080017980 goto release_vdev_ref;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017981 }
17982#ifdef WLAN_FEATURE_11W
Jeff Johnson20227a92018-03-13 09:41:05 -070017983 roam_profile->MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017984#endif
17985
17986 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile */
17987 if (req->ie_len) {
17988 status =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070017989 wlan_hdd_cfg80211_set_ie(adapter, req->ie, req->ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017990 if (0 > status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080017991 hdd_err("Failed to parse the WPA/RSN IE");
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080017992 goto release_vdev_ref;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080017993 }
17994 }
17995
17996 /*incase of WEP set default key information */
17997 if (req->key && req->key_len) {
Jeff Johnson37ecea42018-03-18 17:54:40 -070017998 u32 cipher = req->crypto.ciphers_pairwise[0];
Jeff Johnson68755312017-02-10 11:46:55 -080017999
Jeff Johnson37ecea42018-03-18 17:54:40 -070018000 if ((WLAN_CIPHER_SUITE_WEP40 == cipher) ||
18001 (WLAN_CIPHER_SUITE_WEP104 == cipher)) {
18002 enum hdd_auth_key_mgmt key_mgmt =
18003 sta_ctx->auth_key_mgmt;
18004
18005 if (key_mgmt & HDD_AUTH_KEY_MGMT_802_1X) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070018006 hdd_err("Dynamic WEP not supported");
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080018007 status = -EOPNOTSUPP;
18008 goto release_vdev_ref;
Jeff Johnson68755312017-02-10 11:46:55 -080018009 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018010
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080018011 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >=
18012 req->key_len) && (CSR_MAX_NUM_KEY > req->key_idx))
18013 wlan_hdd_cfg80211_store_wep_key(adapter,
18014 vdev, req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018015 }
18016 }
Varun Reddy Yeturuff4c9982019-02-15 15:59:24 -080018017release_vdev_ref:
18018 hdd_objmgr_put_vdev(vdev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018019
18020 return status;
18021}
18022
wadesongcaad7c72018-08-06 13:26:27 +080018023/**
18024 * wlan_hdd_clear_wapi_privacy() - reset WAPI settings in HDD layer
18025 * @adapter: pointer to HDD adapter object
18026 *
18027 * This function resets all WAPI related parameters imposed before STA
18028 * connection starts. It's invoked when privacy checking against concurrency
18029 * fails, to make sure no improper WAPI settings are still populated before
18030 * returning an error to the upper layer requester.
18031 *
18032 * Return: none
18033 */
18034#ifdef FEATURE_WLAN_WAPI
18035static inline void wlan_hdd_clear_wapi_privacy(struct hdd_adapter *adapter)
18036{
18037 adapter->wapi_info.wapi_mode = 0;
18038 adapter->wapi_info.wapi_auth_mode = WAPI_AUTH_MODE_OPEN;
18039}
18040#else
18041static inline void wlan_hdd_clear_wapi_privacy(struct hdd_adapter *adapter)
18042{
18043}
18044#endif
18045
18046/**
18047 * wlan_hdd_cfg80211_clear_privacy() - reset STA security parameters
18048 * @adapter: pointer to HDD adapter object
18049 *
18050 * This function resets all privacy related parameters imposed
18051 * before STA connection starts. It's invoked when privacy checking
18052 * against concurrency fails, to make sure no improper settings are
18053 * still populated before returning an error to the upper layer requester.
18054 *
18055 * Return: none
18056 */
18057static void wlan_hdd_cfg80211_clear_privacy(struct hdd_adapter *adapter)
18058{
18059 struct hdd_station_ctx *hdd_sta_ctx =
18060 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18061
18062 hdd_debug("resetting all privacy configurations");
18063
18064 hdd_sta_ctx->wpa_versions = 0;
18065
Jeff Johnson96e33512019-02-27 15:10:21 -080018066 hdd_sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_NONE;
wadesongcaad7c72018-08-06 13:26:27 +080018067 hdd_sta_ctx->roam_profile.AuthType.authType[0] = eCSR_AUTH_TYPE_NONE;
18068
Jeff Johnsonb1959842019-02-27 13:04:04 -080018069 hdd_sta_ctx->conn_info.uc_encrypt_type = eCSR_ENCRYPT_TYPE_NONE;
wadesongcaad7c72018-08-06 13:26:27 +080018070 hdd_sta_ctx->roam_profile.EncryptionType.numEntries = 0;
Jeff Johnsonb1959842019-02-27 13:04:04 -080018071 hdd_sta_ctx->conn_info.mc_encrypt_type = eCSR_ENCRYPT_TYPE_NONE;
wadesongcaad7c72018-08-06 13:26:27 +080018072 hdd_sta_ctx->roam_profile.mcEncryptionType.numEntries = 0;
18073
18074 wlan_hdd_clear_wapi_privacy(adapter);
18075}
18076
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018077int wlan_hdd_try_disconnect(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018078{
18079 unsigned long rc;
Jeff Johnsond377dce2017-10-04 10:32:42 -070018080 struct hdd_station_ctx *sta_ctx;
Abhishek Singhbe1849b2016-01-19 14:12:00 +053018081 int status, result = 0;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070018082 mac_handle_t mac_handle;
Abhishek Singhd1f21c72019-01-21 15:16:34 +053018083 uint32_t wait_time = SME_DISCONNECT_TIMEOUT;
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053018084 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018085
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053018086 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnsond377dce2017-10-04 10:32:42 -070018087 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnson34fc63a2018-06-14 10:10:02 -070018088 mac_handle = hdd_adapter_get_mac_handle(adapter);
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018089 if (adapter->device_mode == QDF_STA_MODE) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018090 hdd_debug("Stop firmware roaming");
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018091 sme_stop_roaming(mac_handle, adapter->vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -070018092 eCsrForcedDisassoc);
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080018093
Abhishek Singh533c9da2017-05-04 10:23:34 +053018094 /*
18095 * If firmware has already started roaming process, driver
18096 * needs to wait for processing of this disconnect request.
18097 *
18098 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018099 INIT_COMPLETION(adapter->roaming_comp_var);
nakul kachhwaha5913f352019-05-08 17:11:58 +053018100 if (hdd_is_roaming_in_progress(hdd_ctx) ||
18101 sme_neighbor_middle_of_roaming(mac_handle,
18102 adapter->vdev_id)) {
Abhishek Singh533c9da2017-05-04 10:23:34 +053018103 rc = wait_for_completion_timeout(
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018104 &adapter->roaming_comp_var,
Abhishek Singh533c9da2017-05-04 10:23:34 +053018105 msecs_to_jiffies(WLAN_WAIT_TIME_STOP_ROAM));
18106 if (!rc) {
Jeff Johnson55d2ab42019-03-06 11:43:49 -080018107 hdd_err("roaming comp var timed out vdev id: %d",
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018108 adapter->vdev_id);
Abhishek Singh533c9da2017-05-04 10:23:34 +053018109 }
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018110 if (adapter->roam_ho_fail) {
18111 INIT_COMPLETION(adapter->disconnect_comp_var);
18112 hdd_conn_set_connection_state(adapter,
Abhishek Singh533c9da2017-05-04 10:23:34 +053018113 eConnectionState_Disconnecting);
18114 }
18115 }
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080018116 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018117
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018118 if ((QDF_IBSS_MODE == adapter->device_mode) ||
Jeff Johnsone7951512019-02-27 10:02:51 -080018119 (eConnectionState_Associated == sta_ctx->conn_info.conn_state) ||
18120 (eConnectionState_Connecting == sta_ctx->conn_info.conn_state) ||
18121 (eConnectionState_IbssConnected == sta_ctx->conn_info.conn_state)) {
Abhishek Singh0edeba02018-06-05 10:04:08 +053018122 eConnectionState prev_conn_state;
18123
Jeff Johnsone7951512019-02-27 10:02:51 -080018124 prev_conn_state = sta_ctx->conn_info.conn_state;
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018125 hdd_conn_set_connection_state(adapter,
Jeff Johnson34fc63a2018-06-14 10:10:02 -070018126 eConnectionState_Disconnecting);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018127 /* Issue disconnect to CSR */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018128 INIT_COMPLETION(adapter->disconnect_comp_var);
Abhishek Singhbe1849b2016-01-19 14:12:00 +053018129
Jeff Johnson34fc63a2018-06-14 10:10:02 -070018130 status = sme_roam_disconnect(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018131 adapter->vdev_id,
Abhishek Singhbe1849b2016-01-19 14:12:00 +053018132 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Abhishek Singh0edeba02018-06-05 10:04:08 +053018133
18134 if ((status == QDF_STATUS_CMD_NOT_QUEUED) &&
18135 prev_conn_state != eConnectionState_Connecting) {
18136 hdd_debug("Already disconnect in progress");
18137 result = 0;
18138 /*
18139 * Wait here instead of returning directly. This will
18140 * block the connect command and allow processing
18141 * of the disconnect in SME. As disconnect is already
18142 * in progress, wait here for 1 sec instead of 5 sec.
18143 */
18144 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
18145 } else if (status == QDF_STATUS_CMD_NOT_QUEUED) {
18146 /*
18147 * Wait here instead of returning directly, this will
18148 * block the connect command and allow processing
18149 * of the scan for ssid and the previous connect command
18150 * in CSR.
18151 */
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018152 hdd_debug("Already disconnected or connect was in sme/roam pending list and removed by disconnect");
Abhishek Singhbe1849b2016-01-19 14:12:00 +053018153 } else if (0 != status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018154 hdd_err("sme_roam_disconnect failure, status: %d",
Abhishek Singhbe1849b2016-01-19 14:12:00 +053018155 (int)status);
Jeff Johnson8380f232017-10-25 12:39:44 -070018156 sta_ctx->sta_debug_state = status;
Abhishek Singhbe1849b2016-01-19 14:12:00 +053018157 result = -EINVAL;
18158 goto disconnected;
18159 }
18160
Abhishek Singh0edeba02018-06-05 10:04:08 +053018161 rc = wait_for_completion_timeout(&adapter->disconnect_comp_var,
18162 msecs_to_jiffies(wait_time));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053018163 if (!rc && (QDF_STATUS_CMD_NOT_QUEUED != status)) {
Jeff Johnson55d2ab42019-03-06 11:43:49 -080018164 hdd_err("Sme disconnect event timed out vdev id: %d sta_debug_state: %d",
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018165 adapter->vdev_id, sta_ctx->sta_debug_state);
Abhishek Singhbe1849b2016-01-19 14:12:00 +053018166 result = -ETIMEDOUT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018167 }
18168 } else if (eConnectionState_Disconnecting ==
Jeff Johnsone7951512019-02-27 10:02:51 -080018169 sta_ctx->conn_info.conn_state) {
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018170 rc = wait_for_completion_timeout(&adapter->disconnect_comp_var,
Abhishek Singh0edeba02018-06-05 10:04:08 +053018171 msecs_to_jiffies(wait_time));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018172 if (!rc) {
Jeff Johnson55d2ab42019-03-06 11:43:49 -080018173 hdd_err("Disconnect event timed out vdev id: %d sta_debug_state: %d",
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018174 adapter->vdev_id, sta_ctx->sta_debug_state);
Abhishek Singhbe1849b2016-01-19 14:12:00 +053018175 result = -ETIMEDOUT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018176 }
18177 }
Abhishek Singhbe1849b2016-01-19 14:12:00 +053018178disconnected:
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018179 hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
Abhishek Singhbe1849b2016-01-19 14:12:00 +053018180 return result;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018181}
18182
18183/**
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018184 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
18185 * @adapter: Pointer to the HDD adapter
18186 * @req: Pointer to the structure cfg_connect_params receieved from user space
18187 *
Selvaraj, Sridhar353be2f2016-09-27 15:01:41 +053018188 * This function will start reassociation if prev_bssid is set and bssid/
18189 * bssid_hint, channel/channel_hint parameters are present in connect request.
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018190 *
Vignesh Viswanathan75af0a62018-05-08 17:08:54 +053018191 * Return: 0 if connect was for ReAssociation, non-zero error code otherwise
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018192 */
Selvaraj, Sridhara11edcb2016-09-07 18:49:14 +053018193#if defined(CFG80211_CONNECT_PREV_BSSID) || \
18194 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
Vignesh Viswanathan75af0a62018-05-08 17:08:54 +053018195static int wlan_hdd_reassoc_bssid_hint(struct hdd_adapter *adapter,
18196 struct cfg80211_connect_params *req)
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018197{
Vignesh Viswanathan75af0a62018-05-08 17:08:54 +053018198 int status = -EINVAL;
Selvaraj, Sridhar353be2f2016-09-27 15:01:41 +053018199 const uint8_t *bssid = NULL;
18200 uint16_t channel = 0;
Jeff Johnson731bc322017-10-14 19:53:44 -070018201 struct hdd_station_ctx *sta_ctx;
Selvaraj, Sridhar353be2f2016-09-27 15:01:41 +053018202
18203 if (req->bssid)
18204 bssid = req->bssid;
18205 else if (req->bssid_hint)
18206 bssid = req->bssid_hint;
18207
18208 if (req->channel)
18209 channel = req->channel->hw_value;
18210 else if (req->channel_hint)
18211 channel = req->channel_hint->hw_value;
18212
18213 if (bssid && channel && req->prev_bssid) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070018214 hdd_debug("REASSOC Attempt on channel %d to " QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070018215 channel, QDF_MAC_ADDR_ARRAY(bssid));
Arif Hussain43354e62017-05-24 11:24:25 -070018216 /*
18217 * Save BSSID in a separate variable as
Jeff Johnson5b34fce2017-10-13 13:24:51 -070018218 * roam_profile's BSSID is getting zeroed out in the
Arif Hussain43354e62017-05-24 11:24:25 -070018219 * association process. In case of join failure
18220 * we should send valid BSSID to supplicant
18221 */
Jeff Johnson731bc322017-10-14 19:53:44 -070018222 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18223 qdf_mem_copy(sta_ctx->requested_bssid.bytes, bssid,
Arif Hussain43354e62017-05-24 11:24:25 -070018224 QDF_MAC_ADDR_SIZE);
18225
Vignesh Viswanathan75af0a62018-05-08 17:08:54 +053018226 status = hdd_reassoc(adapter, bssid, channel,
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018227 CONNECT_CMD_USERSPACE);
Vignesh Viswanathan75af0a62018-05-08 17:08:54 +053018228 hdd_debug("hdd_reassoc: status: %d", status);
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018229 }
Vignesh Viswanathan75af0a62018-05-08 17:08:54 +053018230 return status;
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018231}
18232#else
Vignesh Viswanathan75af0a62018-05-08 17:08:54 +053018233static int wlan_hdd_reassoc_bssid_hint(struct hdd_adapter *adapter,
18234 struct cfg80211_connect_params *req)
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018235{
Vignesh Viswanathan75af0a62018-05-08 17:08:54 +053018236 return -ENOTSUPP;
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018237}
18238#endif
18239
Abhishek Singhb59f8d42017-07-31 14:42:47 +053018240
18241/**
18242 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
18243 * connect in HT20 mode
18244 * @hdd_ctx: hdd context
18245 * @adapter: Pointer to the HDD adapter
18246 * @req: Pointer to the structure cfg_connect_params receieved from user space
18247 *
18248 * This function will check if supplicant has indicated to to connect in HT20
18249 * mode. this is currently applicable only for 2.4Ghz mode only.
18250 * if feature is enabled and supplicant indicate HT20 set
18251 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
18252 *
18253 * Return: void
18254 */
18255#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
Jeff Johnson20227a92018-03-13 09:41:05 -070018256static void
18257wlan_hdd_check_ht20_ht40_ind(struct hdd_context *hdd_ctx,
18258 struct hdd_adapter *adapter,
18259 struct cfg80211_connect_params *req)
Abhishek Singhb59f8d42017-07-31 14:42:47 +053018260{
Jeff Johnson61b5e982018-03-15 11:33:31 -070018261 struct csr_roam_profile *roam_profile;
Wu Gaofc81ecf2018-11-22 11:38:41 +080018262 bool is_override_ht20_40_24g;
Abhishek Singhb59f8d42017-07-31 14:42:47 +053018263
Jeff Johnson20227a92018-03-13 09:41:05 -070018264 roam_profile = hdd_roam_profile(adapter);
18265
Abhishek Singhb59f8d42017-07-31 14:42:47 +053018266 roam_profile->force_24ghz_in_ht20 = false;
18267
Wu Gaofc81ecf2018-11-22 11:38:41 +080018268 ucfg_mlme_is_override_ht20_40_24g(hdd_ctx->psoc,
18269 &is_override_ht20_40_24g);
18270 if (is_override_ht20_40_24g &&
Jeff Johnson20227a92018-03-13 09:41:05 -070018271 !(req->ht_capa.cap_info & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
Abhishek Singhb59f8d42017-07-31 14:42:47 +053018272 roam_profile->force_24ghz_in_ht20 = true;
18273
18274 hdd_debug("req->ht_capa.cap_info %x override_ht20_40_24g %d",
18275 req->ht_capa.cap_info,
Wu Gaofc81ecf2018-11-22 11:38:41 +080018276 is_override_ht20_40_24g);
Abhishek Singhb59f8d42017-07-31 14:42:47 +053018277}
18278#else
Jeff Johnson20227a92018-03-13 09:41:05 -070018279static inline void
18280wlan_hdd_check_ht20_ht40_ind(struct hdd_context *hdd_ctx,
18281 struct hdd_adapter *adapter,
18282 struct cfg80211_connect_params *req)
Abhishek Singhb59f8d42017-07-31 14:42:47 +053018283{
Jeff Johnson61b5e982018-03-15 11:33:31 -070018284 struct csr_roam_profile *roam_profile;
Abhishek Singhb59f8d42017-07-31 14:42:47 +053018285
Jeff Johnson20227a92018-03-13 09:41:05 -070018286 roam_profile = hdd_roam_profile(adapter);
Abhishek Singhb59f8d42017-07-31 14:42:47 +053018287
18288 roam_profile->force_24ghz_in_ht20 = false;
18289}
18290#endif
18291
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018292/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018293 * __wlan_hdd_cfg80211_connect() - cfg80211 connect api
18294 * @wiphy: Pointer to wiphy
18295 * @dev: Pointer to network device
18296 * @req: Pointer to cfg80211 connect request
18297 *
18298 * This function is used to start the association process
18299 *
18300 * Return: 0 for success, non-zero for failure
18301 */
18302static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
18303 struct net_device *ndev,
18304 struct cfg80211_connect_params *req)
18305{
18306 int status;
Manikandan Mohan956b69e2019-02-14 13:08:14 -080018307 u16 channel, sap_cnt, sta_cnt;
Arif Hussainee677012017-01-26 17:50:13 -080018308 const u8 *bssid = NULL;
Sreelakshmi Konamki6bd8a2e2015-11-03 16:30:32 +053018309#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
18310 const u8 *bssid_hint = req->bssid_hint;
18311#else
18312 const u8 *bssid_hint = NULL;
18313#endif
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018314 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(ndev);
Jeff Johnsonb8944722017-09-03 09:03:19 -070018315 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018316
Dustin Brown491d54b2018-03-14 12:39:11 -070018317 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018318
Anurag Chouhan6d760662016-02-20 16:05:43 +053018319 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070018320 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018321 return -EINVAL;
18322 }
18323
Jeff Johnson48363022019-02-24 16:26:51 -080018324 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053018325 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053018326
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053018327 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
18328 TRACE_CODE_HDD_CFG80211_CONNECT,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018329 adapter->vdev_id, adapter->device_mode);
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053018330
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018331 hdd_debug("Device_mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -070018332 qdf_opmode_str(adapter->device_mode), adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018333
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018334 if (adapter->device_mode != QDF_STA_MODE &&
Dustin Brown458027c2018-10-19 12:26:27 -070018335 adapter->device_mode != QDF_P2P_CLIENT_MODE) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070018336 hdd_err("Device_mode %s(%d) is not supported",
Dustin Brown458027c2018-10-19 12:26:27 -070018337 qdf_opmode_str(adapter->device_mode),
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018338 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018339 return -EINVAL;
18340 }
18341
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018342 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnsonb8944722017-09-03 09:03:19 -070018343 if (!hdd_ctx) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070018344 hdd_err("HDD context is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018345 return -EINVAL;
18346 }
18347
Jeff Johnsonb8944722017-09-03 09:03:19 -070018348 status = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053018349 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018350 return status;
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018351
Nachiket Kukade413c5fa2019-02-19 17:57:19 +053018352 /*
18353 * Disable NAN Discovery if incoming connection is P2P or if a STA
Manikandan Mohan956b69e2019-02-14 13:08:14 -080018354 * connection already exists and if this is a case of STA+STA
18355 * or SAP+STA concurrency
Nachiket Kukade413c5fa2019-02-19 17:57:19 +053018356 */
Manikandan Mohan956b69e2019-02-14 13:08:14 -080018357 sta_cnt = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
18358 PM_STA_MODE, NULL);
18359 sap_cnt = policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
18360 PM_SAP_MODE, NULL);
Nachiket Kukade089b9832018-12-12 16:38:17 +053018361
Manikandan Mohan956b69e2019-02-14 13:08:14 -080018362 if (adapter->device_mode == QDF_P2P_CLIENT_MODE || sap_cnt || sta_cnt) {
18363 hdd_debug("Invalid NAN concurrency. SAP: %d STA: %d P2P: %d",
18364 sap_cnt, sta_cnt,
18365 (adapter->device_mode == QDF_P2P_CLIENT_MODE));
18366 ucfg_nan_disable_concurrency(hdd_ctx->psoc);
18367 }
Nachiket Kukade413c5fa2019-02-19 17:57:19 +053018368 /*
18369 * STA+NDI concurrency gets preference over NDI+NDI. Disable
18370 * first NDI in case an NDI+NDI concurrency exists.
18371 */
18372 ucfg_nan_check_and_disable_unsupported_ndi(hdd_ctx->psoc);
18373
Arif Hussainee677012017-01-26 17:50:13 -080018374 if (req->bssid)
18375 bssid = req->bssid;
18376 else if (bssid_hint)
18377 bssid = bssid_hint;
18378
Jeff Johnsonb8944722017-09-03 09:03:19 -070018379 if (bssid && hdd_get_adapter_by_macaddr(hdd_ctx, (uint8_t *)bssid)) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070018380 hdd_err("adapter exist with same mac address " QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070018381 QDF_MAC_ADDR_ARRAY(bssid));
Arif Hussain7631afa2017-02-08 14:35:00 -080018382 return -EINVAL;
Arif Hussainee677012017-01-26 17:50:13 -080018383 }
18384
Vignesh Viswanathan75af0a62018-05-08 17:08:54 +053018385 /*
18386 * Check if this is reassoc to same bssid, if reassoc is success, return
18387 */
18388 status = wlan_hdd_reassoc_bssid_hint(adapter, req);
Padma, Santhosh Kumar41552782018-06-29 15:31:25 +053018389 if (!status) {
18390 hdd_set_roaming_in_progress(true);
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018391 return status;
Padma, Santhosh Kumar41552782018-06-29 15:31:25 +053018392 }
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018393
Agrawal Ashishf156e942016-08-04 14:54:47 +053018394 /* Try disconnecting if already in connected state */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018395 status = wlan_hdd_try_disconnect(adapter);
Agrawal Ashishf156e942016-08-04 14:54:47 +053018396 if (0 > status) {
18397 hdd_err("Failed to disconnect the existing connection");
18398 return -EALREADY;
18399 }
18400
Liangwei Dong3fa5cba2018-07-16 06:41:55 -040018401 /*initialise security parameters */
18402 status = wlan_hdd_cfg80211_set_privacy(adapter, req);
18403
18404 if (status < 0) {
18405 hdd_err("Failed to set security params");
18406 return status;
18407 }
18408
18409 /*
18410 * Check for max concurrent connections after doing disconnect if any,
18411 * must be called after the invocation of wlan_hdd_cfg80211_set_privacy
18412 * so privacy is already set for the current adapter before it's
18413 * checked against concurrency.
18414 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018415 if (req->channel) {
Min Liuab6ed4f2018-01-09 13:13:57 +080018416 bool ok = false;
Ajit Pal Singh90a45a42017-04-18 18:53:46 +053018417
18418 if (req->channel->hw_value && policy_mgr_is_chan_ok_for_dnbs(
Dustin Brown76cd2932018-09-11 16:03:05 -070018419 hdd_ctx->psoc,
Ajit Pal Singh90a45a42017-04-18 18:53:46 +053018420 req->channel->hw_value,
18421 &ok)) {
18422 hdd_warn("Unable to get channel:%d eligibility for DNBS",
18423 req->channel->hw_value);
18424 return -EINVAL;
18425 }
18426 /**
18427 * Send connection timedout, so that Android framework does not
18428 * blacklist us.
18429 */
18430 if (!ok) {
18431 struct ieee80211_channel *chan =
Dustin Brown2eb1e452017-08-15 12:40:34 -070018432 ieee80211_get_channel(wiphy,
Ajit Pal Singh90a45a42017-04-18 18:53:46 +053018433 wlan_chan_to_freq(req->channel->hw_value));
18434 struct cfg80211_bss *bss;
18435
18436 hdd_warn("Channel:%d not OK for DNBS",
18437 req->channel->hw_value);
18438 if (chan) {
Abhishek Singh59cdca12019-03-08 13:48:20 +053018439 bss = wlan_cfg80211_get_bss(wiphy, chan,
18440 req->bssid,
18441 req->ssid,
18442 req->ssid_len);
Ajit Pal Singh90a45a42017-04-18 18:53:46 +053018443 if (bss) {
18444 cfg80211_assoc_timeout(ndev, bss);
18445 return -ETIMEDOUT;
18446 }
18447 }
18448 return -EINVAL;
18449 }
18450
Dustin Brown76cd2932018-09-11 16:03:05 -070018451 if (!policy_mgr_allow_concurrency(hdd_ctx->psoc,
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080018452 policy_mgr_convert_device_mode_to_qdf_type(
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018453 adapter->device_mode),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018454 req->channel->hw_value, HW_MODE_20_MHZ)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018455 hdd_warn("This concurrency combination is not allowed");
wadesongcaad7c72018-08-06 13:26:27 +080018456 status = -ECONNREFUSED;
18457 goto con_chk_failed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018458 }
18459 } else {
Dustin Brown76cd2932018-09-11 16:03:05 -070018460 if (!policy_mgr_allow_concurrency(hdd_ctx->psoc,
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080018461 policy_mgr_convert_device_mode_to_qdf_type(
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018462 adapter->device_mode), 0, HW_MODE_20_MHZ)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018463 hdd_warn("This concurrency combination is not allowed");
wadesongcaad7c72018-08-06 13:26:27 +080018464 status = -ECONNREFUSED;
18465 goto con_chk_failed;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018466 }
18467 }
Varun Reddy Yeturu3e91dad2016-07-18 15:58:47 -070018468
Sreelakshmi Konamki6bd8a2e2015-11-03 16:30:32 +053018469 if (req->channel)
18470 channel = req->channel->hw_value;
18471 else
18472 channel = 0;
Abhishek Singhb59f8d42017-07-31 14:42:47 +053018473
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018474 wlan_hdd_check_ht20_ht40_ind(hdd_ctx, adapter, req);
Abhishek Singhb59f8d42017-07-31 14:42:47 +053018475
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018476 status = wlan_hdd_cfg80211_connect_start(adapter, req->ssid,
Sreelakshmi Konamki6bd8a2e2015-11-03 16:30:32 +053018477 req->ssid_len, req->bssid,
Naveen Rawatc77e6e72016-08-05 15:19:03 -070018478 bssid_hint, channel, 0);
Srinivas Girigowdad2412882018-09-07 15:42:04 -070018479 if (0 > status)
Jeff Johnson3d8ac552016-06-29 15:21:37 -070018480 hdd_err("connect failed");
Srinivas Girigowdad2412882018-09-07 15:42:04 -070018481
wadesongcaad7c72018-08-06 13:26:27 +080018482 return status;
18483
18484con_chk_failed:
18485 wlan_hdd_cfg80211_clear_privacy(adapter);
Dustin Browne74003f2018-03-14 12:51:58 -070018486 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018487 return status;
18488}
18489
18490/**
18491 * wlan_hdd_cfg80211_connect() - cfg80211 connect api
18492 * @wiphy: Pointer to wiphy
18493 * @dev: Pointer to network device
18494 * @req: Pointer to cfg80211 connect request
18495 *
18496 * Return: 0 for success, non-zero for failure
18497 */
18498static int wlan_hdd_cfg80211_connect(struct wiphy *wiphy,
18499 struct net_device *ndev,
18500 struct cfg80211_connect_params *req)
18501{
Dustin Brown1d31b082018-11-22 14:41:20 +053018502 int errno;
18503 struct osif_vdev_sync *vdev_sync;
18504
18505 errno = osif_vdev_sync_op_start(ndev, &vdev_sync);
18506 if (errno)
18507 return errno;
Srinivas Girigowda576b2352017-08-25 14:44:26 -070018508
Dustin Brown1d31b082018-11-22 14:41:20 +053018509 errno = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018510
Dustin Brown1d31b082018-11-22 14:41:20 +053018511 osif_vdev_sync_op_stop(vdev_sync);
18512
18513 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018514}
18515
Himanshu Agarwal6c3607a2018-01-12 12:04:19 +053018516int wlan_hdd_disconnect(struct hdd_adapter *adapter, u16 reason)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018517{
Dundi Ravitejacc95c562018-07-27 12:30:24 +053018518 QDF_STATUS status;
18519 int result = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018520 unsigned long rc;
Jeff Johnsond377dce2017-10-04 10:32:42 -070018521 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018522 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Padma, Santhosh Kumar52456c62017-01-05 12:14:08 +053018523 eConnectionState prev_conn_state;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070018524 mac_handle_t mac_handle;
Abhishek Singhd1f21c72019-01-21 15:16:34 +053018525 uint32_t wait_time = SME_DISCONNECT_TIMEOUT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018526
Dustin Brown491d54b2018-03-14 12:39:11 -070018527 hdd_enter();
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053018528
Jeff Johnson34fc63a2018-06-14 10:10:02 -070018529 mac_handle = hdd_ctx->mac_handle;
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018530 if (adapter->device_mode == QDF_STA_MODE) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018531 hdd_debug("Stop firmware roaming");
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018532 status = sme_stop_roaming(mac_handle, adapter->vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -070018533 eCsrForcedDisassoc);
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080018534 /*
Abhishek Singh533c9da2017-05-04 10:23:34 +053018535 * If firmware has already started roaming process, driver
18536 * needs to wait for processing of this disconnect request.
18537 *
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080018538 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018539 INIT_COMPLETION(adapter->roaming_comp_var);
nakul kachhwaha8dbf4b52019-06-03 13:27:49 +053018540 if (hdd_is_roaming_in_progress(hdd_ctx) ||
18541 sme_neighbor_middle_of_roaming(mac_handle,
18542 adapter->vdev_id)) {
Abhishek Singh533c9da2017-05-04 10:23:34 +053018543 rc = wait_for_completion_timeout(
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018544 &adapter->roaming_comp_var,
Abhishek Singh533c9da2017-05-04 10:23:34 +053018545 msecs_to_jiffies(WLAN_WAIT_TIME_STOP_ROAM));
18546 if (!rc) {
Jeff Johnson55d2ab42019-03-06 11:43:49 -080018547 hdd_err("roaming comp var timed out vdev id: %d",
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018548 adapter->vdev_id);
Abhishek Singh533c9da2017-05-04 10:23:34 +053018549 }
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018550 if (adapter->roam_ho_fail) {
18551 INIT_COMPLETION(adapter->disconnect_comp_var);
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -070018552 hdd_debug("Disabling queues");
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018553 wlan_hdd_netif_queue_control(adapter,
Abhishek Singh533c9da2017-05-04 10:23:34 +053018554 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
18555 WLAN_CONTROL_PATH);
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018556 hdd_conn_set_connection_state(adapter,
Abhishek Singh533c9da2017-05-04 10:23:34 +053018557 eConnectionState_Disconnecting);
18558 goto wait_for_disconnect;
18559 }
18560 }
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080018561 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018562
Jeff Johnsone7951512019-02-27 10:02:51 -080018563 prev_conn_state = sta_ctx->conn_info.conn_state;
Srinivas Girigowda6598eea2017-07-06 19:26:19 -070018564 /*stop tx queues */
18565 hdd_info("Disabling queues");
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018566 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +053018567 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER, WLAN_CONTROL_PATH);
Jeff Johnsone7951512019-02-27 10:02:51 -080018568 hdd_debug("Set HDD conn_state to eConnectionState_Disconnecting");
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018569 hdd_conn_set_connection_state(adapter, eConnectionState_Disconnecting);
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -070018570
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018571 INIT_COMPLETION(adapter->disconnect_comp_var);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018572
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080018573 /* issue disconnect */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018574
Jeff Johnson34fc63a2018-06-14 10:10:02 -070018575 status = sme_roam_disconnect(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018576 adapter->vdev_id, reason);
Padma, Santhosh Kumar52456c62017-01-05 12:14:08 +053018577 if ((QDF_STATUS_CMD_NOT_QUEUED == status) &&
18578 prev_conn_state != eConnectionState_Connecting) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018579 hdd_debug("status = %d, already disconnected", status);
Padma, Santhosh Kumar52456c62017-01-05 12:14:08 +053018580 result = 0;
Abhishek Singhe9706cc2017-10-12 17:25:06 +053018581 /*
18582 * Wait here instead of returning directly. This will block the
18583 * next connect command and allow processing of the disconnect
18584 * in SME else we might hit some race conditions leading to SME
18585 * and HDD out of sync. As disconnect is already in progress,
18586 * wait here for 1 sec instead of 5 sec.
18587 */
18588 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
Padma, Santhosh Kumar52456c62017-01-05 12:14:08 +053018589 } else if (QDF_STATUS_CMD_NOT_QUEUED == status) {
18590 /*
18591 * Wait here instead of returning directly, this will block the
18592 * next connect command and allow processing of the scan for
18593 * ssid and the previous connect command in CSR. Else we might
18594 * hit some race conditions leading to SME and HDD out of sync.
18595 */
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018596 hdd_debug("Already disconnected or connect was in sme/roam pending list and removed by disconnect");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018597 } else if (0 != status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018598 hdd_err("csr_roam_disconnect failure, status: %d", (int)status);
Jeff Johnson8380f232017-10-25 12:39:44 -070018599 sta_ctx->sta_debug_state = status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018600 result = -EINVAL;
18601 goto disconnected;
18602 }
Abhishek Singh533c9da2017-05-04 10:23:34 +053018603wait_for_disconnect:
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018604 rc = wait_for_completion_timeout(&adapter->disconnect_comp_var,
Abhishek Singhe9706cc2017-10-12 17:25:06 +053018605 msecs_to_jiffies(wait_time));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018606
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053018607 if (!rc && (QDF_STATUS_CMD_NOT_QUEUED != status)) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070018608 hdd_err("Failed to disconnect, timed out");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018609 result = -ETIMEDOUT;
18610 }
18611disconnected:
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018612 hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018613#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
18614 /* Sending disconnect event to userspace for kernel version < 3.11
18615 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
18616 */
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018617 hdd_debug("Send disconnected event to userspace");
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018618 wlan_hdd_cfg80211_indicate_disconnect(adapter->dev, true,
Srinivas Dasarid4e87252019-07-01 15:35:52 +053018619 WLAN_REASON_UNSPECIFIED, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018620#endif
18621
18622 return result;
18623}
18624
18625/**
Srinivas Girigowdaf2599dd2015-11-16 18:20:46 -080018626 * hdd_ieee80211_reason_code_to_str() - return string conversion of reason code
18627 * @reason: ieee80211 reason code.
18628 *
18629 * This utility function helps log string conversion of reason code.
18630 *
18631 * Return: string conversion of reason code, if match found;
18632 * "Unknown" otherwise.
18633 */
18634static const char *hdd_ieee80211_reason_code_to_str(uint16_t reason)
18635{
18636 switch (reason) {
18637 CASE_RETURN_STRING(WLAN_REASON_UNSPECIFIED);
18638 CASE_RETURN_STRING(WLAN_REASON_PREV_AUTH_NOT_VALID);
18639 CASE_RETURN_STRING(WLAN_REASON_DEAUTH_LEAVING);
18640 CASE_RETURN_STRING(WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
18641 CASE_RETURN_STRING(WLAN_REASON_DISASSOC_AP_BUSY);
18642 CASE_RETURN_STRING(WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
18643 CASE_RETURN_STRING(WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
18644 CASE_RETURN_STRING(WLAN_REASON_DISASSOC_STA_HAS_LEFT);
18645 CASE_RETURN_STRING(WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH);
18646 CASE_RETURN_STRING(WLAN_REASON_DISASSOC_BAD_POWER);
18647 CASE_RETURN_STRING(WLAN_REASON_DISASSOC_BAD_SUPP_CHAN);
18648 CASE_RETURN_STRING(WLAN_REASON_INVALID_IE);
18649 CASE_RETURN_STRING(WLAN_REASON_MIC_FAILURE);
18650 CASE_RETURN_STRING(WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT);
18651 CASE_RETURN_STRING(WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT);
18652 CASE_RETURN_STRING(WLAN_REASON_IE_DIFFERENT);
18653 CASE_RETURN_STRING(WLAN_REASON_INVALID_GROUP_CIPHER);
18654 CASE_RETURN_STRING(WLAN_REASON_INVALID_PAIRWISE_CIPHER);
18655 CASE_RETURN_STRING(WLAN_REASON_INVALID_AKMP);
18656 CASE_RETURN_STRING(WLAN_REASON_UNSUPP_RSN_VERSION);
18657 CASE_RETURN_STRING(WLAN_REASON_INVALID_RSN_IE_CAP);
18658 CASE_RETURN_STRING(WLAN_REASON_IEEE8021X_FAILED);
18659 CASE_RETURN_STRING(WLAN_REASON_CIPHER_SUITE_REJECTED);
18660 CASE_RETURN_STRING(WLAN_REASON_DISASSOC_UNSPECIFIED_QOS);
18661 CASE_RETURN_STRING(WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH);
18662 CASE_RETURN_STRING(WLAN_REASON_DISASSOC_LOW_ACK);
18663 CASE_RETURN_STRING(WLAN_REASON_DISASSOC_QAP_EXCEED_TXOP);
18664 CASE_RETURN_STRING(WLAN_REASON_QSTA_LEAVE_QBSS);
18665 CASE_RETURN_STRING(WLAN_REASON_QSTA_NOT_USE);
18666 CASE_RETURN_STRING(WLAN_REASON_QSTA_REQUIRE_SETUP);
18667 CASE_RETURN_STRING(WLAN_REASON_QSTA_TIMEOUT);
18668 CASE_RETURN_STRING(WLAN_REASON_QSTA_CIPHER_NOT_SUPP);
18669 CASE_RETURN_STRING(WLAN_REASON_MESH_PEER_CANCELED);
18670 CASE_RETURN_STRING(WLAN_REASON_MESH_MAX_PEERS);
18671 CASE_RETURN_STRING(WLAN_REASON_MESH_CONFIG);
18672 CASE_RETURN_STRING(WLAN_REASON_MESH_CLOSE);
18673 CASE_RETURN_STRING(WLAN_REASON_MESH_MAX_RETRIES);
18674 CASE_RETURN_STRING(WLAN_REASON_MESH_CONFIRM_TIMEOUT);
18675 CASE_RETURN_STRING(WLAN_REASON_MESH_INVALID_GTK);
18676 CASE_RETURN_STRING(WLAN_REASON_MESH_INCONSISTENT_PARAM);
18677 CASE_RETURN_STRING(WLAN_REASON_MESH_INVALID_SECURITY);
18678 CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_ERROR);
18679 CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_NOFORWARD);
18680 CASE_RETURN_STRING(WLAN_REASON_MESH_PATH_DEST_UNREACHABLE);
18681 CASE_RETURN_STRING(WLAN_REASON_MAC_EXISTS_IN_MBSS);
18682 CASE_RETURN_STRING(WLAN_REASON_MESH_CHAN_REGULATORY);
18683 CASE_RETURN_STRING(WLAN_REASON_MESH_CHAN);
18684 default:
18685 return "Unknown";
18686 }
18687}
18688
18689/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018690 * __wlan_hdd_cfg80211_disconnect() - cfg80211 disconnect api
18691 * @wiphy: Pointer to wiphy
18692 * @dev: Pointer to network device
18693 * @reason: Disconnect reason code
18694 *
18695 * This function is used to issue a disconnect request to SME
18696 *
18697 * Return: 0 for success, non-zero for failure
18698 */
18699static int __wlan_hdd_cfg80211_disconnect(struct wiphy *wiphy,
18700 struct net_device *dev, u16 reason)
18701{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018702 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018703 int status;
Jeff Johnsond377dce2017-10-04 10:32:42 -070018704 struct hdd_station_ctx *sta_ctx =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018705 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18706 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Min Liu8c5d99e2018-09-10 17:18:44 +080018707 struct wlan_objmgr_vdev *vdev;
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +053018708 bool enable_deauth_to_disassoc_map;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018709
Dustin Brown491d54b2018-03-14 12:39:11 -070018710 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018711
Anurag Chouhan6d760662016-02-20 16:05:43 +053018712 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070018713 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018714 return -EINVAL;
18715 }
18716
Jeff Johnson48363022019-02-24 16:26:51 -080018717 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053018718 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053018719
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053018720 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
18721 TRACE_CODE_HDD_CFG80211_DISCONNECT,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018722 adapter->vdev_id, reason);
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053018723
Srinivas Girigowda44cff5c2018-04-16 15:49:30 -070018724 hdd_print_netdev_txq_status(dev);
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018725 hdd_debug("Device_mode %s(%d) reason code(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -070018726 qdf_opmode_str(adapter->device_mode),
18727 adapter->device_mode, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018728
Jeff Johnsonb8944722017-09-03 09:03:19 -070018729 status = wlan_hdd_validate_context(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018730
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053018731 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018732 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018733
Alok Kumarb64650c2018-03-23 17:05:11 +053018734 qdf_mutex_acquire(&adapter->disconnection_status_lock);
18735 if (adapter->disconnection_in_progress) {
18736 qdf_mutex_release(&adapter->disconnection_status_lock);
18737 hdd_debug("Disconnect is already in progress");
18738 return 0;
18739 }
18740 adapter->disconnection_in_progress = true;
18741 qdf_mutex_release(&adapter->disconnection_status_lock);
18742
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018743 /* Issue disconnect request to SME, if station is in connected state */
Jeff Johnsone7951512019-02-27 10:02:51 -080018744 if ((sta_ctx->conn_info.conn_state == eConnectionState_Associated) ||
18745 (sta_ctx->conn_info.conn_state == eConnectionState_Connecting)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018746 eCsrRoamDisconnectReason reasonCode =
18747 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018748
18749 switch (reason) {
18750 case WLAN_REASON_MIC_FAILURE:
18751 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
18752 break;
18753
18754 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
18755 case WLAN_REASON_DISASSOC_AP_BUSY:
18756 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
18757 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
18758 break;
18759
18760 case WLAN_REASON_PREV_AUTH_NOT_VALID:
18761 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
18762 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
18763 break;
18764
18765 case WLAN_REASON_DEAUTH_LEAVING:
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +053018766 status = ucfg_mlme_get_enable_deauth_to_disassoc_map(
18767 hdd_ctx->psoc,
18768 &enable_deauth_to_disassoc_map);
18769 if (QDF_IS_STATUS_ERROR(status))
18770 return -EINVAL;
18771
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018772 reasonCode =
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +053018773 enable_deauth_to_disassoc_map ?
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018774 eCSR_DISCONNECT_REASON_STA_HAS_LEFT :
18775 eCSR_DISCONNECT_REASON_DEAUTH;
Mohit Khannaceb97782017-04-05 16:27:08 -070018776 qdf_dp_trace_dump_all(
18777 WLAN_DEAUTH_DPTRACE_DUMP_COUNT,
18778 QDF_TRACE_DEFAULT_PDEV_ID);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018779 break;
18780 case WLAN_REASON_DISASSOC_STA_HAS_LEFT:
18781 reasonCode = eCSR_DISCONNECT_REASON_STA_HAS_LEFT;
18782 break;
18783 default:
18784 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
18785 break;
18786 }
Min Liu8c5d99e2018-09-10 17:18:44 +080018787
18788 vdev = hdd_objmgr_get_vdev(adapter);
18789 if (!vdev)
18790 return -EINVAL;
18791 if (ucfg_scan_get_vdev_status(vdev) !=
Sandeep Puligilla5f86d992017-10-29 14:58:53 -070018792 SCAN_NOT_IN_PROGRESS) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018793 hdd_debug("Disconnect is in progress, Aborting Scan");
Dustin Brown07901ec2018-09-07 11:02:41 -070018794 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018795 adapter->vdev_id, INVALID_SCAN_ID,
Dustin Brown07901ec2018-09-07 11:02:41 -070018796 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018797 }
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018798 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018799 /* First clean up the tdls peers if any */
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018800 hdd_notify_sta_disconnect(adapter->vdev_id,
Min Liu8c5d99e2018-09-10 17:18:44 +080018801 false, true, vdev);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +053018802 hdd_objmgr_put_vdev(vdev);
Kabilan Kannanb6153b12017-07-13 17:54:02 -070018803
Dustin Browna7bb6ae2018-08-16 16:51:50 -070018804 hdd_info("Disconnect from userspace; reason:%d (%s)",
18805 reason, hdd_ieee80211_reason_code_to_str(reason));
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018806 status = wlan_hdd_disconnect(adapter, reasonCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018807 if (0 != status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018808 hdd_err("wlan_hdd_disconnect failed, status: %d", status);
Alok Kumarb64650c2018-03-23 17:05:11 +053018809 hdd_set_disconnect_status(adapter, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018810 return -EINVAL;
18811 }
18812 } else {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018813 hdd_err("Unexpected cfg disconnect called while in state: %d",
Jeff Johnsone7951512019-02-27 10:02:51 -080018814 sta_ctx->conn_info.conn_state);
Alok Kumarb64650c2018-03-23 17:05:11 +053018815 hdd_set_disconnect_status(adapter, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018816 }
18817
18818 return status;
18819}
18820
18821/**
18822 * wlan_hdd_cfg80211_disconnect() - cfg80211 disconnect api
18823 * @wiphy: Pointer to wiphy
18824 * @dev: Pointer to network device
18825 * @reason: Disconnect reason code
18826 *
18827 * Return: 0 for success, non-zero for failure
18828 */
18829static int wlan_hdd_cfg80211_disconnect(struct wiphy *wiphy,
18830 struct net_device *dev, u16 reason)
18831{
Dustin Brown1d31b082018-11-22 14:41:20 +053018832 int errno;
18833 struct osif_vdev_sync *vdev_sync;
18834
18835 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
18836 if (errno)
18837 return errno;
Srinivas Girigowda576b2352017-08-25 14:44:26 -070018838
Dustin Brown1d31b082018-11-22 14:41:20 +053018839 errno = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018840
Dustin Brown1d31b082018-11-22 14:41:20 +053018841 osif_vdev_sync_op_stop(vdev_sync);
18842
18843 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018844}
18845
18846/**
18847 * wlan_hdd_cfg80211_set_privacy_ibss() - set ibss privacy
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018848 * @adapter: Pointer to adapter
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018849 * @param: Pointer to IBSS parameters
18850 *
18851 * This function is used to initialize the security settings in IBSS mode
18852 *
18853 * Return: 0 for success, non-zero for failure
18854 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018855static int wlan_hdd_cfg80211_set_privacy_ibss(struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018856 struct cfg80211_ibss_params
18857 *params)
18858{
Naveen Rawat72475db2017-12-13 18:07:35 -080018859 uint32_t ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018860 int status = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018861 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Jeff Johnsond377dce2017-10-04 10:32:42 -070018862 struct hdd_station_ctx *sta_ctx =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018863 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnson20227a92018-03-13 09:41:05 -070018864 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018865
Dustin Brown491d54b2018-03-14 12:39:11 -070018866 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018867
Jeff Johnsonce4a8342017-10-14 13:12:22 -070018868 sta_ctx->wpa_versions = 0;
Jeff Johnsond377dce2017-10-04 10:32:42 -070018869 qdf_mem_zero(&sta_ctx->ibss_enc_key, sizeof(tCsrRoamSetKey));
18870 sta_ctx->ibss_enc_key_installed = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018871
Jeff Johnsond36fa332019-03-18 13:42:25 -070018872 if (params->ie_len && (params->ie)) {
Naveen Rawat08db88f2017-09-08 15:07:48 -070018873 if (wlan_get_ie_ptr_from_eid(WLAN_EID_RSN, params->ie,
18874 params->ie_len)) {
Jeff Johnsonce4a8342017-10-14 13:12:22 -070018875 sta_ctx->wpa_versions = NL80211_WPA_VERSION_2;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018876 encryptionType = eCSR_ENCRYPT_TYPE_AES;
18877 } else if (hdd_is_wpaie_present(params->ie, params->ie_len)) {
Jeff Johnson6a2c0ca2019-03-09 22:08:45 -080018878 tDot11fIEWPA dot11_wpa_ie;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070018879 mac_handle_t mac_handle =
18880 hdd_adapter_get_mac_handle(adapter);
Naveen Rawat08db88f2017-09-08 15:07:48 -070018881 const u8 *ie;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018882
Jeff Johnson6a2c0ca2019-03-09 22:08:45 -080018883 memset(&dot11_wpa_ie, 0, sizeof(dot11_wpa_ie));
Naveen Rawat08db88f2017-09-08 15:07:48 -070018884 ie = wlan_get_ie_ptr_from_eid(DOT11F_EID_WPA,
18885 params->ie, params->ie_len);
Jeff Johnsond36fa332019-03-18 13:42:25 -070018886 if (ie) {
Jeff Johnsonce4a8342017-10-14 13:12:22 -070018887 sta_ctx->wpa_versions = NL80211_WPA_VERSION_1;
Jeff Johnsonf3826e12017-01-12 09:49:40 -080018888 /* Unpack the WPA IE
18889 * Skip past the EID byte and length byte
18890 * and four byte WiFi OUI
18891 */
Hanumanth Reddy Pothulaf6e3db32018-01-24 17:54:15 +053018892 if (ie[1] < DOT11F_IE_WPA_MIN_LEN ||
18893 ie[1] > DOT11F_IE_WPA_MAX_LEN) {
18894 hdd_err("invalid ie len:%d", ie[1]);
18895 return -EINVAL;
18896 }
Naveen Rawat72475db2017-12-13 18:07:35 -080018897 ret = dot11f_unpack_ie_wpa(
Jeff Johnson034f3c92018-11-09 10:46:21 -080018898 MAC_CONTEXT(mac_handle),
Naveen Rawat72475db2017-12-13 18:07:35 -080018899 (uint8_t *)&ie[2 + 4],
Jeff Johnson6a2c0ca2019-03-09 22:08:45 -080018900 ie[1] - 4, &dot11_wpa_ie, false);
Naveen Rawat72475db2017-12-13 18:07:35 -080018901 if (DOT11F_FAILED(ret)) {
18902 hdd_err("unpack failed ret: 0x%x", ret);
18903 return -EINVAL;
18904 }
Selvaraj, Sridhar75afbeb2017-04-03 17:08:59 +053018905 /*
18906 * Extract the multicast cipher, the
Jeff Johnsonf3826e12017-01-12 09:49:40 -080018907 * encType for unicast cipher for
18908 * wpa-none is none
18909 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018910 encryptionType =
18911 hdd_translate_wpa_to_csr_encryption_type
Jeff Johnson6a2c0ca2019-03-09 22:08:45 -080018912 (dot11_wpa_ie.multicast_cipher);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018913 }
18914 }
18915
18916 status =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018917 wlan_hdd_cfg80211_set_ie(adapter, params->ie,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018918 params->ie_len);
18919
18920 if (0 > status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018921 hdd_err("Failed to parse WPA/RSN IE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018922 return status;
18923 }
18924 }
18925
Jeff Johnson20227a92018-03-13 09:41:05 -070018926 roam_profile = hdd_roam_profile(adapter);
18927 roam_profile->AuthType.authType[0] =
Jeff Johnson96e33512019-02-27 15:10:21 -080018928 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018929
18930 if (params->privacy) {
18931 /* Security enabled IBSS, At this time there is no information
Jeff Johnson60ed45a2018-05-06 15:28:49 -070018932 * available about the security parameters, so initialise the
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018933 * encryption type to eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
18934 * The correct security parameters will be updated later in
18935 * wlan_hdd_cfg80211_add_key Hal expects encryption type to be
18936 * set inorder enable privacy bit in beacons
18937 */
18938
18939 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
18940 }
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018941 hdd_debug("encryptionType=%d", encryptionType);
Jeff Johnsonb1959842019-02-27 13:04:04 -080018942 sta_ctx->conn_info.uc_encrypt_type = encryptionType;
Jeff Johnson20227a92018-03-13 09:41:05 -070018943 roam_profile->EncryptionType.numEntries = 1;
18944 roam_profile->EncryptionType.encryptionType[0] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018945 encryptionType;
18946 return status;
18947}
18948
18949/**
18950 * __wlan_hdd_cfg80211_join_ibss() - join ibss
18951 * @wiphy: Pointer to wiphy
18952 * @dev: Pointer to network device
18953 * @param: Pointer to IBSS join parameters
18954 *
18955 * This function is used to create/join an IBSS network
18956 *
18957 * Return: 0 for success, non-zero for failure
18958 */
18959static int __wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy,
18960 struct net_device *dev,
18961 struct cfg80211_ibss_params *params)
18962{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018963 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson61b5e982018-03-15 11:33:31 -070018964 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018965 int status;
Jeff Johnsond377dce2017-10-04 10:32:42 -070018966 struct hdd_station_ctx *sta_ctx =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070018967 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
18968 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +053018969 struct qdf_mac_addr bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018970 u8 channelNum = 0;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070018971 mac_handle_t mac_handle;
Manikandan Mohan2bd09772018-11-28 18:27:32 -080018972 struct wlan_mlme_ibss_cfg ibss_cfg = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018973
Dustin Brown491d54b2018-03-14 12:39:11 -070018974 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018975
Anurag Chouhan6d760662016-02-20 16:05:43 +053018976 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070018977 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018978 return -EINVAL;
18979 }
18980
Jeff Johnson48363022019-02-24 16:26:51 -080018981 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053018982 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053018983
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053018984 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
18985 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080018986 adapter->vdev_id, adapter->device_mode);
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053018987
Srinivas Girigowda13d39252017-03-06 16:12:15 -080018988 hdd_debug("Device_mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -070018989 qdf_opmode_str(adapter->device_mode), adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018990
Jeff Johnsonb8944722017-09-03 09:03:19 -070018991 status = wlan_hdd_validate_context(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018992
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053018993 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018994 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080018995
Manikandan Mohan2bd09772018-11-28 18:27:32 -080018996 if (QDF_IS_STATUS_ERROR(ucfg_mlme_get_ibss_cfg(hdd_ctx->psoc,
18997 &ibss_cfg))) {
18998 return -EINVAL;
18999 }
19000
Jeff Johnson34fc63a2018-06-14 10:10:02 -070019001 mac_handle = hdd_ctx->mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019002 if (NULL !=
Anurag Chouhance0dc992016-02-16 18:18:03 +053019003 params->chandef.chan) {
Wu Gao0821b0d2019-01-11 17:31:11 +080019004 uint32_t numChans = CFG_VALID_CHANNEL_LIST_LEN;
19005 uint8_t validChan[CFG_VALID_CHANNEL_LIST_LEN];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019006 int indx;
19007
19008 /* Get channel number */
19009 channelNum = ieee80211_frequency_to_channel(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019010 params->
19011 chandef.
19012 chan->
19013 center_freq);
Wu Gaof3cbeaf2019-01-15 18:26:25 +080019014 ucfg_mlme_get_valid_channel_list(hdd_ctx->psoc, validChan,
19015 &numChans);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019016
19017 for (indx = 0; indx < numChans; indx++) {
Srinivas Girigowda576b2352017-08-25 14:44:26 -070019018 if (channelNum == validChan[indx])
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019019 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019020 }
19021 if (indx >= numChans) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019022 hdd_err("Not valid Channel: %d", channelNum);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019023 return -EINVAL;
19024 }
19025 }
19026
Nachiket Kukade089b9832018-12-12 16:38:17 +053019027 /* Disable NAN Discovery if enabled */
19028 ucfg_nan_disable_concurrency(hdd_ctx->psoc);
19029
Dustin Brown76cd2932018-09-11 16:03:05 -070019030 if (!policy_mgr_allow_concurrency(hdd_ctx->psoc,
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080019031 PM_IBSS_MODE, channelNum, HW_MODE_20_MHZ)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019032 hdd_err("This concurrency combination is not allowed");
19033 return -ECONNREFUSED;
19034 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019035
Dustin Brown76cd2932018-09-11 16:03:05 -070019036 status = policy_mgr_reset_connection_update(hdd_ctx->psoc);
Krunal Soni3091bcc2016-06-23 12:28:21 -070019037 if (!QDF_IS_STATUS_SUCCESS(status))
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019038 hdd_err("qdf_reset_connection_update failed status: %d", status);
Krunal Soni3091bcc2016-06-23 12:28:21 -070019039
Dustin Brown76cd2932018-09-11 16:03:05 -070019040 status = policy_mgr_current_connections_update(hdd_ctx->psoc,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080019041 adapter->vdev_id, channelNum,
Tushnim Bhattacharyya3b99f4b2018-03-26 14:19:24 -070019042 POLICY_MGR_UPDATE_REASON_JOIN_IBSS);
Krunal Soni3091bcc2016-06-23 12:28:21 -070019043 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019044 hdd_err("connections update failed!!");
Krunal Soni3091bcc2016-06-23 12:28:21 -070019045 return -EINVAL;
19046 }
19047
19048 if (QDF_STATUS_SUCCESS == status) {
Tushnim Bhattacharyya87161582017-03-09 13:03:31 -080019049 status = policy_mgr_wait_for_connection_update(
Dustin Brown76cd2932018-09-11 16:03:05 -070019050 hdd_ctx->psoc);
Krunal Soni3091bcc2016-06-23 12:28:21 -070019051 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019052 hdd_err("qdf wait for event failed!!");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019053 return -EINVAL;
19054 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019055 }
19056
19057 /*Try disconnecting if already in connected state */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019058 status = wlan_hdd_try_disconnect(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019059 if (0 > status) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070019060 hdd_err("Failed to disconnect the existing IBSS connection");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019061 return -EALREADY;
19062 }
19063
Jeff Johnson20227a92018-03-13 09:41:05 -070019064 roam_profile = hdd_roam_profile(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019065
Jeff Johnson5b34fce2017-10-13 13:24:51 -070019066 if (eCSR_BSS_TYPE_START_IBSS != roam_profile->BSSType) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070019067 hdd_err("Interface type is not set to IBSS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019068 return -EINVAL;
19069 }
19070
19071 /* enable selected protection checks in IBSS mode */
Jeff Johnson5b34fce2017-10-13 13:24:51 -070019072 roam_profile->cfg_protection = IBSS_CFG_PROTECTION_ENABLE_MASK;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019073
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019074 /* BSSID is provided by upper layers hence no need to AUTO generate */
Jeff Johnsond36fa332019-03-18 13:42:25 -070019075 if (params->bssid) {
Manikandan Mohan2bd09772018-11-28 18:27:32 -080019076 if (ucfg_mlme_set_ibss_auto_bssid(hdd_ctx->psoc, 0)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053019077 == QDF_STATUS_E_FAILURE) {
Manikandan Mohan2bd09772018-11-28 18:27:32 -080019078 hdd_err("Unable to update MLME IBSS Auto BSSID config");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019079 return -EIO;
19080 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +053019081 qdf_mem_copy(bssid.bytes, params->bssid, QDF_MAC_ADDR_SIZE);
Manikandan Mohan2bd09772018-11-28 18:27:32 -080019082 } else if (ibss_cfg.coalesing_enable == 0) {
19083 if (ucfg_mlme_set_ibss_auto_bssid(hdd_ctx->psoc, 0)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053019084 == QDF_STATUS_E_FAILURE) {
Manikandan Mohan2bd09772018-11-28 18:27:32 -080019085 hdd_err("Unable to update MLME IBSS Auto BSSID config");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019086 return -EIO;
19087 }
Manikandan Mohan2bd09772018-11-28 18:27:32 -080019088 qdf_copy_macaddr(&bssid, &ibss_cfg.bssid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019089 }
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053019090
19091 if (cfg_in_range(CFG_BEACON_INTERVAL, params->beacon_interval))
Jeff Johnson5b34fce2017-10-13 13:24:51 -070019092 roam_profile->beaconInterval = params->beacon_interval;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053019093 else
Dustin Brown05d81302018-09-11 16:49:22 -070019094 roam_profile->beaconInterval = cfg_get(hdd_ctx->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053019095 CFG_BEACON_INTERVAL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019096
19097 /* Set Channel */
19098 if (channelNum) {
19099 /* Set the Operational Channel */
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019100 hdd_debug("set channel %d", channelNum);
Jeff Johnson5b34fce2017-10-13 13:24:51 -070019101 roam_profile->ChannelInfo.numOfChannels = 1;
Jeff Johnson8626e932019-02-27 18:35:22 -080019102 sta_ctx->conn_info.channel = channelNum;
Jeff Johnson5b34fce2017-10-13 13:24:51 -070019103 roam_profile->ChannelInfo.ChannelList =
Jeff Johnson8626e932019-02-27 18:35:22 -080019104 &sta_ctx->conn_info.channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019105 }
19106
19107 /* Initialize security parameters */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019108 status = wlan_hdd_cfg80211_set_privacy_ibss(adapter, params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019109 if (status < 0) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070019110 hdd_err("failed to set security parameters");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019111 return status;
19112 }
19113
19114 /* Issue connect start */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019115 status = wlan_hdd_cfg80211_connect_start(adapter, params->ssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019116 params->ssid_len,
Naveen Rawatc77e6e72016-08-05 15:19:03 -070019117 bssid.bytes, NULL,
Jeff Johnsond377dce2017-10-04 10:32:42 -070019118 sta_ctx->conn_info.
Jeff Johnson8626e932019-02-27 18:35:22 -080019119 channel,
Naveen Rawatc77e6e72016-08-05 15:19:03 -070019120 params->chandef.width);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019121
19122 if (0 > status) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070019123 hdd_err("connect failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019124 return status;
19125 }
Dustin Browne74003f2018-03-14 12:51:58 -070019126 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019127 return 0;
19128}
19129
19130/**
19131 * wlan_hdd_cfg80211_join_ibss() - join ibss
19132 * @wiphy: Pointer to wiphy
19133 * @dev: Pointer to network device
19134 * @param: Pointer to IBSS join parameters
19135 *
19136 * This function is used to create/join an IBSS network
19137 *
19138 * Return: 0 for success, non-zero for failure
19139 */
19140static int wlan_hdd_cfg80211_join_ibss(struct wiphy *wiphy,
19141 struct net_device *dev,
19142 struct cfg80211_ibss_params *params)
19143{
Dustin Brown1d31b082018-11-22 14:41:20 +053019144 int errno;
19145 struct osif_vdev_sync *vdev_sync;
19146
19147 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
19148 if (errno)
19149 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019150
Dustin Brown1d31b082018-11-22 14:41:20 +053019151 errno = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019152
Dustin Brown1d31b082018-11-22 14:41:20 +053019153 osif_vdev_sync_op_stop(vdev_sync);
19154
19155 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019156}
19157
19158/**
19159 * __wlan_hdd_cfg80211_leave_ibss() - leave ibss
19160 * @wiphy: Pointer to wiphy
19161 * @dev: Pointer to network device
19162 *
19163 * This function is used to leave an IBSS network
19164 *
19165 * Return: 0 for success, non-zero for failure
19166 */
19167static int __wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy,
19168 struct net_device *dev)
19169{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019170 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson61b5e982018-03-15 11:33:31 -070019171 struct csr_roam_profile *roam_profile;
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019172 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019173 int status;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070019174 mac_handle_t mac_handle;
Chandrasekaran, Manishekar12a818a2015-12-18 11:44:56 +053019175 unsigned long rc;
Jeff Johnsonc565af12019-03-10 21:09:47 -070019176 tSirUpdateIE update_ie;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019177
Dustin Brown491d54b2018-03-14 12:39:11 -070019178 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019179
Anurag Chouhan6d760662016-02-20 16:05:43 +053019180 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070019181 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019182 return -EINVAL;
19183 }
19184
Jeff Johnson48363022019-02-24 16:26:51 -080019185 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053019186 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053019187
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053019188 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
19189 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080019190 adapter->vdev_id, eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053019191
Jeff Johnsonb8944722017-09-03 09:03:19 -070019192 status = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053019193 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019194 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019195
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019196 hdd_debug("Device_mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -070019197 qdf_opmode_str(adapter->device_mode), adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019198
Jeff Johnson20227a92018-03-13 09:41:05 -070019199 roam_profile = hdd_roam_profile(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019200
19201 /* Issue disconnect only if interface type is set to IBSS */
Jeff Johnson5b34fce2017-10-13 13:24:51 -070019202 if (eCSR_BSS_TYPE_START_IBSS != roam_profile->BSSType) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070019203 hdd_err("BSS Type is not set to IBSS");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019204 return -EINVAL;
19205 }
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080019206 /* Clearing add IE of beacon */
Jeff Johnsonc565af12019-03-10 21:09:47 -070019207 qdf_mem_copy(update_ie.bssid.bytes, adapter->mac_addr.bytes,
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080019208 sizeof(tSirMacAddr));
Jeff Johnsonc565af12019-03-10 21:09:47 -070019209 update_ie.smeSessionId = adapter->vdev_id;
19210 update_ie.ieBufferlength = 0;
19211 update_ie.pAdditionIEBuffer = NULL;
19212 update_ie.append = true;
19213 update_ie.notify = true;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070019214 mac_handle = hdd_ctx->mac_handle;
19215 if (sme_update_add_ie(mac_handle,
Jeff Johnsonc565af12019-03-10 21:09:47 -070019216 &update_ie,
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080019217 eUPDATE_IE_PROBE_BCN) == QDF_STATUS_E_FAILURE) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070019218 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -080019219 }
19220
19221 /* Reset WNI_CFG_PROBE_RSP Flags */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019222 wlan_hdd_reset_prob_rspies(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019223
19224 /* Issue Disconnect request */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019225 INIT_COMPLETION(adapter->disconnect_comp_var);
Jeff Johnson34fc63a2018-06-14 10:10:02 -070019226 status = sme_roam_disconnect(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080019227 adapter->vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -070019228 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
19229 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019230 hdd_err("sme_roam_disconnect failed status: %d",
Jeff Johnson34fc63a2018-06-14 10:10:02 -070019231 status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019232 return -EAGAIN;
19233 }
Chandrasekaran, Manishekar12a818a2015-12-18 11:44:56 +053019234
19235 /* wait for mc thread to cleanup and then return to upper stack
19236 * so by the time upper layer calls the change interface, we are
19237 * all set to proceed further
19238 */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019239 rc = wait_for_completion_timeout(&adapter->disconnect_comp_var,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053019240 msecs_to_jiffies(SME_DISCONNECT_TIMEOUT));
Chandrasekaran, Manishekar12a818a2015-12-18 11:44:56 +053019241 if (!rc) {
19242 hdd_err("Failed to disconnect, timed out");
19243 return -ETIMEDOUT;
19244 }
19245
Dustin Browne74003f2018-03-14 12:51:58 -070019246 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019247 return 0;
19248}
19249
19250/**
19251 * wlan_hdd_cfg80211_leave_ibss() - leave ibss
19252 * @wiphy: Pointer to wiphy
19253 * @dev: Pointer to network device
19254 *
19255 * This function is used to leave an IBSS network
19256 *
19257 * Return: 0 for success, non-zero for failure
19258 */
19259static int wlan_hdd_cfg80211_leave_ibss(struct wiphy *wiphy,
19260 struct net_device *dev)
19261{
Dustin Brown1d31b082018-11-22 14:41:20 +053019262 int errno;
19263 struct osif_vdev_sync *vdev_sync;
19264
19265 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
19266 if (errno)
19267 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019268
Dustin Brown1d31b082018-11-22 14:41:20 +053019269 errno = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019270
Dustin Brown1d31b082018-11-22 14:41:20 +053019271 osif_vdev_sync_op_stop(vdev_sync);
19272
19273 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019274}
19275
19276/**
19277 * __wlan_hdd_cfg80211_set_wiphy_params() - set wiphy parameters
19278 * @wiphy: Pointer to wiphy
19279 * @changed: Parameters changed
19280 *
19281 * This function is used to set the phy parameters. RTS Threshold/FRAG
19282 * Threshold/Retry Count etc.
19283 *
19284 * Return: 0 for success, non-zero for failure
19285 */
19286static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
19287 u32 changed)
19288{
Jeff Johnsonb8944722017-09-03 09:03:19 -070019289 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019290 int status;
19291
Dustin Brown491d54b2018-03-14 12:39:11 -070019292 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019293
Anurag Chouhan6d760662016-02-20 16:05:43 +053019294 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070019295 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019296 return -EINVAL;
19297 }
19298
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053019299 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
19300 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
19301 NO_SESSION, wiphy->rts_threshold);
19302
Jeff Johnsonb8944722017-09-03 09:03:19 -070019303 status = wlan_hdd_validate_context(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019304
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053019305 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019306 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019307
19308 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
19309 u32 rts_threshold = (wiphy->rts_threshold == -1) ?
Harprit Chhabadabec6de42018-09-10 10:21:15 -070019310 cfg_max(CFG_RTS_THRESHOLD) :
19311 wiphy->rts_threshold;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019312
Harprit Chhabadabec6de42018-09-10 10:21:15 -070019313 if ((cfg_min(CFG_RTS_THRESHOLD) > rts_threshold) ||
19314 (cfg_max(CFG_RTS_THRESHOLD) < rts_threshold)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019315 hdd_err("Invalid RTS Threshold value: %u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019316 rts_threshold);
19317 return -EINVAL;
19318 }
19319
Harprit Chhabadabec6de42018-09-10 10:21:15 -070019320 if (0 != ucfg_mlme_set_rts_threshold(hdd_ctx->psoc,
19321 rts_threshold)) {
19322 hdd_err("mlme_set_rts_threshold failed for val %u",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019323 rts_threshold);
19324 return -EIO;
19325 }
19326
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019327 hdd_debug("set rts threshold %u", rts_threshold);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019328 }
19329
19330 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
19331 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
Harprit Chhabadabec6de42018-09-10 10:21:15 -070019332 cfg_max(CFG_FRAG_THRESHOLD) :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019333 wiphy->frag_threshold;
19334
Harprit Chhabadabec6de42018-09-10 10:21:15 -070019335 if ((cfg_min(CFG_FRAG_THRESHOLD) > frag_threshold) ||
19336 (cfg_max(CFG_FRAG_THRESHOLD) < frag_threshold)) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070019337 hdd_err("Invalid frag_threshold value %hu",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019338 frag_threshold);
19339 return -EINVAL;
19340 }
19341
Harprit Chhabadabec6de42018-09-10 10:21:15 -070019342 if (0 != ucfg_mlme_set_frag_threshold(hdd_ctx->psoc,
19343 frag_threshold)) {
19344 hdd_err("mlme_set_frag_threshold failed for val %hu",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019345 frag_threshold);
19346 return -EIO;
19347 }
19348
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019349 hdd_debug("set frag threshold %hu", frag_threshold);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019350 }
19351
Dustin Browne74003f2018-03-14 12:51:58 -070019352 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019353 return 0;
19354}
19355
19356/**
19357 * wlan_hdd_cfg80211_set_wiphy_params() - set wiphy parameters
19358 * @wiphy: Pointer to wiphy
19359 * @changed: Parameters changed
19360 *
19361 * Return: 0 for success, non-zero for failure
19362 */
19363static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
19364{
Dustin Brown363b4792019-02-05 16:11:55 -080019365 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -080019366 int errno;
Arunk Khandavalli447837f2018-11-08 14:32:53 +053019367
Dustin Brown363b4792019-02-05 16:11:55 -080019368 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -080019369 if (errno)
19370 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019371
Dustin Brownf0f00612019-01-31 16:02:24 -080019372 errno = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019373
Dustin Brown363b4792019-02-05 16:11:55 -080019374 osif_psoc_sync_op_stop(psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -080019375
19376 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019377}
19378
19379/**
19380 * __wlan_hdd_set_default_mgmt_key() - dummy implementation of set default mgmt
19381 * key
19382 * @wiphy: Pointer to wiphy
19383 * @dev: Pointer to network device
19384 * @key_index: Key index
19385 *
19386 * Return: 0
19387 */
19388static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
19389 struct net_device *netdev,
19390 u8 key_index)
19391{
Dustin Brown491d54b2018-03-14 12:39:11 -070019392 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019393 return 0;
19394}
19395
19396/**
19397 * wlan_hdd_set_default_mgmt_key() - SSR wrapper for
19398 * wlan_hdd_set_default_mgmt_key
19399 * @wiphy: pointer to wiphy
19400 * @netdev: pointer to net_device structure
19401 * @key_index: key index
19402 *
19403 * Return: 0 on success, error number on failure
19404 */
19405static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
19406 struct net_device *netdev,
19407 u8 key_index)
19408{
Dustin Brown1d31b082018-11-22 14:41:20 +053019409 int errno;
19410 struct osif_vdev_sync *vdev_sync;
19411
19412 errno = osif_vdev_sync_op_start(netdev, &vdev_sync);
19413 if (errno)
19414 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019415
Dustin Brown1d31b082018-11-22 14:41:20 +053019416 errno = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019417
Dustin Brown1d31b082018-11-22 14:41:20 +053019418 osif_vdev_sync_op_stop(vdev_sync);
19419
19420 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019421}
19422
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019423/**
19424 * __wlan_hdd_set_txq_params() - dummy implementation of set tx queue params
19425 * @wiphy: Pointer to wiphy
19426 * @dev: Pointer to network device
19427 * @params: Pointer to tx queue parameters
19428 *
19429 * Return: 0
19430 */
19431static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
19432 struct net_device *dev,
19433 struct ieee80211_txq_params *params)
19434{
Dustin Brown491d54b2018-03-14 12:39:11 -070019435 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019436 return 0;
19437}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019438
19439/**
19440 * wlan_hdd_set_txq_params() - SSR wrapper for wlan_hdd_set_txq_params
19441 * @wiphy: pointer to wiphy
19442 * @netdev: pointer to net_device structure
19443 * @params: pointer to ieee80211_txq_params
19444 *
19445 * Return: 0 on success, error number on failure
19446 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019447static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
19448 struct net_device *dev,
19449 struct ieee80211_txq_params *params)
19450{
Dustin Brown1d31b082018-11-22 14:41:20 +053019451 int errno;
19452 struct osif_vdev_sync *vdev_sync;
19453
19454 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
19455 if (errno)
19456 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019457
Dustin Brown1d31b082018-11-22 14:41:20 +053019458 errno = __wlan_hdd_set_txq_params(wiphy, dev, params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019459
Dustin Brown1d31b082018-11-22 14:41:20 +053019460 osif_vdev_sync_op_stop(vdev_sync);
19461
19462 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019463}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019464
19465/**
19466 * __wlan_hdd_cfg80211_del_station() - delete station v2
19467 * @wiphy: Pointer to wiphy
Jeff Johnson50e37e92019-03-08 11:32:25 -080019468 * @dev: Underlying net device
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019469 * @param: Pointer to delete station parameter
19470 *
19471 * Return: 0 for success, non-zero for failure
19472 */
19473static
19474int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
19475 struct net_device *dev,
Jeff Johnson50e37e92019-03-08 11:32:25 -080019476 struct csr_del_sta_params *param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019477{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019478 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsonb8944722017-09-03 09:03:19 -070019479 struct hdd_context *hdd_ctx;
Anurag Chouhance0dc992016-02-16 18:18:03 +053019480 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070019481 struct hdd_hostapd_state *hapd_state;
Jeff Johnson0a082d92019-03-04 12:25:49 -080019482 uint8_t sta_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019483 uint8_t *mac;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070019484 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019485
Dustin Brown491d54b2018-03-14 12:39:11 -070019486 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019487
Anurag Chouhan6d760662016-02-20 16:05:43 +053019488 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070019489 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019490 return -EINVAL;
19491 }
19492
Jeff Johnson48363022019-02-24 16:26:51 -080019493 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053019494 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053019495
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053019496 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
19497 TRACE_CODE_HDD_CFG80211_DEL_STA,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080019498 adapter->vdev_id, adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019499
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019500 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Abhishek Singh97e8a712019-03-29 12:14:04 +053019501 if (!hdd_ctx) {
19502 hdd_err("hdd_ctx is NULL");
19503 return -EINVAL;
19504 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019505
Jeff Johnson50e37e92019-03-08 11:32:25 -080019506 mac = (uint8_t *) param->peerMacAddr.bytes;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070019507 mac_handle = hdd_ctx->mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019508
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019509 if ((QDF_SAP_MODE == adapter->device_mode) ||
19510 (QDF_P2P_GO_MODE == adapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019511
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019512 hapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019513 if (!hapd_state) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070019514 hdd_err("Hostapd State is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019515 return 0;
19516 }
19517
Anurag Chouhanc5548422016-02-24 18:33:27 +053019518 if (qdf_is_macaddr_broadcast((struct qdf_mac_addr *) mac)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019519 uint16_t i;
Srinivas Girigowda576b2352017-08-25 14:44:26 -070019520
Harprit Chhabadae5742552019-03-21 16:28:48 -070019521 bool is_sap_bcast_deauth_enabled = false;
19522
19523 ucfg_mlme_is_sap_bcast_deauth_enabled(
19524 hdd_ctx->psoc,
19525 &is_sap_bcast_deauth_enabled);
19526 hdd_debug("is_sap_bcast_deauth_enabled %d",
19527 is_sap_bcast_deauth_enabled);
19528
19529 if (is_sap_bcast_deauth_enabled)
19530 goto fn_end;
19531
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019532 for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070019533 if ((adapter->sta_info[i].in_use) &&
19534 (!adapter->sta_info[i].
Jeff Johnsone4f5d932017-10-21 13:21:15 -070019535 is_deauth_in_progress)) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +053019536 qdf_mem_copy(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019537 mac,
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070019538 adapter->sta_info[i].
Jeff Johnsonf2356512017-10-21 16:04:12 -070019539 sta_mac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +053019540 QDF_MAC_ADDR_SIZE);
Yun Parka4bb37c2017-12-08 16:14:22 -080019541
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019542 hdd_debug("Delete STA with MAC::"
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070019543 QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070019544 QDF_MAC_ADDR_ARRAY(mac));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019545
Jeff Johnsonb8944722017-09-03 09:03:19 -070019546 if (hdd_ctx->dev_dfs_cac_status ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019547 DFS_CAC_IN_PROGRESS)
19548 goto fn_end;
19549
Wei Song2f76f642016-11-18 16:32:53 +080019550 qdf_event_reset(&hapd_state->qdf_sta_disassoc_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053019551 qdf_status =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019552 hdd_softap_sta_deauth(adapter,
Jeff Johnson50e37e92019-03-08 11:32:25 -080019553 param);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053019554 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070019555 adapter->sta_info[i].
Jeff Johnsone4f5d932017-10-21 13:21:15 -070019556 is_deauth_in_progress = true;
Anurag Chouhance0dc992016-02-16 18:18:03 +053019557 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053019558 qdf_wait_for_event_completion(
Naveen Rawatb56880c2016-12-13 17:56:03 -080019559 &hapd_state->
19560 qdf_sta_disassoc_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053019561 SME_PEER_DISCONNECT_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +053019562 if (!QDF_IS_STATUS_SUCCESS(
19563 qdf_status))
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019564 hdd_warn("Deauth wait time expired");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019565 }
19566 }
19567 }
19568 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053019569 qdf_status =
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019570 hdd_softap_get_sta_id(adapter,
Anurag Chouhan6d760662016-02-20 16:05:43 +053019571 (struct qdf_mac_addr *) mac,
Jeff Johnson0a082d92019-03-04 12:25:49 -080019572 &sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053019573 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019574 hdd_debug("Skip DEL STA as this is not used::"
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070019575 QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070019576 QDF_MAC_ADDR_ARRAY(mac));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019577 return -ENOENT;
19578 }
19579
Jeff Johnson0a082d92019-03-04 12:25:49 -080019580 if (adapter->sta_info[sta_id].is_deauth_in_progress ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019581 true) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019582 hdd_debug("Skip DEL STA as deauth is in progress::"
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070019583 QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070019584 QDF_MAC_ADDR_ARRAY(mac));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019585 return -ENOENT;
19586 }
19587
Jeff Johnson0a082d92019-03-04 12:25:49 -080019588 adapter->sta_info[sta_id].is_deauth_in_progress = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019589
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070019590 hdd_debug("ucast, Delete STA with MAC:" QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070019591 QDF_MAC_ADDR_ARRAY(mac));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019592
19593 /* Case: SAP in ACS selected DFS ch and client connected
19594 * Now Radar detected. Then if random channel is another
19595 * DFS ch then new CAC is initiated and no TX allowed.
19596 * So do not send any mgmt frames as it will timeout
19597 * during CAC.
19598 */
19599
Jeff Johnsonb8944722017-09-03 09:03:19 -070019600 if (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019601 goto fn_end;
19602
Wei Song2f76f642016-11-18 16:32:53 +080019603 qdf_event_reset(&hapd_state->qdf_sta_disassoc_event);
Jeff Johnson34fc63a2018-06-14 10:10:02 -070019604 sme_send_disassoc_req_frame(mac_handle,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080019605 adapter->vdev_id,
Jeff Johnson50e37e92019-03-08 11:32:25 -080019606 (uint8_t *)&param->peerMacAddr,
19607 param->reason_code, 0);
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019608 qdf_status = hdd_softap_sta_deauth(adapter,
Jeff Johnson50e37e92019-03-08 11:32:25 -080019609 param);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053019610 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson0a082d92019-03-04 12:25:49 -080019611 adapter->sta_info[sta_id].is_deauth_in_progress =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019612 false;
Srinivas Girigowda13d39252017-03-06 16:12:15 -080019613 hdd_debug("STA removal failed for ::"
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070019614 QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070019615 QDF_MAC_ADDR_ARRAY(mac));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019616 return -ENOENT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019617 }
Nachiket Kukade0396b732017-11-14 16:35:16 +053019618 qdf_status = qdf_wait_for_event_completion(
Srinivas Girigowda576b2352017-08-25 14:44:26 -070019619 &hapd_state->
19620 qdf_sta_disassoc_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053019621 SME_PEER_DISCONNECT_TIMEOUT);
Srinivas Girigowda576b2352017-08-25 14:44:26 -070019622 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
19623 hdd_warn("Deauth wait time expired");
Ashish Kumar Dhanotiya443d31f2017-10-13 12:41:19 +053019624
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019625 }
19626 }
19627
19628fn_end:
Dustin Browne74003f2018-03-14 12:51:58 -070019629 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019630 return 0;
19631}
19632
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080019633#if defined(USE_CFG80211_DEL_STA_V2)
19634/**
19635 * wlan_hdd_del_station() - delete station wrapper
19636 * @adapter: pointer to the hdd adapter
19637 *
19638 * Return: None
19639 */
Jeff Johnsone5006672017-08-29 14:39:02 -070019640void wlan_hdd_del_station(struct hdd_adapter *adapter)
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080019641{
19642 struct station_del_parameters del_sta;
Srinivas Girigowda576b2352017-08-25 14:44:26 -070019643
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080019644 del_sta.mac = NULL;
19645 del_sta.subtype = SIR_MAC_MGMT_DEAUTH >> 4;
19646 del_sta.reason_code = eCsrForcedDeauthSta;
19647
19648 wlan_hdd_cfg80211_del_station(adapter->wdev.wiphy, adapter->dev,
19649 &del_sta);
19650}
19651#else
Jeff Johnsone5006672017-08-29 14:39:02 -070019652void wlan_hdd_del_station(struct hdd_adapter *adapter)
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080019653{
19654 wlan_hdd_cfg80211_del_station(adapter->wdev.wiphy, adapter->dev, NULL);
19655}
19656#endif
19657
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019658/**
Dustin Brown1d31b082018-11-22 14:41:20 +053019659 * wlan_hdd_cfg80211_del_station() - delete station entry handler
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019660 * @wiphy: Pointer to wiphy
Dustin Brown1d31b082018-11-22 14:41:20 +053019661 * @dev: net_device to operate against
19662 * @mac: binary mac address
19663 * @reason_code: reason for the deauthorization/disassociation
19664 * @subtype: management frame subtype to indicate removal
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019665 *
Dustin Brown1d31b082018-11-22 14:41:20 +053019666 * Return: Errno
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019667 */
Dustin Brown1d31b082018-11-22 14:41:20 +053019668static int _wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
19669 struct net_device *dev,
19670 const uint8_t *mac,
19671 uint16_t reason_code,
19672 uint8_t subtype)
19673{
19674 int errno;
19675 struct csr_del_sta_params delStaParams;
19676 struct osif_vdev_sync *vdev_sync;
19677
19678 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
19679 if (errno)
19680 return errno;
19681
Dustin Brown1d31b082018-11-22 14:41:20 +053019682 wlansap_populate_del_sta_params(mac, reason_code, subtype,
19683 &delStaParams);
19684 errno = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
Dustin Brown1d31b082018-11-22 14:41:20 +053019685
19686 osif_vdev_sync_op_stop(vdev_sync);
19687
19688 return errno;
19689}
19690
19691#ifdef USE_CFG80211_DEL_STA_V2
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019692int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
19693 struct net_device *dev,
19694 struct station_del_parameters *param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019695{
Dustin Brown1d31b082018-11-22 14:41:20 +053019696 if (!param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019697 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019698
Dustin Brown1d31b082018-11-22 14:41:20 +053019699 return _wlan_hdd_cfg80211_del_station(wiphy, dev, param->mac,
19700 param->reason_code,
19701 param->subtype);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019702}
Dustin Brown1d31b082018-11-22 14:41:20 +053019703#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19704int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
19705 const uint8_t *mac)
19706{
19707 uint16_t reason = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
19708 uint8_t subtype = SIR_MAC_MGMT_DEAUTH >> 4;
19709
19710 return _wlan_hdd_cfg80211_del_station(wiphy, dev, mac, reason, subtype);
19711}
19712#else
19713int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, struct net_device *dev,
19714 uint8_t *mac)
19715{
19716 uint16_t reason = eSIR_MAC_DEAUTH_LEAVING_BSS_REASON;
19717 uint8_t subtype = SIR_MAC_MGMT_DEAUTH >> 4;
19718
19719 return _wlan_hdd_cfg80211_del_station(wiphy, dev, mac, reason, subtype);
19720}
19721#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019722
19723/**
19724 * __wlan_hdd_cfg80211_add_station() - add station
19725 * @wiphy: Pointer to wiphy
19726 * @mac: Pointer to station mac address
19727 * @pmksa: Pointer to add station parameter
19728 *
19729 * Return: 0 for success, non-zero for failure
19730 */
19731static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19732 struct net_device *dev,
19733 const uint8_t *mac,
19734 struct station_parameters *params)
19735{
19736 int status = -EPERM;
19737#ifdef FEATURE_WLAN_TDLS
Jeff Johnsonce2ba702017-10-02 13:30:24 -070019738 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsonb8944722017-09-03 09:03:19 -070019739 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019740 u32 mask, set;
19741
Dustin Brown491d54b2018-03-14 12:39:11 -070019742 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019743
Anurag Chouhan6d760662016-02-20 16:05:43 +053019744 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070019745 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019746 return -EINVAL;
19747 }
19748
Jeff Johnson48363022019-02-24 16:26:51 -080019749 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053019750 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053019751
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053019752 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
19753 TRACE_CODE_HDD_CFG80211_ADD_STA,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080019754 adapter->vdev_id, params->listen_interval);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019755
Jeff Johnsonb8944722017-09-03 09:03:19 -070019756 if (0 != wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019757 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019758
19759 mask = params->sta_flags_mask;
19760
19761 set = params->sta_flags_set;
19762
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070019763 hdd_debug("mask 0x%x set 0x%x " QDF_MAC_ADDR_STR, mask, set,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070019764 QDF_MAC_ADDR_ARRAY(mac));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019765
19766 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Min Liu8c5d99e2018-09-10 17:18:44 +080019767 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
19768 struct wlan_objmgr_vdev *vdev;
19769
19770 vdev = hdd_objmgr_get_vdev(adapter);
19771 if (vdev) {
19772 status = wlan_cfg80211_tdls_add_peer(vdev,
19773 mac);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +053019774 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +080019775 }
19776 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019777 }
19778#endif
Dustin Browne74003f2018-03-14 12:51:58 -070019779 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019780 return status;
19781}
19782
19783/**
19784 * wlan_hdd_cfg80211_add_station() - add station
19785 * @wiphy: Pointer to wiphy
19786 * @mac: Pointer to station mac address
19787 * @pmksa: Pointer to add station parameter
19788 *
19789 * Return: 0 for success, non-zero for failure
19790 */
19791#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19792static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19793 struct net_device *dev,
19794 const uint8_t *mac,
19795 struct station_parameters *params)
19796#else
19797static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
19798 struct net_device *dev, uint8_t *mac,
19799 struct station_parameters *params)
19800#endif
19801{
Dustin Brown1d31b082018-11-22 14:41:20 +053019802 int errno;
19803 struct osif_vdev_sync *vdev_sync;
19804
19805 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
19806 if (errno)
19807 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019808
Dustin Brown1d31b082018-11-22 14:41:20 +053019809 errno = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019810
Dustin Brown1d31b082018-11-22 14:41:20 +053019811 osif_vdev_sync_op_stop(vdev_sync);
19812
19813 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080019814}
19815
Liangwei Donga44d55b2019-03-20 03:22:08 -040019816#ifdef WLAN_CONV_CRYPTO_IE_SUPPORT
19817static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter,
19818 tPmkidCacheInfo *pmk_cache)
19819{
19820 QDF_STATUS result;
19821 struct wlan_crypto_pmksa *pmksa;
19822 struct wlan_objmgr_vdev *vdev;
19823
19824 vdev = hdd_objmgr_get_vdev(adapter);
19825 if (!vdev)
19826 return QDF_STATUS_E_FAILURE;
19827
19828 pmksa = qdf_mem_malloc(sizeof(*pmksa));
19829 if (!pmksa) {
19830 hdd_objmgr_put_vdev(vdev);
19831 return QDF_STATUS_E_NOMEM;
19832 }
19833 qdf_copy_macaddr(&pmksa->bssid, &pmk_cache->BSSID);
19834 qdf_mem_copy(pmksa->pmkid, pmk_cache->PMKID, PMKID_LEN);
19835 qdf_mem_copy(pmksa->pmk, pmk_cache->pmk, pmk_cache->pmk_len);
19836 pmksa->pmk_len = pmk_cache->pmk_len;
19837
19838 result = wlan_crypto_set_del_pmksa(vdev, pmksa, true);
19839 if (result != QDF_STATUS_SUCCESS) {
19840 qdf_mem_zero(pmksa, sizeof(*pmksa));
19841 qdf_mem_free(pmksa);
19842 }
19843 hdd_objmgr_put_vdev(vdev);
19844
19845 return result;
19846}
19847
19848static QDF_STATUS wlan_hdd_del_pmksa_cache(struct hdd_adapter *adapter,
19849 tPmkidCacheInfo *pmk_cache)
19850{
19851 QDF_STATUS result;
19852 struct wlan_crypto_pmksa pmksa;
19853 struct wlan_objmgr_vdev *vdev;
19854
19855 vdev = hdd_objmgr_get_vdev(adapter);
19856 if (!vdev)
19857 return QDF_STATUS_E_FAILURE;
19858
19859 qdf_copy_macaddr(&pmksa.bssid, &pmk_cache->BSSID);
19860 result = wlan_crypto_set_del_pmksa(adapter->vdev, &pmksa, false);
19861 hdd_objmgr_put_vdev(vdev);
19862
19863 return result;
19864}
19865
19866QDF_STATUS wlan_hdd_flush_pmksa_cache(struct hdd_adapter *adapter)
19867{
19868 QDF_STATUS result;
19869 struct wlan_objmgr_vdev *vdev;
19870
19871 vdev = hdd_objmgr_get_vdev(adapter);
19872 if (!vdev)
19873 return QDF_STATUS_E_FAILURE;
19874
19875 result = wlan_crypto_set_del_pmksa(adapter->vdev, NULL, false);
19876 hdd_objmgr_put_vdev(vdev);
19877
19878 return result;
19879}
19880#else
19881static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter,
19882 tPmkidCacheInfo *pmk_cache)
19883{
19884 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
19885
19886 return sme_roam_set_pmkid_cache(
19887 hdd_ctx->mac_handle, adapter->vdev_id, pmk_cache, 1, false);
19888}
19889
19890static QDF_STATUS wlan_hdd_del_pmksa_cache(struct hdd_adapter *adapter,
19891 tPmkidCacheInfo *pmk_cache)
19892{
19893 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
19894
19895 return sme_roam_del_pmkid_from_cache(
19896 hdd_ctx->mac_handle, adapter->vdev_id, pmk_cache,
19897 false);
19898}
19899
19900QDF_STATUS wlan_hdd_flush_pmksa_cache(struct hdd_adapter *adapter)
19901{
19902 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
19903
19904 return sme_roam_del_pmkid_from_cache(
19905 hdd_ctx->mac_handle, adapter->vdev_id, NULL, true);
19906}
19907#endif
19908
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +053019909#if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
19910 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019911/*
19912 * wlan_hdd_is_pmksa_valid: API to validate pmksa
19913 * @pmksa: pointer to cfg80211_pmksa structure
19914 *
19915 * Return: True if valid else false
19916 */
19917static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
19918{
19919 if (!pmksa->bssid) {
Vignesh Viswanathanfa90d622017-12-22 13:13:26 +053019920 hdd_warn("bssid (%pK) is NULL",
19921 pmksa->bssid);
19922 if (!pmksa->ssid || !pmksa->cache_id) {
19923 hdd_err("either ssid (%pK) or cache_id (%pK) are NULL",
19924 pmksa->ssid, pmksa->cache_id);
19925 return false;
19926 }
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019927 }
19928 return true;
19929}
19930
19931/*
19932 * hdd_fill_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
gaurank kathpalia99d06c12018-05-16 16:28:35 +053019933 * @adapter: Pointer to hdd adapter
19934 * @pmk_cache: pmk that needs to be udated
19935 * @pmksa: pmk from supplicant
19936 * @is_delete: Bool to decide set or delete PMK
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019937 * Return: None
19938 */
gaurank kathpalia99d06c12018-05-16 16:28:35 +053019939static void hdd_fill_pmksa_info(struct hdd_adapter *adapter,
19940 tPmkidCacheInfo *pmk_cache,
19941 struct cfg80211_pmksa *pmksa, bool is_delete)
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019942{
19943 if (pmksa->bssid) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070019944 hdd_debug("%s PMKSA for " QDF_MAC_ADDR_STR,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053019945 is_delete ? "Delete" : "Set",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070019946 QDF_MAC_ADDR_ARRAY(pmksa->bssid));
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019947 qdf_mem_copy(pmk_cache->BSSID.bytes,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053019948 pmksa->bssid, QDF_MAC_ADDR_SIZE);
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019949 } else {
Jeff Johnson9c749db2018-05-07 12:50:46 -070019950 qdf_mem_copy(pmk_cache->ssid, pmksa->ssid, pmksa->ssid_len);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053019951 qdf_mem_copy(pmk_cache->cache_id, pmksa->cache_id,
19952 CACHE_ID_LEN);
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019953 pmk_cache->ssid_len = pmksa->ssid_len;
19954 hdd_debug("%s PMKSA for ssid %*.*s cache_id %x %x",
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053019955 is_delete ? "Delete" : "Set",
19956 pmk_cache->ssid_len, pmk_cache->ssid_len,
19957 pmk_cache->ssid, pmk_cache->cache_id[0],
19958 pmk_cache->cache_id[1]);
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019959 }
19960
19961 if (is_delete)
19962 return;
19963
Srinivas Girigowdaff8f5ef2019-03-26 17:20:55 -070019964 qdf_mem_copy(pmk_cache->PMKID, pmksa->pmkid, PMKID_LEN);
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019965 if (pmksa->pmk_len && (pmksa->pmk_len <= CSR_RSN_MAX_PMK_LEN)) {
19966 qdf_mem_copy(pmk_cache->pmk, pmksa->pmk, pmksa->pmk_len);
19967 pmk_cache->pmk_len = pmksa->pmk_len;
19968 } else
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +053019969 hdd_debug("pmk len is %zu", pmksa->pmk_len);
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019970}
19971#else
19972/*
19973 * wlan_hdd_is_pmksa_valid: API to validate pmksa
19974 * @pmksa: pointer to cfg80211_pmksa structure
19975 *
19976 * Return: True if valid else false
19977 */
19978static inline bool wlan_hdd_is_pmksa_valid(struct cfg80211_pmksa *pmksa)
19979{
19980 if (!pmksa->bssid) {
Jeff Johnson36e74c42017-09-18 08:15:42 -070019981 hdd_err("both bssid is NULL %pK", pmksa->bssid);
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019982 return false;
19983 }
19984 return true;
19985}
19986
19987/*
19988 * hdd_fill_pmksa_info: API to update tPmkidCacheInfo from cfg80211_pmksa
gaurank kathpalia99d06c12018-05-16 16:28:35 +053019989 * @adapter: Pointer to hdd adapter
19990 * @pmk_cache: pmk which needs to be updated
19991 * @pmksa: pmk from supplicant
19992 * @is_delete: Bool to decide whether to set or delete PMK
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019993 *
19994 * Return: None
19995 */
gaurank kathpalia99d06c12018-05-16 16:28:35 +053019996static void hdd_fill_pmksa_info(struct hdd_adapter *adapter,
19997 tPmkidCacheInfo *pmk_cache,
19998 struct cfg80211_pmksa *pmksa, bool is_delete)
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053019999{
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020000 mac_handle_t mac_handle;
Srinivas Girigowda50335342018-09-07 15:21:01 -070020001
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070020002 hdd_debug("%s PMKSA for " QDF_MAC_ADDR_STR, is_delete ? "Delete" : "Set",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070020003 QDF_MAC_ADDR_ARRAY(pmksa->bssid));
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053020004 qdf_mem_copy(pmk_cache->BSSID.bytes,
20005 pmksa->bssid, QDF_MAC_ADDR_SIZE);
20006
20007 if (is_delete)
20008 return;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020009 mac_handle = hdd_adapter_get_mac_handle(adapter);
Jeff Johnsoncf07c312019-02-04 13:53:29 -080020010 sme_get_pmk_info(mac_handle, adapter->vdev_id, pmk_cache);
Srinivas Girigowdaff8f5ef2019-03-26 17:20:55 -070020011 qdf_mem_copy(pmk_cache->PMKID, pmksa->pmkid, PMKID_LEN);
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053020012}
20013#endif
20014
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020015/**
20016 * __wlan_hdd_cfg80211_set_pmksa() - set pmksa
20017 * @wiphy: Pointer to wiphy
20018 * @dev: Pointer to network device
20019 * @pmksa: Pointer to set pmksa parameter
20020 *
20021 * Return: 0 for success, non-zero for failure
20022 */
20023static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy,
20024 struct net_device *dev,
20025 struct cfg80211_pmksa *pmksa)
20026{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020027 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20028 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020029 mac_handle_t mac_handle;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053020030 QDF_STATUS result = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020031 int status;
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053020032 tPmkidCacheInfo pmk_cache;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020033
Dustin Brown491d54b2018-03-14 12:39:11 -070020034 hdd_enter();
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053020035
Anurag Chouhan6d760662016-02-20 16:05:43 +053020036 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020037 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020038 return -EINVAL;
20039 }
20040
Jeff Johnson48363022019-02-24 16:26:51 -080020041 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053020042 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053020043
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020044 if (!pmksa) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020045 hdd_err("pmksa is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020046 return -EINVAL;
20047 }
20048
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053020049 if (!pmksa->pmkid) {
Jeff Johnson36e74c42017-09-18 08:15:42 -070020050 hdd_err("pmksa->pmkid(%pK) is NULL",
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053020051 pmksa->pmkid);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020052 return -EINVAL;
20053 }
20054
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053020055 if (!wlan_hdd_is_pmksa_valid(pmksa))
20056 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020057
Jeff Johnsonb8944722017-09-03 09:03:19 -070020058 status = wlan_hdd_validate_context(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020059
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053020060 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020061 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020062
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020063 mac_handle = hdd_ctx->mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020064
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053020065 qdf_mem_zero(&pmk_cache, sizeof(pmk_cache));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020066
gaurank kathpalia99d06c12018-05-16 16:28:35 +053020067 hdd_fill_pmksa_info(adapter, &pmk_cache, pmksa, false);
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053020068
20069 /*
20070 * Add to the PMKSA Cache in CSR
20071 * PMKSA cache will be having following
20072 * 1. pmkid id
20073 * 2. pmk
20074 * 3. bssid or cache identifier
20075 */
Liangwei Donga44d55b2019-03-20 03:22:08 -040020076 result = wlan_hdd_set_pmksa_cache(adapter, &pmk_cache);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020077
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053020078 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
20079 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080020080 adapter->vdev_id, result);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020081
Jeff Johnsoncf07c312019-02-04 13:53:29 -080020082 sme_set_del_pmkid_cache(mac_handle, adapter->vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020083 &pmk_cache, true);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053020084
Ashish Kumar Dhanotiya36510832019-02-20 22:13:25 +053020085 qdf_mem_zero(&pmk_cache, sizeof(pmk_cache));
Dustin Browne74003f2018-03-14 12:51:58 -070020086 hdd_exit();
Ashish Kumar Dhanotiya36510832019-02-20 22:13:25 +053020087
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053020088 return QDF_IS_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020089}
20090
20091/**
20092 * wlan_hdd_cfg80211_set_pmksa() - set pmksa
20093 * @wiphy: Pointer to wiphy
20094 * @dev: Pointer to network device
20095 * @pmksa: Pointer to set pmksa parameter
20096 *
20097 * Return: 0 for success, non-zero for failure
20098 */
20099static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy,
20100 struct net_device *dev,
20101 struct cfg80211_pmksa *pmksa)
20102{
Dustin Brown1d31b082018-11-22 14:41:20 +053020103 int errno;
20104 struct osif_vdev_sync *vdev_sync;
20105
20106 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
20107 if (errno)
20108 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020109
Dustin Brown1d31b082018-11-22 14:41:20 +053020110 errno = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020111
Dustin Brown1d31b082018-11-22 14:41:20 +053020112 osif_vdev_sync_op_stop(vdev_sync);
20113
20114 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020115}
20116
20117/**
20118 * __wlan_hdd_cfg80211_del_pmksa() - delete pmksa
20119 * @wiphy: Pointer to wiphy
20120 * @dev: Pointer to network device
20121 * @pmksa: Pointer to pmksa parameter
20122 *
20123 * Return: 0 for success, non-zero for failure
20124 */
20125static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy,
20126 struct net_device *dev,
20127 struct cfg80211_pmksa *pmksa)
20128{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020129 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20130 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020131 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020132 int status = 0;
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053020133 tPmkidCacheInfo pmk_cache;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020134
Dustin Brown491d54b2018-03-14 12:39:11 -070020135 hdd_enter();
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053020136
Anurag Chouhan6d760662016-02-20 16:05:43 +053020137 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020138 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020139 return -EINVAL;
20140 }
20141
Jeff Johnson48363022019-02-24 16:26:51 -080020142 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053020143 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053020144
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020145 if (!pmksa) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020146 hdd_err("pmksa is NULL");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020147 return -EINVAL;
20148 }
20149
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053020150 if (!wlan_hdd_is_pmksa_valid(pmksa))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020151 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020152
Jeff Johnsonb8944722017-09-03 09:03:19 -070020153 status = wlan_hdd_validate_context(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020154
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053020155 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020156 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020157
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020158 mac_handle = hdd_ctx->mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020159
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053020160 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
20161 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080020162 adapter->vdev_id, 0);
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053020163
20164 qdf_mem_zero(&pmk_cache, sizeof(pmk_cache));
20165
gaurank kathpalia99d06c12018-05-16 16:28:35 +053020166 hdd_fill_pmksa_info(adapter, &pmk_cache, pmksa, true);
Sridhar Selvarajc3684c72017-08-21 14:32:47 +053020167
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020168 /* Delete the PMKID CSR cache */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053020169 if (QDF_STATUS_SUCCESS !=
Liangwei Donga44d55b2019-03-20 03:22:08 -040020170 wlan_hdd_del_pmksa_cache(adapter, &pmk_cache)) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070020171 hdd_err("Failed to delete PMKSA for " QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070020172 QDF_MAC_ADDR_ARRAY(pmksa->bssid));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020173 status = -EINVAL;
20174 }
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053020175
Jeff Johnsoncf07c312019-02-04 13:53:29 -080020176 sme_set_del_pmkid_cache(mac_handle, adapter->vdev_id, &pmk_cache,
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020177 false);
Ashish Kumar Dhanotiya36510832019-02-20 22:13:25 +053020178 qdf_mem_zero(&pmk_cache, sizeof(pmk_cache));
20179
Dustin Browne74003f2018-03-14 12:51:58 -070020180 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020181 return status;
20182}
20183
20184/**
20185 * wlan_hdd_cfg80211_del_pmksa() - delete pmksa
20186 * @wiphy: Pointer to wiphy
20187 * @dev: Pointer to network device
20188 * @pmksa: Pointer to pmksa parameter
20189 *
20190 * Return: 0 for success, non-zero for failure
20191 */
20192static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy,
20193 struct net_device *dev,
20194 struct cfg80211_pmksa *pmksa)
20195{
Dustin Brown1d31b082018-11-22 14:41:20 +053020196 int errno;
20197 struct osif_vdev_sync *vdev_sync;
20198
20199 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
20200 if (errno)
20201 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020202
Dustin Brown1d31b082018-11-22 14:41:20 +053020203 errno = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020204
Dustin Brown1d31b082018-11-22 14:41:20 +053020205 osif_vdev_sync_op_stop(vdev_sync);
20206
20207 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020208
20209}
20210
20211/**
20212 * __wlan_hdd_cfg80211_flush_pmksa() - flush pmksa
20213 * @wiphy: Pointer to wiphy
20214 * @dev: Pointer to network device
20215 *
20216 * Return: 0 for success, non-zero for failure
20217 */
20218static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy,
20219 struct net_device *dev)
20220{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020221 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20222 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020223 mac_handle_t mac_handle;
20224 int errno;
20225 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020226
Dustin Brown491d54b2018-03-14 12:39:11 -070020227 hdd_enter();
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053020228
Anurag Chouhan6d760662016-02-20 16:05:43 +053020229 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020230 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020231 return -EINVAL;
20232 }
20233
Jeff Johnson48363022019-02-24 16:26:51 -080020234 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053020235 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053020236
Srinivas Girigowda13d39252017-03-06 16:12:15 -080020237 hdd_debug("Flushing PMKSA");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020238
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020239 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020240 errno = wlan_hdd_validate_context(hdd_ctx);
20241 if (errno)
20242 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020243
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020244 mac_handle = hdd_ctx->mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020245
Liangwei Donga44d55b2019-03-20 03:22:08 -040020246 status = wlan_hdd_flush_pmksa_cache(adapter);
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020247 if (QDF_IS_STATUS_ERROR(status)) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020248 hdd_err("Cannot flush PMKIDCache");
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020249 errno = -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020250 }
Vignesh Viswanathane8a26b22017-10-11 20:38:47 +053020251
Jeff Johnsoncf07c312019-02-04 13:53:29 -080020252 sme_set_del_pmkid_cache(mac_handle, adapter->vdev_id, NULL, false);
Dustin Browne74003f2018-03-14 12:51:58 -070020253 hdd_exit();
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020254 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020255}
20256
20257/**
20258 * wlan_hdd_cfg80211_flush_pmksa() - flush pmksa
20259 * @wiphy: Pointer to wiphy
20260 * @dev: Pointer to network device
20261 *
20262 * Return: 0 for success, non-zero for failure
20263 */
20264static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy,
20265 struct net_device *dev)
20266{
Dustin Brown1d31b082018-11-22 14:41:20 +053020267 int errno;
20268 struct osif_vdev_sync *vdev_sync;
20269
20270 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
20271 if (errno)
20272 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020273
Dustin Brown1d31b082018-11-22 14:41:20 +053020274 errno = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020275
Dustin Brown1d31b082018-11-22 14:41:20 +053020276 osif_vdev_sync_op_stop(vdev_sync);
20277
20278 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020279}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020280
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -080020281#if defined(KERNEL_SUPPORT_11R_CFG80211)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020282/**
20283 * __wlan_hdd_cfg80211_update_ft_ies() - update fast transition ies
20284 * @wiphy: Pointer to wiphy
20285 * @dev: Pointer to network device
20286 * @ftie: Pointer to fast transition ie parameter
20287 *
20288 * Return: 0 for success, non-zero for failure
20289 */
20290static int
20291__wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
20292 struct net_device *dev,
20293 struct cfg80211_update_ft_ies_params *ftie)
20294{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070020295 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020296 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond377dce2017-10-04 10:32:42 -070020297 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020298 int status;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020299 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020300
Dustin Brown491d54b2018-03-14 12:39:11 -070020301 hdd_enter();
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053020302
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020303 status = wlan_hdd_validate_context(hdd_ctx);
20304 if (status)
20305 return status;
20306
Anurag Chouhan6d760662016-02-20 16:05:43 +053020307 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020308 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020309 return -EINVAL;
20310 }
20311
Jeff Johnson48363022019-02-24 16:26:51 -080020312 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053020313 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053020314
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053020315 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
20316 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
Jeff Johnsone7951512019-02-27 10:02:51 -080020317 adapter->vdev_id, sta_ctx->conn_info.conn_state);
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053020318
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020319 /* Added for debug on reception of Re-assoc Req. */
Jeff Johnsone7951512019-02-27 10:02:51 -080020320 if (eConnectionState_Associated != sta_ctx->conn_info.conn_state) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020321 hdd_err("Called with Ie of length = %zu when not associated",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020322 ftie->ie_len);
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020323 hdd_err("Should be Re-assoc Req IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020324 }
Srinivas Girigowda13d39252017-03-06 16:12:15 -080020325 hdd_debug("%s called with Ie of length = %zu", __func__,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020326 ftie->ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020327
20328 /* Pass the received FT IEs to SME */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070020329 mac_handle = hdd_ctx->mac_handle;
Jeff Johnsoncf07c312019-02-04 13:53:29 -080020330 sme_set_ft_ies(mac_handle, adapter->vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020331 (const u8 *)ftie->ie, ftie->ie_len);
Dustin Browne74003f2018-03-14 12:51:58 -070020332 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020333 return 0;
20334}
20335
20336/**
20337 * wlan_hdd_cfg80211_update_ft_ies() - update fast transition ies
20338 * @wiphy: Pointer to wiphy
20339 * @dev: Pointer to network device
20340 * @ftie: Pointer to fast transition ie parameter
20341 *
20342 * Return: 0 for success, non-zero for failure
20343 */
20344static int
20345wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
20346 struct net_device *dev,
20347 struct cfg80211_update_ft_ies_params *ftie)
20348{
Dustin Brown1d31b082018-11-22 14:41:20 +053020349 int errno;
20350 struct osif_vdev_sync *vdev_sync;
20351
20352 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
20353 if (errno)
20354 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020355
Dustin Brown1d31b082018-11-22 14:41:20 +053020356 errno = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020357
Dustin Brown1d31b082018-11-22 14:41:20 +053020358 osif_vdev_sync_op_stop(vdev_sync);
20359
20360 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020361}
20362#endif
20363
Min Liu0daa0982019-02-01 17:50:44 +080020364#ifdef CFG80211_EXTERNAL_DH_UPDATE_SUPPORT
20365/**
20366 * __wlan_hdd_cfg80211_update_owe_info() - update OWE info
20367 * @wiphy: Pointer to wiphy
20368 * @dev: Pointer to network device
20369 * @owe_info: Pointer to OWE info
20370 *
20371 * Return: 0 for success, non-zero for failure
20372 */
20373static int
20374__wlan_hdd_cfg80211_update_owe_info(struct wiphy *wiphy,
20375 struct net_device *dev,
20376 struct cfg80211_update_owe_info *owe_info)
20377{
20378 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
20379 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
20380 QDF_STATUS status;
Dustin Brown96b98dd2019-03-06 12:39:37 -080020381 int errno;
Min Liu0daa0982019-02-01 17:50:44 +080020382
20383 hdd_enter_dev(dev);
20384
20385 errno = wlan_hdd_validate_context(hdd_ctx);
20386 if (errno)
20387 return errno;
20388
20389 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
20390 hdd_err("Command not allowed in FTM mode");
20391 return -EINVAL;
20392 }
20393
Jeff Johnsona6b398d2019-02-24 16:26:51 -080020394 if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) {
20395 hdd_err("invalid vdev id: %d", adapter->vdev_id);
Min Liu0daa0982019-02-01 17:50:44 +080020396 return -EINVAL;
20397 }
20398
20399 hdd_debug("owe_status %d", owe_info->status);
20400
20401 status = wlansap_update_owe_info(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Min Liue2b469f2019-04-10 19:13:42 +080020402 owe_info->peer, owe_info->ie,
Min Liu0daa0982019-02-01 17:50:44 +080020403 owe_info->ie_len, owe_info->status);
20404 if (QDF_IS_STATUS_ERROR(status)) {
20405 hdd_err("Failed to update OWE info");
20406 errno = qdf_status_to_os_return(status);
20407 }
20408
20409 hdd_exit();
20410 return errno;
20411}
20412
20413/**
20414 * wlan_hdd_cfg80211_update_owe_info() - update OWE info
20415 * @wiphy: Pointer to wiphy
20416 * @dev: Pointer to network device
20417 * @owe_info: Pointer to OWE info
20418 *
20419 * Return: 0 for success, non-zero for failure
20420 */
20421static int
20422wlan_hdd_cfg80211_update_owe_info(struct wiphy *wiphy,
Dustin Brown96b98dd2019-03-06 12:39:37 -080020423 struct net_device *net_dev,
Min Liu0daa0982019-02-01 17:50:44 +080020424 struct cfg80211_update_owe_info *owe_info)
20425{
Dustin Brown96b98dd2019-03-06 12:39:37 -080020426 struct osif_vdev_sync *vdev_sync;
20427 int errno;
Min Liu0daa0982019-02-01 17:50:44 +080020428
Dustin Brown96b98dd2019-03-06 12:39:37 -080020429 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
20430 if (errno)
20431 return errno;
Min Liu0daa0982019-02-01 17:50:44 +080020432
Dustin Brown96b98dd2019-03-06 12:39:37 -080020433 errno = __wlan_hdd_cfg80211_update_owe_info(wiphy, net_dev, owe_info);
20434
20435 osif_vdev_sync_op_stop(vdev_sync);
20436
20437 return errno;
Min Liu0daa0982019-02-01 17:50:44 +080020438}
20439#endif
20440
Ashish Kumar Dhanotiyacf11bae2017-04-04 03:29:47 +053020441void wlan_hdd_cfg80211_update_replay_counter_cb(
Mukul Sharma3d36c392017-01-18 18:39:12 +053020442 void *cb_ctx, struct pmo_gtk_rsp_params *gtk_rsp_param)
20443
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020444{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020445 struct hdd_adapter *adapter = (struct hdd_adapter *)cb_ctx;
Mukul Sharma3d36c392017-01-18 18:39:12 +053020446 uint8_t temp_replay_counter[8];
20447 int i;
20448 uint8_t *p;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020449
Dustin Brown491d54b2018-03-14 12:39:11 -070020450 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020451
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020452 if (!adapter) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020453 hdd_err("HDD adapter is Null");
Mukul Sharma3d36c392017-01-18 18:39:12 +053020454 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020455 }
20456
Mukul Sharma3d36c392017-01-18 18:39:12 +053020457 if (!gtk_rsp_param) {
20458 hdd_err("gtk_rsp_param is Null");
20459 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020460 }
20461
Mukul Sharma3d36c392017-01-18 18:39:12 +053020462 if (gtk_rsp_param->status_flag != QDF_STATUS_SUCCESS) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020463 hdd_err("wlan Failed to get replay counter value");
Mukul Sharma3d36c392017-01-18 18:39:12 +053020464 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020465 }
20466
Srinivas Girigowda13d39252017-03-06 16:12:15 -080020467 hdd_debug("updated replay counter: %llu from fwr",
Mukul Sharma3d36c392017-01-18 18:39:12 +053020468 gtk_rsp_param->replay_counter);
20469 /* convert little to big endian since supplicant works on big endian */
20470 p = (uint8_t *)&gtk_rsp_param->replay_counter;
20471 for (i = 0; i < 8; i++)
20472 temp_replay_counter[7 - i] = (uint8_t) p[i];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020473
Srinivas Girigowda13d39252017-03-06 16:12:15 -080020474 hdd_debug("gtk_rsp_param bssid %pM", gtk_rsp_param->bssid.bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020475 /* Update replay counter to NL */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020476 cfg80211_gtk_rekey_notify(adapter->dev,
Mukul Sharma3d36c392017-01-18 18:39:12 +053020477 gtk_rsp_param->bssid.bytes,
20478 temp_replay_counter, GFP_KERNEL);
20479out:
Dustin Browne74003f2018-03-14 12:51:58 -070020480 hdd_exit();
Mukul Sharma3d36c392017-01-18 18:39:12 +053020481
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020482}
20483
Wu Gaoa9d336b2018-05-30 14:48:04 +080020484#ifdef WLAN_FEATURE_GTK_OFFLOAD
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053020485/**
20486 * wlan_hdd_copy_gtk_kek - Copy the KEK from GTK rekey data to GTK request
20487 * @gtk_req: Pointer to GTK request
20488 * @data: Pointer to rekey data
20489 *
20490 * Return: none
20491 */
20492#ifdef CFG80211_REKEY_DATA_KEK_LEN
20493static
20494void wlan_hdd_copy_gtk_kek(struct pmo_gtk_req *gtk_req,
20495 struct cfg80211_gtk_rekey_data *data)
20496{
20497 qdf_mem_copy(gtk_req->kek, data->kek, data->kek_len);
20498 gtk_req->kek_len = data->kek_len;
20499}
20500#else
20501static
20502void wlan_hdd_copy_gtk_kek(struct pmo_gtk_req *gtk_req,
20503 struct cfg80211_gtk_rekey_data *data)
20504{
20505 qdf_mem_copy(gtk_req->kek, data->kek, NL80211_KEK_LEN);
20506 gtk_req->kek_len = NL80211_KEK_LEN;
20507}
20508#endif
20509
20510/**
20511 * __wlan_hdd_cfg80211_set_rekey_data() - set rekey data
20512 * @wiphy: Pointer to wiphy
20513 * @dev: Pointer to network device
20514 * @data: Pointer to rekey data
20515 *
20516 * This function is used to offload GTK rekeying job to the firmware.
20517 *
20518 * Return: 0 for success, non-zero for failure
20519 */
Jeff Johnson8b8a04b2016-10-05 15:49:43 -070020520static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020521int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy,
Mukul Sharma3d36c392017-01-18 18:39:12 +053020522 struct net_device *dev,
20523 struct cfg80211_gtk_rekey_data *data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020524{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020525 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma3d36c392017-01-18 18:39:12 +053020526 int result, i;
20527 struct pmo_gtk_req *gtk_req = NULL;
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020528 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Mukul Sharma3d36c392017-01-18 18:39:12 +053020529 uint8_t *buf;
Min Liu8c5d99e2018-09-10 17:18:44 +080020530 struct wlan_objmgr_vdev *vdev;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053020531 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020532
Dustin Brown491d54b2018-03-14 12:39:11 -070020533 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020534
Anurag Chouhan6d760662016-02-20 16:05:43 +053020535 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020536 hdd_err("Command not allowed in FTM mode");
Mukul Sharma3d36c392017-01-18 18:39:12 +053020537 result = -EINVAL;
20538 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020539 }
20540
Jeff Johnson48363022019-02-24 16:26:51 -080020541 if (wlan_hdd_validate_vdev_id(adapter->vdev_id)) {
Mukul Sharma3d36c392017-01-18 18:39:12 +053020542 result = -EINVAL;
20543 goto out;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053020544 }
20545
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053020546 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
20547 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080020548 adapter->vdev_id, adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020549
Mukul Sharma3d36c392017-01-18 18:39:12 +053020550 result = wlan_hdd_validate_context(hdd_ctx);
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053020551 if (0 != result)
Mukul Sharma3d36c392017-01-18 18:39:12 +053020552 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020553
Mukul Sharma3d36c392017-01-18 18:39:12 +053020554 gtk_req = qdf_mem_malloc(sizeof(*gtk_req));
20555 if (!gtk_req) {
Mukul Sharma3d36c392017-01-18 18:39:12 +053020556 result = -ENOMEM;
20557 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020558 }
20559
Mukul Sharma3d36c392017-01-18 18:39:12 +053020560 /* convert big to little endian since driver work on little endian */
20561 buf = (uint8_t *)&gtk_req->replay_counter;
20562 for (i = 0; i < 8; i++)
20563 buf[7 - i] = data->replay_ctr[i];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020564
Srinivas Girigowda13d39252017-03-06 16:12:15 -080020565 hdd_debug("current replay counter: %llu in user space",
Mukul Sharma3d36c392017-01-18 18:39:12 +053020566 gtk_req->replay_counter);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053020567
20568 wlan_hdd_copy_gtk_kek(gtk_req, data);
nakul kachhwahaa580cc32019-03-15 17:45:17 +053020569 if (data->kck)
20570 qdf_mem_copy(gtk_req->kck, data->kck, NL80211_KCK_LEN);
gaurank kathpalia82a1b2b2018-07-10 16:49:10 +053020571 gtk_req->is_fils_connection = hdd_is_fils_connection(adapter);
Min Liu8c5d99e2018-09-10 17:18:44 +080020572 vdev = hdd_objmgr_get_vdev(adapter);
20573 if (!vdev) {
20574 result = -EINVAL;
20575 goto out;
20576 }
20577 status = ucfg_pmo_cache_gtk_offload_req(vdev, gtk_req);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +053020578 hdd_objmgr_put_vdev(vdev);
Mukul Sharma3d36c392017-01-18 18:39:12 +053020579 if (status != QDF_STATUS_SUCCESS) {
20580 hdd_err("Failed to cache GTK Offload");
20581 result = qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020582 }
Mukul Sharma3d36c392017-01-18 18:39:12 +053020583out:
20584 if (gtk_req)
20585 qdf_mem_free(gtk_req);
Dustin Browne74003f2018-03-14 12:51:58 -070020586 hdd_exit();
Mukul Sharma3d36c392017-01-18 18:39:12 +053020587
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020588 return result;
20589}
20590
20591/**
20592 * wlan_hdd_cfg80211_set_rekey_data() - set rekey data
20593 * @wiphy: Pointer to wiphy
20594 * @dev: Pointer to network device
20595 * @data: Pointer to rekey data
20596 *
20597 * This function is used to offload GTK rekeying job to the firmware.
20598 *
20599 * Return: 0 for success, non-zero for failure
20600 */
Jeff Johnson8b8a04b2016-10-05 15:49:43 -070020601static
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020602int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy,
20603 struct net_device *dev,
20604 struct cfg80211_gtk_rekey_data *data)
20605{
Dustin Brown1d31b082018-11-22 14:41:20 +053020606 int errno;
20607 struct osif_vdev_sync *vdev_sync;
20608
20609 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
20610 if (errno)
20611 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020612
Dustin Brown1d31b082018-11-22 14:41:20 +053020613 errno = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020614
Dustin Brown1d31b082018-11-22 14:41:20 +053020615 osif_vdev_sync_op_stop(vdev_sync);
20616
20617 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020618}
Wu Gaoa9d336b2018-05-30 14:48:04 +080020619#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020620
20621/**
20622 * __wlan_hdd_cfg80211_set_mac_acl() - set access control policy
20623 * @wiphy: Pointer to wiphy
20624 * @dev: Pointer to network device
20625 * @param: Pointer to access control parameter
20626 *
20627 * Return: 0 for success, non-zero for failure
20628 */
20629static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20630 struct net_device *dev,
20631 const struct cfg80211_acl_data *params)
20632{
20633 int i;
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020634 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson5c19ade2017-10-04 09:52:12 -070020635 struct hdd_hostapd_state *hostapd_state;
Jeff Johnson8f8ceb92019-03-24 08:16:55 -070020636 struct sap_config *config;
Jeff Johnsonb8944722017-09-03 09:03:19 -070020637 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020638 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053020639 QDF_STATUS qdf_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020640
Dustin Brown491d54b2018-03-14 12:39:11 -070020641 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020642
Anurag Chouhan6d760662016-02-20 16:05:43 +053020643 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020644 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020645 return -EINVAL;
20646 }
20647
Jeff Johnsond36fa332019-03-18 13:42:25 -070020648 if (!params) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020649 hdd_err("params is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020650 return -EINVAL;
20651 }
20652
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020653 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnsonb8944722017-09-03 09:03:19 -070020654 status = wlan_hdd_validate_context(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020655
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053020656 if (0 != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020657 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020658
Jeff Johnson5c19ade2017-10-04 09:52:12 -070020659 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020660
Jeff Johnsond36fa332019-03-18 13:42:25 -070020661 if (!hostapd_state) {
Jeff Johnson5c19ade2017-10-04 09:52:12 -070020662 hdd_err("hostapd_state is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020663 return -EINVAL;
20664 }
20665
Srinivas Girigowda13d39252017-03-06 16:12:15 -080020666 hdd_debug("acl policy: %d num acl entries: %d", params->acl_policy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020667 params->n_acl_entries);
20668
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053020669 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
20670 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080020671 adapter->vdev_id, adapter->device_mode);
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053020672
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020673 if (QDF_SAP_MODE == adapter->device_mode) {
Jeff Johnson954903d2019-03-07 20:41:27 -080020674 config = &adapter->session.ap.sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020675
20676 /* default value */
Jeff Johnson954903d2019-03-07 20:41:27 -080020677 config->num_accept_mac = 0;
20678 config->num_deny_mac = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020679
20680 /**
20681 * access control policy
20682 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
20683 * listed in hostapd.deny file.
20684 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
20685 * listed in hostapd.accept file.
20686 */
20687 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy) {
Jeff Johnson954903d2019-03-07 20:41:27 -080020688 config->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020689 } else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED ==
20690 params->acl_policy) {
Jeff Johnson954903d2019-03-07 20:41:27 -080020691 config->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020692 } else {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080020693 hdd_warn("Acl Policy : %d is not supported",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020694 params->acl_policy);
20695 return -ENOTSUPP;
20696 }
20697
Jeff Johnson954903d2019-03-07 20:41:27 -080020698 if (eSAP_DENY_UNLESS_ACCEPTED == config->SapMacaddr_acl) {
20699 config->num_accept_mac = params->n_acl_entries;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020700 for (i = 0; i < params->n_acl_entries; i++) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080020701 hdd_debug("** Add ACL MAC entry %i in WhiletList :"
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070020702 QDF_MAC_ADDR_STR, i,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070020703 QDF_MAC_ADDR_ARRAY(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020704 params->mac_addrs[i].addr));
20705
Jeff Johnson954903d2019-03-07 20:41:27 -080020706 qdf_mem_copy(&config->accept_mac[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020707 params->mac_addrs[i].addr,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -080020708 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020709 }
Jeff Johnson954903d2019-03-07 20:41:27 -080020710 } else if (eSAP_ACCEPT_UNLESS_DENIED == config->SapMacaddr_acl) {
20711 config->num_deny_mac = params->n_acl_entries;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020712 for (i = 0; i < params->n_acl_entries; i++) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080020713 hdd_debug("** Add ACL MAC entry %i in BlackList :"
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070020714 QDF_MAC_ADDR_STR, i,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070020715 QDF_MAC_ADDR_ARRAY(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020716 params->mac_addrs[i].addr));
20717
Jeff Johnson954903d2019-03-07 20:41:27 -080020718 qdf_mem_copy(&config->deny_mac[i],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020719 params->mac_addrs[i].addr,
Srinivas Girigowdaa47b45f2019-02-27 12:29:02 -080020720 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020721 }
20722 }
Dustin Brown6ba30a12016-09-13 13:59:43 -070020723 qdf_status = wlansap_set_mac_acl(
Jeff Johnson954903d2019-03-07 20:41:27 -080020724 WLAN_HDD_GET_SAP_CTX_PTR(adapter), config);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053020725 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020726 hdd_err("SAP Set Mac Acl fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020727 return -EINVAL;
20728 }
20729 } else {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080020730 hdd_debug("Invalid device_mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -070020731 qdf_opmode_str(adapter->device_mode),
20732 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020733 return -EINVAL;
20734 }
Dustin Browne74003f2018-03-14 12:51:58 -070020735 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020736 return 0;
20737}
20738
20739/**
20740 * wlan_hdd_cfg80211_set_mac_acl() - SSR wrapper for
20741 * __wlan_hdd_cfg80211_set_mac_acl
20742 * @wiphy: pointer to wiphy structure
20743 * @dev: pointer to net_device
20744 * @params: pointer to cfg80211_acl_data
20745 *
20746 * Return; 0 on success, error number otherwise
20747 */
20748static int
20749wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
20750 struct net_device *dev,
20751 const struct cfg80211_acl_data *params)
20752{
Dustin Brown1d31b082018-11-22 14:41:20 +053020753 int errno;
20754 struct osif_vdev_sync *vdev_sync;
20755
20756 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
20757 if (errno)
20758 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020759
Dustin Brown1d31b082018-11-22 14:41:20 +053020760 errno = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020761
Dustin Brown1d31b082018-11-22 14:41:20 +053020762 osif_vdev_sync_op_stop(vdev_sync);
20763
20764 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020765}
20766
20767#ifdef WLAN_NL80211_TESTMODE
20768#ifdef FEATURE_WLAN_LPHB
20769/**
20770 * wlan_hdd_cfg80211_lphb_ind_handler() - handle low power heart beat indication
Jeff Johnsonb8944722017-09-03 09:03:19 -070020771 * @hdd_ctx: Pointer to hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020772 * @lphbInd: Pointer to low power heart beat indication parameter
20773 *
20774 * Return: none
20775 */
Jeff Johnsonb8944722017-09-03 09:03:19 -070020776static void wlan_hdd_cfg80211_lphb_ind_handler(void *hdd_ctx,
Mukul Sharmafcd57f52017-03-20 18:18:59 +053020777 struct pmo_lphb_rsp *lphb_ind)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020778{
20779 struct sk_buff *skb;
20780
Srinivas Girigowda13d39252017-03-06 16:12:15 -080020781 hdd_debug("LPHB indication arrived");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020782
Jeff Johnsonb8944722017-09-03 09:03:19 -070020783 if (0 != wlan_hdd_validate_context((struct hdd_context *) hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020784 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020785
Mukul Sharmafcd57f52017-03-20 18:18:59 +053020786 if (!lphb_ind) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020787 hdd_err("invalid argument lphbInd");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020788 return;
20789 }
20790
Jeff Johnsonb8944722017-09-03 09:03:19 -070020791 skb = cfg80211_testmode_alloc_event_skb(((struct hdd_context *) hdd_ctx)->
Mukul Sharmafcd57f52017-03-20 18:18:59 +053020792 wiphy, sizeof(*lphb_ind), GFP_ATOMIC);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020793 if (!skb) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020794 hdd_err("LPHB timeout, NL buffer alloc fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020795 return;
20796 }
20797
20798 if (nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB)) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020799 hdd_err("WLAN_HDD_TM_ATTR_CMD put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020800 goto nla_put_failure;
20801 }
Mukul Sharmafcd57f52017-03-20 18:18:59 +053020802 if (nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphb_ind->protocol_type)) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020803 hdd_err("WLAN_HDD_TM_ATTR_TYPE put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020804 goto nla_put_failure;
20805 }
Mukul Sharmafcd57f52017-03-20 18:18:59 +053020806 if (nla_put(skb, WLAN_HDD_TM_ATTR_DATA, sizeof(*lphb_ind),
20807 lphb_ind)) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020808 hdd_err("WLAN_HDD_TM_ATTR_DATA put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020809 goto nla_put_failure;
20810 }
20811 cfg80211_testmode_event(skb, GFP_ATOMIC);
20812 return;
20813
20814nla_put_failure:
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020815 hdd_err("NLA Put fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020816 kfree_skb(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020817}
20818#endif /* FEATURE_WLAN_LPHB */
20819
20820/**
20821 * __wlan_hdd_cfg80211_testmode() - test mode
20822 * @wiphy: Pointer to wiphy
20823 * @data: Data pointer
20824 * @len: Data length
20825 *
20826 * Return: 0 for success, non-zero for failure
20827 */
20828static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20829 void *data, int len)
20830{
20831 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
20832 int err;
Jeff Johnsonb8944722017-09-03 09:03:19 -070020833 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020834
Dustin Brown491d54b2018-03-14 12:39:11 -070020835 hdd_enter();
Hanumantha Reddy Pothula2db50ed2015-11-23 10:48:33 +053020836
Jeff Johnsonb8944722017-09-03 09:03:19 -070020837 err = wlan_hdd_validate_context(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020838 if (err)
20839 return err;
20840
Ryan Hsu4df41382018-06-15 15:45:22 -070020841 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
20842 hdd_err("Driver Modules are closed");
20843 return -EINVAL;
20844 }
20845
Dustin Brown4ea21db2018-01-05 14:13:17 -080020846 err = wlan_cfg80211_nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data,
20847 len, wlan_hdd_tm_policy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020848 if (err) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020849 hdd_err("Testmode INV ATTR");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020850 return err;
20851 }
20852
20853 if (!tb[WLAN_HDD_TM_ATTR_CMD]) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020854 hdd_err("Testmode INV CMD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020855 return -EINVAL;
20856 }
20857
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +053020858 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
20859 TRACE_CODE_HDD_CFG80211_TESTMODE,
20860 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]));
20861
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020862 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])) {
20863#ifdef FEATURE_WLAN_LPHB
20864 /* Low Power Heartbeat configuration request */
20865 case WLAN_HDD_TM_CMD_WLAN_HB:
20866 {
20867 int buf_len;
20868 void *buf;
Mukul Sharmafcd57f52017-03-20 18:18:59 +053020869 struct pmo_lphb_req *hb_params = NULL;
20870 struct pmo_lphb_req *hb_params_temp = NULL;
20871 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020872
20873 if (!tb[WLAN_HDD_TM_ATTR_DATA]) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020874 hdd_err("Testmode INV DATA");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020875 return -EINVAL;
20876 }
20877
20878 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
20879 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Rajeev Kumar Sirasanagandla012e7b72019-03-14 21:54:43 +053020880 if (buf_len < sizeof(*hb_params_temp)) {
20881 hdd_err("Invalid buffer length for TM_ATTR_DATA");
20882 return -EINVAL;
20883 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020884
Mukul Sharmafcd57f52017-03-20 18:18:59 +053020885 hb_params_temp = (struct pmo_lphb_req *) buf;
20886 if ((hb_params_temp->cmd == pmo_lphb_set_tcp_pararm_indid)
20887 && (hb_params_temp->params.lphb_tcp_params.
20888 time_period_sec == 0))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020889 return -EINVAL;
20890
Manjeet Singh00b2a562017-01-03 12:08:10 +053020891 if (buf_len > sizeof(*hb_params)) {
20892 hdd_err("buf_len=%d exceeded hb_params size limit",
20893 buf_len);
20894 return -ERANGE;
20895 }
20896
Mukul Sharmafcd57f52017-03-20 18:18:59 +053020897 hb_params = (struct pmo_lphb_req *)qdf_mem_malloc(
20898 sizeof(*hb_params));
Min Liu74a1a502018-10-10 19:59:07 +080020899 if (!hb_params)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020900 return -ENOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020901
Ashish Kumar Dhanotiya0fa8ee02017-07-13 14:04:31 +053020902 qdf_mem_zero(hb_params, sizeof(*hb_params));
Anurag Chouhan600c3a02016-03-01 10:33:54 +053020903 qdf_mem_copy(hb_params, buf, buf_len);
Wu Gaod7dd6e42018-10-16 17:22:56 +080020904 status = ucfg_pmo_lphb_config_req(
20905 hdd_ctx->psoc,
Jeff Johnsonb8944722017-09-03 09:03:19 -070020906 hb_params, (void *)hdd_ctx,
Wu Gaod7dd6e42018-10-16 17:22:56 +080020907 wlan_hdd_cfg80211_lphb_ind_handler);
Mukul Sharmafcd57f52017-03-20 18:18:59 +053020908 if (status != QDF_STATUS_SUCCESS)
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020909 hdd_err("LPHB Config Fail, disable");
Mukul Sharmafcd57f52017-03-20 18:18:59 +053020910
20911 qdf_mem_free(hb_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020912 return 0;
20913 }
20914#endif /* FEATURE_WLAN_LPHB */
20915
20916#if defined(QCA_WIFI_FTM)
20917 case WLAN_HDD_TM_CMD_WLAN_FTM:
20918 {
Ryan Hsu4df41382018-06-15 15:45:22 -070020919 if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam()) {
20920 hdd_err("Command not allowed in FTM mode, mode %d",
20921 hdd_get_conparam());
20922 return -EINVAL;
20923 }
20924
Dustin Brown07901ec2018-09-07 11:02:41 -070020925 err = wlan_cfg80211_ftm_testmode_cmd(hdd_ctx->pdev,
Ryan Hsuc8b27a42018-01-02 13:57:56 -080020926 data, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020927 break;
20928 }
20929#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020930 default:
Srinivas Girigowda13d39252017-03-06 16:12:15 -080020931 hdd_err("command: %d not supported",
Ryan Hsuc8b27a42018-01-02 13:57:56 -080020932 nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020933 return -EOPNOTSUPP;
20934 }
Ryan Hsuc8b27a42018-01-02 13:57:56 -080020935
Dustin Browne74003f2018-03-14 12:51:58 -070020936 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020937 return err;
20938}
20939
20940/**
20941 * wlan_hdd_cfg80211_testmode() - test mode
20942 * @wiphy: Pointer to wiphy
20943 * @dev: Pointer to network device
20944 * @data: Data pointer
20945 * @len: Data length
20946 *
20947 * Return: 0 for success, non-zero for failure
20948 */
20949static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
20950#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 12, 0))
20951 struct wireless_dev *wdev,
20952#endif
20953 void *data, int len)
20954{
Dustin Brown363b4792019-02-05 16:11:55 -080020955 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -080020956 int errno;
Arunk Khandavalli447837f2018-11-08 14:32:53 +053020957
Dustin Brown363b4792019-02-05 16:11:55 -080020958 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -080020959 if (errno)
20960 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020961
Dustin Brownf0f00612019-01-31 16:02:24 -080020962 errno = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020963
Dustin Brown363b4792019-02-05 16:11:55 -080020964 osif_psoc_sync_op_stop(psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -080020965
20966 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020967}
20968
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020969#endif /* CONFIG_NL80211_TESTMODE */
20970
20971#ifdef QCA_HT_2040_COEX
20972/**
20973 * __wlan_hdd_cfg80211_set_ap_channel_width() - set ap channel bandwidth
20974 * @wiphy: Pointer to wiphy
20975 * @dev: Pointer to network device
20976 * @chandef: Pointer to channel definition parameter
20977 *
20978 * Return: 0 for success, non-zero for failure
20979 */
20980static int
20981__wlan_hdd_cfg80211_set_ap_channel_width(struct wiphy *wiphy,
20982 struct net_device *dev,
20983 struct cfg80211_chan_def *chandef)
20984{
Jeff Johnsonce2ba702017-10-02 13:30:24 -070020985 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsonb8944722017-09-03 09:03:19 -070020986 struct hdd_context *hdd_ctx;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053020987 QDF_STATUS status;
Sridhar Selvaraj48c47092017-07-31 18:18:14 +053020988 int retval = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020989
Anurag Chouhan6d760662016-02-20 16:05:43 +053020990 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Jeff Johnson3d8ac552016-06-29 15:21:37 -070020991 hdd_err("Command not allowed in FTM mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080020992 return -EINVAL;
20993 }
20994
Jeff Johnson48363022019-02-24 16:26:51 -080020995 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053020996 return -EINVAL;
Dustin Brown63500612018-08-07 11:36:09 -070020997
Abhishek Singh9d5f4582017-10-11 17:59:48 +053020998 if (!(adapter->device_mode == QDF_SAP_MODE ||
20999 adapter->device_mode == QDF_P2P_GO_MODE))
21000 return -EOPNOTSUPP;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053021001
Jeff Johnsonce2ba702017-10-02 13:30:24 -070021002 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnsonb8944722017-09-03 09:03:19 -070021003 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +053021004 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021005 return status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021006
Abhishek Singh9d5f4582017-10-11 17:59:48 +053021007 hdd_debug("Channel width changed to %d ",
21008 cfg80211_get_chandef_type(chandef));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021009
21010 /* Change SAP ht2040 mode */
Jeff Johnsonce2ba702017-10-02 13:30:24 -070021011 status = hdd_set_sap_ht2040_mode(adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021012 cfg80211_get_chandef_type(chandef));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053021013 if (status != QDF_STATUS_SUCCESS) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080021014 hdd_err("Cannot set SAP HT20/40 mode!");
Sridhar Selvaraj48c47092017-07-31 18:18:14 +053021015 retval = -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021016 }
21017
Sridhar Selvaraj48c47092017-07-31 18:18:14 +053021018 return retval;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021019}
21020
21021/**
21022 * wlan_hdd_cfg80211_set_ap_channel_width() - set ap channel bandwidth
21023 * @wiphy: Pointer to wiphy
21024 * @dev: Pointer to network device
21025 * @chandef: Pointer to channel definition parameter
21026 *
21027 * Return: 0 for success, non-zero for failure
21028 */
21029static int
21030wlan_hdd_cfg80211_set_ap_channel_width(struct wiphy *wiphy,
21031 struct net_device *dev,
21032 struct cfg80211_chan_def *chandef)
21033{
Dustin Brown1d31b082018-11-22 14:41:20 +053021034 int errno;
21035 struct osif_vdev_sync *vdev_sync;
21036
21037 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
21038 if (errno)
21039 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021040
Dustin Brown1d31b082018-11-22 14:41:20 +053021041 errno = __wlan_hdd_cfg80211_set_ap_channel_width(wiphy, dev, chandef);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021042
Dustin Brown1d31b082018-11-22 14:41:20 +053021043 osif_vdev_sync_op_stop(vdev_sync);
21044
21045 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021046}
21047#endif
21048
Abhishek Singh1bdb1572015-10-16 16:24:19 +053021049#ifdef CHANNEL_SWITCH_SUPPORTED
21050/**
21051 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21052 * channel in SAP/GO
21053 * @wiphy: wiphy pointer
21054 * @dev: dev pointer.
21055 * @csa_params: Change channel params
21056 *
21057 * This function is called to switch channel in SAP/GO
21058 *
21059 * Return: 0 if success else return non zero
21060 */
21061static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21062 struct net_device *dev,
21063 struct cfg80211_csa_settings *csa_params)
21064{
Jeff Johnsone5006672017-08-29 14:39:02 -070021065 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070021066 struct hdd_context *hdd_ctx;
Abhishek Singh1bdb1572015-10-16 16:24:19 +053021067 uint8_t channel;
21068 uint16_t freq;
21069 int ret;
Kiran Kumar Lokere13644672016-02-29 15:40:10 -080021070 enum phy_ch_width ch_width;
Abhishek Singh1bdb1572015-10-16 16:24:19 +053021071
Srinivas Girigowda13d39252017-03-06 16:12:15 -080021072 hdd_debug("Set Freq %d",
Abhishek Singh1bdb1572015-10-16 16:24:19 +053021073 csa_params->chandef.chan->center_freq);
21074
Jeff Johnson48363022019-02-24 16:26:51 -080021075 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053021076 return -EINVAL;
Hanumanth Reddy Pothulad9491f42016-10-24 19:08:38 +053021077
Abhishek Singh1bdb1572015-10-16 16:24:19 +053021078 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21079 ret = wlan_hdd_validate_context(hdd_ctx);
21080
21081 if (0 != ret)
21082 return ret;
21083
Krunal Sonib4326f22016-03-10 13:05:51 -080021084 if ((QDF_P2P_GO_MODE != adapter->device_mode) &&
21085 (QDF_SAP_MODE != adapter->device_mode))
Abhishek Singh1bdb1572015-10-16 16:24:19 +053021086 return -ENOTSUPP;
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +053021087 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->vdev_id,
21088 CSA_REASON_USER_INITIATED);
Abhishek Singh1bdb1572015-10-16 16:24:19 +053021089
21090 freq = csa_params->chandef.chan->center_freq;
21091 channel = cds_freq_to_chan(freq);
21092
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +053021093 ch_width = hdd_map_nl_chan_width(csa_params->chandef.width);
21094
Min Liu2fef5792018-01-19 17:59:42 +080021095 ret = hdd_softap_set_channel_change(dev, channel, ch_width, false);
Abhishek Singh1bdb1572015-10-16 16:24:19 +053021096 return ret;
21097}
21098
21099/**
21100 * wlan_hdd_cfg80211_channel_switch()- function to switch
21101 * channel in SAP/GO
21102 * @wiphy: wiphy pointer
21103 * @dev: dev pointer.
21104 * @csa_params: Change channel params
21105 *
21106 * This function is called to switch channel in SAP/GO
21107 *
21108 * Return: 0 if success else return non zero
21109 */
21110static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21111 struct net_device *dev,
21112 struct cfg80211_csa_settings *csa_params)
21113{
Dustin Brown1d31b082018-11-22 14:41:20 +053021114 int errno;
21115 struct osif_vdev_sync *vdev_sync;
21116
21117 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
21118 if (errno)
21119 return errno;
Abhishek Singh1bdb1572015-10-16 16:24:19 +053021120
Dustin Brown1d31b082018-11-22 14:41:20 +053021121 errno = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
Dustin Brown1d31b082018-11-22 14:41:20 +053021122
21123 osif_vdev_sync_op_stop(vdev_sync);
21124
21125 return errno;
Abhishek Singh1bdb1572015-10-16 16:24:19 +053021126}
21127#endif
21128
Krunal Sonied3bc8e2018-01-26 12:13:34 -080021129int wlan_hdd_change_hw_mode_for_given_chnl(struct hdd_adapter *adapter,
21130 uint8_t channel,
21131 enum policy_mgr_conn_update_reason reason)
21132{
21133 QDF_STATUS status;
21134 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21135
Dustin Brown491d54b2018-03-14 12:39:11 -070021136 hdd_enter();
Krunal Sonied3bc8e2018-01-26 12:13:34 -080021137 if (0 != wlan_hdd_validate_context(hdd_ctx))
21138 return -EINVAL;
21139
Dustin Brown76cd2932018-09-11 16:03:05 -070021140 status = policy_mgr_reset_connection_update(hdd_ctx->psoc);
Krunal Sonied3bc8e2018-01-26 12:13:34 -080021141 if (!QDF_IS_STATUS_SUCCESS(status))
21142 hdd_err("clearing event failed");
21143
Dustin Brown76cd2932018-09-11 16:03:05 -070021144 status = policy_mgr_current_connections_update(hdd_ctx->psoc,
Jeff Johnsoncf07c312019-02-04 13:53:29 -080021145 adapter->vdev_id, channel, reason);
Krunal Sonied3bc8e2018-01-26 12:13:34 -080021146 switch (status) {
21147 case QDF_STATUS_E_FAILURE:
21148 /*
Jeff Johnson11d7c9d2018-05-06 15:44:09 -070021149 * QDF_STATUS_E_FAILURE indicates that some error has occurred
Krunal Sonied3bc8e2018-01-26 12:13:34 -080021150 * while changing the hw mode
21151 */
21152 hdd_err("ERROR: connections update failed!!");
21153 return -EINVAL;
21154
21155 case QDF_STATUS_SUCCESS:
21156 /*
21157 * QDF_STATUS_SUCCESS indicates that HW mode change has been
21158 * triggered and wait for it to finish.
21159 */
21160 status = policy_mgr_wait_for_connection_update(
Dustin Brown76cd2932018-09-11 16:03:05 -070021161 hdd_ctx->psoc);
Krunal Sonied3bc8e2018-01-26 12:13:34 -080021162 if (!QDF_IS_STATUS_SUCCESS(status)) {
21163 hdd_err("ERROR: qdf wait for event failed!!");
21164 return -EINVAL;
21165 }
21166 if (QDF_MONITOR_MODE == adapter->device_mode)
21167 hdd_info("Monitor mode:channel:%d (SMM->DBS)", channel);
21168 break;
21169
21170 default:
21171 /*
21172 * QDF_STATUS_E_NOSUPPORT indicates that no HW mode change is
21173 * required, so caller can proceed further.
21174 */
21175 break;
21176
21177 }
Dustin Browne74003f2018-03-14 12:51:58 -070021178 hdd_exit();
Krunal Sonied3bc8e2018-01-26 12:13:34 -080021179
21180 return 0;
21181}
21182
Nirav Shah73713f72018-05-17 14:50:41 +053021183#ifdef FEATURE_MONITOR_MODE_SUPPORT
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021184/**
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021185 * wlan_hdd_cfg80211_set_mon_ch() - Set monitor mode capture channel
21186 * @wiphy: Handle to struct wiphy to get handle to module context.
21187 * @chandef: Contains information about the capture channel to be set.
21188 *
21189 * This interface is called if and only if monitor mode interface alone is
21190 * active.
21191 *
21192 * Return: 0 success or error code on failure.
21193 */
21194static int __wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy,
21195 struct cfg80211_chan_def *chandef)
21196{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070021197 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
Jeff Johnsone5006672017-08-29 14:39:02 -070021198 struct hdd_adapter *adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -070021199 struct hdd_station_ctx *sta_ctx;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021200 struct hdd_mon_set_ch_info *ch_info;
21201 QDF_STATUS status;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070021202 mac_handle_t mac_handle;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021203 struct qdf_mac_addr bssid;
Jeff Johnson61b5e982018-03-15 11:33:31 -070021204 struct csr_roam_profile roam_profile;
Amar Singhal5cccafe2017-02-15 12:42:58 -080021205 struct ch_params ch_params;
Sandeep Puligilla1cc23f62016-04-27 16:52:49 -070021206 uint8_t sec_ch = 0;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021207 int ret;
21208 uint16_t chan_num = cds_freq_to_chan(chandef->chan->center_freq);
21209
Dustin Brown491d54b2018-03-14 12:39:11 -070021210 hdd_enter();
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021211
21212 ret = wlan_hdd_validate_context(hdd_ctx);
21213 if (ret)
21214 return ret;
21215
Jeff Johnson34fc63a2018-06-14 10:10:02 -070021216 mac_handle = hdd_ctx->mac_handle;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021217
21218 adapter = hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
21219 if (!adapter)
21220 return -EIO;
21221
Srinivas Girigowda13d39252017-03-06 16:12:15 -080021222 hdd_debug("%s: set monitor mode Channel %d and freq %d",
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021223 adapter->dev->name, chan_num, chandef->chan->center_freq);
21224
21225 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
21226 ch_info = &sta_ctx->ch_info;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021227 roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
21228 roam_profile.ChannelInfo.numOfChannels = 1;
21229 roam_profile.phyMode = ch_info->phy_mode;
Naveen Rawat3184dd82017-07-05 14:58:18 -070021230 roam_profile.ch_params.ch_width = hdd_map_nl_chan_width(chandef->width);
Naveen Rawatc77e6e72016-08-05 15:19:03 -070021231 hdd_select_cbmode(adapter, chan_num, &roam_profile.ch_params);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021232
Jeff Johnson1e851a12017-10-28 14:36:12 -070021233 qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021234 QDF_MAC_ADDR_SIZE);
21235
Naveen Rawat3184dd82017-07-05 14:58:18 -070021236 ch_params.ch_width = hdd_map_nl_chan_width(chandef->width);
Sandeep Puligilla1cc23f62016-04-27 16:52:49 -070021237 /*
21238 * CDS api expects secondary channel for calculating
21239 * the channel params
21240 */
21241 if ((ch_params.ch_width == CH_WIDTH_40MHZ) &&
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -070021242 (WLAN_REG_IS_24GHZ_CH(chan_num))) {
Sandeep Puligilla1cc23f62016-04-27 16:52:49 -070021243 if (chan_num >= 1 && chan_num <= 5)
21244 sec_ch = chan_num + 4;
21245 else if (chan_num >= 6 && chan_num <= 13)
21246 sec_ch = chan_num - 4;
21247 }
Dustin Brown07901ec2018-09-07 11:02:41 -070021248 wlan_reg_set_channel_params(hdd_ctx->pdev, chan_num,
21249 sec_ch, &ch_params);
Krunal Sonied3bc8e2018-01-26 12:13:34 -080021250 if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan_num,
21251 POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
21252 hdd_err("Failed to change hw mode");
21253 return -EINVAL;
21254 }
Jeff Johnson34fc63a2018-06-14 10:10:02 -070021255 status = sme_roam_channel_change_req(mac_handle, bssid, &ch_params,
21256 &roam_profile);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021257 if (status) {
Srinivas Girigowda13d39252017-03-06 16:12:15 -080021258 hdd_err("Failed to set sme_RoamChannel for monitor mode status: %d",
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021259 status);
21260 ret = qdf_status_to_os_return(status);
21261 return ret;
21262 }
Dustin Browne74003f2018-03-14 12:51:58 -070021263 hdd_exit();
Krunal Sonied3bc8e2018-01-26 12:13:34 -080021264
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021265 return 0;
21266}
21267
21268/**
21269 * wlan_hdd_cfg80211_set_mon_ch() - Set monitor mode capture channel
21270 * @wiphy: Handle to struct wiphy to get handle to module context.
21271 * @chandef: Contains information about the capture channel to be set.
21272 *
21273 * This interface is called if and only if monitor mode interface alone is
21274 * active.
21275 *
21276 * Return: 0 success or error code on failure.
21277 */
21278static int wlan_hdd_cfg80211_set_mon_ch(struct wiphy *wiphy,
21279 struct cfg80211_chan_def *chandef)
21280{
Dustin Brown363b4792019-02-05 16:11:55 -080021281 struct osif_psoc_sync *psoc_sync;
Dustin Brownf0f00612019-01-31 16:02:24 -080021282 int errno;
Arunk Khandavalli447837f2018-11-08 14:32:53 +053021283
Dustin Brown363b4792019-02-05 16:11:55 -080021284 errno = osif_psoc_sync_op_start(wiphy_dev(wiphy), &psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -080021285 if (errno)
21286 return errno;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021287
Dustin Brownf0f00612019-01-31 16:02:24 -080021288 errno = __wlan_hdd_cfg80211_set_mon_ch(wiphy, chandef);
Arunk Khandavalli447837f2018-11-08 14:32:53 +053021289
Dustin Brown363b4792019-02-05 16:11:55 -080021290 osif_psoc_sync_op_stop(psoc_sync);
Dustin Brownf0f00612019-01-31 16:02:24 -080021291
21292 return errno;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021293}
Nirav Shah73713f72018-05-17 14:50:41 +053021294#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070021295
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021296#define CNT_DIFF(cur, prev) \
21297 ((cur >= prev) ? (cur - prev) : (cur + (MAX_COUNT - (prev) + 1)))
21298#define MAX_COUNT 0xffffffff
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070021299static void hdd_update_chan_info(struct hdd_context *hdd_ctx,
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021300 struct scan_chan_info *chan,
21301 struct scan_chan_info *info, uint32_t cmd_flag)
21302{
21303 if ((info->cmd_flag != WMI_CHAN_InFO_START_RESP) &&
21304 (info->cmd_flag != WMI_CHAN_InFO_END_RESP))
21305 hdd_err("cmd flag is invalid: %d", info->cmd_flag);
21306
21307 mutex_lock(&hdd_ctx->chan_info_lock);
21308
21309 if (info->cmd_flag == WMI_CHAN_InFO_START_RESP)
21310 qdf_mem_zero(chan, sizeof(*chan));
21311
21312 chan->freq = info->freq;
21313 chan->noise_floor = info->noise_floor;
21314 chan->clock_freq = info->clock_freq;
21315 chan->cmd_flag = info->cmd_flag;
21316 chan->cycle_count = CNT_DIFF(info->cycle_count, chan->cycle_count);
21317
21318 chan->rx_clear_count =
21319 CNT_DIFF(info->rx_clear_count, chan->rx_clear_count);
21320
21321 chan->tx_frame_count =
21322 CNT_DIFF(info->tx_frame_count, chan->tx_frame_count);
21323
21324 mutex_unlock(&hdd_ctx->chan_info_lock);
21325
21326}
21327#undef CNT_DIFF
21328#undef MAX_COUNT
21329
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053021330#ifndef UPDATE_ASSOC_IE
21331#define UPDATE_ASSOC_IE BIT(0)
21332#endif
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021333
21334#ifndef UPDATE_FILS_ERP_INFO
21335#define UPDATE_FILS_ERP_INFO BIT(1)
21336#endif
21337
21338#ifndef UPDATE_FILS_AUTH_TYPE
21339#define UPDATE_FILS_AUTH_TYPE BIT(2)
21340#endif
21341
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053021342#if defined(WLAN_FEATURE_FILS_SK) &&\
21343 defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) &&\
21344 (defined(CFG80211_UPDATE_CONNECT_PARAMS) ||\
21345 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)))
21346
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021347/**
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053021348 * hdd_update_connect_params_fils_info() - Update fils parameters based on
21349 * the update_connect_params received from userspace
21350 * @adapter: Pointer to hdd_adapter
21351 * @hdd_ctx: Pointer to hdd_context
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021352 * @req: Pointer to connect params
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053021353 * @changed: bitmap indicating which parameters have changed
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021354 *
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053021355 * Return 0 on SUCCESS or error code on FAILURE
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021356 */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070021357static int
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053021358hdd_update_connect_params_fils_info(struct hdd_adapter *adapter,
21359 struct hdd_context *hdd_ctx,
21360 struct cfg80211_connect_params *req,
21361 uint32_t changed)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021362{
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021363 uint8_t *buf;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021364 QDF_STATUS status;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070021365 mac_handle_t mac_handle;
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053021366 struct csr_roam_profile *roam_profile;
21367 struct cds_fils_connection_info *fils_info;
21368 enum eAniAuthType auth_type;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021369
Jeff Johnson20227a92018-03-13 09:41:05 -070021370 roam_profile = hdd_roam_profile(adapter);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021371 fils_info = roam_profile->fils_con_info;
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053021372 mac_handle = hdd_ctx->mac_handle;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021373 if (!fils_info) {
21374 hdd_err("No valid FILS conn info");
21375 return -EINVAL;
21376 }
21377
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053021378 fils_info->is_fils_connection = true;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021379 if (changed & UPDATE_FILS_ERP_INFO) {
Varun Reddy Yeturu448cb9d2017-11-20 20:36:31 -080021380 if (!wlan_hdd_fils_data_in_limits(req))
Jeff Johnsonb8adae42018-02-27 16:12:00 -080021381 return -EINVAL;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021382 fils_info->key_nai_length = req->fils_erp_username_len +
21383 sizeof(char) +
21384 req->fils_erp_realm_len;
Dundi Raviteja170d2872018-03-23 15:49:54 +053021385 if (fils_info->key_nai_length >
21386 FILS_MAX_KEYNAME_NAI_LENGTH) {
21387 hdd_err("Key NAI Length %d",
21388 fils_info->key_nai_length);
21389 return -EINVAL;
21390 }
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021391 if (req->fils_erp_username_len && req->fils_erp_username) {
21392 buf = fils_info->keyname_nai;
21393 qdf_mem_copy(buf, req->fils_erp_username,
21394 req->fils_erp_username_len);
21395 buf += req->fils_erp_username_len;
21396 *buf++ = '@';
21397 qdf_mem_copy(buf, req->fils_erp_realm,
21398 req->fils_erp_realm_len);
21399 }
21400
Pragaspathi Thilagaraj87a60af2019-02-20 20:42:47 +053021401 fils_info->sequence_number = req->fils_erp_next_seq_num + 1;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021402 fils_info->r_rk_length = req->fils_erp_rrk_len;
21403
21404 if (req->fils_erp_rrk_len && req->fils_erp_rrk)
21405 qdf_mem_copy(fils_info->r_rk, req->fils_erp_rrk,
21406 fils_info->r_rk_length);
21407
21408 fils_info->realm_len = req->fils_erp_realm_len;
21409 if (req->fils_erp_realm_len && req->fils_erp_realm)
21410 qdf_mem_copy(fils_info->realm, req->fils_erp_realm,
21411 fils_info->realm_len);
21412 }
21413
21414 if (changed & UPDATE_FILS_AUTH_TYPE) {
21415 auth_type = wlan_hdd_get_fils_auth_type(req->auth_type);
Varun Reddy Yeturu5faa1772017-10-23 11:22:01 -070021416 if (auth_type == eSIR_DONOT_USE_AUTH_TYPE) {
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021417 hdd_err("invalid auth type for fils %d",
21418 req->auth_type);
21419 return -EINVAL;
21420 }
21421
21422 roam_profile->fils_con_info->auth_type = auth_type;
21423 }
21424
Varun Reddy Yeturu448cb9d2017-11-20 20:36:31 -080021425 hdd_debug("fils conn update: changed %x is_fils %d keyname nai len %d",
21426 changed, roam_profile->fils_con_info->is_fils_connection,
21427 roam_profile->fils_con_info->key_nai_length);
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053021428 /*
21429 * Update the FILS config from adapter->roam_profile to
21430 * csr_session
21431 */
Jeff Johnsoncf07c312019-02-04 13:53:29 -080021432 status = sme_update_fils_config(mac_handle, adapter->vdev_id,
Jeff Johnson34fc63a2018-06-14 10:10:02 -070021433 roam_profile);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021434 if (QDF_IS_STATUS_ERROR(status))
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053021435 hdd_err("Update FILS connect params to csr failed %d", status);
21436
21437 return 0;
21438}
21439#else
21440
Lin Bai9dc616c2019-04-10 10:08:49 +080021441static inline int
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053021442hdd_update_connect_params_fils_info(struct hdd_adapter *adapter,
21443 struct hdd_context *hdd_ctx,
21444 struct cfg80211_connect_params *req,
21445 uint32_t changed)
21446{
21447 return -EINVAL;
21448}
21449
21450#endif
21451
21452#if defined(CFG80211_UPDATE_CONNECT_PARAMS) ||\
21453 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
21454
21455/**
21456 * __wlan_hdd_cfg80211_update_connect_params - update connect params
21457 * @wiphy: Handle to struct wiphy to get handle to module context.
21458 * @dev: Pointer to network device
21459 * @req: Pointer to connect params
21460 * @changed: Bitmap used to indicate the changed params
21461 *
21462 * Update the connect parameters while connected to a BSS. The updated
21463 * parameters can be used by driver/firmware for subsequent BSS selection
21464 * (roaming) decisions and to form the Authentication/(Re)Association
21465 * Request frames. This call does not request an immediate disassociation
21466 * or reassociation with the current BSS, i.e., this impacts only
21467 * subsequent (re)associations. The bits in changed are defined in enum
21468 * cfg80211_connect_params_changed
21469 *
21470 * Return: zero for success, non-zero for failure
21471 */
21472static int
21473__wlan_hdd_cfg80211_update_connect_params(struct wiphy *wiphy,
21474 struct net_device *dev,
21475 struct cfg80211_connect_params *req,
21476 uint32_t changed)
21477{
21478 struct csr_roam_profile *roam_profile;
21479 int ret;
21480 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21481 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
21482 QDF_STATUS status;
21483 mac_handle_t mac_handle;
21484
21485 hdd_enter_dev(dev);
21486
21487 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
21488 return -EINVAL;
21489
21490 ret = wlan_hdd_validate_context(hdd_ctx);
21491 if (ret)
21492 return -EINVAL;
21493
21494 mac_handle = hdd_ctx->mac_handle;
21495 roam_profile = hdd_roam_profile(adapter);
21496
21497 if (changed & UPDATE_ASSOC_IE) {
21498 /*
21499 * Validate the elements of the IE and copy it to
21500 * roam_profile in adapter
21501 */
21502 wlan_hdd_cfg80211_set_ie(adapter, req->ie, req->ie_len);
21503
21504 /*
21505 * Update this assoc IE received from user space to
21506 * csr_session. RSO command will pick up the assoc
21507 * IEs to be sent to firmware from the csr_session.
21508 */
21509 sme_update_session_assoc_ie(mac_handle, adapter->vdev_id,
21510 roam_profile);
21511 }
21512
21513 if ((changed & UPDATE_FILS_ERP_INFO) ||
21514 (changed & UPDATE_FILS_AUTH_TYPE)) {
21515 ret = hdd_update_connect_params_fils_info(adapter, hdd_ctx,
21516 req, changed);
21517 if (ret)
21518 return -EINVAL;
21519
21520 if (!hdd_ctx->is_fils_roaming_supported) {
21521 hdd_debug("FILS roaming support %d",
21522 hdd_ctx->is_fils_roaming_supported);
21523 return 0;
21524 }
21525 }
21526
21527 if (changed) {
21528 status = sme_send_rso_connect_params(mac_handle,
21529 adapter->vdev_id,
21530 roam_profile);
21531 if (QDF_IS_STATUS_ERROR(status))
21532 hdd_err("Update connect params to fw failed %d",
21533 status);
21534 }
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021535
21536 return 0;
21537}
21538
21539/**
21540 * wlan_hdd_cfg80211_update_connect_params - SSR wrapper for
21541 * __wlan_hdd_cfg80211_update_connect_params
21542 * @wiphy: Pointer to wiphy structure
21543 * @dev: Pointer to net_device
21544 * @req: Pointer to connect params
21545 * @changed: flags used to indicate the changed params
21546 *
21547 * Return: zero for success, non-zero for failure
21548 */
Jeff Johnson34fc63a2018-06-14 10:10:02 -070021549static int
21550wlan_hdd_cfg80211_update_connect_params(struct wiphy *wiphy,
21551 struct net_device *dev,
21552 struct cfg80211_connect_params *req,
21553 uint32_t changed)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021554{
Dustin Brown1d31b082018-11-22 14:41:20 +053021555 int errno;
21556 struct osif_vdev_sync *vdev_sync;
21557
21558 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
21559 if (errno)
21560 return errno;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021561
Dustin Brown1d31b082018-11-22 14:41:20 +053021562 errno = __wlan_hdd_cfg80211_update_connect_params(wiphy, dev,
21563 req, changed);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021564
Dustin Brown1d31b082018-11-22 14:41:20 +053021565 osif_vdev_sync_op_stop(vdev_sync);
21566
21567 return errno;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021568}
21569#endif
21570
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053021571#if defined(WLAN_FEATURE_SAE) && \
21572 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
Srinivas Dasari29186ca2019-02-11 18:45:48 +053021573#if defined(CFG80211_EXTERNAL_AUTH_AP_SUPPORT)
21574/**
21575 * wlan_hdd_extauth_cache_pmkid() - Extract and cache pmkid
21576 * @adapter: hdd vdev/net_device context
21577 * @mac_handle: Handle to the MAC
21578 * @params: Pointer to external auth params.
21579 *
21580 * Extract the PMKID and BSS from external auth params and add to the
21581 * PMKSA Cache in CSR.
21582 */
21583static void
21584wlan_hdd_extauth_cache_pmkid(struct hdd_adapter *adapter,
21585 mac_handle_t mac_handle,
21586 struct cfg80211_external_auth_params *params)
21587{
21588 tPmkidCacheInfo pmk_cache;
21589 QDF_STATUS result;
21590 if (params->pmkid) {
21591 qdf_mem_zero(&pmk_cache, sizeof(pmk_cache));
21592 qdf_mem_copy(pmk_cache.BSSID.bytes, params->bssid,
21593 QDF_MAC_ADDR_SIZE);
21594 qdf_mem_copy(pmk_cache.PMKID, params->pmkid,
Srinivas Girigowdaff8f5ef2019-03-26 17:20:55 -070021595 PMKID_LEN);
Liangwei Donga44d55b2019-03-20 03:22:08 -040021596 result = wlan_hdd_set_pmksa_cache(adapter, &pmk_cache);
Srinivas Dasari29186ca2019-02-11 18:45:48 +053021597 if (!QDF_IS_STATUS_SUCCESS(result))
21598 hdd_debug("external_auth: Failed to cache PMKID");
21599 }
21600}
21601#else
21602static void
21603wlan_hdd_extauth_cache_pmkid(struct hdd_adapter *adapter,
21604 mac_handle_t mac_handle,
21605 struct cfg80211_external_auth_params *params)
21606{}
21607#endif
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053021608/**
21609 * __wlan_hdd_cfg80211_external_auth() - Handle external auth
Srinivas Dasari29186ca2019-02-11 18:45:48 +053021610 *
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053021611 * @wiphy: Pointer to wireless phy
21612 * @dev: net device
Srinivas Dasari29186ca2019-02-11 18:45:48 +053021613 * @params: Pointer to external auth params.
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053021614 * Return: 0 on success, negative errno on failure
Srinivas Dasari29186ca2019-02-11 18:45:48 +053021615 *
21616 * Userspace sends status of the external authentication(e.g., SAE) with a peer.
21617 * The message carries BSSID of the peer and auth status (WLAN_STATUS_SUCCESS/
21618 * WLAN_STATUS_UNSPECIFIED_FAILURE) in params.
21619 * Userspace may send PMKID in params, which can be used for
21620 * further connections.
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053021621 */
21622static int
21623__wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
21624 struct net_device *dev,
21625 struct cfg80211_external_auth_params *params)
21626{
21627 struct hdd_context *hdd_ctx = wiphy_priv(wiphy);
21628 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21629 int ret;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070021630 mac_handle_t mac_handle;
Srinivas Dasarie854ff02019-02-11 17:24:48 +053021631 struct qdf_mac_addr peer_mac_addr;
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053021632
21633 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
21634 hdd_err("Command not allowed in FTM mode");
21635 return -EPERM;
21636 }
21637
Jeff Johnson48363022019-02-24 16:26:51 -080021638 if (wlan_hdd_validate_vdev_id(adapter->vdev_id))
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053021639 return -EINVAL;
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053021640
21641 ret = wlan_hdd_validate_context(hdd_ctx);
21642 if (ret)
21643 return ret;
21644
Srinivas Dasarie854ff02019-02-11 17:24:48 +053021645 hdd_debug("external_auth status: %d peer mac: " QDF_MAC_ADDR_STR,
21646 params->status, QDF_MAC_ADDR_ARRAY(params->bssid));
Jeff Johnson34fc63a2018-06-14 10:10:02 -070021647 mac_handle = hdd_ctx->mac_handle;
Srinivas Dasarie854ff02019-02-11 17:24:48 +053021648 qdf_mem_copy(peer_mac_addr.bytes, params->bssid, QDF_MAC_ADDR_SIZE);
Srinivas Dasari29186ca2019-02-11 18:45:48 +053021649
21650 wlan_hdd_extauth_cache_pmkid(adapter, mac_handle, params);
21651
Srinivas Dasarie854ff02019-02-11 17:24:48 +053021652 sme_handle_sae_msg(mac_handle, adapter->vdev_id, params->status,
21653 peer_mac_addr);
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053021654
21655 return ret;
21656}
21657
21658/**
21659 * wlan_hdd_cfg80211_external_auth() - Handle external auth
21660 * @wiphy: Pointer to wireless phy
21661 * @dev: net device
21662 * @params: Pointer to external auth params
21663 *
21664 * Return: 0 on success, negative errno on failure
21665 */
21666static int
21667wlan_hdd_cfg80211_external_auth(struct wiphy *wiphy,
21668 struct net_device *dev,
21669 struct cfg80211_external_auth_params *params)
21670{
Dustin Brown1d31b082018-11-22 14:41:20 +053021671 int errno;
21672 struct osif_vdev_sync *vdev_sync;
21673
21674 errno = osif_vdev_sync_op_start(dev, &vdev_sync);
21675 if (errno)
21676 return errno;
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053021677
Dustin Brown1d31b082018-11-22 14:41:20 +053021678 errno = __wlan_hdd_cfg80211_external_auth(wiphy, dev, params);
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053021679
Dustin Brown1d31b082018-11-22 14:41:20 +053021680 osif_vdev_sync_op_stop(vdev_sync);
21681
21682 return errno;
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053021683}
21684#endif
21685
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021686/**
21687 * wlan_hdd_chan_info_cb() - channel info callback
21688 * @chan_info: struct scan_chan_info
21689 *
21690 * Store channel info into HDD context
21691 *
21692 * Return: None.
21693 */
21694static void wlan_hdd_chan_info_cb(struct scan_chan_info *info)
21695{
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070021696 struct hdd_context *hdd_ctx;
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021697 struct scan_chan_info *chan;
21698 uint8_t idx;
21699
Dustin Brown491d54b2018-03-14 12:39:11 -070021700 hdd_enter();
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021701
21702 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
21703 if (wlan_hdd_validate_context(hdd_ctx) != 0) {
21704 hdd_err("hdd_ctx is invalid");
21705 return;
21706 }
21707
21708 if (!hdd_ctx->chan_info) {
21709 hdd_err("chan_info is NULL");
21710 return;
21711 }
21712
21713 chan = hdd_ctx->chan_info;
21714 for (idx = 0; idx < SIR_MAX_NUM_CHANNELS; idx++) {
21715 if (chan[idx].freq == info->freq) {
21716 hdd_update_chan_info(hdd_ctx, &chan[idx], info,
21717 info->cmd_flag);
Rajeev Kumareb6ec172018-09-26 20:45:36 -070021718 hdd_debug("cmd:%d freq:%u nf:%d cc:%u rcc:%u clk:%u cmd:%d tfc:%d index:%d",
21719 chan[idx].cmd_flag, chan[idx].freq,
21720 chan[idx].noise_floor,
21721 chan[idx].cycle_count,
21722 chan[idx].rx_clear_count,
21723 chan[idx].clock_freq, chan[idx].cmd_flag,
21724 chan[idx].tx_frame_count, idx);
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021725 if (chan[idx].freq == 0)
21726 break;
21727
21728 }
21729 }
21730
Dustin Browne74003f2018-03-14 12:51:58 -070021731 hdd_exit();
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021732}
21733
21734/**
21735 * wlan_hdd_init_chan_info() - init chan info in hdd context
21736 * @hdd_ctx: HDD context pointer
21737 *
21738 * Return: none
21739 */
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070021740void wlan_hdd_init_chan_info(struct hdd_context *hdd_ctx)
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021741{
Rajeev Kumar Sirasanagandla9770bba2018-09-24 20:12:28 +053021742 uint32_t num_2g, num_5g, index = 0;
Jeff Johnson34fc63a2018-06-14 10:10:02 -070021743 mac_handle_t mac_handle;
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021744
Kapil Gupta63e75282017-05-18 20:55:10 +053021745 hdd_ctx->chan_info = NULL;
Jeff Johnsona8fef4e2019-03-11 14:38:49 -070021746 if (!hdd_ctx->config->enable_snr_monitoring) {
Dustin Brown31116772018-08-15 14:59:21 -070021747 hdd_debug("SNR monitoring is disabled");
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021748 return;
21749 }
21750
21751 hdd_ctx->chan_info =
21752 qdf_mem_malloc(sizeof(struct scan_chan_info)
21753 * QDF_MAX_NUM_CHAN);
Min Liu74a1a502018-10-10 19:59:07 +080021754 if (!hdd_ctx->chan_info)
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021755 return;
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021756 mutex_init(&hdd_ctx->chan_info_lock);
21757
21758 num_2g = QDF_ARRAY_SIZE(hdd_channels_2_4_ghz);
21759 for (; index < num_2g; index++) {
21760 hdd_ctx->chan_info[index].freq =
21761 hdd_channels_2_4_ghz[index].center_freq;
21762 }
21763
21764 num_5g = QDF_ARRAY_SIZE(hdd_channels_5_ghz);
21765 for (; (index - num_2g) < num_5g; index++) {
Dustin Brown07901ec2018-09-07 11:02:41 -070021766 if (wlan_reg_is_dsrc_chan(hdd_ctx->pdev,
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070021767 hdd_channels_5_ghz[index - num_2g].hw_value))
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021768 continue;
21769 hdd_ctx->chan_info[index].freq =
21770 hdd_channels_5_ghz[index - num_2g].center_freq;
21771 }
Rajeev Kumar Sirasanagandla9770bba2018-09-24 20:12:28 +053021772
21773 index = num_2g + num_5g;
21774 index = wlan_hdd_populate_srd_chan_info(hdd_ctx, index);
21775
Jeff Johnson34fc63a2018-06-14 10:10:02 -070021776 mac_handle = hdd_ctx->mac_handle;
21777 sme_set_chan_info_callback(mac_handle,
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021778 &wlan_hdd_chan_info_cb);
21779}
21780
21781/**
21782 * wlan_hdd_deinit_chan_info() - deinit chan info in hdd context
21783 * @hdd_ctx: hdd context pointer
21784 *
21785 * Return: none
21786 */
Jeff Johnson7aeb95b2017-08-28 12:06:33 -070021787void wlan_hdd_deinit_chan_info(struct hdd_context *hdd_ctx)
Kapil Gupta4f0c0c12017-02-07 15:21:15 +053021788{
21789 struct scan_chan_info *chan;
21790
21791 chan = hdd_ctx->chan_info;
21792 hdd_ctx->chan_info = NULL;
21793 if (chan)
21794 qdf_mem_free(chan);
21795}
21796
Dustin Brown32cb4792017-06-15 15:33:42 -070021797#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || defined(WITH_BACKPORTS)
21798static enum rate_info_bw hdd_map_hdd_bw_to_os(enum hdd_rate_info_bw hdd_bw)
21799{
21800 switch (hdd_bw) {
21801 case HDD_RATE_BW_5:
21802 return RATE_INFO_BW_5;
21803 case HDD_RATE_BW_10:
21804 return RATE_INFO_BW_10;
21805 case HDD_RATE_BW_20:
21806 return RATE_INFO_BW_20;
21807 case HDD_RATE_BW_40:
21808 return RATE_INFO_BW_40;
21809 case HDD_RATE_BW_80:
21810 return RATE_INFO_BW_80;
21811 case HDD_RATE_BW_160:
21812 return RATE_INFO_BW_160;
21813 }
21814
21815 hdd_err("Unhandled HDD_RATE_BW: %d", hdd_bw);
21816
21817 return RATE_INFO_BW_20;
21818}
21819
21820void hdd_set_rate_bw(struct rate_info *info, enum hdd_rate_info_bw hdd_bw)
21821{
21822 info->bw = hdd_map_hdd_bw_to_os(hdd_bw);
21823}
21824#else
21825static enum rate_info_flags hdd_map_hdd_bw_to_os(enum hdd_rate_info_bw hdd_bw)
21826{
21827 switch (hdd_bw) {
21828 case HDD_RATE_BW_5:
21829 case HDD_RATE_BW_10:
21830 case HDD_RATE_BW_20:
21831 return (enum rate_info_flags)0;
21832 case HDD_RATE_BW_40:
21833 return RATE_INFO_FLAGS_40_MHZ_WIDTH;
21834 case HDD_RATE_BW_80:
21835 return RATE_INFO_FLAGS_80_MHZ_WIDTH;
21836 case HDD_RATE_BW_160:
21837 return RATE_INFO_FLAGS_160_MHZ_WIDTH;
21838 }
21839
21840 hdd_err("Unhandled HDD_RATE_BW: %d", hdd_bw);
21841
21842 return (enum rate_info_flags)0;
21843}
21844
21845void hdd_set_rate_bw(struct rate_info *info, enum hdd_rate_info_bw hdd_bw)
21846{
21847 const enum rate_info_flags all_bws =
21848 RATE_INFO_FLAGS_40_MHZ_WIDTH |
21849 RATE_INFO_FLAGS_80_MHZ_WIDTH |
21850 RATE_INFO_FLAGS_80P80_MHZ_WIDTH |
21851 RATE_INFO_FLAGS_160_MHZ_WIDTH;
21852
21853 info->flags &= ~all_bws;
21854 info->flags |= hdd_map_hdd_bw_to_os(hdd_bw);
21855}
21856#endif
21857
Min Liue34708a2019-02-01 15:00:34 +080021858#ifdef CFG80211_EXTERNAL_DH_UPDATE_SUPPORT
21859void hdd_send_update_owe_info_event(struct hdd_adapter *adapter,
21860 uint8_t sta_addr[],
21861 uint8_t *owe_ie,
21862 uint32_t owe_ie_len)
21863{
21864 struct cfg80211_update_owe_info owe_info;
21865 struct net_device *dev = adapter->dev;
21866
21867 hdd_enter_dev(dev);
21868
Min Liue2b469f2019-04-10 19:13:42 +080021869 qdf_mem_copy(owe_info.peer, sta_addr, ETH_ALEN);
Min Liue34708a2019-02-01 15:00:34 +080021870 owe_info.ie = owe_ie;
21871 owe_info.ie_len = owe_ie_len;
21872
21873 cfg80211_update_owe_info_event(dev, &owe_info, GFP_KERNEL);
21874
21875 hdd_exit();
21876}
21877#endif
21878
Mahesh A Saptasagar6dda2022016-09-03 12:59:09 +053021879/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021880 * struct cfg80211_ops - cfg80211_ops
21881 *
21882 * @add_virtual_intf: Add virtual interface
21883 * @del_virtual_intf: Delete virtual interface
21884 * @change_virtual_intf: Change virtual interface
21885 * @change_station: Change station
21886 * @add_beacon: Add beacon in sap mode
21887 * @del_beacon: Delete beacon in sap mode
21888 * @set_beacon: Set beacon in sap mode
21889 * @start_ap: Start ap
21890 * @change_beacon: Change beacon
21891 * @stop_ap: Stop ap
21892 * @change_bss: Change bss
21893 * @add_key: Add key
21894 * @get_key: Get key
21895 * @del_key: Delete key
21896 * @set_default_key: Set default key
21897 * @set_channel: Set channel
21898 * @scan: Scan
21899 * @connect: Connect
21900 * @disconnect: Disconnect
21901 * @join_ibss = Join ibss
21902 * @leave_ibss = Leave ibss
21903 * @set_wiphy_params = Set wiphy params
21904 * @set_tx_power = Set tx power
21905 * @get_tx_power = get tx power
21906 * @remain_on_channel = Remain on channel
21907 * @cancel_remain_on_channel = Cancel remain on channel
21908 * @mgmt_tx = Tx management frame
21909 * @mgmt_tx_cancel_wait = Cancel management tx wait
21910 * @set_default_mgmt_key = Set default management key
21911 * @set_txq_params = Set tx queue parameters
21912 * @get_station = Get station
21913 * @set_power_mgmt = Set power management
21914 * @del_station = Delete station
21915 * @add_station = Add station
21916 * @set_pmksa = Set pmksa
21917 * @del_pmksa = Delete pmksa
21918 * @flush_pmksa = Flush pmksa
21919 * @update_ft_ies = Update FT IEs
21920 * @tdls_mgmt = Tdls management
21921 * @tdls_oper = Tdls operation
21922 * @set_rekey_data = Set rekey data
21923 * @sched_scan_start = Scheduled scan start
21924 * @sched_scan_stop = Scheduled scan stop
21925 * @resume = Resume wlan
21926 * @suspend = Suspend wlan
21927 * @set_mac_acl = Set mac acl
21928 * @testmode_cmd = Test mode command
21929 * @set_ap_chanwidth = Set AP channel bandwidth
21930 * @dump_survey = Dump survey
21931 * @key_mgmt_set_pmk = Set pmk key management
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053021932 * @update_connect_params = Update connect params
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021933 */
21934static struct cfg80211_ops wlan_hdd_cfg80211_ops = {
21935 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21936 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21937 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21938 .change_station = wlan_hdd_change_station,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021939 .start_ap = wlan_hdd_cfg80211_start_ap,
21940 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21941 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021942 .change_bss = wlan_hdd_cfg80211_change_bss,
21943 .add_key = wlan_hdd_cfg80211_add_key,
21944 .get_key = wlan_hdd_cfg80211_get_key,
21945 .del_key = wlan_hdd_cfg80211_del_key,
21946 .set_default_key = wlan_hdd_cfg80211_set_default_key,
21947 .scan = wlan_hdd_cfg80211_scan,
21948 .connect = wlan_hdd_cfg80211_connect,
21949 .disconnect = wlan_hdd_cfg80211_disconnect,
21950 .join_ibss = wlan_hdd_cfg80211_join_ibss,
21951 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
21952 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
21953 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
21954 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
21955 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
21956 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
21957 .mgmt_tx = wlan_hdd_mgmt_tx,
21958 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
21959 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
21960 .set_txq_params = wlan_hdd_set_txq_params,
Himanshu Agarwal37e42412016-07-21 14:35:09 +053021961 .dump_station = wlan_hdd_cfg80211_dump_station,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021962 .get_station = wlan_hdd_cfg80211_get_station,
21963 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
21964 .del_station = wlan_hdd_cfg80211_del_station,
21965 .add_station = wlan_hdd_cfg80211_add_station,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021966 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
21967 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
21968 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -080021969#if defined(KERNEL_SUPPORT_11R_CFG80211)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021970 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
21971#endif
Min Liu0daa0982019-02-01 17:50:44 +080021972#ifdef CFG80211_EXTERNAL_DH_UPDATE_SUPPORT
21973 .update_owe_info = wlan_hdd_cfg80211_update_owe_info,
21974#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080021975#ifdef FEATURE_WLAN_TDLS
21976 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
21977 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
21978#endif
21979#ifdef WLAN_FEATURE_GTK_OFFLOAD
21980 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
21981#endif /* WLAN_FEATURE_GTK_OFFLOAD */
21982#ifdef FEATURE_WLAN_SCAN_PNO
21983 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
21984 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
21985#endif /*FEATURE_WLAN_SCAN_PNO */
21986 .resume = wlan_hdd_cfg80211_resume_wlan,
21987 .suspend = wlan_hdd_cfg80211_suspend_wlan,
21988 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
21989#ifdef WLAN_NL80211_TESTMODE
21990 .testmode_cmd = wlan_hdd_cfg80211_testmode,
21991#endif
21992#ifdef QCA_HT_2040_COEX
21993 .set_ap_chanwidth = wlan_hdd_cfg80211_set_ap_channel_width,
21994#endif
21995 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Abhishek Singh1bdb1572015-10-16 16:24:19 +053021996#ifdef CHANNEL_SWITCH_SUPPORTED
21997 .channel_switch = wlan_hdd_cfg80211_channel_switch,
21998#endif
Nirav Shah73713f72018-05-17 14:50:41 +053021999#ifdef FEATURE_MONITOR_MODE_SUPPORT
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -070022000 .set_monitor_channel = wlan_hdd_cfg80211_set_mon_ch,
Nirav Shah73713f72018-05-17 14:50:41 +053022001#endif
Vidyullatha, Kanchanapally528789e2016-05-11 20:38:37 +053022002#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 5, 0)) || \
Srinivas Girigowda576b2352017-08-25 14:44:26 -070022003 defined(CFG80211_ABORT_SCAN)
Vidyullatha, Kanchanapally528789e2016-05-11 20:38:37 +053022004 .abort_scan = wlan_hdd_cfg80211_abort_scan,
22005#endif
Pragaspathi Thilagaraj6695ba92019-04-04 17:59:47 +053022006#if defined(CFG80211_UPDATE_CONNECT_PARAMS) || \
22007 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0))
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +053022008 .update_connect_params = wlan_hdd_cfg80211_update_connect_params,
22009#endif
Padma, Santhosh Kumareb90a552018-01-16 19:41:58 +053022010#if defined(WLAN_FEATURE_SAE) && \
22011 defined(CFG80211_EXTERNAL_AUTH_SUPPORT)
22012 .external_auth = wlan_hdd_cfg80211_external_auth,
22013#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080022014};