blob: 6b207c326888d2f6c909a6fa7cdf5210e0bd72b5 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Jeff Johnson30e9bb62018-12-27 20:57:09 -08002 * 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_main.c
21 *
22 * WLAN Host Device Driver implementation
23 *
24 */
25
26/* Include Files */
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053027#include <wbuff.h>
Dustin Brown84f46ea2018-02-15 11:57:36 -080028#include "cfg_ucfg_api.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080029#include <wlan_hdd_includes.h>
30#include <cds_api.h>
31#include <cds_sched.h>
Arun Khandavallifae92942016-08-01 13:31:08 +053032#include <linux/cpu.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080033#include <linux/etherdevice.h>
34#include <linux/firmware.h>
35#include <wlan_hdd_tx_rx.h>
36#include <wni_api.h>
37#include <wlan_hdd_cfg.h>
38#include <wlan_ptt_sock_svc.h>
39#include <dbglog_host.h>
40#include <wlan_logging_sock_svc.h>
Qiwei Caiad9b01c2018-07-09 17:21:31 +080041#include <wlan_roam_debug.h>
Dustin Brown6412d1f2019-02-05 14:52:29 -080042#include "osif_sync.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080043#include <wlan_hdd_wowl.h>
44#include <wlan_hdd_misc.h>
45#include <wlan_hdd_wext.h>
46#include "wlan_hdd_trace.h"
47#include "wlan_hdd_ioctl.h"
48#include "wlan_hdd_ftm.h"
49#include "wlan_hdd_power.h"
50#include "wlan_hdd_stats.h"
Prashanth Bhatta527fd752016-04-28 12:35:23 -070051#include "wlan_hdd_scan.h"
Krunal Sonie9c12f52018-10-04 11:45:42 -070052#include "wlan_policy_mgr_ucfg.h"
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +053053#include "wlan_osif_priv.h"
Naveen Rawate02f8f52018-04-05 11:58:04 -070054#include <wlan_osif_request_manager.h>
Dustin Brown26b3d042017-12-21 11:13:27 -080055#ifdef CONFIG_LEAK_DETECTION
Dustin Brown4bc0a622017-12-06 15:56:50 -080056#include "qdf_debug_domain.h"
Dustin Brown26b3d042017-12-21 11:13:27 -080057#endif
Dustin Brown8d8ab302019-03-05 16:19:36 -080058#include "qdf_delayed_work.h"
Dustin Brown4a93bb52019-03-13 11:46:34 -070059#include "qdf_periodic_work.h"
Dustin Brownd4241942018-02-26 12:51:37 -080060#include "qdf_str.h"
Dustin Brownd315c452018-11-27 11:28:48 -080061#include "qdf_talloc.h"
Dustin Brownd4241942018-02-26 12:51:37 -080062#include "qdf_trace.h"
63#include "qdf_types.h"
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070064#include <cdp_txrx_peer_ops.h>
Dhanashri Atrea8f82f22017-01-23 12:58:24 -080065#include <cdp_txrx_misc.h>
Mohit Khannaca4173b2017-09-12 21:52:19 -070066#include <cdp_txrx_stats.h>
bings0e03a982018-05-09 08:40:59 +080067#include "cdp_txrx_flow_ctrl_legacy.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080068
69#include <net/addrconf.h>
70#include <linux/wireless.h>
71#include <net/cfg80211.h>
72#include <linux/inetdevice.h>
73#include <net/addrconf.h>
74#include "wlan_hdd_cfg80211.h"
75#include "wlan_hdd_ext_scan.h"
76#include "wlan_hdd_p2p.h"
77#include <linux/rtnetlink.h>
78#include "sap_api.h"
79#include <linux/semaphore.h>
80#include <linux/ctype.h>
81#include <linux/compat.h>
Subrat Dash5f36fbe2019-02-12 16:28:14 +053082#include <linux/ethtool.h>
Tiger Yu8b119e92019-04-09 13:55:07 +080083
84#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
85#include "qdf_periodic_work.h"
86#endif
87
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080088#ifdef MSM_PLATFORM
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080089#include <soc/qcom/subsystem_restart.h>
90#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080091#include <wlan_hdd_hostapd.h>
92#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson8bb61112018-03-31 13:33:54 -070093#include <wlan_hdd_green_ap.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080094#include "qwlan_version.h"
95#include "wma_types.h"
96#include "wlan_hdd_tdls.h"
97#ifdef FEATURE_WLAN_CH_AVOID
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +053098#include "cds_regdomain.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080099#endif /* FEATURE_WLAN_CH_AVOID */
Dustin Brownce46d1d2017-08-15 13:34:24 -0700100#include "cdp_txrx_flow_ctrl_v2.h"
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -0700101#include "pld_common.h"
Tushnim Bhattacharyya15596cf2016-02-12 11:57:02 -0800102#include "wlan_hdd_ocb.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800103#include "wlan_hdd_nan.h"
104#include "wlan_hdd_debugfs.h"
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +0530105#include "wlan_hdd_debugfs_csr.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800106#include "wlan_hdd_driver_ops.h"
107#include "epping_main.h"
Poddar, Siddarth34872782017-08-10 14:08:51 +0530108#include "wlan_hdd_data_stall_detection.h"
stonezc9936cb2019-03-11 16:41:22 +0800109#include "wlan_hdd_mpta_helper.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800110
111#include <wlan_hdd_ipa.h>
112#include "hif.h"
113#include "wma.h"
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -0800114#include "wlan_policy_mgr_api.h"
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700115#include "wlan_hdd_tsf.h"
Komal Seelamec702b02016-02-24 18:42:16 +0530116#include "bmi.h"
Amar Singhale4f28ee2015-10-21 14:36:56 -0700117#include <wlan_hdd_regulatory.h>
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700118#include "wlan_hdd_lpass.h"
Nachiket Kukade63bb63d2018-11-21 14:42:14 +0530119#include "wlan_nan_api.h"
Orhan K AKYILDIZ1481aff2016-05-16 12:40:13 -0700120#include <wlan_hdd_napi.h>
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +0530121#include "wlan_hdd_disa.h"
Rajeev Kumar97767a02016-11-30 11:20:40 -0800122#include <dispatcher_init_deinit.h>
Rajeev Kumar699debf2017-01-06 14:17:00 -0800123#include "wlan_hdd_object_manager.h"
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +0530124#include "cds_utils.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800125#include <cdp_txrx_handle.h>
Sandeep Puligillafdd201e2017-02-02 18:43:46 -0800126#include <qca_vendor.h>
Mukul Sharma9d797a02017-01-05 20:26:03 +0530127#include "wlan_pmo_ucfg_api.h"
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +0530128#include "sir_api.h"
Naveen Rawat910726a2017-03-06 11:42:51 -0800129#include "os_if_wifi_pos.h"
130#include "wifi_pos_api.h"
131#include "wlan_hdd_oemdata.h"
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800132#include "wlan_hdd_he.h"
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700133#include "os_if_nan.h"
134#include "nan_public_structs.h"
Nachiket Kukade85aa3782018-11-02 20:12:34 +0530135#include "nan_ucfg_api.h"
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -0700136#include "wlan_reg_ucfg_api.h"
bings81fe50a2017-11-27 14:33:26 +0800137#include "wlan_dfs_ucfg_api.h"
Ravi Joshi4f095952017-06-29 15:39:19 -0700138#include "wlan_hdd_rx_monitor.h"
Mukul Sharmad16c2022017-07-25 18:56:12 +0530139#include "sme_power_save_api.h"
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +0530140#include "enet.h"
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700141#include <cdp_txrx_cmn_struct.h>
Mohit Khanna70322002018-05-15 19:21:32 -0700142#include <dp_txrx.h>
Amar Singhal0928b192017-12-01 10:50:54 -0800143#include "wlan_hdd_sysfs.h"
Nachiket Kukade98f562a2017-12-15 12:18:07 +0530144#include "wlan_disa_ucfg_api.h"
Wu Gao52084c12018-05-17 20:47:11 +0800145#include "wlan_disa_obj_mgmt_api.h"
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +0530146#include "wlan_action_oui_ucfg_api.h"
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +0530147#include "wlan_ipa_ucfg_api.h"
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530148#include <target_if.h>
Alok Kumarb64650c2018-03-23 17:05:11 +0530149#include "wlan_hdd_nud_tracking.h"
Nachiket Kukaded0dd62e2018-05-21 18:39:22 +0530150#include "wlan_hdd_apf.h"
Varun Reddy Yeturue93d2462018-05-22 13:54:52 -0700151#include "wlan_hdd_twt.h"
Rachit Kankane0dc3e852018-05-07 17:33:42 +0530152#include "qc_sap_ioctl.h"
Sandeep Puligillac5609d52018-05-17 19:23:41 -0700153#include "wlan_mlme_main.h"
Wu Gaoe5689792018-07-05 19:20:13 +0800154#include "wlan_p2p_cfg_api.h"
Wu Gao637d58a2018-12-08 10:37:34 +0800155#include "wlan_cfg80211_p2p.h"
Paul Zhang37185672019-05-14 11:20:14 +0800156#include "wlan_cfg80211_interop_issues_ap.h"
Wu Gaobdb7f272018-07-05 19:33:26 +0800157#include "wlan_tdls_cfg_api.h"
Qiwei Caie689a262018-07-26 15:50:22 +0800158#include <wlan_hdd_rssi_monitor.h>
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +0530159#include "wlan_mlme_ucfg_api.h"
Sourav Mohapatra113685f2018-08-29 14:21:55 +0530160#include "wlan_fwol_ucfg_api.h"
Krunal Sonie71838d2018-09-27 10:45:05 -0700161#include "wlan_policy_mgr_ucfg.h"
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +0530162#ifdef CNSS_GENL
163#include <net/cnss_nl.h>
164#endif
Amar Singhal5cccafe2017-02-15 12:42:58 -0800165#include "wlan_reg_ucfg_api.h"
Zhang Qian47e22ce2018-01-04 15:38:38 +0800166#include "wlan_ocb_ucfg_api.h"
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -0800167#include <wlan_hdd_spectralscan.h>
gaurank kathpalia4a205fc2018-09-15 00:59:15 +0530168#include "wlan_green_ap_ucfg_api.h"
Liangwei Dong3abfe8f2018-09-20 02:25:44 -0400169#include <wlan_p2p_ucfg_api.h>
Paul Zhang37185672019-05-14 11:20:14 +0800170#include <wlan_interop_issues_ap_ucfg_api.h>
Mohit Khanna81418772018-10-30 14:14:46 -0700171#include <target_type.h>
Arun Kumar Khandavallideda5a82019-03-11 15:32:19 +0530172#include <wlan_hdd_debugfs_coex.h>
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +0530173#include "wlan_blm_ucfg_api.h"
Tiger Yue40e7832019-04-25 10:46:53 +0800174#include "ol_txrx.h"
Sourav Mohapatra43e6dea2019-08-18 11:39:23 +0530175#include "wlan_hdd_sta_info.h"
Arun Kumar Khandavalli42b44872019-10-21 19:02:04 +0530176#include "mac_init_api.h"
Liangwei Dong3abfe8f2018-09-20 02:25:44 -0400177
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800178#ifdef MODULE
179#define WLAN_MODULE_NAME module_name(THIS_MODULE)
180#else
181#define WLAN_MODULE_NAME "wlan"
182#endif
183
184#ifdef TIMER_MANAGER
185#define TIMER_MANAGER_STR " +TIMER_MANAGER"
186#else
187#define TIMER_MANAGER_STR ""
188#endif
189
190#ifdef MEMORY_DEBUG
191#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
192#else
193#define MEMORY_DEBUG_STR ""
194#endif
195
Dustin Brownc1034df2018-02-07 14:51:32 -0800196#ifdef PANIC_ON_BUG
197#define PANIC_ON_BUG_STR " +PANIC_ON_BUG"
198#else
199#define PANIC_ON_BUG_STR ""
200#endif
201
Sachin Ahujadddd2632017-03-07 19:07:24 +0530202int wlan_start_ret_val;
203static DECLARE_COMPLETION(wlan_start_comp);
204static unsigned int dev_num = 1;
205static struct cdev wlan_hdd_state_cdev;
206static struct class *class;
207static dev_t device;
Arun Khandavallifae92942016-08-01 13:31:08 +0530208#ifndef MODULE
209static struct gwlan_loader *wlan_loader;
210static ssize_t wlan_boot_cb(struct kobject *kobj,
211 struct kobj_attribute *attr,
212 const char *buf, size_t count);
213struct gwlan_loader {
214 bool loaded_state;
215 struct kobject *boot_wlan_obj;
216 struct attribute_group *attr_group;
217};
218
219static struct kobj_attribute wlan_boot_attribute =
220 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
221
222static struct attribute *attrs[] = {
223 &wlan_boot_attribute.attr,
224 NULL,
225};
226
227#define MODULE_INITIALIZED 1
Qun Zhang4a83a462018-09-11 16:28:51 +0800228
229#ifdef MULTI_IF_NAME
230#define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME
231#else
232#define WLAN_LOADER_NAME "boot_wlan"
233#endif
Arun Khandavallifae92942016-08-01 13:31:08 +0530234#endif
235
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800236/* the Android framework expects this param even though we don't use it */
237#define BUF_LEN 20
238static char fwpath_buffer[BUF_LEN];
239static struct kparam_string fwpath = {
240 .string = fwpath_buffer,
241 .maxlen = BUF_LEN,
242};
243
244static char *country_code;
245static int enable_11d = -1;
246static int enable_dfs_chan_scan = -1;
Rajeev Kumar588a2542019-04-08 10:57:19 -0700247static bool is_mode_change_psoc_idle_shutdown;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800248
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800249#define WLAN_NLINK_CESIUM 30
250
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530251static qdf_wake_lock_t wlan_wake_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800252
253#define WOW_MAX_FILTER_LISTS 1
254#define WOW_MAX_FILTERS_PER_LIST 4
255#define WOW_MIN_PATTERN_SIZE 6
256#define WOW_MAX_PATTERN_SIZE 64
257
Bala Venkatesh110b03e2018-07-10 16:02:08 +0530258/* max peer can be tdls peers + self peer + bss peer */
259#define HDD_MAX_VDEV_PEER_COUNT (HDD_MAX_NUM_TDLS_STA + 2)
Sourav Mohapatra808e3d42018-07-04 09:34:23 +0530260#define IS_IDLE_STOP (!cds_is_driver_unloading() && \
261 !cds_is_driver_recovering() && !cds_is_driver_loading())
Bala Venkatesh110b03e2018-07-10 16:02:08 +0530262
Ashish Kumar Dhanotiyaeadb28b2019-06-28 14:34:19 +0530263#define HDD_FW_VER_MAJOR_SPID(tgt_fw_ver) ((tgt_fw_ver & 0xf0000000) >> 28)
264#define HDD_FW_VER_MINOR_SPID(tgt_fw_ver) ((tgt_fw_ver & 0xf000000) >> 24)
265#define HDD_FW_VER_SIID(tgt_fw_ver) ((tgt_fw_ver & 0xf00000) >> 20)
266#define HDD_FW_VER_CRM_ID(tgt_fw_ver) (tgt_fw_ver & 0x7fff)
267#define HDD_FW_VER_SUB_ID(tgt_fw_ver_ext) \
268((tgt_fw_ver_ext & 0xf0000000) >> 28)
269#define HDD_FW_VER_REL_ID(tgt_fw_ver_ext) \
270((tgt_fw_ver_ext & 0xf800000) >> 23)
271
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800272#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
273static const struct wiphy_wowlan_support wowlan_support_reg_init = {
274 .flags = WIPHY_WOWLAN_ANY |
275 WIPHY_WOWLAN_MAGIC_PKT |
276 WIPHY_WOWLAN_DISCONNECT |
277 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
278 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
279 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
280 WIPHY_WOWLAN_4WAY_HANDSHAKE |
281 WIPHY_WOWLAN_RFKILL_RELEASE,
282 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
283 .pattern_min_len = WOW_MIN_PATTERN_SIZE,
284 .pattern_max_len = WOW_MAX_PATTERN_SIZE,
285};
286#endif
287
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700288static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
289 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL},
290 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL},
291 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL},
292 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL},
293 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL},
294 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL},
295 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL},
296 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL},
297 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL},
298 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL},
299 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL},
300 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
301 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
302 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL},
303 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL},
304 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL},
305 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL},
306 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL},
307 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL},
308 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL},
309 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL},
310 [QDF_MODULE_ID_DP] = {QDF_TRACE_LEVEL_ALL},
311 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL},
312 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL},
313 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL},
314 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL},
315 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL},
316 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL},
317 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL},
318 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL},
319 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL},
320 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL},
321 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL},
322 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL},
Arif Hussainfde76e72017-09-05 16:58:23 -0700323 [QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumarca8ef9d2017-10-06 10:43:21 -0700324 [QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL},
Deepak Dhamdheref918d422017-07-06 12:56:29 -0700325 [QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL},
Himanshu Agarwalb229a142017-12-21 10:16:45 +0530326 [QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL},
Zhang Qian47e22ce2018-01-04 15:38:38 +0800327 [QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL},
Sravan Kumar Kairam1309e7e2018-03-13 09:29:52 +0530328 [QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +0530329 [QDF_MODULE_ID_ACTION_OUI] = {QDF_TRACE_LEVEL_ALL},
Dustin Brown84f46ea2018-02-15 11:57:36 -0800330 [QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL},
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +0530331 [QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL},
Ashish Kumar Dhanotiya8d039c82018-07-11 20:41:14 +0530332 [QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL},
Kiran Kumar Lokere4ce40482018-08-30 16:31:00 -0700333 [QDF_MODULE_ID_CRYPTO] = {QDF_TRACE_LEVEL_ALL},
Sourav Mohapatra113685f2018-08-29 14:21:55 +0530334 [QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL},
Abhishek Singh0b0105f2018-09-25 10:44:16 +0530335 [QDF_MODULE_ID_SM_ENGINE] = {QDF_TRACE_LEVEL_ALL},
336 [QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL},
Nachiket Kukade089b9832018-12-12 16:38:17 +0530337 [QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL},
Ashish Kumar Dhanotiya6ed44342019-02-07 21:11:00 +0530338 [QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL},
Paul Zhang37185672019-05-14 11:20:14 +0800339 [QDF_MODULE_ID_INTEROP_ISSUES_AP] = {QDF_TRACE_LEVEL_ALL},
gaurank kathpalia7ef72182019-05-29 19:41:25 +0530340 [QDF_MODULE_ID_BLACKLIST_MGR] = {QDF_TRACE_LEVEL_ALL},
Wu Gaoe73c3882019-05-29 16:22:10 +0800341 [QDF_MODULE_ID_DIRECT_BUF_RX] = {QDF_TRACE_LEVEL_ALL},
342 [QDF_MODULE_ID_SPECTRAL] = {QDF_TRACE_LEVEL_ALL},
Ashish Kumar Dhanotiya0c913502019-10-16 17:57:10 +0530343 [QDF_MODULE_ID_WIFIPOS] = {QDF_TRACE_LEVEL_ALL},
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700344};
345
Ashish Kumar Dhanotiyacf11bae2017-04-04 03:29:47 +0530346struct notifier_block hdd_netdev_notifier;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800347
348struct sock *cesium_nl_srv_sock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800349#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700350static void wlan_hdd_auto_shutdown_cb(void);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800351#endif
352
Arun Kumar Khandavalli42b44872019-10-21 19:02:04 +0530353QDF_STATUS hdd_common_roam_callback(struct wlan_objmgr_psoc *psoc,
354 uint8_t session_id,
355 struct csr_roam_info *roam_info,
356 uint32_t roam_id,
357 eRoamCmdStatus roam_status,
358 eCsrRoamResult roam_result)
359{
360 struct hdd_context *hdd_ctx;
361 struct hdd_adapter *adapter;
362
363 adapter = wlan_hdd_get_adapter_from_vdev(psoc, session_id);
364 if (!adapter)
365 return QDF_STATUS_E_INVAL;
366
367 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
368 if (!hdd_ctx)
369 return QDF_STATUS_E_INVAL;
370
371 switch (adapter->device_mode) {
372 case QDF_STA_MODE:
373 case QDF_NDI_MODE:
374 case QDF_P2P_CLIENT_MODE:
375 case QDF_P2P_DEVICE_MODE:
376 hdd_sme_roam_callback(adapter, roam_info, roam_id, roam_status,
377 roam_result);
378 break;
379 case QDF_SAP_MODE:
380 case QDF_P2P_GO_MODE:
381 wlansap_roam_callback(adapter->session.ap.sap_context,
382 roam_info, roam_id, roam_status,
383 roam_result);
384 break;
385 default:
386 hdd_err("Wrong device mode");
387 break;
388 }
389
390 return QDF_STATUS_SUCCESS;
391}
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +0530392/**
393 * hdd_mic_flush_work() - disable and flush pending mic work
394 * @adapter: Pointer to hdd adapter
395 *
396 * Return: None
397 */
398static void
399hdd_mic_flush_work(struct hdd_adapter *adapter)
400{
401 hdd_debug("Flush the MIC error work");
402
403 qdf_spin_lock_bh(&adapter->mic_work.lock);
Rakshith Suresh Patkar30bb8c12019-08-23 15:57:40 +0530404 if (adapter->mic_work.status != MIC_SCHEDULED) {
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +0530405 qdf_spin_unlock_bh(&adapter->mic_work.lock);
406 return;
407 }
408 adapter->mic_work.status = MIC_DISABLED;
409 qdf_spin_unlock_bh(&adapter->mic_work.lock);
410
411 qdf_flush_work(&adapter->mic_work.work);
412}
413
414/**
415 * hdd_mic_enable_work() - enable mic error work
416 * @adapter: Pointer to hdd adapter
417 *
418 * Return: None
419 */
420static void
421hdd_mic_enable_work(struct hdd_adapter *adapter)
422{
423 hdd_debug("Enable the MIC error work");
424
425 qdf_spin_lock_bh(&adapter->mic_work.lock);
426 if (adapter->mic_work.status == MIC_DISABLED)
427 adapter->mic_work.status = MIC_INITIALIZED;
428 qdf_spin_unlock_bh(&adapter->mic_work.lock);
429}
430
431/**
432 * hdd_mic_deinit_work() - deinitialize mic error work
433 * @hdd_adapter: Pointer to hdd adapter
434 *
435 * Return: None
436 */
437static void
438hdd_mic_deinit_work(struct hdd_adapter *adapter)
439{
440 hdd_debug("DeInitialize the MIC error work");
441
442 if (adapter->mic_work.status != MIC_UNINITIALIZED) {
443 qdf_destroy_work(NULL, &adapter->mic_work.work);
444
445 qdf_spin_lock_bh(&adapter->mic_work.lock);
446 adapter->mic_work.status = MIC_UNINITIALIZED;
447 if (adapter->mic_work.info) {
448 qdf_mem_free(adapter->mic_work.info);
449 adapter->mic_work.info = NULL;
450 }
451 qdf_spin_unlock_bh(&adapter->mic_work.lock);
452 qdf_spinlock_destroy(&adapter->mic_work.lock);
453 }
454}
455
456/**
457 * hdd_process_sta_mic_error() - Indicate STA mic error to supplicant
458 * @adapter: Pointer to hdd adapter
459 *
460 * Return: None
461 */
462static void
463hdd_process_sta_mic_error(struct hdd_adapter *adapter)
464{
465 struct hdd_station_ctx *sta_ctx;
466 struct hdd_mic_error_info *info;
467
468 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
469
470 if (eConnectionState_Associated !=
471 sta_ctx->conn_info.conn_state)
472 return;
473
474 info = adapter->mic_work.info;
475 /* inform mic failure to nl80211 */
476 cfg80211_michael_mic_failure(adapter->dev,
477 (uint8_t *)&info->ta_mac_addr,
478 info->multicast ?
479 NL80211_KEYTYPE_GROUP :
480 NL80211_KEYTYPE_PAIRWISE,
481 info->key_id,
482 info->tsc,
483 GFP_KERNEL);
484}
485
486/**
487 * hdd_process_sap_mic_error() - Indicate SAP mic error to supplicant
488 * @adapter: Pointer to hdd adapter
489 *
490 * Return: None
491 */
492static void
493hdd_process_sap_mic_error(struct hdd_adapter *adapter)
494{
495 struct hdd_mic_error_info *info;
496
497 info = adapter->mic_work.info;
498 /* inform mic failure to nl80211 */
499 cfg80211_michael_mic_failure(adapter->dev,
500 (uint8_t *)&info->ta_mac_addr,
501 info->multicast ?
502 NL80211_KEYTYPE_GROUP :
503 NL80211_KEYTYPE_PAIRWISE,
504 info->key_id,
505 info->tsc,
506 GFP_KERNEL);
507}
508
509/**
510 * __hdd_process_mic_error() - Indicate mic error to supplicant
511 * @adapter: Pointer to hdd adapter
512 *
513 * Return: None
514 */
515static void
516__hdd_process_mic_error(struct hdd_adapter *adapter)
517{
518 if (adapter->device_mode == QDF_STA_MODE ||
519 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
520 hdd_process_sta_mic_error(adapter);
521 } else if (adapter->device_mode == QDF_SAP_MODE ||
522 adapter->device_mode == QDF_P2P_GO_MODE) {
523 hdd_process_sap_mic_error(adapter);
524 } else {
525 hdd_err("Invalid interface type:%d", adapter->device_mode);
526 }
527}
528
529/**
530 * hdd_process_mic_error() - process mic error work
531 * @data: void pointer to hdd adapter
532 *
533 * Return: None
534 */
535static void
536hdd_process_mic_error(void *data)
537{
538 struct hdd_adapter *adapter = data;
539 struct osif_vdev_sync *vdev_sync;
540
541 if (hdd_validate_adapter(adapter))
542 goto exit;
543
544 if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync))
545 goto exit;
546
547 __hdd_process_mic_error(adapter);
548
549 osif_vdev_sync_op_stop(vdev_sync);
550exit:
551 qdf_spin_lock_bh(&adapter->mic_work.lock);
552 if (adapter->mic_work.info) {
553 qdf_mem_free(adapter->mic_work.info);
554 adapter->mic_work.info = NULL;
555 }
556 if (adapter->mic_work.status == MIC_SCHEDULED)
557 adapter->mic_work.status = MIC_INITIALIZED;
558 qdf_spin_unlock_bh(&adapter->mic_work.lock);
559}
560
561/**
562 * hdd_mic_init_work() - init mic error work
563 * @hdd_adapter: Pointer to hdd adapter
564 *
565 * Return: None
566 */
567static void
568hdd_mic_init_work(struct hdd_adapter *adapter)
569{
570 qdf_spinlock_create(&adapter->mic_work.lock);
571 qdf_create_work(0, &adapter->mic_work.work,
572 hdd_process_mic_error, adapter);
573 adapter->mic_work.status = MIC_INITIALIZED;
574 adapter->mic_work.info = NULL;
575}
576
Sachin Ahujadddd2632017-03-07 19:07:24 +0530577void hdd_start_complete(int ret)
578{
579 wlan_start_ret_val = ret;
580
581 complete(&wlan_start_comp);
582}
583
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800584/**
Nirav Shahbd36b062016-07-18 11:12:59 +0530585 * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700586 * @hdd_ctx: pointer to struct hdd_context
Nirav Shahbd36b062016-07-18 11:12:59 +0530587 *
588 * Return: none
589 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700590static void hdd_set_rps_cpu_mask(struct hdd_context *hdd_ctx)
Nirav Shahbd36b062016-07-18 11:12:59 +0530591{
Jeff Johnson9d295242017-08-29 14:39:48 -0700592 struct hdd_adapter *adapter;
Nirav Shahbd36b062016-07-18 11:12:59 +0530593
Dustin Brown920397d2017-12-13 16:27:50 -0800594 hdd_for_each_adapter(hdd_ctx, adapter)
595 hdd_send_rps_ind(adapter);
Nirav Shahbd36b062016-07-18 11:12:59 +0530596}
597
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530598#ifdef QCA_HL_NETDEV_FLOW_CONTROL
599void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter,
600 enum netif_action_type action)
601{
602 if (!adapter->tx_flow_timer_initialized)
603 return;
604
605 if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) {
606 qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
Ajit Pal Singhe6da1de2018-12-27 16:20:45 +0530607 adapter->hdd_stats.tx_rx_stats.is_txflow_paused = false;
608 adapter->hdd_stats.tx_rx_stats.txflow_unpause_cnt++;
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530609 } else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) {
610 QDF_STATUS status =
611 qdf_mc_timer_start(&adapter->tx_flow_control_timer,
612 WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
613
614 if (!QDF_IS_STATUS_SUCCESS(status))
615 hdd_err("Failed to start tx_flow_control_timer");
616 else
617 adapter->
618 hdd_stats.tx_rx_stats.txflow_timer_cnt++;
619
620 adapter->hdd_stats.tx_rx_stats.txflow_pause_cnt++;
621 adapter->hdd_stats.tx_rx_stats.is_txflow_paused = true;
622 }
623}
624#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
625
Tiger Yu8b119e92019-04-09 13:55:07 +0800626#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
Alok Kumar2fad6442018-11-08 19:19:28 +0530627void wlan_hdd_update_tcp_rx_param(struct hdd_context *hdd_ctx, void *data)
628{
629 if (!hdd_ctx) {
630 hdd_err("HDD context is null");
631 return;
632 }
633
634 if (!data) {
635 hdd_err("Data is null");
636 return;
637 }
638 if (hdd_ctx->config->enable_tcp_param_update)
639 wlan_hdd_send_tcp_param_update_event(hdd_ctx, data, 1);
640 else
641 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
642 WLAN_SVC_WLAN_TP_IND,
643 data,
644 sizeof(struct wlan_rx_tp_data));
645}
646
647void wlan_hdd_update_tcp_tx_param(struct hdd_context *hdd_ctx, void *data)
648{
649 enum wlan_tp_level next_tx_level;
650 struct wlan_tx_tp_data *tx_tp_data;
651
652 if (!hdd_ctx) {
653 hdd_err("HDD context is null");
654 return;
655 }
656
657 if (!data) {
658 hdd_err("Data is null");
659 return;
660 }
661
662 tx_tp_data = (struct wlan_tx_tp_data *)data;
663 next_tx_level = tx_tp_data->level;
664
665 if (hdd_ctx->config->enable_tcp_param_update)
666 wlan_hdd_send_tcp_param_update_event(hdd_ctx, data, 0);
667 else
668 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
669 WLAN_SVC_WLAN_TP_TX_IND,
670 &next_tx_level,
671 sizeof(next_tx_level));
672}
673
674/**
675 * wlan_hdd_send_tcp_param_update_event() - Send vendor event to update
676 * TCP parameter through Wi-Fi HAL
677 * @hdd_ctx: Pointer to HDD context
678 * @data: Parameters to update
679 * @dir: Direction(tx/rx) to update
680 *
681 * Return: None
682 */
683void wlan_hdd_send_tcp_param_update_event(struct hdd_context *hdd_ctx,
684 void *data,
685 uint8_t dir)
686{
687 struct sk_buff *vendor_event;
688 uint32_t event_len;
689 bool tcp_limit_output = false;
690 bool tcp_del_ack_ind_enabled = false;
691 bool tcp_adv_win_scl_enabled = false;
692 enum wlan_tp_level next_tp_level = WLAN_SVC_TP_NONE;
693
694 event_len = sizeof(uint8_t) + sizeof(uint8_t) + NLMSG_HDRLEN;
695
696 if (dir == 0) /*TX Flow */ {
697 struct wlan_tx_tp_data *tx_tp_data =
698 (struct wlan_tx_tp_data *)data;
699
700 next_tp_level = tx_tp_data->level;
701
702 if (tx_tp_data->tcp_limit_output) {
703 /* TCP_LIMIT_OUTPUT_BYTES */
704 event_len += sizeof(uint32_t);
705 tcp_limit_output = true;
706 }
707 } else if (dir == 1) /* RX Flow */ {
708 struct wlan_rx_tp_data *rx_tp_data =
709 (struct wlan_rx_tp_data *)data;
710
711 next_tp_level = rx_tp_data->level;
712
713 if (rx_tp_data->rx_tp_flags & TCP_DEL_ACK_IND_MASK) {
714 event_len += sizeof(uint32_t); /* TCP_DELACK_SEG */
715 tcp_del_ack_ind_enabled = true;
716 }
717 if (rx_tp_data->rx_tp_flags & TCP_ADV_WIN_SCL_MASK) {
718 event_len += sizeof(uint32_t); /* TCP_ADV_WIN_SCALE */
719 tcp_adv_win_scl_enabled = true;
720 }
721 } else {
722 hdd_err("Invalid Direction [%d]", dir);
723 return;
724 }
725
726 vendor_event =
727 cfg80211_vendor_event_alloc(
728 hdd_ctx->wiphy,
729 NULL, event_len,
730 QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT_INDEX,
731 GFP_KERNEL);
732
733 if (!vendor_event) {
734 hdd_err("cfg80211_vendor_event_alloc failed");
735 return;
736 }
737
738 if (nla_put_u8(
739 vendor_event,
740 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION,
741 dir))
742 goto tcp_param_change_nla_failed;
743
744 if (nla_put_u8(
745 vendor_event,
746 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL,
747 (next_tp_level == WLAN_SVC_TP_LOW ?
748 QCA_WLAN_THROUGHPUT_LEVEL_LOW :
749 QCA_WLAN_THROUGHPUT_LEVEL_HIGH)))
750 goto tcp_param_change_nla_failed;
751
752 if (tcp_limit_output &&
753 nla_put_u32(
754 vendor_event,
755 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES,
756 (next_tp_level == WLAN_SVC_TP_LOW ?
757 TCP_LIMIT_OUTPUT_BYTES_LOW :
758 TCP_LIMIT_OUTPUT_BYTES_HI)))
759 goto tcp_param_change_nla_failed;
760
761 if (tcp_del_ack_ind_enabled &&
762 (nla_put_u32(
763 vendor_event,
764 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG,
765 (next_tp_level == WLAN_SVC_TP_LOW ?
766 TCP_DEL_ACK_LOW : TCP_DEL_ACK_HI))))
767 goto tcp_param_change_nla_failed;
768
769 if (tcp_adv_win_scl_enabled &&
770 (nla_put_u32(
771 vendor_event,
772 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE,
773 (next_tp_level == WLAN_SVC_TP_LOW ?
774 WIN_SCALE_LOW : WIN_SCALE_HI))))
775 goto tcp_param_change_nla_failed;
776
777 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
778 return;
779
780tcp_param_change_nla_failed:
781 hdd_err("nla_put api failed");
782 kfree_skb(vendor_event);
783}
Tiger Yu8b119e92019-04-09 13:55:07 +0800784#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
Alok Kumar2fad6442018-11-08 19:19:28 +0530785
Nirav Shahbd36b062016-07-18 11:12:59 +0530786/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800787 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
788 * @vdev_id: vdev_id
789 * @action: action type
790 * @reason: reason type
791 *
792 * Return: none
793 */
794void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
795 enum netif_action_type action, enum netif_reason_type reason)
796{
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700797 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson9d295242017-08-29 14:39:48 -0700798 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800799
800 if (!hdd_ctx) {
801 hdd_err("hdd ctx is NULL");
802 return;
803 }
804 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530805 wlan_hdd_mod_fc_timer(adapter, action);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800806 wlan_hdd_netif_queue_control(adapter, action, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800807}
808
809/*
Dustin Brownab482ac2017-06-09 17:00:44 -0700810 * Store WLAN driver version and timestamp info in global variables such that
811 * crash debugger can extract them from driver debug symbol and crashdump for
812 * post processing
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800813 */
Dustin Brown96cd9632017-11-13 12:45:04 -0800814#ifdef BUILD_TAG
Rajeev Kumare555e2d2018-09-17 11:52:37 -0700815uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR "; " BUILD_TAG;
Dustin Brown96cd9632017-11-13 12:45:04 -0800816#else
Rajeev Kumare555e2d2018-09-17 11:52:37 -0700817uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR;
Naveen Rawat93836252017-06-20 16:30:59 -0700818#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800819
Jeff Johnson9d295242017-08-29 14:39:48 -0700820int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
Tushnim Bhattacharyya6c40b112019-10-30 11:39:25 -0700821 uint32_t chan_freq,
822 enum phy_ch_width chan_bw)
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530823{
Jeff Johnson16528362018-06-14 12:34:16 -0700824 mac_handle_t mac_handle;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530825
Jeff Johnson16528362018-06-14 12:34:16 -0700826 mac_handle = hdd_adapter_get_mac_handle(adapter);
827 if (!mac_handle) {
828 hdd_err("Invalid MAC handle");
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530829 return -EINVAL;
830 }
831
Tushnim Bhattacharyya6c40b112019-10-30 11:39:25 -0700832 if (INVALID_CHANNEL == wlan_reg_get_chan_enum_for_freq(chan_freq)) {
833 hdd_err("Channel freq %d not in driver's valid channel list", chan_freq);
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530834 return -EOPNOTSUPP;
835 }
836
Tushnim Bhattacharyya6c40b112019-10-30 11:39:25 -0700837 if ((!WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) &&
838 (!WLAN_REG_IS_5GHZ_CH_FREQ(chan_freq)) &&
839 (!WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_freq))) {
840 hdd_err("CH %d is not in 2.4GHz or 5GHz or 6GHz", chan_freq);
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530841 return -EINVAL;
842 }
843
Tushnim Bhattacharyya6c40b112019-10-30 11:39:25 -0700844 if (WLAN_REG_IS_24GHZ_CH_FREQ(chan_freq)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530845 if (chan_bw == CH_WIDTH_80MHZ) {
846 hdd_err("BW80 not possible in 2.4GHz band");
847 return -EINVAL;
848 }
Tushnim Bhattacharyya6c40b112019-10-30 11:39:25 -0700849 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_freq == 2484) &&
850 (chan_bw != CH_WIDTH_MAX)) {
851 hdd_err("Only BW20 possible on channel freq 2484");
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530852 return -EINVAL;
853 }
854 }
855
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530856 return 0;
857}
858
wadesonga8940a22019-11-11 16:58:16 +0800859uint32_t hdd_get_adapter_home_channel(struct hdd_adapter *adapter)
Will Huang79af29f2019-04-11 15:46:26 +0800860{
wadesonga8940a22019-11-11 16:58:16 +0800861 uint32_t home_chan_freq = 0;
Jingxiang Gece7c5472019-07-23 16:19:23 +0800862 struct hdd_context *hdd_ctx;
863
864 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
865 if (!hdd_ctx) {
866 hdd_err("hdd context is NULL");
867 return 0;
868 }
Will Huang79af29f2019-04-11 15:46:26 +0800869
870 if ((adapter->device_mode == QDF_SAP_MODE ||
871 adapter->device_mode == QDF_P2P_GO_MODE) &&
872 test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
wadesonga8940a22019-11-11 16:58:16 +0800873 home_chan_freq = adapter->session.ap.operating_chan_freq;
Will Huang79af29f2019-04-11 15:46:26 +0800874 } else if ((adapter->device_mode == QDF_STA_MODE ||
875 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
876 adapter->session.station.conn_info.conn_state ==
877 eConnectionState_Associated) {
wadesonga8940a22019-11-11 16:58:16 +0800878 home_chan_freq = adapter->session.station.conn_info.chan_freq;
Will Huang79af29f2019-04-11 15:46:26 +0800879 }
880
wadesonga8940a22019-11-11 16:58:16 +0800881 return home_chan_freq;
Will Huang79af29f2019-04-11 15:46:26 +0800882}
883
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800884#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
Dustin Brown98f7c822019-03-06 12:25:49 -0800885static inline struct net_device *hdd_net_dev_from_notifier(void *context)
886{
887 struct netdev_notifier_info *info = context;
888
889 return info->dev;
890}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800891#else
Dustin Brown98f7c822019-03-06 12:25:49 -0800892static inline struct net_device *hdd_net_dev_from_notifier(void *context)
893{
894 return context;
895}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800896#endif
Dustin Brown98f7c822019-03-06 12:25:49 -0800897
898static int __hdd_netdev_notifier_call(struct net_device *net_dev,
899 unsigned long state)
900{
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530901 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700902 struct hdd_context *hdd_ctx;
Min Liu8c5d99e2018-09-10 17:18:44 +0800903 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800904
Dustin Brown98f7c822019-03-06 12:25:49 -0800905 hdd_enter_dev(net_dev);
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800906
Dustin Brown98f7c822019-03-06 12:25:49 -0800907 if (!net_dev->ieee80211_ptr) {
Dustin Brownaeb55642018-07-30 17:20:32 -0700908 hdd_debug("ieee80211_ptr is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800909 return NOTIFY_DONE;
910 }
911
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530912 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
913 if (!hdd_ctx) {
914 hdd_err("HDD Context is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800915 return NOTIFY_DONE;
916 }
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800917
918 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -0700919 hdd_debug("%s: Driver module is closed", __func__);
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800920 return NOTIFY_DONE;
921 }
922
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530923 /* Make sure that this callback corresponds to our device. */
Dustin Brown98f7c822019-03-06 12:25:49 -0800924 adapter = hdd_get_adapter_by_iface_name(hdd_ctx, net_dev->name);
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530925 if (!adapter) {
Dustin Brown98f7c822019-03-06 12:25:49 -0800926 hdd_debug("failed to look up adapter for '%s'", net_dev->name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800927 return NOTIFY_DONE;
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530928 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800929
Dustin Brown98f7c822019-03-06 12:25:49 -0800930 if (adapter != WLAN_HDD_GET_PRIV_PTR(net_dev)) {
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530931 hdd_err("HDD adapter mismatch!");
932 return NOTIFY_DONE;
933 }
934
Dustin Brownaeb55642018-07-30 17:20:32 -0700935 if (cds_is_driver_recovering()) {
936 hdd_debug("Driver is recovering");
937 return NOTIFY_DONE;
938 }
939
940 if (cds_is_driver_in_bad_state()) {
941 hdd_debug("Driver is in failed recovery state");
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530942 return NOTIFY_DONE;
943 }
944
Dustin Brown98f7c822019-03-06 12:25:49 -0800945 hdd_debug("%s New Net Device State = %lu", net_dev->name, state);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800946
947 switch (state) {
948 case NETDEV_REGISTER:
949 break;
950
951 case NETDEV_UNREGISTER:
952 break;
953
954 case NETDEV_UP:
Jeff Johnson16528362018-06-14 12:34:16 -0700955 sme_ch_avoid_update_req(hdd_ctx->mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800956 break;
957
958 case NETDEV_DOWN:
959 break;
960
961 case NETDEV_CHANGE:
Jeff Johnsonc72c5732017-10-28 12:49:37 -0700962 if (adapter->is_link_up_service_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800963 complete(&adapter->linkup_event_var);
964 break;
965
966 case NETDEV_GOING_DOWN:
Min Liu8c5d99e2018-09-10 17:18:44 +0800967 vdev = hdd_objmgr_get_vdev(adapter);
968 if (!vdev)
969 break;
970 if (ucfg_scan_get_vdev_status(vdev) !=
Sandeep Puligilla5f86d992017-10-29 14:58:53 -0700971 SCAN_NOT_IN_PROGRESS) {
Dustin Brown07901ec2018-09-07 11:02:41 -0700972 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
Jeff Johnson5a6fc962019-02-04 14:20:25 -0800973 adapter->vdev_id, INVALID_SCAN_ID,
Dustin Brown07901ec2018-09-07 11:02:41 -0700974 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800975 }
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +0530976 hdd_objmgr_put_vdev(vdev);
Min Liu9be5d4a2018-05-17 11:51:53 +0800977 cds_flush_work(&adapter->scan_block_work);
978 /* Need to clean up blocked scan request */
Dustin Brown96b98dd2019-03-06 12:39:37 -0800979 wlan_hdd_cfg80211_scan_block(adapter);
Min Liu9be5d4a2018-05-17 11:51:53 +0800980 hdd_debug("Scan is not Pending from user");
Arunk Khandavallif0c0d762017-12-07 10:18:50 +0530981 /*
982 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
983 * of return status of hdd_stop call, kernel resets the IFF_UP
984 * flag after which driver does not send the cfg80211_scan_done.
985 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN
986 */
Dustin Brown98f7c822019-03-06 12:25:49 -0800987 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, net_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800988 break;
989
990 default:
991 break;
992 }
993
994 return NOTIFY_DONE;
995}
996
997/**
998 * hdd_netdev_notifier_call() - netdev notifier callback function
999 * @nb: pointer to notifier block
1000 * @state: state
Dustin Brown98f7c822019-03-06 12:25:49 -08001001 * @context: notifier callback context pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001002 *
1003 * Return: 0 on success, error number otherwise.
1004 */
1005static int hdd_netdev_notifier_call(struct notifier_block *nb,
1006 unsigned long state,
Dustin Brown98f7c822019-03-06 12:25:49 -08001007 void *context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001008{
Dustin Brown98f7c822019-03-06 12:25:49 -08001009 struct net_device *net_dev = hdd_net_dev_from_notifier(context);
1010 struct osif_vdev_sync *vdev_sync;
1011 int errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001012
Dustin Brown98f7c822019-03-06 12:25:49 -08001013 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
1014 if (errno)
Alan Chene1416982019-10-28 15:43:04 -07001015 return NOTIFY_DONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001016
Dustin Brown98f7c822019-03-06 12:25:49 -08001017 errno = __hdd_netdev_notifier_call(net_dev, state);
1018
1019 osif_vdev_sync_op_stop(vdev_sync);
1020
Alan Chene1416982019-10-28 15:43:04 -07001021 return NOTIFY_DONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001022}
1023
1024struct notifier_block hdd_netdev_notifier = {
1025 .notifier_call = hdd_netdev_notifier_call,
1026};
1027
1028/* variable to hold the insmod parameters */
1029static int con_mode;
Prashanth Bhatta05aaf012015-12-10 17:34:24 -08001030
Arunk Khandavalliba3d5582017-07-11 19:48:32 +05301031static int con_mode_ftm;
Nirav Shah6aeecf92019-02-13 14:05:03 +05301032int con_mode_epping;
Arunk Khandavalliba3d5582017-07-11 19:48:32 +05301033
Prashanth Bhatta05aaf012015-12-10 17:34:24 -08001034/* Variable to hold connection mode including module parameter con_mode */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001035static int curr_con_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001036
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301037/**
1038 * hdd_map_nl_chan_width() - Map NL channel width to internal representation
1039 * @ch_width: NL channel width
1040 *
1041 * Converts the NL channel width to the driver's internal representation
1042 *
1043 * Return: Converted channel width. In case of non matching NL channel width,
1044 * CH_WIDTH_MAX will be returned.
1045 */
Kiran Kumar Lokere13644672016-02-29 15:40:10 -08001046enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301047{
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001048 uint8_t fw_ch_bw;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001049
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001050 fw_ch_bw = wma_get_vht_ch_width();
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301051 switch (ch_width) {
1052 case NL80211_CHAN_WIDTH_20_NOHT:
1053 case NL80211_CHAN_WIDTH_20:
1054 return CH_WIDTH_20MHZ;
1055 case NL80211_CHAN_WIDTH_40:
1056 return CH_WIDTH_40MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301057 case NL80211_CHAN_WIDTH_80:
1058 return CH_WIDTH_80MHZ;
1059 case NL80211_CHAN_WIDTH_80P80:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001060 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
1061 return CH_WIDTH_80P80MHZ;
1062 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1063 return CH_WIDTH_160MHZ;
1064 else
1065 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301066 case NL80211_CHAN_WIDTH_160:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001067 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1068 return CH_WIDTH_160MHZ;
1069 else
1070 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301071 case NL80211_CHAN_WIDTH_5:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -08001072 return CH_WIDTH_5MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301073 case NL80211_CHAN_WIDTH_10:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -08001074 return CH_WIDTH_10MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301075 default:
1076 hdd_err("Invalid channel width %d, setting to default",
1077 ch_width);
Kiran Kumar Lokere13644672016-02-29 15:40:10 -08001078 return CH_WIDTH_INVALID;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301079 }
1080}
1081
Dustin Brown56377e12018-10-10 17:04:04 -07001082QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type,
1083 enum QDF_OPMODE *out_qdf_type)
1084{
1085 switch (nl_type) {
1086 case NL80211_IFTYPE_ADHOC:
1087 *out_qdf_type = QDF_IBSS_MODE;
1088 break;
1089 case NL80211_IFTYPE_AP:
1090 *out_qdf_type = QDF_SAP_MODE;
1091 break;
1092 case NL80211_IFTYPE_MONITOR:
1093 *out_qdf_type = QDF_MONITOR_MODE;
1094 break;
1095 case NL80211_IFTYPE_OCB:
1096 *out_qdf_type = QDF_OCB_MODE;
1097 break;
1098 case NL80211_IFTYPE_P2P_CLIENT:
1099 *out_qdf_type = QDF_P2P_CLIENT_MODE;
1100 break;
1101 case NL80211_IFTYPE_P2P_DEVICE:
1102 *out_qdf_type = QDF_P2P_DEVICE_MODE;
1103 break;
1104 case NL80211_IFTYPE_P2P_GO:
1105 *out_qdf_type = QDF_P2P_GO_MODE;
1106 break;
1107 case NL80211_IFTYPE_STATION:
1108 *out_qdf_type = QDF_STA_MODE;
1109 break;
1110 case NL80211_IFTYPE_WDS:
1111 *out_qdf_type = QDF_WDS_MODE;
1112 break;
1113 default:
1114 hdd_err("Invalid nl80211 interface type %d", nl_type);
1115 return QDF_STATUS_E_INVAL;
1116 }
1117
1118 return QDF_STATUS_SUCCESS;
1119}
1120
Jeff Johnson16528362018-06-14 12:34:16 -07001121uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel,
1122 uint8_t bw_offset)
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +05301123{
1124 uint8_t opclass = 0;
1125
Jeff Johnson16528362018-06-14 12:34:16 -07001126 sme_get_opclass(mac_handle, channel, bw_offset, &opclass);
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +05301127 return opclass;
1128}
1129
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001130/**
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301131 * hdd_qdf_trace_enable() - configure initial QDF Trace enable
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301132 * @module_id: Module whose trace level is being configured
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001133 * @bitmask: Bitmask of log levels to be enabled
1134 *
1135 * Called immediately after the cfg.ini is read in order to configure
1136 * the desired trace levels.
1137 *
1138 * Return: None
1139 */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301140int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001141{
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301142 QDF_TRACE_LEVEL level;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301143 int qdf_print_idx = -1;
1144 int status = -1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001145 /*
1146 * if the bitmask is the default value, then a bitmask was not
1147 * specified in cfg.ini, so leave the logging level alone (it
1148 * will remain at the "compiled in" default value)
1149 */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001150 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301151 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001152
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301153 qdf_print_idx = qdf_get_pidx();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001154
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301155 /* a mask was specified. start by disabling all logging */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301156 status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301157 QDF_TRACE_LEVEL_NONE, 0);
1158
1159 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301160 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001161 /* now cycle through the bitmask until all "set" bits are serviced */
Ashish Kumar Dhanotiya83f286b2017-09-15 19:52:58 +05301162 level = QDF_TRACE_LEVEL_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001163 while (0 != bitmask) {
1164 if (bitmask & 1) {
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301165 status = qdf_print_set_category_verbose(qdf_print_idx,
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301166 module_id, level, 1);
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301167 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301168 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001169 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001170
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001171 level++;
1172 bitmask >>= 1;
1173 }
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301174 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001175}
1176
Dustin Brownda351e32018-07-23 15:48:22 -07001177int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func)
Chris Guo1751acf2017-07-03 14:09:01 +08001178{
Dustin Brownda351e32018-07-23 15:48:22 -07001179 if (!hdd_ctx) {
1180 hdd_err("HDD context is null (via %s)", func);
1181 return -ENODEV;
1182 }
1183
1184 if (!hdd_ctx->config) {
1185 hdd_err("HDD config is null (via %s)", func);
Chris Guo1751acf2017-07-03 14:09:01 +08001186 return -ENODEV;
1187 }
1188
1189 if (cds_is_driver_recovering()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001190 hdd_debug("Recovery in progress (via %s); state:0x%x",
1191 func, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001192 return -EAGAIN;
1193 }
1194
Yue Ma9f275d92017-09-14 16:58:41 -07001195 if (cds_is_load_or_unload_in_progress()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001196 hdd_debug("Load/unload in progress (via %s); state:0x%x",
1197 func, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001198 return -EAGAIN;
Yue Ma9f275d92017-09-14 16:58:41 -07001199 }
Arun Khandavallia172c3e2016-08-26 17:33:13 +05301200
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301201 if (cds_is_driver_in_bad_state()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001202 hdd_debug("Driver in bad state (via %s); state:0x%x",
1203 func, cds_get_driver_state());
Sourav Mohapatra21b3c982018-04-03 17:33:03 +05301204 return -EAGAIN;
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301205 }
1206
Arunk Khandavalli2859fa12018-02-14 10:46:26 +05301207 if (cds_is_fw_down()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001208 hdd_debug("FW is down (via %s); state:0x%x",
1209 func, cds_get_driver_state());
Sourav Mohapatra21b3c982018-04-03 17:33:03 +05301210 return -EAGAIN;
Arunk Khandavalli2859fa12018-02-14 10:46:26 +05301211 }
1212
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001213 return 0;
1214}
1215
Dustin Browna8700cc2018-08-07 12:04:47 -07001216int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func)
Dustin Brownf13b8c32017-05-19 17:23:08 -07001217{
1218 if (!adapter) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001219 hdd_err("adapter is null (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001220 return -EINVAL;
1221 }
1222
1223 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001224 hdd_err("bad adapter magic (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001225 return -EINVAL;
1226 }
1227
1228 if (!adapter->dev) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001229 hdd_err("adapter net_device is null (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001230 return -EINVAL;
1231 }
1232
1233 if (!(adapter->dev->flags & IFF_UP)) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001234 hdd_debug_rl("adapter '%s' is not up (via %s)",
1235 adapter->dev->name, func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001236 return -EAGAIN;
1237 }
1238
Jeff Johnson7eb6e842019-02-23 14:33:34 -08001239 return __wlan_hdd_validate_vdev_id(adapter->vdev_id, func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001240}
1241
Jeff Johnson7eb6e842019-02-23 14:33:34 -08001242int __wlan_hdd_validate_vdev_id(uint8_t vdev_id, const char *func)
Dustin Brown63500612018-08-07 11:36:09 -07001243{
Srinivas Girigowdad8697d42019-03-08 15:34:39 -08001244 if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) {
Dustin Brown63500612018-08-07 11:36:09 -07001245 hdd_debug_rl("adapter is not up (via %s)", func);
1246 return -EINVAL;
1247 }
1248
Jeff Johnson7eb6e842019-02-23 14:33:34 -08001249 if (vdev_id >= WLAN_MAX_VDEVS) {
1250 hdd_err("bad vdev Id:%u (via %s)", vdev_id, func);
Dustin Brown63500612018-08-07 11:36:09 -07001251 return -EINVAL;
1252 }
1253
1254 return 0;
1255}
1256
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05301257QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr,
1258 const char *func)
1259{
1260 if (!mac_addr) {
1261 hdd_err("Received NULL mac address (via %s)", func);
1262 return QDF_STATUS_E_INVAL;
1263 }
1264
1265 if (qdf_is_macaddr_zero(mac_addr)) {
1266 hdd_err("MAC is all zero (via %s)", func);
1267 return QDF_STATUS_E_INVAL;
1268 }
1269
1270 if (qdf_is_macaddr_broadcast(mac_addr)) {
1271 hdd_err("MAC is Broadcast (via %s)", func);
1272 return QDF_STATUS_E_INVAL;
1273 }
1274
1275 if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) {
1276 hdd_err("MAC is Multicast (via %s)", func);
1277 return QDF_STATUS_E_INVAL;
1278 }
1279
1280 return QDF_STATUS_SUCCESS;
1281}
1282
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001283/**
Arun Khandavallica892f62017-05-26 14:25:50 +05301284 * wlan_hdd_validate_modules_state() - Check modules status
1285 * @hdd_ctx: HDD context pointer
1286 *
1287 * Check's the driver module's state and returns true if the
1288 * modules are enabled returns false if modules are closed.
1289 *
1290 * Return: True if modules are enabled or false.
1291 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001292bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx)
Arun Khandavallica892f62017-05-26 14:25:50 +05301293{
Arun Khandavallica892f62017-05-26 14:25:50 +05301294 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07001295 hdd_info("Modules not enabled, Present status: %d",
1296 hdd_ctx->driver_status);
Arun Khandavallica892f62017-05-26 14:25:50 +05301297 return false;
1298 }
Dustin Brownf688ea12019-03-19 17:02:32 -07001299
Arun Khandavallica892f62017-05-26 14:25:50 +05301300 return true;
1301}
1302
Abhishek Ambure68677462019-09-13 12:44:26 +05301303#ifdef QCA_IBSS_SUPPORT
Jeff Johnson9d295242017-08-29 14:39:48 -07001304QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001306 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001307
Jeff Johnsond36fa332019-03-18 13:42:25 -07001308 if (!hdd_ctx) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001309 hdd_err("HDD context is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301310 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001311 }
1312
Manikandan Mohan2bd09772018-11-28 18:27:32 -08001313 return ucfg_mlme_ibss_power_save_setup(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08001314 adapter->vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001315}
Abhishek Ambure68677462019-09-13 12:44:26 +05301316#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001317
Yue Macd359b72017-10-03 15:21:00 -07001318#ifdef FEATURE_RUNTIME_PM
1319/**
1320 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
1321 * @hdd_ctx: HDD context
1322 *
1323 * Return: None
1324 */
1325static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
1326{
1327 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1328
Yue Macd359b72017-10-03 15:21:00 -07001329 qdf_runtime_lock_init(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001330 qdf_runtime_lock_init(&ctx->connect);
Alan Chendf858ef2019-10-10 15:44:29 -07001331 qdf_runtime_lock_init(&ctx->user);
1332
1333 ctx->is_user_wakelock_acquired = false;
Yue Macd359b72017-10-03 15:21:00 -07001334
Dustin Brown07901ec2018-09-07 11:02:41 -07001335 wlan_scan_runtime_pm_init(hdd_ctx->pdev);
Yue Macd359b72017-10-03 15:21:00 -07001336}
1337
1338/**
1339 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
1340 * @hdd_ctx: HDD Context
1341 *
1342 * Return: None
1343 */
1344static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
1345{
1346 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1347
Alan Chendf858ef2019-10-10 15:44:29 -07001348 if (ctx->is_user_wakelock_acquired)
1349 qdf_runtime_pm_allow_suspend(&ctx->user);
1350
1351 qdf_runtime_lock_deinit(&ctx->user);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001352 qdf_runtime_lock_deinit(&ctx->connect);
Alan Chendf858ef2019-10-10 15:44:29 -07001353 qdf_runtime_lock_deinit(&ctx->dfs);
Yue Macd359b72017-10-03 15:21:00 -07001354
Dustin Brown07901ec2018-09-07 11:02:41 -07001355 wlan_scan_runtime_pm_deinit(hdd_ctx->pdev);
Yue Macd359b72017-10-03 15:21:00 -07001356}
1357
Yue Macd359b72017-10-03 15:21:00 -07001358#else /* FEATURE_RUNTIME_PM */
1359static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {}
1360static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {}
Yue Macd359b72017-10-03 15:21:00 -07001361#endif /* FEATURE_RUNTIME_PM */
1362
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001363#define INTF_MACADDR_MASK 0x7
1364
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301365void hdd_update_macaddr(struct hdd_context *hdd_ctx,
1366 struct qdf_mac_addr hw_macaddr, bool generate_mac_auto)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001367{
1368 int8_t i;
1369 uint8_t macaddr_b3, tmp_br3;
1370
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301371 /*
1372 * If "generate_mac_auto" is true, it indicates that all the
1373 * addresses are derived addresses, else the first addresses
1374 * is not derived address (It is provided by fw).
1375 */
1376 if (!generate_mac_auto) {
1377 qdf_mem_copy(hdd_ctx->provisioned_mac_addr[0].bytes,
1378 hw_macaddr.bytes, QDF_MAC_ADDR_SIZE);
1379 hdd_ctx->num_provisioned_addr++;
1380 hdd_info("hdd_ctx->provisioned_mac_addr[0]: "
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07001381 QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07001382 QDF_MAC_ADDR_ARRAY(hdd_ctx->
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301383 provisioned_mac_addr[0].bytes));
1384 } else {
1385 qdf_mem_copy(hdd_ctx->derived_mac_addr[0].bytes,
1386 hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301387 QDF_MAC_ADDR_SIZE);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301388 hdd_ctx->num_derived_addr++;
1389 hdd_info("hdd_ctx->derived_mac_addr[0]: "
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07001390 QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07001391 QDF_MAC_ADDR_ARRAY(hdd_ctx->derived_mac_addr[0].bytes));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301392 }
1393 for (i = hdd_ctx->num_derived_addr; i < (QDF_MAX_CONCURRENCY_PERSONA -
1394 hdd_ctx->num_provisioned_addr);
1395 i++) {
1396 qdf_mem_copy(hdd_ctx->derived_mac_addr[i].bytes,
1397 hw_macaddr.bytes,
1398 QDF_MAC_ADDR_SIZE);
1399 macaddr_b3 = hdd_ctx->derived_mac_addr[i].bytes[3];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001400 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
1401 INTF_MACADDR_MASK;
1402 macaddr_b3 += tmp_br3;
1403
1404 /* XOR-ing bit-24 of the mac address. This will give enough
1405 * mac address range before collision
1406 */
1407 macaddr_b3 ^= (1 << 7);
1408
1409 /* Set locally administered bit */
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301410 hdd_ctx->derived_mac_addr[i].bytes[0] |= 0x02;
1411 hdd_ctx->derived_mac_addr[i].bytes[3] = macaddr_b3;
1412 hdd_info("hdd_ctx->derived_mac_addr[%d]: "
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07001413 QDF_MAC_ADDR_STR, i,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07001414 QDF_MAC_ADDR_ARRAY(hdd_ctx->derived_mac_addr[i].bytes));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301415 hdd_ctx->num_derived_addr++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001416 }
1417}
1418
Jeff Johnson2de58792019-02-08 07:49:17 -08001419#ifdef FEATURE_WLAN_TDLS
Kabilan Kannan44a58372017-12-06 18:16:11 -08001420static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1421{
Dustin Brown1dbefe62018-09-11 16:32:03 -07001422 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001423 struct tdls_start_params tdls_cfg;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001424 QDF_STATUS status;
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301425 struct wlan_mlme_nss_chains vdev_ini_cfg;
1426
1427 /* Populate the nss chain params from ini for this vdev type */
1428 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
1429 QDF_TDLS_MODE,
1430 hdd_ctx->num_rf_chains);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001431
Dustin Brown1dbefe62018-09-11 16:32:03 -07001432 cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301433 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]);
Dustin Brown1dbefe62018-09-11 16:32:03 -07001434 cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301435 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]);
jiad7b8a5e02018-11-26 16:37:57 +08001436 hdd_init_tdls_config(&tdls_cfg);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001437 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
1438 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
1439 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
1440 tdls_cfg.tdls_evt_cb_data = psoc;
Jeff Johnson1d40f5b2018-03-02 08:35:53 -08001441 tdls_cfg.tdls_peer_context = hdd_ctx;
1442 tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer;
1443 tdls_cfg.tdls_dereg_peer = hdd_tdls_deregister_peer;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001444 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
1445 tdls_cfg.tdls_wmm_cb_data = psoc;
1446 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
1447 tdls_cfg.tdls_rx_cb_data = psoc;
1448 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
Arun Kumar Khandavalli43fdd252019-04-24 18:34:18 +05301449 tdls_cfg.tdls_osif_init_cb = wlan_cfg80211_tdls_osif_priv_init;
1450 tdls_cfg.tdls_osif_deinit_cb = wlan_cfg80211_tdls_osif_priv_deinit;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001451
1452 status = ucfg_tdls_update_config(psoc, &tdls_cfg);
1453 if (status != QDF_STATUS_SUCCESS) {
1454 hdd_err("failed pmo psoc configuration");
1455 return -EINVAL;
1456 }
1457
1458 hdd_ctx->tdls_umac_comp_active = true;
1459 /* enable napier specific tdls data path */
1460 hdd_ctx->tdls_nap_active = true;
1461
1462 return 0;
1463}
Jeff Johnson74c6bb22019-02-15 10:15:07 -08001464#else
1465static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1466{
1467 return 0;
1468}
1469#endif
Kabilan Kannan44a58372017-12-06 18:16:11 -08001470
Wu Gaoca416ff2018-09-17 11:05:07 +08001471#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1472static void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1473 struct wma_tgt_services *cfg)
1474{
1475 bool roam_offload_enable;
1476
Dustin Brown1dbefe62018-09-11 16:32:03 -07001477 ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable);
1478 ucfg_mlme_set_roaming_offload(hdd_ctx->psoc,
Wu Gaoca416ff2018-09-17 11:05:07 +08001479 roam_offload_enable &
1480 cfg->en_roam_offload);
1481}
1482#else
1483static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1484 struct wma_tgt_services *cfg)
1485{
1486}
1487#endif
1488
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001489static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001490 struct wma_tgt_services *cfg)
1491{
1492 struct hdd_config *config = hdd_ctx->config;
Wu Gao66454f12018-09-26 19:55:41 +08001493 bool arp_offload_enable;
Wu Gao1ab05582018-11-08 16:22:49 +08001494 bool mawc_enabled;
Wu Gaobdb7f272018-07-05 19:33:26 +08001495#ifdef FEATURE_WLAN_TDLS
1496 bool tdls_support;
1497 bool tdls_off_channel;
1498 bool tdls_buffer_sta;
1499 uint32_t tdls_uapsd_mask;
1500#endif
Will Huangb9cb1242019-04-02 14:52:17 +08001501 bool get_peer_info_enable;
jiad7b8a5e02018-11-26 16:37:57 +08001502
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001503 /* Set up UAPSD */
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05301504 ucfg_mlme_set_sap_uapsd_flag(hdd_ctx->psoc, cfg->uapsd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001505
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08001506 /* 11AX mode support */
1507 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
1508 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
1509 config->dot11Mode = eHDD_DOT11_MODE_11ac;
1510
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001511 /* 11AC mode support */
1512 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
1513 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
1514 config->dot11Mode = eHDD_DOT11_MODE_AUTO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001515
1516 /* ARP offload: override user setting if invalid */
Wu Gao66454f12018-09-26 19:55:41 +08001517 arp_offload_enable =
1518 ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc);
1519 ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc,
1520 arp_offload_enable & cfg->arp_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001521#ifdef FEATURE_WLAN_SCAN_PNO
1522 /* PNO offload */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001523 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001524 if (cfg->pno_offload)
Pragaspathi Thilagaraj24789d32018-12-10 22:28:03 +05301525 ucfg_scan_set_pno_offload(hdd_ctx->psoc, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001526#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001527#ifdef FEATURE_WLAN_TDLS
Dustin Brown1dbefe62018-09-11 16:32:03 -07001528 cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support);
1529 cfg_tdls_set_support_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001530 tdls_support & cfg->en_tdls);
1531
Dustin Brown1dbefe62018-09-11 16:32:03 -07001532 cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel);
1533 cfg_tdls_set_off_channel_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001534 tdls_off_channel &&
1535 cfg->en_tdls_offchan);
1536
Dustin Brown1dbefe62018-09-11 16:32:03 -07001537 cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta);
1538 cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001539 tdls_buffer_sta &&
1540 cfg->en_tdls_uapsd_buf_sta);
1541
Dustin Brown1dbefe62018-09-11 16:32:03 -07001542 cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask);
Wu Gaobdb7f272018-07-05 19:33:26 +08001543 if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta)
Dustin Brown1dbefe62018-09-11 16:32:03 -07001544 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001545 else
Dustin Brown1dbefe62018-09-11 16:32:03 -07001546 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001547#endif
Wu Gaoca416ff2018-09-17 11:05:07 +08001548 hdd_update_roam_offload(hdd_ctx, cfg);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05301549
Will Huangb9cb1242019-04-02 14:52:17 +08001550 if (ucfg_mlme_get_sap_get_peer_info(
1551 hdd_ctx->psoc, &get_peer_info_enable) == QDF_STATUS_SUCCESS) {
1552 get_peer_info_enable &= cfg->get_peer_info_enabled;
1553 ucfg_mlme_set_sap_get_peer_info(hdd_ctx->psoc,
1554 get_peer_info_enable);
1555 }
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05301556
Wu Gao1ab05582018-11-08 16:22:49 +08001557 ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled);
1558 ucfg_mlme_set_mawc_enabled(hdd_ctx->psoc,
1559 mawc_enabled & cfg->is_fw_mawc_capable);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001560 hdd_update_tdls_config(hdd_ctx);
Jeff Johnson16528362018-06-14 12:34:16 -07001561 sme_update_tgt_services(hdd_ctx->mac_handle, cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001562}
1563
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001564/**
1565 * hdd_update_vdev_nss() - sets the vdev nss
1566 * @hdd_ctx: HDD context
1567 *
1568 * Sets the Nss per vdev type based on INI
1569 *
1570 * Return: None
1571 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001572static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx)
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001573{
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001574 uint8_t max_supp_nss = 1;
Jeff Johnson16528362018-06-14 12:34:16 -07001575 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301576 QDF_STATUS status;
1577 bool bval;
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001578
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301579 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
1580 if (!QDF_IS_STATUS_SUCCESS(status))
1581 hdd_err("unable to get vht_enable2x2");
1582
1583 if (bval && !cds_is_sub_20_mhz_enabled())
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001584 max_supp_nss = 2;
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301585
1586 hdd_debug("max nss %d", max_supp_nss);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001587
Jeff Johnson16528362018-06-14 12:34:16 -07001588 mac_handle = hdd_ctx->mac_handle;
1589 sme_update_vdev_type_nss(mac_handle, max_supp_nss,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301590 NSS_CHAINS_BAND_2GHZ);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001591
Jeff Johnson16528362018-06-14 12:34:16 -07001592 sme_update_vdev_type_nss(mac_handle, max_supp_nss,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301593 NSS_CHAINS_BAND_5GHZ);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001594}
1595
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301596/**
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301597 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
1598 * @hdd_ctx: HDD context
1599 *
1600 * Updates wiphy vhtcap fields
1601 *
1602 * Return: None
1603 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001604static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx)
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301605{
1606 struct ieee80211_supported_band *band_5g =
1607 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301608 QDF_STATUS status;
1609 uint8_t value = 0, value1 = 0;
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301610
1611 if (!band_5g) {
1612 hdd_debug("5GHz band disabled, skipping capability population");
1613 return;
1614 }
1615
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301616 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
1617 &value);
1618 if (!QDF_IS_STATUS_SUCCESS(status))
1619 hdd_err("unable to get tx_bfee_ant_supp");
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301620
Abhinav Kumare057b412018-10-09 17:28:16 +05301621 band_5g->vht_cap.cap |=
1622 (value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301623
1624 value1 = NUM_OF_SOUNDING_DIMENSIONS;
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301625 band_5g->vht_cap.cap |=
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301626 (value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301627
Dustin Brown7e761c72018-07-31 13:50:17 -07001628 hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301629 band_5g->vht_cap.cap, value, value1);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301630}
1631
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001632static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001633 struct wma_tgt_ht_cap *cfg)
1634{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301635 QDF_STATUS status;
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301636 qdf_size_t value_len;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301637 uint32_t value;
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301638 uint8_t mpdu_density;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301639 struct mlme_ht_capabilities_info ht_cap_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001640 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301641 bool b_enable1x1;
Jeff Johnson16528362018-06-14 12:34:16 -07001642
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001643 /* get the MPDU density */
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301644 status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density);
1645 if (QDF_IS_STATUS_ERROR(status)) {
1646 hdd_err("could not get HT MPDU Density");
1647 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001648 }
1649
1650 /*
1651 * MPDU density:
1652 * override user's setting if value is larger
1653 * than the one supported by target
1654 */
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301655 if (mpdu_density > cfg->mpdu_density) {
1656 status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc,
1657 cfg->mpdu_density);
1658 if (QDF_IS_STATUS_ERROR(status))
1659 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001660 }
1661
1662 /* get the HT capability info */
Dustin Brown1dbefe62018-09-11 16:32:03 -07001663 status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301664 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001665 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001666 return;
1667 }
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301668
1669 /* check and update RX STBC */
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301670 if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc)
1671 ht_cap_info.rx_stbc = cfg->ht_rx_stbc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001672
1673 /* Set the LDPC capability */
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301674 ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001675
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301676 if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20)
1677 ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001678
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301679 if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40)
1680 ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001681
1682 hdd_ctx->num_rf_chains = cfg->num_rf_chains;
1683 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
1684
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301685 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1);
1686 if (!QDF_IS_STATUS_SUCCESS(status))
1687 hdd_err("unable to get vht_enable2x2");
1688
1689 b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2);
1690
1691 status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1);
1692 if (!QDF_IS_STATUS_SUCCESS(status))
1693 hdd_err("unable to set vht_enable2x2");
1694
Abhinav Kumare057b412018-10-09 17:28:16 +05301695 if (!b_enable1x1) {
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301696 ht_cap_info.tx_stbc = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001697
1698 /* 1x1 */
1699 /* Update Rx Highest Long GI data Rate */
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301700 status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(
1701 hdd_ctx->psoc,
1702 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1);
1703 if (!QDF_IS_STATUS_SUCCESS(status))
1704 hdd_err("Failed to set rx_supp_data_rate");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001705 /* Update Tx Highest Long GI data Rate */
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301706 status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(
1707 hdd_ctx->psoc,
1708 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1);
1709 if (!QDF_IS_STATUS_SUCCESS(status))
1710 hdd_err("Failed to set tx_supp_data_rate");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001711 }
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301712 if (!(cfg->ht_tx_stbc && b_enable1x1))
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301713 ht_cap_info.tx_stbc = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001714
Dustin Brown1dbefe62018-09-11 16:32:03 -07001715 status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301716 if (status != QDF_STATUS_SUCCESS)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001717 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001718#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301719 value_len = SIZE_OF_SUPPORTED_MCS_SET;
1720 if (ucfg_mlme_get_supported_mcs_set(
1721 hdd_ctx->psoc, mcs_set,
1722 &value_len) == QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001723 hdd_debug("Read MCS rate set");
gaurank kathpalia18b49362018-04-15 23:12:03 +05301724 if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET)
1725 cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301726
1727 if (b_enable1x1) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001728 for (value = 0; value < cfg->num_rf_chains; value++)
1729 mcs_set[value] =
1730 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
1731
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301732 status = ucfg_mlme_set_supported_mcs_set(
1733 hdd_ctx->psoc,
1734 mcs_set,
1735 (qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET);
1736 if (QDF_IS_STATUS_ERROR(status))
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001737 hdd_err("could not set MCS SET to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001738 }
1739 }
1740#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
1741}
1742
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001743static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001744 struct wma_tgt_vht_cap *cfg)
1745{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301746 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001747 struct wiphy *wiphy = hdd_ctx->wiphy;
1748 struct ieee80211_supported_band *band_5g =
Srinivas Girigowda11c28e02017-06-27 20:06:21 -07001749 wiphy->bands[HDD_NL80211_BAND_5GHZ];
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001750 uint32_t ch_width;
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001751 struct wma_caps_per_phy caps_per_phy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001752
Dustin Brown5e06bd32016-10-04 12:49:10 -07001753 if (!band_5g) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001754 hdd_debug("5GHz band disabled, skipping capability population");
Dustin Brown5e06bd32016-10-04 12:49:10 -07001755 return;
1756 }
1757
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301758 status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg);
1759 if (QDF_IS_STATUS_ERROR(status))
1760 hdd_err("could not update vht capabilities");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001761
1762 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
1763 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1764 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
1765 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1766 else
1767 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1768
1769
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001770 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001771 band_5g->vht_cap.cap |=
1772 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001773 ch_width = VHT_CAP_160_AND_80P80_SUPP;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001774 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001775 band_5g->vht_cap.cap |=
1776 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001777 ch_width = VHT_CAP_160_SUPP;
1778 } else {
1779 ch_width = VHT_CAP_NO_160M_SUPP;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001780 }
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001781
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001782 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, ch_width);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301783 if (QDF_IS_STATUS_ERROR(status))
1784 hdd_err("could not set the channel width");
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001785 else
1786 hdd_debug("supported channel width %d", ch_width);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001787
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001788 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001789 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001790 hdd_debug("VHT RxLDPC capability is set");
1791 } else {
1792 /*
1793 * Get the RX LDPC capability for the NON DBS
1794 * hardware mode for 5G band
1795 */
1796 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
1797 HW_MODE_DBS_NONE, CDS_BAND_5GHZ);
1798 if ((QDF_IS_STATUS_SUCCESS(status)) &&
1799 (caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) {
1800 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
1801 hdd_debug("VHT RX LDPC capability is set");
1802 }
1803 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001804
1805 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
1806 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1807 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
1808 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1809
1810 if (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)
1811 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
1812
1813 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
1814 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1815 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)
1816 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
1817 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
1818 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
1819
1820 band_5g->vht_cap.cap |=
1821 (cfg->vht_max_ampdu_len_exp <<
1822 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
1823
1824 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
1825 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1826 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
1827 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1828 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
1829 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1830 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
1831 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1832
1833 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
1834 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1835
1836}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001837
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001838/**
1839 * hdd_generate_macaddr_auto() - Auto-generate mac address
1840 * @hdd_ctx: Pointer to the HDD context
1841 *
1842 * Auto-generate mac address using device serial number.
1843 * Keep the first 3 bytes of OUI as before and replace
1844 * the last 3 bytes with the lower 3 bytes of serial number.
1845 *
1846 * Return: 0 for success
1847 * Non zero failure code for errors
1848 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001849static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx)
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001850{
1851 unsigned int serialno = 0;
1852 struct qdf_mac_addr mac_addr = {
1853 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
1854 };
1855
Yuanyuan Liuf97e8222016-09-21 10:31:38 -07001856 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001857 if (serialno == 0)
1858 return -EINVAL;
1859
1860 serialno &= 0x00ffffff;
1861
1862 mac_addr.bytes[3] = (serialno >> 16) & 0xff;
1863 mac_addr.bytes[4] = (serialno >> 8) & 0xff;
1864 mac_addr.bytes[5] = serialno & 0xff;
1865
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301866 hdd_update_macaddr(hdd_ctx, mac_addr, true);
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001867 return 0;
1868}
1869
Jeff Johnsonf9176382018-07-17 19:15:58 -07001870static void hdd_sar_target_config(struct hdd_context *hdd_ctx,
1871 struct wma_tgt_cfg *cfg)
1872{
1873 hdd_ctx->sar_version = cfg->sar_version;
1874}
1875
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001876static void hdd_update_vhtcap_2g(struct hdd_context *hdd_ctx)
1877{
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001878 uint32_t chip_mode = 0;
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001879 QDF_STATUS status;
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001880 bool b2g_vht_cfg = false;
1881 bool b2g_vht_target = false;
1882 struct wma_caps_per_phy caps_per_phy;
1883 struct wmi_unified *wmi_handle;
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001884
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001885 wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc);
1886 if (!wmi_handle) {
1887 hdd_err("wmi handle is NULL");
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001888 return;
1889 }
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001890
1891 status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &b2g_vht_cfg);
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001892 if (QDF_IS_STATUS_ERROR(status)) {
1893 hdd_err("Failed to get 2g vht mode");
1894 return;
1895 }
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001896 if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) {
1897 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
1898 HW_MODE_DBS_NONE,
Liangwei Dong4547b892019-11-20 15:00:23 +08001899 CDS_BAND_2GHZ);
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001900 if (QDF_IS_STATUS_ERROR(status)) {
1901 hdd_err("Failed to get phy caps");
1902 return;
1903 }
1904 if (caps_per_phy.vht_2g)
1905 b2g_vht_target = true;
1906 } else {
1907 status = wlan_reg_get_chip_mode(hdd_ctx->pdev, &chip_mode);
1908 if (QDF_IS_STATUS_ERROR(status)) {
1909 hdd_err("Failed to get chip mode");
1910 return;
1911 }
1912 b2g_vht_target =
1913 (chip_mode & WMI_HOST_REGDMN_MODE_11AC_VHT20_2G) ?
1914 true : false;
1915 }
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001916
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001917 b2g_vht_cfg = b2g_vht_cfg && b2g_vht_target;
1918 hdd_debug("vht 2g target: %d, cfg: %d", b2g_vht_target, b2g_vht_cfg);
1919 status = ucfg_mlme_set_vht_for_24ghz(hdd_ctx->psoc, b2g_vht_cfg);
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001920 if (QDF_IS_STATUS_ERROR(status)) {
1921 hdd_err("Failed to update 2g vht mode");
1922 return;
1923 }
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001924}
1925
Ashish Kumar Dhanotiyaeadb28b2019-06-28 14:34:19 +05301926static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx)
1927{
1928 hdd_ctx->fw_version_info.major_spid =
1929 HDD_FW_VER_MAJOR_SPID(hdd_ctx->target_fw_version);
1930 hdd_ctx->fw_version_info.minor_spid =
1931 HDD_FW_VER_MINOR_SPID(hdd_ctx->target_fw_version);
1932 hdd_ctx->fw_version_info.siid =
1933 HDD_FW_VER_SIID(hdd_ctx->target_fw_version);
1934 hdd_ctx->fw_version_info.crmid =
1935 HDD_FW_VER_CRM_ID(hdd_ctx->target_fw_version);
1936 hdd_ctx->fw_version_info.sub_id =
1937 HDD_FW_VER_SUB_ID(hdd_ctx->target_fw_vers_ext);
1938 hdd_ctx->fw_version_info.rel_id =
1939 HDD_FW_VER_REL_ID(hdd_ctx->target_fw_vers_ext);
1940}
1941
gaurank kathpaliaccfca4a2019-08-13 11:51:27 +05301942#if defined(WLAN_FEATURE_11AX) && \
1943 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
1944static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx)
1945{
1946 tDot11fIEhe_cap he_cap_cfg;
1947 struct ieee80211_supported_band *band_2g =
1948 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ];
1949 struct ieee80211_supported_band *band_5g =
1950 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ];
1951 QDF_STATUS status;
1952
1953 status = ucfg_mlme_cfg_get_he_caps(hdd_ctx->psoc, &he_cap_cfg);
1954
1955 if (QDF_IS_STATUS_ERROR(status))
1956 return;
1957
1958 if (band_2g) {
1959 hdd_ctx->iftype_data_2g->types_mask =
1960 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
1961 hdd_ctx->iftype_data_2g->he_cap.has_he = he_cap_cfg.present;
1962 band_2g->n_iftype_data = 1;
1963 band_2g->iftype_data = hdd_ctx->iftype_data_2g;
1964 }
1965 if (band_5g) {
1966 hdd_ctx->iftype_data_5g->types_mask =
1967 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
1968 hdd_ctx->iftype_data_5g->he_cap.has_he = he_cap_cfg.present;
1969 band_5g->n_iftype_data = 1;
1970 band_5g->iftype_data = hdd_ctx->iftype_data_5g;
1971 }
1972}
1973#else
1974static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx)
1975{
1976}
1977#endif
1978
Ashish Kumar Dhanotiyab0355702019-09-19 18:06:30 +05301979static void hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev)
1980{
1981 ucfg_mlme_cfg_chan_to_freq(pdev);
1982}
1983
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05301984int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001985{
Rajeev Kumarf49dfdb2017-01-13 15:40:35 -08001986 int ret;
Jeff Johnsonea70b942018-07-02 09:42:31 -07001987 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301988 uint8_t temp_band_cap, band_capability;
Naveen Rawat64e477e2016-05-20 10:34:56 -07001989 struct cds_config_info *cds_cfg = cds_get_ini_config();
Nitesh Shahe50711f2017-04-26 16:30:45 +05301990 uint8_t antenna_mode;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301991 uint8_t sub_20_chan_width;
Arif Hussainee10f902017-12-27 16:30:17 -08001992 QDF_STATUS status;
Jeff Johnson16528362018-06-14 12:34:16 -07001993 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301994 bool bval = false;
1995 uint8_t value = 0;
Arif Hussainbd5194c2018-11-27 19:01:15 -08001996 uint32_t fine_time_meas_cap = 0;
gaurank kathpaliafa7ad0a2019-03-12 19:17:56 +05301997 enum nss_chains_band_info band;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301998
gaurank kathpalia843f7c32018-07-02 18:04:14 +05301999 if (!hdd_ctx) {
2000 hdd_err("HDD context is NULL");
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302001 return -EINVAL;
gaurank kathpalia843f7c32018-07-02 18:04:14 +05302002 }
Dustin Brownbd68fe12017-11-21 15:28:52 -08002003 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
2004 if (ret) {
Dustin Brown64204d22018-08-15 16:35:19 -07002005 QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret);
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302006 return -EINVAL;
Dustin Brown64204d22018-08-15 16:35:19 -07002007 }
2008
2009 hdd_debug("New pdev has been created with pdev_id = %u",
Dustin Brown07901ec2018-09-07 11:02:41 -07002010 hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id);
Dustin Brown64204d22018-08-15 16:35:19 -07002011
Dustin Brown07901ec2018-09-07 11:02:41 -07002012 status = dispatcher_pdev_open(hdd_ctx->pdev);
Dustin Brown64204d22018-08-15 16:35:19 -07002013 if (QDF_IS_STATUS_ERROR(status)) {
2014 QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d",
2015 status);
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302016 ret = qdf_status_to_os_return(status);
2017 goto exit;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302018 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002019
Sandeep Puligillab7beb472018-08-13 22:54:20 -07002020 status = hdd_component_pdev_open(hdd_ctx->pdev);
2021 if (QDF_IS_STATUS_ERROR(status)) {
2022 QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d",
2023 status);
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302024 ret = qdf_status_to_os_return(status);
2025 goto dispatcher_close;
Sandeep Puligillab7beb472018-08-13 22:54:20 -07002026 }
Ashish Kumar Dhanotiyab0355702019-09-19 18:06:30 +05302027 /*
2028 * For 6GHz support this api is added to convert mlme cfgs
2029 * channel numbers to frequency
2030 */
2031 hdd_component_cfg_chan_to_freq(hdd_ctx->pdev);
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302032
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05302033 cdp_pdev_set_ctrl_pdev(cds_get_context(QDF_MODULE_ID_SOC),
2034 cds_get_context(QDF_MODULE_ID_TXRX),
Dustin Brown07901ec2018-09-07 11:02:41 -07002035 (struct cdp_ctrl_objmgr_pdev *)hdd_ctx->pdev);
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05302036
Dustin Brown07901ec2018-09-07 11:02:41 -07002037 wlan_pdev_set_dp_handle(hdd_ctx->pdev,
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05302038 cds_get_context(QDF_MODULE_ID_TXRX));
2039
Will Huang07244172018-05-14 14:23:30 +08002040 hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count);
2041
Dustin Brown1dbefe62018-09-11 16:32:03 -07002042 ucfg_ipa_set_dp_handle(hdd_ctx->psoc,
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05302043 cds_get_context(QDF_MODULE_ID_SOC));
Vevek Venkatesan29076ec2019-08-22 17:53:12 +05302044 ucfg_ipa_set_pdev_id(hdd_ctx->psoc, OL_TXRX_PDEV_ID);
Dustin Brown07901ec2018-09-07 11:02:41 -07002045 ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev,
Vevek Venkatesan78f7f092019-05-23 17:16:28 +05302046 hdd_softap_ipa_start_xmit);
Dustin Brown07901ec2018-09-07 11:02:41 -07002047 ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev,
Vevek Venkatesan3b6be822019-05-28 18:19:15 +05302048 hdd_ipa_send_nbuf_to_network);
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05302049
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05302050 status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
2051 &sub_20_chan_width);
2052 if (QDF_IS_STATUS_ERROR(status)) {
2053 hdd_err("Failed to get sub_20_chan_width config");
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302054 ret = qdf_status_to_os_return(status);
2055 goto pdev_close;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05302056 }
2057
Naveen Rawat64e477e2016-05-20 10:34:56 -07002058 if (cds_cfg) {
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05302059 if (sub_20_chan_width !=
2060 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
Naveen Rawat64e477e2016-05-20 10:34:56 -07002061 hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
2062 cds_cfg->sub_20_channel_width =
2063 WLAN_SUB_20_CH_WIDTH_NONE;
2064 } else {
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05302065 cds_cfg->sub_20_channel_width = sub_20_chan_width;
Naveen Rawat64e477e2016-05-20 10:34:56 -07002066 }
2067 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002068
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302069 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
2070 if (QDF_IS_STATUS_ERROR(status)) {
2071 hdd_err("Failed to get MLME band capability");
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302072 ret = qdf_status_to_os_return(status);
2073 goto pdev_close;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302074 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002075
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302076 /* first store the INI band capability */
2077 temp_band_cap = band_capability;
2078
2079 band_capability = cfg->band_cap;
Vignesh Viswanathan731186f2017-09-18 13:47:37 +05302080 hdd_ctx->is_fils_roaming_supported =
2081 cfg->services.is_fils_roaming_supported;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002082
Vignesh Viswanathan694e28e2018-01-18 20:53:57 +05302083 hdd_ctx->config->is_11k_offload_supported =
2084 cfg->services.is_11k_offload_supported;
2085
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08002086 /*
2087 * now overwrite the target band capability with INI
2088 * setting if INI setting is a subset
2089 */
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302090 if ((band_capability == BAND_ALL) &&
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002091 (temp_band_cap != BAND_ALL))
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302092 band_capability = temp_band_cap;
2093 else if ((band_capability != BAND_ALL) &&
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002094 (temp_band_cap != BAND_ALL) &&
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302095 (band_capability != temp_band_cap)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07002096 hdd_warn("ini BandCapability not supported by the target");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002097 }
2098
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302099 status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability);
2100 if (QDF_IS_STATUS_ERROR(status)) {
2101 hdd_err("Failed to set MLME Band Capability");
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302102 ret = qdf_status_to_os_return(status);
2103 goto pdev_close;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302104 }
2105
2106 hdd_ctx->curr_band = band_capability;
sheenam monga40e89f12019-10-14 16:24:26 +05302107 hdd_ctx->psoc->soc_nif.user_config.band_capability = hdd_ctx->curr_band;
Amar Singhal58b45ef2017-08-01 13:43:54 -07002108
Qun Zhang043635a2019-02-27 15:19:29 +08002109 status = wlan_hdd_update_wiphy_supported_band(hdd_ctx);
2110 if (QDF_IS_STATUS_ERROR(status)) {
2111 hdd_err("Failed to update wiphy band info");
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302112 goto pdev_close;
Qun Zhang043635a2019-02-27 15:19:29 +08002113 }
2114
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05302115 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002116 hdd_ctx->reg.reg_domain = cfg->reg_domain;
2117 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
2118 }
2119
2120 /* This can be extended to other configurations like ht, vht cap... */
2121
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05302122 if (!qdf_is_macaddr_zero(&cfg->hw_macaddr))
2123 qdf_mem_copy(&hdd_ctx->hw_macaddr, &cfg->hw_macaddr,
2124 QDF_MAC_ADDR_SIZE);
2125 else
2126 hdd_info("hw_mac is zero");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002127
2128 hdd_ctx->target_fw_version = cfg->target_fw_version;
Sandeep Puligilla3d6a8e22016-10-11 18:57:14 -07002129 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
Ashish Kumar Dhanotiyaeadb28b2019-06-28 14:34:19 +05302130 hdd_extract_fw_version_info(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002131
Ryan Hsuc6918552018-05-16 13:29:59 -07002132 hdd_ctx->hw_bd_id = cfg->hw_bd_id;
2133 qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info,
2134 sizeof(cfg->hw_bd_info));
2135
Dustin Brownad06be62019-02-04 14:52:56 -08002136 if (cfg->max_intf_count > WLAN_MAX_VDEVS) {
Dustin Brownbee82832018-07-23 10:10:51 -07002137 hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u",
Dustin Brownad06be62019-02-04 14:52:56 -08002138 cfg->max_intf_count, WLAN_MAX_VDEVS, WLAN_MAX_VDEVS);
2139 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS;
Dustin Brownbee82832018-07-23 10:10:51 -07002140 } else {
2141 hdd_ctx->max_intf_count = cfg->max_intf_count;
2142 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002143
Jeff Johnsonf9176382018-07-17 19:15:58 -07002144 hdd_sar_target_config(hdd_ctx, cfg);
Jeff Johnsonc875e242016-09-23 18:12:34 -07002145 hdd_lpass_target_config(hdd_ctx, cfg);
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08002146
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002147 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
Pragaspathi Thilagarajeb367282019-02-19 00:42:28 +05302148
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149 hdd_update_tgt_services(hdd_ctx, &cfg->services);
2150
2151 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
2152
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002153 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
Krishna Kumaar Natarajaned1efd92016-09-24 18:05:47 -07002154 if (cfg->services.en_11ax) {
2155 hdd_info("11AX: 11ax is enabled - update HDD config");
2156 hdd_update_tgt_he_cap(hdd_ctx, cfg);
gaurank kathpaliaccfca4a2019-08-13 11:51:27 +05302157 hdd_update_wiphy_he_cap(hdd_ctx);
Krishna Kumaar Natarajaned1efd92016-09-24 18:05:47 -07002158 }
Varun Reddy Yeturue93d2462018-05-22 13:54:52 -07002159 hdd_update_tgt_twt_cap(hdd_ctx, cfg);
Tushnim Bhattacharyyaf44a9d82016-07-05 10:52:06 -07002160
gaurank kathpaliafa7ad0a2019-03-12 19:17:56 +05302161 for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) {
2162 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2163 QDF_STA_MODE, band);
2164 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2165 QDF_SAP_MODE, band);
2166 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2167 QDF_TDLS_MODE, band);
2168 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2169 QDF_P2P_DEVICE_MODE,
2170 band);
2171 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2172 QDF_OCB_MODE, band);
2173 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2174 QDF_TDLS_MODE, band);
2175 }
2176
Tushnim Bhattacharyyaf44a9d82016-07-05 10:52:06 -07002177 hdd_update_vdev_nss(hdd_ctx);
2178
gaurank kathpalia5fcefa92018-10-24 15:03:15 +05302179 hdd_ctx->dynamic_nss_chains_support =
2180 cfg->dynamic_nss_chains_support;
Arif Hussainbd5194c2018-11-27 19:01:15 -08002181 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap);
2182 fine_time_meas_cap &= cfg->fine_time_measurement_cap;
2183 status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc,
2184 fine_time_meas_cap);
2185 if (QDF_IS_STATUS_ERROR(status)) {
2186 hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x",
2187 fine_time_meas_cap, cfg->fine_time_measurement_cap);
2188 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
2189 &fine_time_meas_cap);
2190 }
2191
Krunal Sonie3531942016-04-12 17:43:53 -07002192 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
Arif Hussainbd5194c2018-11-27 19:01:15 -08002193 hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap);
Archana Ramachandran393f3792015-11-13 17:13:21 -08002194
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302195 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
2196 if (!QDF_IS_STATUS_SUCCESS(status))
2197 hdd_err("unable to get vht_enable2x2");
2198
2199 antenna_mode = (bval == 0x01) ?
Nitesh Shahe50711f2017-04-26 16:30:45 +05302200 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
2201 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002202 hdd_debug("Init current antenna mode: %d",
Arif Hussainee10f902017-12-27 16:30:17 -08002203 hdd_ctx->current_antenna_mode);
Archana Ramachandran393f3792015-11-13 17:13:21 -08002204
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05302205 hdd_ctx->rcpi_enabled = cfg->rcpi_enabled;
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05302206
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302207 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
Abhinav Kumare057b412018-10-09 17:28:16 +05302208 &value);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302209 if (QDF_IS_STATUS_ERROR(status)) {
2210 status = false;
2211 hdd_err("set tx_bfee_ant_supp failed");
2212 }
2213
Pragaspathi Thilagaraj6fc0a9a2019-05-17 16:49:45 +05302214 if ((value > MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302215 !cfg->tx_bfee_8ss_enabled) {
Pragaspathi Thilagaraj6fc0a9a2019-05-17 16:49:45 +05302216 status = ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
2217 MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302218 if (QDF_IS_STATUS_ERROR(status)) {
2219 status = false;
2220 hdd_err("set tx_bfee_ant_supp failed");
2221 }
2222 }
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302223
Jeff Johnson16528362018-06-14 12:34:16 -07002224 mac_handle = hdd_ctx->mac_handle;
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302225
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302226 hdd_debug("txBFCsnValue %d", value);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05302227
2228 /*
2229 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
2230 */
2231 hdd_update_wiphy_vhtcap(hdd_ctx);
Manjeet Singh70d3d932016-12-20 20:41:10 +05302232
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08002233 hdd_update_vhtcap_2g(hdd_ctx);
2234
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05302235 hdd_ctx->wmi_max_len = cfg->wmi_max_len;
2236
Ashish Kumar Dhanotiya908925d2019-03-01 17:35:30 +05302237 wlan_config_sched_scan_plans_to_wiphy(hdd_ctx->wiphy, hdd_ctx->psoc);
Yue Macd359b72017-10-03 15:21:00 -07002238 /*
2239 * This needs to be done after HDD pdev is created and stored since
2240 * it will access the HDD pdev object lock.
2241 */
2242 hdd_runtime_suspend_context_init(hdd_ctx);
2243
Deepak Dhamdhere13230d32016-05-26 00:46:53 -07002244 /* Configure NAN datapath features */
2245 hdd_nan_datapath_target_config(hdd_ctx, cfg);
Nachiket Kukade85aa3782018-11-02 20:12:34 +05302246 ucfg_nan_set_tgt_caps(hdd_ctx->psoc, &cfg->nan_caps);
Arif Hussain759a0232017-03-20 13:17:18 -07002247 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08002248 hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share;
Liangwei Dong0da14262018-07-03 03:30:23 -04002249 hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload;
Wu Gao5f764082019-01-04 15:54:38 +08002250 status = ucfg_mlme_set_obss_detection_offload_enabled(
2251 hdd_ctx->psoc, cfg->obss_detection_offloaded);
Arif Hussainee10f902017-12-27 16:30:17 -08002252 if (QDF_IS_STATUS_ERROR(status))
2253 hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG");
Arif Hussain05fb4872018-01-03 16:02:55 -08002254
Wu Gao5f764082019-01-04 15:54:38 +08002255 status = ucfg_mlme_set_obss_color_collision_offload_enabled(
2256 hdd_ctx->psoc, cfg->obss_color_collision_offloaded);
Arif Hussain05fb4872018-01-03 16:02:55 -08002257 if (QDF_IS_STATUS_ERROR(status))
2258 hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD");
Arif Hussain50689082019-03-26 12:07:58 -07002259
2260 ucfg_mlme_get_bcast_twt(hdd_ctx->psoc, &bval);
2261 if (bval)
2262 ucfg_mlme_set_bcast_twt(hdd_ctx->psoc, cfg->bcast_twt_support);
2263 else
2264 hdd_debug("bcast twt is disable in ini, fw cap %d",
2265 cfg->bcast_twt_support);
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302266 return 0;
2267
2268dispatcher_close:
2269 dispatcher_pdev_close(hdd_ctx->pdev);
2270pdev_close:
2271 hdd_component_pdev_close(hdd_ctx->pdev);
2272exit:
2273 hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
2274
2275 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002276}
2277
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002278bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002279{
Jeff Johnson9d295242017-08-29 14:39:48 -07002280 struct hdd_adapter *adapter;
Jeff Johnson87251032017-08-29 13:31:11 -07002281 struct hdd_ap_ctx *ap_ctx;
Arif Hussain224d3812018-11-16 17:58:38 -08002282 bool dfs_disable_channel_switch = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002283
Jiachao Wuf610d912018-01-23 17:47:32 +08002284 if (!hdd_ctx) {
2285 hdd_info("Couldn't get hdd_ctx");
2286 return true;
2287 }
2288
Arif Hussain224d3812018-11-16 17:58:38 -08002289 ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc,
2290 &dfs_disable_channel_switch);
2291 if (dfs_disable_channel_switch) {
Jeff Johnson36e74c42017-09-18 08:15:42 -07002292 hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d",
Arif Hussain224d3812018-11-16 17:58:38 -08002293 hdd_ctx, dfs_disable_channel_switch);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302294 return true;
Arif Hussaincd151632017-02-11 16:57:19 -08002295 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002296
Dustin Brown920397d2017-12-13 16:27:50 -08002297 hdd_for_each_adapter(hdd_ctx, adapter) {
Arif Hussaincd151632017-02-11 16:57:19 -08002298 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
2299
2300 if ((QDF_SAP_MODE == adapter->device_mode ||
2301 QDF_P2P_GO_MODE == adapter->device_mode) &&
Will Huang4b097f52019-08-29 10:51:56 -07002302 (wlan_reg_is_passive_or_disable_for_freq(hdd_ctx->pdev,
2303 ap_ctx->operating_chan_freq))) {
Arif Hussaincd151632017-02-11 16:57:19 -08002304 WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx =
2305 true;
Jeff Johnson7eb6e842019-02-23 14:33:34 -08002306 hdd_info("tx blocked for vdev: %d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -08002307 adapter->vdev_id);
bings6fb9bf62018-07-05 14:01:53 +08002308 if (adapter->txrx_vdev)
2309 cdp_fc_vdev_flush(
2310 cds_get_context(QDF_MODULE_ID_SOC),
Rakesh Pillaif94b1622019-11-07 19:54:01 +05302311 adapter->vdev_id);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302312 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002313 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302314
2315 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002316}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002317
Jeff Johnson030cd902018-11-11 10:19:40 -08002318bool hdd_is_valid_mac_address(const uint8_t *mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002319{
2320 int xdigit = 0;
2321 int separator = 0;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002322
Jeff Johnson030cd902018-11-11 10:19:40 -08002323 while (*mac_addr) {
2324 if (isxdigit(*mac_addr)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002325 xdigit++;
Jeff Johnson030cd902018-11-11 10:19:40 -08002326 } else if (':' == *mac_addr) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002327 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
2328 break;
2329
2330 ++separator;
2331 } else {
2332 /* Invalid MAC found */
Jeff Johnson030cd902018-11-11 10:19:40 -08002333 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002334 }
Jeff Johnson030cd902018-11-11 10:19:40 -08002335 ++mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002336 }
2337 return xdigit == 12 && (separator == 5 || separator == 0);
2338}
2339
2340/**
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302341 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
2342 * @dev: Handle to struct net_device to be updated.
2343 *
2344 * Return: None
2345 */
2346static void hdd_mon_mode_ether_setup(struct net_device *dev)
2347{
2348 dev->header_ops = NULL;
2349 dev->type = ARPHRD_IEEE80211_RADIOTAP;
2350 dev->hard_header_len = ETH_HLEN;
2351 dev->mtu = ETH_DATA_LEN;
2352 dev->addr_len = ETH_ALEN;
2353 dev->tx_queue_len = 1000; /* Ethernet wants good queues */
2354 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
2355 dev->priv_flags |= IFF_TX_SKB_SHARING;
2356
2357 memset(dev->broadcast, 0xFF, ETH_ALEN);
2358}
2359
Nirav Shah73713f72018-05-17 14:50:41 +05302360#ifdef FEATURE_MONITOR_MODE_SUPPORT
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302361/**
chenguo71303962018-10-24 19:44:34 +08002362 * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device.
2363 * @hdd_ctx: Pointer to HDD context.
2364 *
2365 * Return: None
2366 */
2367static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx)
2368{
2369 ucfg_pmo_set_power_save_mode(hdd_ctx->psoc, PS_NOT_SUPPORTED);
2370 ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH);
2371}
2372
2373/**
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002374 * __hdd__mon_open() - HDD Open function
2375 * @dev: Pointer to net_device structure
2376 *
2377 * This is called in response to ifconfig up
2378 *
2379 * Return: 0 for success; non-zero for failure
2380 */
2381static int __hdd_mon_open(struct net_device *dev)
2382{
2383 int ret;
Ravi Joshia307f632017-07-17 23:41:41 -07002384 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2385 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002386
Dustin Brownfdf17c12018-03-14 12:55:34 -07002387 hdd_enter_dev(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002388
2389 ret = wlan_hdd_validate_context(hdd_ctx);
2390 if (ret)
2391 return ret;
2392
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302393 hdd_mon_mode_ether_setup(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002394
2395 if (con_mode == QDF_GLOBAL_MONITOR_MODE) {
Rajeev Kumar473f9af2019-04-05 14:25:56 -07002396 ret = hdd_trigger_psoc_idle_restart(hdd_ctx);
Ravi Joshia307f632017-07-17 23:41:41 -07002397 if (ret) {
2398 hdd_err("Failed to start WLAN modules return");
2399 return ret;
2400 }
2401 hdd_err("hdd_wlan_start_modules() successful !");
2402
2403 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
2404 ret = hdd_start_adapter(adapter);
2405 if (ret) {
2406 hdd_err("Failed to start adapter :%d",
2407 adapter->device_mode);
2408 return ret;
2409 }
2410 hdd_err("hdd_start_adapters() successful !");
2411 }
chenguo71303962018-10-24 19:44:34 +08002412 hdd_mon_turn_off_ps_and_wow(hdd_ctx);
Ravi Joshia307f632017-07-17 23:41:41 -07002413 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
2414 }
2415
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002416 ret = hdd_set_mon_rx_cb(dev);
Ravi Joshi4f095952017-06-29 15:39:19 -07002417
2418 if (!ret)
2419 ret = hdd_enable_monitor_mode(dev);
2420
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002421 return ret;
2422}
2423
2424/**
2425 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
2426 * @dev: Pointer to net_device structure
2427 *
2428 * This is called in response to ifconfig up
2429 *
2430 * Return: 0 for success; non-zero for failure
2431 */
Dustin Brown0e1e1622019-01-17 11:00:22 -08002432static int hdd_mon_open(struct net_device *net_dev)
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002433{
Dustin Brown0e1e1622019-01-17 11:00:22 -08002434 int errno;
2435 struct osif_vdev_sync *vdev_sync;
2436
2437 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
2438 if (errno)
2439 return errno;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002440
Dustin Brown0e1e1622019-01-17 11:00:22 -08002441 errno = __hdd_mon_open(net_dev);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002442
Dustin Brown0e1e1622019-01-17 11:00:22 -08002443 osif_vdev_sync_trans_stop(vdev_sync);
2444
2445 return errno;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002446}
Nirav Shah73713f72018-05-17 14:50:41 +05302447#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002448
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002449static QDF_STATUS
2450wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
2451{
2452 struct policy_mgr_dual_mac_config cfg = {0};
2453 QDF_STATUS status;
Krunal Sonie64b17e2018-12-13 16:00:02 -08002454 uint32_t chnl_sel_logic_conc = 0;
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002455 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Krunal Sonidf29bc42018-11-15 13:26:29 -08002456 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002457
2458 if (!hdd_ctx) {
2459 hdd_err("HDD context is NULL");
2460 return QDF_STATUS_E_FAILURE;
2461 }
2462
Krunal Sonie64b17e2018-12-13 16:00:02 -08002463 /*
2464 * ROME platform doesn't support any DBS related commands in FW,
2465 * so if driver sends wmi command with dual_mac_config with all set to
2466 * 0 then FW wouldn't respond back and driver would timeout on waiting
2467 * for response. Check if FW supports DBS to eliminate ROME vs
2468 * NON-ROME platform.
2469 */
2470 if (!policy_mgr_find_if_fw_supports_dbs(hdd_ctx->psoc))
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002471 return QDF_STATUS_SUCCESS;
2472
2473 cfg.scan_config = 0;
2474 cfg.fw_mode_config = 0;
2475 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
Krunal Sonie64b17e2018-12-13 16:00:02 -08002476 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) {
2477 status =
2478 ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc,
2479 &chnl_sel_logic_conc);
2480 if (status != QDF_STATUS_SUCCESS) {
2481 hdd_err("can't get chnl sel policy, use def");
2482 return status;
2483 }
Krunal Sonidf29bc42018-11-15 13:26:29 -08002484 }
2485 status =
2486 ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
2487 &dual_mac_feature);
2488 if (status != QDF_STATUS_SUCCESS) {
2489 hdd_err("ucfg_policy_mgr_get_dual_mac_feature failed, use def");
2490 return status;
2491 }
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002492
Krunal Sonidf29bc42018-11-15 13:26:29 -08002493 if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) {
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002494 status = policy_mgr_get_updated_scan_and_fw_mode_config(
Dustin Brown1dbefe62018-09-11 16:32:03 -07002495 hdd_ctx->psoc, &cfg.scan_config,
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002496 &cfg.fw_mode_config,
Krunal Sonidf29bc42018-11-15 13:26:29 -08002497 dual_mac_feature,
Krunal Sonie64b17e2018-12-13 16:00:02 -08002498 chnl_sel_logic_conc);
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002499
2500 if (status != QDF_STATUS_SUCCESS) {
2501 hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",
2502 status);
2503 return status;
2504 }
2505 }
2506
2507 hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw",
2508 cfg.scan_config, cfg.fw_mode_config);
2509
2510 status = sme_soc_set_dual_mac_config(cfg);
2511 if (status != QDF_STATUS_SUCCESS) {
2512 hdd_err("sme_soc_set_dual_mac_config failed %d", status);
2513 return status;
2514 }
2515
2516 return QDF_STATUS_SUCCESS;
2517}
2518
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002519/**
Arun Khandavallifae92942016-08-01 13:31:08 +05302520 * hdd_start_adapter() - Wrapper function for device specific adapter
2521 * @adapter: pointer to HDD adapter
2522 *
2523 * This function is called to start the device specific adapter for
2524 * the mode passed in the adapter's device_mode.
2525 *
2526 * Return: 0 for success; non-zero for failure
2527 */
Jeff Johnson9d295242017-08-29 14:39:48 -07002528int hdd_start_adapter(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05302529{
2530
2531 int ret;
Jeff Johnsonc1e62782017-11-09 09:50:17 -08002532 enum QDF_OPMODE device_mode = adapter->device_mode;
Arun Khandavallifae92942016-08-01 13:31:08 +05302533
Dustin Brownfdf17c12018-03-14 12:55:34 -07002534 hdd_enter_dev(adapter->dev);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002535 hdd_debug("Start_adapter for mode : %d", adapter->device_mode);
Arun Khandavallifae92942016-08-01 13:31:08 +05302536
2537 switch (device_mode) {
2538 case QDF_P2P_CLIENT_MODE:
2539 case QDF_P2P_DEVICE_MODE:
2540 case QDF_OCB_MODE:
2541 case QDF_STA_MODE:
2542 case QDF_MONITOR_MODE:
2543 ret = hdd_start_station_adapter(adapter);
2544 if (ret)
2545 goto err_start_adapter;
Alok Kumar81e1d732018-09-04 11:10:36 +05302546
2547 hdd_nud_ignore_tracking(adapter, false);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05302548 hdd_mic_enable_work(adapter);
Arun Khandavallifae92942016-08-01 13:31:08 +05302549 break;
2550 case QDF_P2P_GO_MODE:
2551 case QDF_SAP_MODE:
2552 ret = hdd_start_ap_adapter(adapter);
2553 if (ret)
2554 goto err_start_adapter;
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05302555 hdd_mic_enable_work(adapter);
Arun Khandavallifae92942016-08-01 13:31:08 +05302556 break;
Arun Khandavallib2f6c262016-08-18 19:07:19 +05302557 case QDF_IBSS_MODE:
2558 /*
2559 * For IBSS interface is initialized as part of
2560 * hdd_init_station_mode()
2561 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08002562 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302563 case QDF_FTM_MODE:
Dustin Browndb2a8be2017-12-20 11:49:56 -08002564 /* vdevs are dynamically managed by firmware in FTM */
Arun Kumar Khandavallif573e062019-04-16 17:17:40 +05302565 hdd_register_wext(adapter->dev);
Dustin Browndb2a8be2017-12-20 11:49:56 -08002566 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302567 default:
2568 hdd_err("Invalid session type %d", device_mode);
2569 QDF_ASSERT(0);
2570 goto err_start_adapter;
2571 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08002572
Arun Khandavallifae92942016-08-01 13:31:08 +05302573 if (hdd_set_fw_params(adapter))
2574 hdd_err("Failed to set the FW params for the adapter!");
2575
Jeff Johnson912b1bb2019-03-06 10:12:36 -08002576 if (adapter->vdev_id != WLAN_UMAC_VDEV_ID_MAX) {
Dustin Browne7e71d32018-05-11 16:00:08 -07002577 ret = wlan_hdd_cfg80211_register_frames(adapter);
2578 if (ret < 0) {
2579 hdd_err("Failed to register frames - ret %d", ret);
2580 goto err_start_adapter;
2581 }
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302582 }
Dustin Browne7e71d32018-05-11 16:00:08 -07002583
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002584 wlan_hdd_update_dbs_scan_and_fw_mode_config();
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302585
Dustin Browndb2a8be2017-12-20 11:49:56 -08002586exit_with_success:
Dustin Browne74003f2018-03-14 12:51:58 -07002587 hdd_exit();
Dustin Browndb2a8be2017-12-20 11:49:56 -08002588
Arun Khandavallifae92942016-08-01 13:31:08 +05302589 return 0;
Dustin Browndb2a8be2017-12-20 11:49:56 -08002590
Arun Khandavallifae92942016-08-01 13:31:08 +05302591err_start_adapter:
2592 return -EINVAL;
2593}
2594
2595/**
Komal Seelamf2136bb2016-09-28 18:30:44 +05302596 * hdd_enable_power_management() - API to Enable Power Management
2597 *
2598 * API invokes Bus Interface Layer power management functionality
2599 *
2600 * Return: None
2601 */
2602static void hdd_enable_power_management(void)
2603{
2604 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2605
2606 if (!hif_ctx) {
2607 hdd_err("Bus Interface Context is Invalid");
2608 return;
2609 }
2610
2611 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
2612}
2613
2614/**
2615 * hdd_disable_power_management() - API to disable Power Management
2616 *
2617 * API disable Bus Interface Layer Power management functionality
2618 *
2619 * Return: None
2620 */
2621static void hdd_disable_power_management(void)
2622{
2623 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2624
2625 if (!hif_ctx) {
2626 hdd_err("Bus Interface Context is Invalid");
2627 return;
2628 }
2629
2630 hif_disable_power_management(hif_ctx);
2631}
2632
Ryan Hsuaadba072018-04-20 13:01:53 -07002633void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx)
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302634{
2635 void *hif_sc;
Dustin Brown6f17a022017-07-19 13:40:55 -07002636 size_t target_hw_name_len;
2637 const char *target_hw_name;
Ryan Hsuaadba072018-04-20 13:01:53 -07002638 uint8_t *buf;
2639 uint32_t buf_len;
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302640
2641 hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
2642 if (!hif_sc) {
2643 hdd_err("HIF context is NULL");
2644 return;
2645 }
2646
Ryan Hsuaadba072018-04-20 13:01:53 -07002647 hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302648 &hdd_ctx->target_hw_revision,
Dustin Brown6f17a022017-07-19 13:40:55 -07002649 &target_hw_name);
2650
2651 if (hdd_ctx->target_hw_name)
2652 qdf_mem_free(hdd_ctx->target_hw_name);
2653
2654 target_hw_name_len = strlen(target_hw_name) + 1;
2655 hdd_ctx->target_hw_name = qdf_mem_malloc(target_hw_name_len);
2656 if (hdd_ctx->target_hw_name)
2657 qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name,
2658 target_hw_name_len);
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302659
Ryan Hsuaadba072018-04-20 13:01:53 -07002660 buf = qdf_mem_malloc(WE_MAX_STR_LEN);
2661 if (buf) {
2662 buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf);
2663 hdd_info("%s", buf);
2664 qdf_mem_free(buf);
2665 }
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302666}
2667
2668/**
gbian62edd7e2017-03-07 13:12:13 +08002669 * hdd_update_cds_ac_specs_params() - update cds ac_specs params
2670 * @hdd_ctx: Pointer to hdd context
2671 *
2672 * Return: none
2673 */
2674static void
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002675hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx)
gbian62edd7e2017-03-07 13:12:13 +08002676{
jitiphil8e15ea62018-11-16 18:05:34 +05302677 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM] = {0};
2678 qdf_size_t out_size = 0;
gbian62edd7e2017-03-07 13:12:13 +08002679 int i;
Jeff Johnson2b6982c2018-05-29 14:56:11 -07002680 struct cds_context *cds_ctx;
gbian62edd7e2017-03-07 13:12:13 +08002681
Jeff Johnsond36fa332019-03-18 13:42:25 -07002682 if (!hdd_ctx)
gbian62edd7e2017-03-07 13:12:13 +08002683 return;
2684
Jeff Johnsond36fa332019-03-18 13:42:25 -07002685 if (!hdd_ctx->config) {
gbian62edd7e2017-03-07 13:12:13 +08002686 /* Do nothing if hdd_ctx is invalid */
2687 hdd_err("%s: Warning: hdd_ctx->cfg_ini is NULL", __func__);
2688 return;
2689 }
2690
2691 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2692
2693 if (!cds_ctx) {
2694 hdd_err("Invalid CDS Context");
2695 return;
2696 }
2697
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002698 for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
gbian62edd7e2017-03-07 13:12:13 +08002699 switch (i) {
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002700 case QCA_WLAN_AC_BE:
jitiphil8e15ea62018-11-16 18:05:34 +05302701 qdf_uint8_array_parse(
2702 cfg_get(hdd_ctx->psoc,
2703 CFG_DP_ENABLE_TX_SCHED_WRR_BE),
2704 tx_sched_wrr_param,
2705 sizeof(tx_sched_wrr_param),
2706 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002707 break;
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002708 case QCA_WLAN_AC_BK:
jitiphil8e15ea62018-11-16 18:05:34 +05302709 qdf_uint8_array_parse(
2710 cfg_get(hdd_ctx->psoc,
2711 CFG_DP_ENABLE_TX_SCHED_WRR_BK),
2712 tx_sched_wrr_param,
2713 sizeof(tx_sched_wrr_param),
2714 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002715 break;
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002716 case QCA_WLAN_AC_VI:
jitiphil8e15ea62018-11-16 18:05:34 +05302717 qdf_uint8_array_parse(
2718 cfg_get(hdd_ctx->psoc,
2719 CFG_DP_ENABLE_TX_SCHED_WRR_VI),
2720 tx_sched_wrr_param,
2721 sizeof(tx_sched_wrr_param),
2722 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002723 break;
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002724 case QCA_WLAN_AC_VO:
jitiphil8e15ea62018-11-16 18:05:34 +05302725 qdf_uint8_array_parse(
2726 cfg_get(hdd_ctx->psoc,
2727 CFG_DP_ENABLE_TX_SCHED_WRR_VO),
2728 tx_sched_wrr_param,
2729 sizeof(tx_sched_wrr_param),
2730 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002731 break;
2732 default:
gbian62edd7e2017-03-07 13:12:13 +08002733 break;
2734 }
2735
jitiphil8e15ea62018-11-16 18:05:34 +05302736 if (out_size == TX_SCHED_WRR_PARAMS_NUM) {
gbian62edd7e2017-03-07 13:12:13 +08002737 cds_ctx->ac_specs[i].wrr_skip_weight =
2738 tx_sched_wrr_param[0];
2739 cds_ctx->ac_specs[i].credit_threshold =
2740 tx_sched_wrr_param[1];
2741 cds_ctx->ac_specs[i].send_limit =
2742 tx_sched_wrr_param[2];
2743 cds_ctx->ac_specs[i].credit_reserve =
2744 tx_sched_wrr_param[3];
2745 cds_ctx->ac_specs[i].discard_weight =
2746 tx_sched_wrr_param[4];
2747 }
2748
jitiphil8e15ea62018-11-16 18:05:34 +05302749 out_size = 0;
gbian62edd7e2017-03-07 13:12:13 +08002750 }
2751}
2752
Ryan Hsuaadba072018-04-20 13:01:53 -07002753uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx,
2754 const size_t version_len, uint8_t *version)
2755{
2756 uint32_t size;
Sourav Mohapatra939e0742019-07-26 09:07:18 +05302757 uint8_t reg_major = 0, reg_minor = 0, bdf_major = 0, bdf_minor = 0;
2758 struct target_psoc_info *tgt_hdl;
Ryan Hsuaadba072018-04-20 13:01:53 -07002759
2760 if (!hdd_ctx) {
2761 hdd_err("Invalid context, HDD context is null");
2762 return 0;
2763 }
2764
Ashish Kumar Dhanotiya7353f882018-05-15 12:50:19 +05302765 if (!version || version_len == 0) {
Ryan Hsuaadba072018-04-20 13:01:53 -07002766 hdd_err("Invalid buffer pointr or buffer len\n");
2767 return 0;
2768 }
Sourav Mohapatra939e0742019-07-26 09:07:18 +05302769 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
2770 if (tgt_hdl)
2771 target_psoc_get_version_info(tgt_hdl, &reg_major, &reg_minor,
2772 &bdf_major, &bdf_minor);
Ryan Hsuaadba072018-04-20 13:01:53 -07002773
Ryan Hsuaadba072018-04-20 13:01:53 -07002774 size = scnprintf(version, version_len,
Sourav Mohapatra939e0742019-07-26 09:07:18 +05302775 "Host SW:%s, FW:%d.%d.%d.%d.%d.%d, HW:%s, Board ver: %x Ref design id: %x, Customer id: %x, Project id: %x, Board Data Rev: %x, REG DB: %u:%u, BDF REG DB: %u:%u",
Ryan Hsuaadba072018-04-20 13:01:53 -07002776 QWLAN_VERSIONSTR,
Ashish Kumar Dhanotiyaeadb28b2019-06-28 14:34:19 +05302777 hdd_ctx->fw_version_info.major_spid,
2778 hdd_ctx->fw_version_info.minor_spid,
2779 hdd_ctx->fw_version_info.siid,
2780 hdd_ctx->fw_version_info.rel_id,
2781 hdd_ctx->fw_version_info.crmid,
2782 hdd_ctx->fw_version_info.sub_id,
Ryan Hsuc6918552018-05-16 13:29:59 -07002783 hdd_ctx->target_hw_name,
2784 hdd_ctx->hw_bd_info.bdf_version,
2785 hdd_ctx->hw_bd_info.ref_design_id,
2786 hdd_ctx->hw_bd_info.customer_id,
2787 hdd_ctx->hw_bd_info.project_id,
Sourav Mohapatra939e0742019-07-26 09:07:18 +05302788 hdd_ctx->hw_bd_info.board_data_rev,
2789 reg_major, reg_minor, bdf_major, bdf_minor);
Ryan Hsuaadba072018-04-20 13:01:53 -07002790
2791 return size;
2792}
2793
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302794int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value,
2795 struct sap_config *sap_config)
2796{
2797 uint8_t preamble = 0, nss = 0, rix = 0;
2798 int ret;
2799 mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
2800
2801 if (!sap_config) {
2802 if (!sme_is_feature_supported_by_fw(DOT11AX)) {
2803 hdd_err("Target does not support 11ax");
2804 return -EIO;
2805 }
2806 } else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax &&
2807 sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) {
Kiran Kumar Lokere229212a2019-08-20 19:03:30 -07002808 hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch_freq = %d",
2809 sap_config->SapHw_mode, sap_config->chan_freq);
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302810 return -EIO;
2811 }
2812
2813 if (set_value != 0xff) {
2814 rix = RC_2_RATE_IDX_11AX(set_value);
2815 preamble = WMI_RATE_PREAMBLE_HE;
2816 nss = HT_RC_2_STREAMS_11AX(set_value);
2817
2818 set_value = hdd_assemble_rate_code(preamble, nss, rix);
2819 } else {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08002820 ret = sme_set_auto_rate_he_ltf(mac_handle, adapter->vdev_id,
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302821 QCA_WLAN_HE_LTF_AUTO);
2822 }
2823
2824 hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d",
2825 set_value, rix, preamble, nss);
2826
Jeff Johnson5a6fc962019-02-04 14:20:25 -08002827 ret = wma_cli_set_command(adapter->vdev_id,
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302828 WMI_VDEV_PARAM_FIXED_RATE,
2829 set_value, VDEV_CMD);
2830
2831 return ret;
2832}
2833
2834int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate)
2835{
2836 int set_value;
2837
2838 if (sme_is_feature_supported_by_fw(DOT11AX))
2839 set_value = WMI_ASSEMBLE_RATECODE_V1(rate, nss, preamble);
2840 else
2841 set_value = (preamble << 6) | (nss << 4) | rate;
2842
2843 return set_value;
2844}
2845
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002846#ifdef FEATURE_WLAN_WAPI
2847/**
2848 * hdd_wapi_security_sta_exist() - return wapi security sta exist or not
2849 *
2850 * This API returns the wapi security station exist or not
2851 *
2852 * Return: true - wapi security station exist
2853 */
2854static bool hdd_wapi_security_sta_exist(void)
2855{
2856 struct hdd_adapter *adapter = NULL;
2857 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2858
2859 hdd_for_each_adapter(hdd_ctx, adapter) {
2860 if ((adapter->device_mode == QDF_STA_MODE) &&
2861 adapter->wapi_info.wapi_mode &&
2862 (adapter->wapi_info.wapi_auth_mode != WAPI_AUTH_MODE_OPEN))
2863 return true;
2864 }
2865 return false;
2866}
2867#else
2868static bool hdd_wapi_security_sta_exist(void)
2869{
2870 return false;
2871}
2872#endif
2873
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002874#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002875static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
2876 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
2877{
Jeff Johnson9d295242017-08-29 14:39:48 -07002878 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002879 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002880
2881 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2882 if (!adapter) {
2883 hdd_err("Adapter is NULL");
2884 return PM_MAX_NUM_OF_MODE;
2885 }
2886
2887 return policy_mgr_convert_device_mode_to_qdf_type(
2888 adapter->device_mode);
2889}
2890
Abhishek Singh3bbf6cb2019-03-28 14:05:43 +05302891/**
2892 * hdd_is_chan_switch_in_progress() - Check if any adapter has channel switch in
2893 * progress
2894 *
2895 * Return: true, if any adapter has channel switch in
2896 * progress else false
2897 */
2898static bool hdd_is_chan_switch_in_progress(void)
2899{
2900 struct hdd_adapter *adapter = NULL;
2901 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2902
2903 hdd_for_each_adapter(hdd_ctx, adapter) {
2904 if ((adapter->device_mode == QDF_SAP_MODE ||
2905 adapter->device_mode == QDF_P2P_GO_MODE) &&
2906 qdf_atomic_read(&adapter->ch_switch_in_progress)) {
2907 hdd_debug("channel switch progress for vdev_id %d",
2908 adapter->vdev_id);
2909 return true;
2910 }
2911 }
2912
2913 return false;
2914}
2915
Rachit Kankane914b79a2019-10-10 13:52:57 +05302916/**
2917 * hdd_is_cac_in_progress() - Check if any SAP connection is performing
2918 * CAC on DFS channel
2919 *
2920 * Return: true, if any of existing SAP is performing CAC
2921 * or else false
2922 */
2923static bool hdd_is_cac_in_progress(void)
2924{
2925 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2926
2927 return (hdd_ctx->dev_dfs_cac_status == DFS_CAC_IN_PROGRESS);
2928}
Abhishek Singh3bbf6cb2019-03-28 14:05:43 +05302929
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002930static void hdd_register_policy_manager_callback(
2931 struct wlan_objmgr_psoc *psoc)
2932{
2933 struct policy_mgr_hdd_cbacks hdd_cbacks;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07002934
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002935 qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks));
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002936 hdd_cbacks.sap_restart_chan_switch_cb =
Jeff Johnson23812942017-10-06 11:33:55 -07002937 hdd_sap_restart_chan_switch_cb;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002938 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
2939 wlan_hdd_get_channel_for_sap_restart;
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002940 hdd_cbacks.get_mode_for_non_connected_vdev =
2941 wlan_hdd_get_mode_for_non_connected_vdev;
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05302942 hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode;
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002943 hdd_cbacks.hdd_wapi_security_sta_exist =
2944 hdd_wapi_security_sta_exist;
Abhishek Singh3bbf6cb2019-03-28 14:05:43 +05302945 hdd_cbacks.hdd_is_chan_switch_in_progress =
2946 hdd_is_chan_switch_in_progress;
Rachit Kankane914b79a2019-10-10 13:52:57 +05302947 hdd_cbacks.hdd_is_cac_in_progress =
2948 hdd_is_cac_in_progress;
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +05302949 hdd_cbacks.wlan_hdd_set_sap_csa_reason =
2950 wlan_hdd_set_sap_csa_reason;
Abhishek Singh3bbf6cb2019-03-28 14:05:43 +05302951
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002952 if (QDF_STATUS_SUCCESS !=
2953 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
2954 hdd_err("HDD callback registration with policy manager failed");
2955 }
2956}
2957#else
2958static void hdd_register_policy_manager_callback(
2959 struct wlan_objmgr_psoc *psoc)
2960{
2961}
2962#endif
2963
Nachiket Kukade2fb1fdb2019-01-08 15:35:27 +05302964#ifdef WLAN_FEATURE_NAN
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002965static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002966{
2967 struct nan_callbacks cb_obj = {0};
2968
2969 cb_obj.ndi_open = hdd_ndi_open;
2970 cb_obj.ndi_close = hdd_ndi_close;
2971 cb_obj.ndi_start = hdd_ndi_start;
2972 cb_obj.ndi_delete = hdd_ndi_delete;
2973 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
2974 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
2975
Naveen Rawat37f62c82017-03-26 22:24:43 -07002976 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002977 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
Naveen Rawat37f62c82017-03-26 22:24:43 -07002978
Dustin Brown1dbefe62018-09-11 16:32:03 -07002979 os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002980}
jiadff1ac132018-11-26 16:27:48 +08002981#else
2982static inline void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
2983{
2984}
2985#endif
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002986
Dustin Brown26b3d042017-12-21 11:13:27 -08002987#ifdef CONFIG_LEAK_DETECTION
Dustin Brown4c5b9902017-12-19 11:17:19 -08002988/**
2989 * hdd_check_for_leaks() - Perform runtime memory leak checks
Dustin Browna6246dd2018-05-24 14:35:58 -07002990 * @hdd_ctx: the global HDD context
Dustin Brown29533f22018-07-24 13:11:56 -07002991 * @is_ssr: true if SSR is in progress
Dustin Brown4c5b9902017-12-19 11:17:19 -08002992 *
2993 * This API triggers runtime memory leak detection. This feature enforces the
2994 * policy that any memory allocated at runtime must also be released at runtime.
2995 *
2996 * Allocating memory at runtime and releasing it at unload is effectively a
2997 * memory leak for configurations which never unload (e.g. LONU, statically
2998 * compiled driver). Such memory leaks are NOT false positives, and must be
2999 * fixed.
3000 *
3001 * Return: None
3002 */
Dustin Brown29533f22018-07-24 13:11:56 -07003003static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
Dustin Brown4bc0a622017-12-06 15:56:50 -08003004{
Dustin Brown4c5b9902017-12-19 11:17:19 -08003005 /* DO NOT REMOVE these checks; for false positives, read above first */
3006
Dustin Brown1dbefe62018-09-11 16:32:03 -07003007 wlan_objmgr_psoc_check_for_peer_leaks(hdd_ctx->psoc);
3008 wlan_objmgr_psoc_check_for_vdev_leaks(hdd_ctx->psoc);
3009 wlan_objmgr_psoc_check_for_pdev_leaks(hdd_ctx->psoc);
Dustin Brown29533f22018-07-24 13:11:56 -07003010
3011 /* many adapter resources are not freed by design during SSR */
3012 if (is_ssr)
3013 return;
3014
Dustin Brownc2796312019-03-13 16:43:36 -07003015 qdf_delayed_work_check_for_leaks();
Dustin Brown677e0862017-10-10 16:30:09 -07003016 qdf_mc_timer_check_for_leaks();
Dustin Brown8e711502017-12-07 16:49:11 -08003017 qdf_nbuf_map_check_for_leaks();
Dustin Brown4a93bb52019-03-13 11:46:34 -07003018 qdf_periodic_work_check_for_leaks();
Dustin Browne6b9d5a2017-12-14 15:18:49 -08003019 qdf_mem_check_for_leaks();
Dustin Brown4bc0a622017-12-06 15:56:50 -08003020}
3021
Dustin Brown26b3d042017-12-21 11:13:27 -08003022#define hdd_debug_domain_set(domain) qdf_debug_domain_set(domain)
3023#else
Dustin Brown29533f22018-07-24 13:11:56 -07003024static inline void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
3025{ }
Dustin Brown26b3d042017-12-21 11:13:27 -08003026
3027#define hdd_debug_domain_set(domain)
3028#endif /* CONFIG_LEAK_DETECTION */
3029
Lin Bai56386f52019-08-08 13:58:23 +08003030#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
3031/**
3032 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
3033 * @data: pointer to struct hdd_context
3034 *
3035 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
3036 * Then new ACS request will do a fresh scan without reusing the cached
3037 * scan information.
3038 *
3039 * Return: void
3040 */
3041static void hdd_skip_acs_scan_timer_handler(void *data)
3042{
3043 struct hdd_context *hdd_ctx = data;
3044 mac_handle_t mac_handle;
3045
3046 hdd_debug("ACS Scan result expired. Reset ACS scan skip");
3047 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
3048 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
Lin Bai96f66092019-08-20 11:23:14 +08003049 qdf_mem_free(hdd_ctx->last_acs_freq_list);
3050 hdd_ctx->last_acs_freq_list = NULL;
Lin Bai56386f52019-08-08 13:58:23 +08003051 hdd_ctx->num_of_channels = 0;
3052 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
3053
3054 mac_handle = hdd_ctx->mac_handle;
3055 if (!mac_handle)
3056 return;
3057}
3058
3059static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx)
3060{
3061 QDF_STATUS status;
3062
3063 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
3064 QDF_TIMER_TYPE_SW,
3065 hdd_skip_acs_scan_timer_handler,
3066 hdd_ctx);
3067 if (QDF_IS_STATUS_ERROR(status))
3068 hdd_err("Failed to init ACS Skip timer");
3069 qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
3070}
3071
3072static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx)
3073{
3074 if (QDF_TIMER_STATE_RUNNING ==
3075 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
3076 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
3077 }
3078
3079 if (!QDF_IS_STATUS_SUCCESS
3080 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
3081 hdd_err("Cannot deallocate ACS Skip timer");
3082 }
3083 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
Lin Bai96f66092019-08-20 11:23:14 +08003084 qdf_mem_free(hdd_ctx->last_acs_freq_list);
3085 hdd_ctx->last_acs_freq_list = NULL;
Lin Bai56386f52019-08-08 13:58:23 +08003086 hdd_ctx->num_of_channels = 0;
3087 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
3088}
3089#else
3090static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) {}
3091static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) {}
3092#endif
3093
gbian62edd7e2017-03-07 13:12:13 +08003094/**
Paul Zhange03cf4c2018-01-19 18:33:22 +08003095 * hdd_update_country_code - Update country code
3096 * @hdd_ctx: HDD context
3097 *
3098 * Update country code based on module parameter country_code
3099 *
3100 * Return: 0 on success and errno on failure
3101 */
3102static int hdd_update_country_code(struct hdd_context *hdd_ctx)
3103{
3104 if (!country_code)
3105 return 0;
3106
3107 return hdd_reg_set_country(hdd_ctx, country_code);
3108}
3109
Jingxiang Ge645300a2019-11-15 12:30:27 +08003110/**
3111 * wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
3112 * @hdd_ctx: hdd context
3113 *
3114 * Return: 0 for success or error code
3115 */
3116static int wlan_hdd_init_tx_rx_histogram(struct hdd_context *hdd_ctx)
3117{
3118 hdd_ctx->hdd_txrx_hist = qdf_mem_malloc(
3119 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
3120 if (!hdd_ctx->hdd_txrx_hist) {
3121 hdd_err("failed to alloc memory");
3122 return -ENOMEM;
3123 }
3124 return 0;
3125}
3126
3127/**
3128 * wlan_hdd_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
3129 * @hdd_ctx: hdd context
3130 *
3131 * Return: none
3132 */
3133static void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx)
3134{
3135 if (!hdd_ctx || !hdd_ctx->hdd_txrx_hist)
3136 return;
3137
3138 qdf_mem_free(hdd_ctx->hdd_txrx_hist);
3139 hdd_ctx->hdd_txrx_hist = NULL;
3140}
3141
Dustin Browne7e71d32018-05-11 16:00:08 -07003142int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
Arun Khandavallifae92942016-08-01 13:31:08 +05303143{
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07003144 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05303145 qdf_device_t qdf_dev;
3146 QDF_STATUS status;
Arun Khandavallifae92942016-08-01 13:31:08 +05303147 bool unint = false;
3148 void *hif_ctx;
Alan Chenf4e958f2019-10-04 16:53:05 -07003149 struct target_psoc_info *tgt_hdl;
Arun Khandavallifae92942016-08-01 13:31:08 +05303150
Arun Khandavallifae92942016-08-01 13:31:08 +05303151 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
3152 if (!qdf_dev) {
3153 hdd_err("QDF Device Context is Invalid return");
3154 return -EINVAL;
3155 }
3156
Dustin Brown4c663222018-10-23 14:19:36 -07003157 hdd_psoc_idle_timer_stop(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303158
Arun Khandavalli5a62a822017-11-14 19:43:00 +05303159 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07003160 hdd_debug("Driver modules already Enabled");
Dustin Browne74003f2018-03-14 12:51:58 -07003161 hdd_exit();
Arun Khandavalli5a62a822017-11-14 19:43:00 +05303162 return 0;
3163 }
3164
Arun Khandavallifae92942016-08-01 13:31:08 +05303165 switch (hdd_ctx->driver_status) {
3166 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown550f6d22017-12-14 15:44:01 -08003167 hdd_info("Wlan transitioning (UNINITIALIZED -> CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +05303168 unint = true;
3169 /* Fall through dont add break here */
3170 case DRIVER_MODULES_CLOSED:
Dustin Brown1a20b082018-08-03 17:27:15 -07003171 hdd_info("Wlan transitioning (CLOSED -> ENABLED)");
Dustin Brown550f6d22017-12-14 15:44:01 -08003172
Dustin Brown26b3d042017-12-21 11:13:27 -08003173 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
Dustin Brown4bc0a622017-12-06 15:56:50 -08003174
Arun Khandavallifae92942016-08-01 13:31:08 +05303175 if (!reinit && !unint) {
3176 ret = pld_power_on(qdf_dev->dev);
3177 if (ret) {
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07003178 hdd_err("Failed to power up device; errno:%d",
Dustin Browndca39692017-11-09 15:30:25 -08003179 ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05303180 goto release_lock;
3181 }
3182 }
Yuanyuan Liuf8fe4bc2017-06-07 16:55:58 -07003183
3184 pld_set_fw_log_mode(hdd_ctx->parent_dev,
3185 hdd_ctx->config->enable_fw_log);
Arun Khandavallifae92942016-08-01 13:31:08 +05303186 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
3187 qdf_dev->bus_type,
3188 (reinit == true) ? HIF_ENABLE_TYPE_REINIT :
3189 HIF_ENABLE_TYPE_PROBE);
3190 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08003191 hdd_err("Failed to open hif; errno: %d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05303192 goto power_down;
3193 }
3194
3195 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
Arun Khandavalli1318b992016-08-09 11:04:57 +05303196 if (!hif_ctx) {
3197 hdd_err("hif context is null!!");
Dustin Browndca39692017-11-09 15:30:25 -08003198 ret = -EINVAL;
Arun Khandavalli1318b992016-08-09 11:04:57 +05303199 goto power_down;
3200 }
3201
Arun Khandavallifae92942016-08-01 13:31:08 +05303202 status = ol_cds_init(qdf_dev, hif_ctx);
3203 if (status != QDF_STATUS_SUCCESS) {
Dustin Browndca39692017-11-09 15:30:25 -08003204 hdd_err("No Memory to Create BMI Context; status: %d",
3205 status);
3206 ret = qdf_status_to_os_return(status);
Arun Khandavallifae92942016-08-01 13:31:08 +05303207 goto hif_close;
3208 }
3209
Nirav Shah6aeecf92019-02-13 14:05:03 +05303210 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
3211 status = epping_open();
3212 if (status) {
3213 hdd_err("Failed to open in epping mode: %d",
3214 status);
3215 ret = -EINVAL;
3216 goto cds_free;
3217 }
3218
3219 status = epping_enable(qdf_dev->dev, false);
3220 if (status) {
3221 hdd_err("Failed to enable in epping mode : %d",
3222 status);
3223 epping_close();
3224 goto cds_free;
3225 }
3226
3227 hdd_info("epping mode enabled");
3228 break;
3229 }
3230
jitiphil4c256a32018-09-07 08:51:52 +05303231 ucfg_ipa_component_config_update(hdd_ctx->psoc);
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05303232
gbian62edd7e2017-03-07 13:12:13 +08003233 hdd_update_cds_ac_specs_params(hdd_ctx);
3234
Dustin Brown1dbefe62018-09-11 16:32:03 -07003235 status = hdd_component_psoc_open(hdd_ctx->psoc);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05303236 if (QDF_IS_STATUS_ERROR(status)) {
3237 hdd_err("Failed to Open legacy components; status: %d",
3238 status);
3239 ret = qdf_status_to_os_return(status);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05303240 goto cds_free;
3241 }
3242
3243 ret = hdd_update_config(hdd_ctx);
3244 if (ret) {
3245 hdd_err("Failed to update configuration; errno: %d",
3246 ret);
3247 goto cds_free;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05303248 }
3249
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +05303250 status = wbuff_module_init();
3251 if (QDF_IS_STATUS_ERROR(status))
3252 hdd_err("WBUFF init unsuccessful; status: %d", status);
3253
Dustin Brown1dbefe62018-09-11 16:32:03 -07003254 status = cds_open(hdd_ctx->psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07003255 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08003256 hdd_err("Failed to Open CDS; status: %d", status);
Dustin Brown28b17892017-10-10 13:29:38 -07003257 ret = qdf_status_to_os_return(status);
Krunal Sonie71838d2018-09-27 10:45:05 -07003258 goto psoc_close;
Arun Khandavallifae92942016-08-01 13:31:08 +05303259 }
3260
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +05303261 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
3262
Manjunathappa Prakashb6b4ff12018-06-04 12:32:33 -07003263 if (hdd_ctx->config->rx_thread_affinity_mask)
3264 cds_set_rx_thread_cpu_mask(
3265 hdd_ctx->config->rx_thread_affinity_mask);
3266
3267 /* initialize components configurations after psoc open */
Mukul Sharma9d797a02017-01-05 20:26:03 +05303268 ret = hdd_update_components_config(hdd_ctx);
3269 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08003270 hdd_err("Failed to update component configs; errno: %d",
Mukul Sharma9d797a02017-01-05 20:26:03 +05303271 ret);
3272 goto close;
3273 }
Sourav Mohapatra674925f2018-04-16 11:16:58 +05303274
Dustin Brown1dbefe62018-09-11 16:32:03 -07003275 status = cds_dp_open(hdd_ctx->psoc);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003276 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08003277 hdd_err("Failed to Open cds post open; status: %d",
3278 status);
3279 ret = qdf_status_to_os_return(status);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003280 goto close;
3281 }
Mukul Sharma9d797a02017-01-05 20:26:03 +05303282
Sourav Mohapatra674925f2018-04-16 11:16:58 +05303283 ret = hdd_register_cb(hdd_ctx);
3284 if (ret) {
3285 hdd_err("Failed to register HDD callbacks!");
3286 goto cds_txrx_free;
3287 }
3288
Naveen Rawatcb5c5402017-03-22 10:12:19 -07003289 /*
3290 * NAN compoenet requires certian operations like, open adapter,
3291 * close adapter, etc. to be initiated by HDD, for those
3292 * register HDD callbacks with UMAC's NAN componenet.
3293 */
3294 hdd_nan_register_callbacks(hdd_ctx);
3295
Jeff Johnson3a280122017-09-13 07:42:00 -07003296 status = cds_pre_enable();
Arun Khandavallifae92942016-08-01 13:31:08 +05303297 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08003298 hdd_err("Failed to pre-enable CDS; status: %d", status);
3299 ret = qdf_status_to_os_return(status);
Sourav Mohapatra674925f2018-04-16 11:16:58 +05303300 goto deregister_cb;
Arun Khandavallifae92942016-08-01 13:31:08 +05303301 }
3302
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07003303 hdd_register_policy_manager_callback(
Dustin Brown1dbefe62018-09-11 16:32:03 -07003304 hdd_ctx->psoc);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07003305
Wu Gao6fc2b722019-11-06 23:20:51 +08003306 /*
3307 * Call this function before hdd_enable_power_management. Since
3308 * it is required to trigger WMI_PDEV_DMA_RING_CFG_REQ_CMDID
3309 * to FW when power save isn't enable.
3310 */
3311 hdd_spectral_register_to_dbr(hdd_ctx);
3312
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05303313 hdd_sysfs_create_driver_root_obj();
Dustin Brown1dbefe62018-09-11 16:32:03 -07003314 hdd_sysfs_create_version_interface(hdd_ctx->psoc);
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05303315 hdd_sysfs_create_powerstats_interface();
Arunk Khandavalli67193d52017-02-21 12:03:48 +05303316 hdd_update_hw_sw_info(hdd_ctx);
Dustin Brown550f6d22017-12-14 15:44:01 -08003317
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05303318 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Mahesh Kumar Kalikot Veetil59a9a782019-07-16 16:05:11 -07003319 hdd_enable_power_management();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05303320 hdd_err("in ftm mode, no need to configure cds modules");
Dustin Browndca39692017-11-09 15:30:25 -08003321 ret = -EINVAL;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05303322 break;
3323 }
Dustin Browndca39692017-11-09 15:30:25 -08003324
Dustin Browne7e71d32018-05-11 16:00:08 -07003325 ret = hdd_configure_cds(hdd_ctx);
Dustin Browndca39692017-11-09 15:30:25 -08003326 if (ret) {
3327 hdd_err("Failed to Enable cds modules; errno: %d", ret);
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05303328 goto destroy_driver_sysfs;
Arun Khandavallifae92942016-08-01 13:31:08 +05303329 }
Dustin Browndca39692017-11-09 15:30:25 -08003330
Komal Seelamf2136bb2016-09-28 18:30:44 +05303331 hdd_enable_power_management();
Dustin Brown550f6d22017-12-14 15:44:01 -08003332
Lin Bai56386f52019-08-08 13:58:23 +08003333 hdd_skip_acs_scan_timer_init(hdd_ctx);
3334
Jingxiang Ge645300a2019-11-15 12:30:27 +08003335 wlan_hdd_init_tx_rx_histogram(hdd_ctx);
3336
Venkata Sharath Chandra Manchala06f1f122019-10-29 13:22:15 -07003337 hdd_set_hif_init_phase(hif_ctx, false);
3338
Arun Khandavallifae92942016-08-01 13:31:08 +05303339 break;
Dustin Brown550f6d22017-12-14 15:44:01 -08003340
Arun Khandavallifae92942016-08-01 13:31:08 +05303341 default:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07003342 QDF_DEBUG_PANIC("Unknown driver state:%d",
Arun Khandavallifae92942016-08-01 13:31:08 +05303343 hdd_ctx->driver_status);
Dustin Browndca39692017-11-09 15:30:25 -08003344 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05303345 goto release_lock;
3346 }
Dustin Brown550f6d22017-12-14 15:44:01 -08003347
Dustin Brown1a20b082018-08-03 17:27:15 -07003348 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
3349 hdd_info("Wlan transitioned (now ENABLED)");
3350
Dustin Browne74003f2018-03-14 12:51:58 -07003351 hdd_exit();
Dustin Brown550f6d22017-12-14 15:44:01 -08003352
Arun Khandavallifae92942016-08-01 13:31:08 +05303353 return 0;
3354
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05303355destroy_driver_sysfs:
3356 hdd_sysfs_destroy_powerstats_interface();
3357 hdd_sysfs_destroy_version_interface();
3358 hdd_sysfs_destroy_driver_root_obj();
Rajeev Kumarbe021242017-02-16 16:12:23 -08003359 cds_post_disable();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003360
Sourav Mohapatra674925f2018-04-16 11:16:58 +05303361deregister_cb:
3362 hdd_deregister_cb(hdd_ctx);
3363
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003364cds_txrx_free:
Jingxiang Ge95912f82018-04-19 12:01:26 +08003365
Alan Chenf4e958f2019-10-04 16:53:05 -07003366 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
3367
3368 if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl))
3369 hdd_runtime_suspend_context_deinit(hdd_ctx);
3370
Jingxiang Geaaded482019-09-11 20:02:37 +08003371 if (hdd_ctx->pdev) {
Dustin Brown07901ec2018-09-07 11:02:41 -07003372 dispatcher_pdev_close(hdd_ctx->pdev);
Jingxiang Ge95912f82018-04-19 12:01:26 +08003373 hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
3374 }
3375
Dustin Brown1dbefe62018-09-11 16:32:03 -07003376 cds_dp_close(hdd_ctx->psoc);
Dustin Brown550f6d22017-12-14 15:44:01 -08003377
Arun Khandavallifae92942016-08-01 13:31:08 +05303378close:
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003379 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -08003380 hdd_info("Wlan transition aborted (now CLOSED)");
3381
Dustin Brown1dbefe62018-09-11 16:32:03 -07003382 cds_close(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +05303383
Krunal Sonie71838d2018-09-27 10:45:05 -07003384psoc_close:
Dustin Brown1dbefe62018-09-11 16:32:03 -07003385 hdd_component_psoc_close(hdd_ctx->psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07003386 cds_deinit_ini_config();
3387
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003388cds_free:
Arun Khandavallifae92942016-08-01 13:31:08 +05303389 ol_cds_free();
3390
3391hif_close:
Jeff Johnson60dc2b12017-09-28 14:56:02 -07003392 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
3393 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303394power_down:
3395 if (!reinit && !unint)
3396 pld_power_off(qdf_dev->dev);
3397release_lock:
Abhinav Kumar7ae9b7b2017-12-19 15:11:54 +05303398 if (hdd_ctx->target_hw_name) {
3399 qdf_mem_free(hdd_ctx->target_hw_name);
3400 hdd_ctx->target_hw_name = NULL;
3401 }
Dustin Brown29533f22018-07-24 13:11:56 -07003402
3403 hdd_check_for_leaks(hdd_ctx, reinit);
Dustin Brown26b3d042017-12-21 11:13:27 -08003404 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -08003405
Dustin Browne74003f2018-03-14 12:51:58 -07003406 hdd_exit();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003407
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07003408 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05303409}
3410
Naveen Rawat910726a2017-03-06 11:42:51 -08003411#ifdef WIFI_POS_CONVERGED
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003412static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003413{
3414 int ret = os_if_wifi_pos_register_nl();
3415
3416 if (ret)
3417 hdd_err("os_if_wifi_pos_register_nl failed");
3418
3419 return ret;
3420}
3421
3422static int hdd_deactivate_wifi_pos(void)
3423{
3424 int ret = os_if_wifi_pos_deregister_nl();
3425
3426 if (ret)
3427 hdd_err("os_if_wifi_pos_deregister_nl failed");
3428
3429 return ret;
3430}
3431
3432/**
3433 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
3434 * @hdd_ctx: hdd context
3435 *
3436 * Return: status of operation
3437 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003438static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003439{
Dustin Brown1dbefe62018-09-11 16:32:03 -07003440 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Wu Gao1ab05582018-11-08 16:22:49 +08003441 uint16_t neighbor_scan_max_chan_time;
3442 uint16_t neighbor_scan_min_chan_time;
Naveen Rawat910726a2017-03-06 11:42:51 -08003443
3444 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
3445 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
3446 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
3447 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
3448 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
3449 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
Wu Gao1ab05582018-11-08 16:22:49 +08003450 ucfg_mlme_get_neighbor_scan_max_chan_time(psoc,
3451 &neighbor_scan_max_chan_time);
3452 ucfg_mlme_get_neighbor_scan_min_chan_time(psoc,
3453 &neighbor_scan_min_chan_time);
3454 wifi_pos_set_dwell_time_min(psoc, neighbor_scan_min_chan_time);
3455 wifi_pos_set_dwell_time_max(psoc, neighbor_scan_max_chan_time);
Naveen Rawat910726a2017-03-06 11:42:51 -08003456}
3457#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003458static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003459{
3460 return oem_activate_service(hdd_ctx);
3461}
3462
3463static int hdd_deactivate_wifi_pos(void)
3464{
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05303465 return oem_deactivate_service();
Naveen Rawat910726a2017-03-06 11:42:51 -08003466}
3467
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003468static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003469{
3470}
3471#endif
3472
Arun Khandavallifae92942016-08-01 13:31:08 +05303473/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003474 * __hdd_open() - HDD Open function
3475 * @dev: Pointer to net_device structure
3476 *
3477 * This is called in response to ifconfig up
3478 *
3479 * Return: 0 for success; non-zero for failure
3480 */
3481static int __hdd_open(struct net_device *dev)
3482{
Jeff Johnson9d295242017-08-29 14:39:48 -07003483 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003484 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003485 int ret;
3486
Dustin Brownfdf17c12018-03-14 12:55:34 -07003487 hdd_enter_dev(dev);
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +05303488
3489 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
3490 TRACE_CODE_HDD_OPEN_REQUEST,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08003491 adapter->vdev_id, adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003492
Ashish Kumar Dhanotiya15a7db52017-08-03 10:27:34 +05303493 /* Nothing to be done if device is unloading */
3494 if (cds_is_driver_unloading()) {
3495 hdd_err("Driver is unloading can not open the hdd");
3496 return -EBUSY;
3497 }
3498
Dustin Brown01847752017-10-25 13:56:27 -07003499 if (cds_is_driver_recovering()) {
3500 hdd_err("WLAN is currently recovering; Please try again.");
3501 return -EBUSY;
3502 }
3503
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303504 /*
3505 * This scenario can be hit in cases where in the wlan driver after
3506 * registering the netdevices and there is a failure in driver
3507 * initialization. So return error gracefully because the netdevices
3508 * will be de-registered as part of the load failure.
3509 */
3510
3511 if (!cds_is_driver_loaded()) {
3512 hdd_err("Failed to start the wlan driver!!");
Dustin Brown3da3a832019-03-19 15:51:54 -07003513 return -EIO;
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303514 }
Abhishek Singh23edd1c2016-05-05 11:56:06 +05303515
Rajeev Kumar473f9af2019-04-05 14:25:56 -07003516 ret = hdd_trigger_psoc_idle_restart(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303517 if (ret) {
3518 hdd_err("Failed to start WLAN modules return");
Dustin Brown3da3a832019-03-19 15:51:54 -07003519 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05303520 }
3521
Arun Khandavallifae92942016-08-01 13:31:08 +05303522 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
3523 ret = hdd_start_adapter(adapter);
3524 if (ret) {
3525 hdd_err("Failed to start adapter :%d",
3526 adapter->device_mode);
Dustin Brown3da3a832019-03-19 15:51:54 -07003527 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05303528 }
3529 }
3530
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003531 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3532 if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003533 hdd_debug("Enabling Tx Queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003534 /* Enable TX queues only when we are connected */
3535 wlan_hdd_netif_queue_control(adapter,
Arun Khandavallifae92942016-08-01 13:31:08 +05303536 WLAN_START_ALL_NETIF_QUEUE,
3537 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003538 }
3539
Naveen Rawat286def52016-09-23 15:38:02 -07003540 /* Enable carrier and transmit queues for NDI */
3541 if (WLAN_HDD_IS_NDI(adapter)) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003542 hdd_debug("Enabling Tx Queues");
Naveen Rawat286def52016-09-23 15:38:02 -07003543 wlan_hdd_netif_queue_control(adapter,
3544 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
3545 WLAN_CONTROL_PATH);
3546 }
3547
Naveen Rawat910726a2017-03-06 11:42:51 -08003548 hdd_populate_wifi_pos_cfg(hdd_ctx);
Arunk Khandavalli40943af2017-05-15 19:25:34 +05303549 hdd_lpass_notify_start(hdd_ctx, adapter);
Naveen Rawat910726a2017-03-06 11:42:51 -08003550
Dustin Brown3da3a832019-03-19 15:51:54 -07003551 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003552}
3553
3554/**
3555 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
Dustin Brown98f7c822019-03-06 12:25:49 -08003556 * @net_dev: Pointer to net_device structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003557 *
3558 * This is called in response to ifconfig up
3559 *
3560 * Return: 0 for success; non-zero for failure
3561 */
Dustin Brown0e1e1622019-01-17 11:00:22 -08003562static int hdd_open(struct net_device *net_dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003563{
Dustin Brown0e1e1622019-01-17 11:00:22 -08003564 int errno;
3565 struct osif_vdev_sync *vdev_sync;
3566
Alan Chen4bc1c112019-10-11 13:38:51 -07003567 errno = osif_vdev_sync_trans_start_wait(net_dev, &vdev_sync);
Dustin Brown0e1e1622019-01-17 11:00:22 -08003568 if (errno)
3569 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003570
Dustin Brown0e1e1622019-01-17 11:00:22 -08003571 errno = __hdd_open(net_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003572
Dustin Brown0e1e1622019-01-17 11:00:22 -08003573 osif_vdev_sync_trans_stop(vdev_sync);
3574
3575 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003576}
3577
3578/**
3579 * __hdd_stop() - HDD stop function
3580 * @dev: Pointer to net_device structure
3581 *
3582 * This is called in response to ifconfig down
3583 *
3584 * Return: 0 for success; non-zero for failure
3585 */
3586static int __hdd_stop(struct net_device *dev)
3587{
Jeff Johnson9d295242017-08-29 14:39:48 -07003588 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003589 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003590 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -07003591 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003592
Dustin Brownfdf17c12018-03-14 12:55:34 -07003593 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003594
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +05303595 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
3596 TRACE_CODE_HDD_STOP_REQUEST,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08003597 adapter->vdev_id, adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003598
3599 ret = wlan_hdd_validate_context(hdd_ctx);
Arunk Khandavalli987c8d52018-06-21 17:40:31 +05303600 if (ret) {
3601 set_bit(DOWN_DURING_SSR, &adapter->event_flags);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003602 return ret;
Arunk Khandavalli987c8d52018-06-21 17:40:31 +05303603 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003604
3605 /* Nothing to be done if the interface is not opened */
3606 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003607 hdd_err("NETDEV Interface is not OPENED");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003608 return -ENODEV;
3609 }
3610
3611 /* Make sure the interface is marked as closed */
3612 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303613
Jeff Johnson16528362018-06-14 12:34:16 -07003614 mac_handle = hdd_ctx->mac_handle;
3615
Mukul Sharmad16c2022017-07-25 18:56:12 +05303616 hdd_debug("Disabling Auto Power save timer");
3617 sme_ps_disable_auto_ps_timer(
Jeff Johnson16528362018-06-14 12:34:16 -07003618 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08003619 adapter->vdev_id);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303620
3621 /*
3622 * Disable TX on the interface, after this hard_start_xmit() will not
3623 * be called on that interface
3624 */
Dustin Browna7bb6ae2018-08-16 16:51:50 -07003625 hdd_debug("Disabling queues, adapter device mode: %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07003626 qdf_opmode_str(adapter->device_mode), adapter->device_mode);
Kabilan Kannan8dac3502017-10-30 12:40:27 -07003627
Himanshu Agarwal865201d2017-04-12 15:45:31 +05303628 wlan_hdd_netif_queue_control(adapter,
3629 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
3630 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003631
Arunk Khandavalli40943af2017-05-15 19:25:34 +05303632 if (adapter->device_mode == QDF_STA_MODE)
3633 hdd_lpass_notify_stop(hdd_ctx);
3634
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003635 /*
Naveen Rawat286def52016-09-23 15:38:02 -07003636 * NAN data interface is different in some sense. The traffic on NDI is
3637 * bursty in nature and depends on the need to transfer. The service
3638 * layer may down the interface after the usage and up again when
3639 * required. In some sense, the NDI is expected to be available
3640 * (like SAP) iface until NDI delete request is issued by the service
3641 * layer. Skip BSS termination and adapter deletion for NAN Data
3642 * interface (NDI).
3643 */
3644 if (WLAN_HDD_IS_NDI(adapter))
3645 return 0;
3646
3647 /*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003648 * The interface is marked as down for outside world (aka kernel)
3649 * But the driver is pretty much alive inside. The driver needs to
3650 * tear down the existing connection on the netdev (session)
3651 * cleanup the data pipes and wait until the control plane is stabilized
3652 * for this interface. The call also needs to wait until the above
3653 * mentioned actions are completed before returning to the caller.
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003654 * Notice that hdd_stop_adapter is requested not to close the session
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003655 * That is intentional to be able to scan if it is a STA/P2P interface
3656 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08003657 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003658
3659 /* DeInit the adapter. This ensures datapath cleanup as well */
3660 hdd_deinit_adapter(hdd_ctx, adapter, true);
3661
Dustin Brown4c663222018-10-23 14:19:36 -07003662 if (!hdd_is_any_interface_open(hdd_ctx))
3663 hdd_psoc_idle_timer_start(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303664
Dustin Browne74003f2018-03-14 12:51:58 -07003665 hdd_exit();
Dustin Brown4c663222018-10-23 14:19:36 -07003666
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003667 return 0;
3668}
3669
3670/**
3671 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
3672 * @dev: pointer to net_device structure
3673 *
3674 * This is called in response to ifconfig down
3675 *
3676 * Return: 0 for success and error number for failure
3677 */
Dustin Brown0e1e1622019-01-17 11:00:22 -08003678static int hdd_stop(struct net_device *net_dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003679{
Dustin Brown0e1e1622019-01-17 11:00:22 -08003680 int errno;
3681 struct osif_vdev_sync *vdev_sync;
3682
3683 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
3684 if (errno)
3685 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003686
Dustin Brown0e1e1622019-01-17 11:00:22 -08003687 errno = __hdd_stop(net_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003688
Dustin Brown0e1e1622019-01-17 11:00:22 -08003689 osif_vdev_sync_trans_stop(vdev_sync);
3690
3691 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003692}
3693
3694/**
Dustin Brown96b98dd2019-03-06 12:39:37 -08003695 * hdd_uninit() - HDD uninit function
3696 * @dev: Pointer to net_device structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003697 *
3698 * This is called during the netdev unregister to uninitialize all data
3699 * associated with the device
3700 *
Dustin Brown96b98dd2019-03-06 12:39:37 -08003701 * This function must be protected by a transition
3702 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003703 * Return: None
3704 */
Dustin Brown96b98dd2019-03-06 12:39:37 -08003705static void hdd_uninit(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003706{
Jeff Johnson9d295242017-08-29 14:39:48 -07003707 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson399c6272017-08-30 10:51:00 -07003708 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003709
Dustin Brownfdf17c12018-03-14 12:55:34 -07003710 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003711
Dustin Brown96b98dd2019-03-06 12:39:37 -08003712 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
3713 hdd_err("Invalid magic");
3714 goto exit;
3715 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003716
Dustin Brown96b98dd2019-03-06 12:39:37 -08003717 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3718 if (!hdd_ctx) {
3719 hdd_err("NULL hdd_ctx");
3720 goto exit;
3721 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003722
Dustin Brown96b98dd2019-03-06 12:39:37 -08003723 if (dev != adapter->dev)
3724 hdd_err("Invalid device reference");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003725
Dustin Brown96b98dd2019-03-06 12:39:37 -08003726 hdd_deinit_adapter(hdd_ctx, adapter, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003727
Dustin Brown96b98dd2019-03-06 12:39:37 -08003728 /* after uninit our adapter structure will no longer be valid */
3729 adapter->dev = NULL;
3730 adapter->magic = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003731
Dustin Brown96b98dd2019-03-06 12:39:37 -08003732exit:
Dustin Browne74003f2018-03-14 12:51:58 -07003733 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003734}
3735
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003736static int hdd_open_cesium_nl_sock(void)
3737{
3738#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3739 struct netlink_kernel_cfg cfg = {
3740 .groups = WLAN_NLINK_MCAST_GRP_ID,
3741 .input = NULL
3742 };
3743#endif
3744 int ret = 0;
3745
3746#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3747 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3748#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
3749 THIS_MODULE,
3750#endif
3751 &cfg);
3752#else
3753 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3754 WLAN_NLINK_MCAST_GRP_ID,
3755 NULL, NULL, THIS_MODULE);
3756#endif
3757
Jeff Johnsond36fa332019-03-18 13:42:25 -07003758 if (!cesium_nl_srv_sock) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003759 hdd_err("NLINK: cesium netlink_kernel_create failed");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003760 ret = -ECONNREFUSED;
3761 }
3762
3763 return ret;
3764}
3765
3766static void hdd_close_cesium_nl_sock(void)
3767{
Jeff Johnsond36fa332019-03-18 13:42:25 -07003768 if (cesium_nl_srv_sock) {
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003769 netlink_kernel_release(cesium_nl_srv_sock);
3770 cesium_nl_srv_sock = NULL;
3771 }
3772}
3773
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303774void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx,
3775 struct qdf_mac_addr *curr_mac_addr,
3776 struct qdf_mac_addr *new_mac_addr)
3777{
3778 uint8_t i;
3779
3780 hdd_enter();
3781
3782 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303783 if (!qdf_mem_cmp(
3784 curr_mac_addr->bytes,
3785 &hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes[0],
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303786 sizeof(struct qdf_mac_addr))) {
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303787 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].dynamic_mac,
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303788 new_mac_addr->bytes,
3789 sizeof(struct qdf_mac_addr));
3790 break;
3791 }
3792 }
3793
3794 hdd_exit();
3795}
3796
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003797/**
3798 * __hdd_set_mac_address() - set the user specified mac address
3799 * @dev: Pointer to the net device.
3800 * @addr: Pointer to the sockaddr.
3801 *
3802 * This function sets the user specified mac address using
Jeff Johnson06095fb2018-05-06 16:16:42 -07003803 * the command ifconfig wlanX hw ether <mac address>.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003804 *
3805 * Return: 0 for success, non zero for failure
3806 */
3807static int __hdd_set_mac_address(struct net_device *dev, void *addr)
3808{
Jeff Johnson9d295242017-08-29 14:39:48 -07003809 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +05303810 struct hdd_adapter *adapter_temp;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003811 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003812 struct sockaddr *psta_mac_addr = addr;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303813 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003814 int ret;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303815 struct qdf_mac_addr mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003816
Dustin Brownfdf17c12018-03-14 12:55:34 -07003817 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003818
Hanumanth Reddy Pothula5c7a7812018-03-09 12:55:32 +05303819 if (netif_running(dev)) {
3820 hdd_err("On iface up, set mac address change isn't supported");
3821 return -EBUSY;
3822 }
3823
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003824 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3825 ret = wlan_hdd_validate_context(hdd_ctx);
3826 if (0 != ret)
3827 return ret;
3828
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303829 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +05303830 adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
3831 if (adapter_temp) {
3832 if (!qdf_str_cmp(adapter_temp->dev->name, dev->name))
3833 return 0;
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003834 hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_STR,
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +05303835 adapter_temp->dev->name,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003836 QDF_MAC_ADDR_ARRAY(mac_addr.bytes));
Ashish Kumar Dhanotiyaf974f332018-04-19 16:03:15 +05303837 return -EINVAL;
3838 }
3839
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05303840 qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr);
3841 if (QDF_IS_STATUS_ERROR(qdf_ret_status))
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303842 return -EINVAL;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303843
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003844 hdd_info("Changing MAC to " QDF_MAC_ADDR_STR " of the interface %s ",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003845 QDF_MAC_ADDR_ARRAY(mac_addr.bytes), dev->name);
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303846
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303847 hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr);
Jeff Johnson1e851a12017-10-28 14:36:12 -07003848 memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003849 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
3850
Dustin Browne74003f2018-03-14 12:51:58 -07003851 hdd_exit();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303852 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003853}
3854
3855/**
3856 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
Dustin Brown98f7c822019-03-06 12:25:49 -08003857 * function from SSR
3858 * @net_dev: pointer to net_device structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003859 * @addr: Pointer to the sockaddr
3860 *
3861 * This function sets the user specified mac address using
Jeff Johnson06095fb2018-05-06 16:16:42 -07003862 * the command ifconfig wlanX hw ether <mac address>.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003863 *
3864 * Return: 0 for success.
3865 */
Dustin Brown98f7c822019-03-06 12:25:49 -08003866static int hdd_set_mac_address(struct net_device *net_dev, void *addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003867{
Dustin Brown98f7c822019-03-06 12:25:49 -08003868 struct osif_vdev_sync *vdev_sync;
3869 int errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003870
Dustin Brown98f7c822019-03-06 12:25:49 -08003871 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
3872 if (errno)
3873 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003874
Dustin Brown98f7c822019-03-06 12:25:49 -08003875 errno = __hdd_set_mac_address(net_dev, addr);
3876
3877 osif_vdev_sync_op_stop(vdev_sync);
3878
3879 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003880}
3881
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303882static uint8_t *wlan_hdd_get_derived_intf_addr(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003883{
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303884 int i, j;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003885
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303886 i = qdf_ffz(hdd_ctx->derived_intf_addr_mask);
3887 if (i < 0 || i >= hdd_ctx->num_derived_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003888 return NULL;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303889 qdf_atomic_set_bit(i, &hdd_ctx->derived_intf_addr_mask);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003890 hdd_info("Assigning MAC from derived list" QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003891 QDF_MAC_ADDR_ARRAY(hdd_ctx->derived_mac_addr[i].bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003892
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303893 /* Copy the mac in dynamic mac list at first free position */
3894 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) {
3895 if (qdf_is_macaddr_zero(&hdd_ctx->
3896 dynamic_mac_list[j].dynamic_mac))
3897 break;
3898 }
3899 if (j == QDF_MAX_CONCURRENCY_PERSONA) {
3900 hdd_err("Max interfaces are up");
3901 return NULL;
3902 }
Dustin Brown61cc3932018-10-18 16:12:13 -07003903
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303904 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes,
3905 &hdd_ctx->derived_mac_addr[i].bytes,
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303906 sizeof(struct qdf_mac_addr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303907 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = false;
3908 hdd_ctx->dynamic_mac_list[j].bit_position = i;
3909
3910 return hdd_ctx->derived_mac_addr[i].bytes;
3911}
3912
3913static uint8_t *wlan_hdd_get_provisioned_intf_addr(struct hdd_context *hdd_ctx)
3914{
3915 int i, j;
3916
3917 i = qdf_ffz(hdd_ctx->provisioned_intf_addr_mask);
3918 if (i < 0 || i >= hdd_ctx->num_provisioned_addr)
3919 return NULL;
3920 qdf_atomic_set_bit(i, &hdd_ctx->provisioned_intf_addr_mask);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003921 hdd_info("Assigning MAC from provisioned list" QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003922 QDF_MAC_ADDR_ARRAY(hdd_ctx->provisioned_mac_addr[i].bytes));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303923
3924 /* Copy the mac in dynamic mac list at first free position */
3925 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) {
3926 if (qdf_is_macaddr_zero(&hdd_ctx->
3927 dynamic_mac_list[j].dynamic_mac))
3928 break;
3929 }
3930 if (j == QDF_MAX_CONCURRENCY_PERSONA) {
3931 hdd_err("Max interfaces are up");
3932 return NULL;
3933 }
3934
3935 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes,
3936 &hdd_ctx->provisioned_mac_addr[i].bytes,
3937 sizeof(struct qdf_mac_addr));
3938 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = true;
3939 hdd_ctx->dynamic_mac_list[j].bit_position = i;
3940 return hdd_ctx->provisioned_mac_addr[i].bytes;
3941}
3942
3943uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx,
3944 enum QDF_OPMODE interface_type)
3945{
3946 uint8_t *mac_addr = NULL;
3947
3948 if (qdf_atomic_test_bit(interface_type,
3949 (unsigned long *)
3950 (&hdd_ctx->config->provisioned_intf_pool)))
3951 mac_addr = wlan_hdd_get_provisioned_intf_addr(hdd_ctx);
3952
3953 if ((!mac_addr) &&
3954 (qdf_atomic_test_bit(interface_type,
3955 (unsigned long *)
3956 (&hdd_ctx->config->derived_intf_pool))))
3957 mac_addr = wlan_hdd_get_derived_intf_addr(hdd_ctx);
3958
3959 if (!mac_addr)
3960 hdd_err("MAC is not available in both the lists");
3961 return mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003962}
3963
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07003964void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
3965 uint8_t *releaseAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003966{
3967 int i;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303968 int mac_pos_in_mask;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003969
Anurag Chouhan6d760662016-02-20 16:05:43 +05303970 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003971 if (!memcmp(releaseAddr,
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303972 hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes,
3973 QDF_MAC_ADDR_SIZE)) {
3974 mac_pos_in_mask =
3975 hdd_ctx->dynamic_mac_list[i].bit_position;
3976 if (hdd_ctx->dynamic_mac_list[i].is_provisioned_mac) {
3977 qdf_atomic_clear_bit(
3978 mac_pos_in_mask,
3979 &hdd_ctx->
3980 provisioned_intf_addr_mask);
3981 hdd_info("Releasing MAC from provisioned list");
3982 hdd_info(
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003983 QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003984 QDF_MAC_ADDR_ARRAY(releaseAddr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303985 } else {
3986 qdf_atomic_clear_bit(
3987 mac_pos_in_mask, &hdd_ctx->
3988 derived_intf_addr_mask);
3989 hdd_info("Releasing MAC from derived list");
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003990 hdd_info(QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003991 QDF_MAC_ADDR_ARRAY(releaseAddr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303992 }
3993 qdf_zero_macaddr(&hdd_ctx->
3994 dynamic_mac_list[i].dynamic_mac);
3995 hdd_ctx->dynamic_mac_list[i].is_provisioned_mac =
3996 false;
3997 hdd_ctx->dynamic_mac_list[i].bit_position = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003998 break;
3999 }
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05304000
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004001 }
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05304002 if (i == QDF_MAX_CONCURRENCY_PERSONA)
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07004003 hdd_err("Releasing non existing MAC" QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07004004 QDF_MAC_ADDR_ARRAY(releaseAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004005}
4006
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004007/**
4008 * __hdd_set_multicast_list() - set the multicast address list
4009 * @dev: Pointer to the WLAN device.
4010 * @skb: Pointer to OS packet (sk_buff).
4011 *
4012 * This funciton sets the multicast address list.
4013 *
4014 * Return: None
4015 */
4016static void __hdd_set_multicast_list(struct net_device *dev)
4017{
Jeff Johnson9d295242017-08-29 14:39:48 -07004018 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Dustin Brown0f874482018-06-13 14:39:22 -07004019 int i = 0, errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004020 struct netdev_hw_addr *ha;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004021 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304022 struct pmo_mc_addr_list_params *mc_list_request = NULL;
Dustin Brown1dbefe62018-09-11 16:32:03 -07004023 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304024 int mc_count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004025
Alan Chene825c3b2019-10-02 13:58:51 -07004026 if (hdd_ctx->hdd_wlan_suspended) {
4027 hdd_err_rl("Device is system suspended");
4028 return;
4029 }
4030
Dustin Brownfdf17c12018-03-14 12:55:34 -07004031 hdd_enter_dev(dev);
Anurag Chouhan6d760662016-02-20 16:05:43 +05304032 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304033 goto out;
Mukul Sharma51c44942015-10-30 19:30:19 +05304034
Dustin Brown0f874482018-06-13 14:39:22 -07004035 errno = wlan_hdd_validate_context(hdd_ctx);
4036 if (errno)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304037 goto out;
4038
Dustin Brown0f874482018-06-13 14:39:22 -07004039 errno = hdd_validate_adapter(adapter);
4040 if (errno)
Dustin Brownc788acb2017-08-01 17:43:51 -07004041 goto out;
4042
Arunk Khandavalli6a227882017-12-12 19:31:08 +05304043 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
4044 hdd_err("%s: Driver module is closed", __func__);
Dustin Brown0f874482018-06-13 14:39:22 -07004045 goto out;
Arunk Khandavalli6a227882017-12-12 19:31:08 +05304046 }
4047
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304048 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
Min Liu74a1a502018-10-10 19:59:07 +08004049 if (!mc_list_request)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304050 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004051
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05304052 /* Delete already configured multicast address list */
4053 if (adapter->mc_addr_list.mc_cnt > 0) {
Dustin Brown0f874482018-06-13 14:39:22 -07004054 hdd_debug("clear previously configured MC address list");
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05304055 hdd_disable_and_flush_mc_addr_list(adapter,
4056 pmo_mc_list_change_notify);
4057 }
4058
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004059 if (dev->flags & IFF_ALLMULTI) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004060 hdd_debug("allow all multicast frames");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304061 hdd_disable_and_flush_mc_addr_list(adapter,
4062 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004063 } else {
4064 mc_count = netdev_mc_count(dev);
Wu Gaod7dd6e42018-10-16 17:22:56 +08004065 if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004066 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
Wu Gaod7dd6e42018-10-16 17:22:56 +08004067 ucfg_pmo_max_mc_addr_supported(psoc));
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304068 hdd_disable_and_flush_mc_addr_list(adapter,
4069 pmo_mc_list_change_notify);
stonezdf2bdfd2018-11-20 14:45:06 +08004070 adapter->mc_addr_list.mc_cnt = 0;
Dustin Brown0f874482018-06-13 14:39:22 -07004071 goto free_req;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004072 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004073 netdev_for_each_mc_addr(ha, dev) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07004074 hdd_debug("ha_addr[%d] "QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07004075 i, QDF_MAC_ADDR_ARRAY(ha->addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004076 if (i == mc_count)
4077 break;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304078 memset(&(mc_list_request->mc_addr[i].bytes),
4079 0, ETH_ALEN);
4080 memcpy(&(mc_list_request->mc_addr[i].bytes),
4081 ha->addr, ETH_ALEN);
Dustin Brown0f874482018-06-13 14:39:22 -07004082 hdd_debug("mlist[%d] = %pM", i,
4083 mc_list_request->mc_addr[i].bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004084 i++;
4085 }
4086 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304087
stonezdf2bdfd2018-11-20 14:45:06 +08004088 adapter->mc_addr_list.mc_cnt = mc_count;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304089 mc_list_request->psoc = psoc;
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004090 mc_list_request->vdev_id = adapter->vdev_id;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304091 mc_list_request->count = mc_count;
Dustin Brown0f874482018-06-13 14:39:22 -07004092
4093 errno = hdd_cache_mc_addr_list(mc_list_request);
4094 if (errno) {
4095 hdd_err("Failed to cache MC address list for vdev %u; errno:%d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004096 adapter->vdev_id, errno);
Dustin Brown0f874482018-06-13 14:39:22 -07004097 goto free_req;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004098 }
Dustin Brown0f874482018-06-13 14:39:22 -07004099
4100 hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify);
4101
4102free_req:
4103 qdf_mem_free(mc_list_request);
4104
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304105out:
Dustin Browne74003f2018-03-14 12:51:58 -07004106 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004107}
4108
4109/**
4110 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
Dustin Brown98f7c822019-03-06 12:25:49 -08004111 * @net_dev: pointer to net_device
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004112 *
4113 * Return: none
4114 */
Dustin Brown98f7c822019-03-06 12:25:49 -08004115static void hdd_set_multicast_list(struct net_device *net_dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004116{
Dustin Brown98f7c822019-03-06 12:25:49 -08004117 struct osif_vdev_sync *vdev_sync;
4118
4119 if (osif_vdev_sync_op_start(net_dev, &vdev_sync))
4120 return;
4121
4122 __hdd_set_multicast_list(net_dev);
4123
4124 osif_vdev_sync_op_stop(vdev_sync);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004125}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004126
Subrat Dash5f36fbe2019-02-12 16:28:14 +05304127#ifdef WLAN_FEATURE_TSF_PTP
4128static const struct ethtool_ops wlan_ethtool_ops = {
4129 .get_ts_info = wlan_get_ts_info,
4130};
4131#endif
4132
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004133static const struct net_device_ops wlan_drv_ops = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004134 .ndo_open = hdd_open,
4135 .ndo_stop = hdd_stop,
4136 .ndo_uninit = hdd_uninit,
4137 .ndo_start_xmit = hdd_hard_start_xmit,
4138 .ndo_tx_timeout = hdd_tx_timeout,
4139 .ndo_get_stats = hdd_get_stats,
4140 .ndo_do_ioctl = hdd_ioctl,
4141 .ndo_set_mac_address = hdd_set_mac_address,
4142 .ndo_select_queue = hdd_select_queue,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004143 .ndo_set_rx_mode = hdd_set_multicast_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004144};
4145
Nirav Shah73713f72018-05-17 14:50:41 +05304146#ifdef FEATURE_MONITOR_MODE_SUPPORT
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004147/* Monitor mode net_device_ops, doesnot Tx and most of operations. */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004148static const struct net_device_ops wlan_mon_drv_ops = {
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004149 .ndo_open = hdd_mon_open,
4150 .ndo_stop = hdd_stop,
4151 .ndo_get_stats = hdd_get_stats,
4152};
4153
Subrat Dash5f36fbe2019-02-12 16:28:14 +05304154#ifdef WLAN_FEATURE_TSF_PTP
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004155/**
4156 * hdd_set_station_ops() - update net_device ops for monitor mode
Jeff Johnson5505db82017-11-02 21:19:23 -07004157 * @dev: Handle to struct net_device to be updated.
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004158 * Return: None
4159 */
Jeff Johnson5505db82017-11-02 21:19:23 -07004160void hdd_set_station_ops(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004161{
Subrat Dash5f36fbe2019-02-12 16:28:14 +05304162 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) {
4163 dev->netdev_ops = &wlan_mon_drv_ops;
4164 } else {
4165 dev->netdev_ops = &wlan_drv_ops;
4166 dev->ethtool_ops = &wlan_ethtool_ops;
4167 }
4168}
4169#else
4170void hdd_set_station_ops(struct net_device *dev)
4171{
4172 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
Jeff Johnson5505db82017-11-02 21:19:23 -07004173 dev->netdev_ops = &wlan_mon_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004174 else
Jeff Johnson5505db82017-11-02 21:19:23 -07004175 dev->netdev_ops = &wlan_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004176}
Subrat Dash5f36fbe2019-02-12 16:28:14 +05304177
4178#endif
4179#else
4180#ifdef WLAN_FEATURE_TSF_PTP
4181void hdd_set_station_ops(struct net_device *dev)
4182{
4183 dev->netdev_ops = &wlan_drv_ops;
4184 dev->ethtool_ops = &wlan_ethtool_ops;
4185}
Nirav Shah73713f72018-05-17 14:50:41 +05304186#else
4187void hdd_set_station_ops(struct net_device *dev)
4188{
4189 dev->netdev_ops = &wlan_drv_ops;
4190}
4191#endif
Subrat Dash5f36fbe2019-02-12 16:28:14 +05304192#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004193
4194/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08004195 * hdd_alloc_station_adapter() - allocate the station hdd adapter
4196 * @hdd_ctx: global hdd context
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004197 * @mac_addr: mac address to assign to the interface
Ryan Hsu07495ea2016-01-21 15:25:39 -08004198 * @name: User-visible name of the interface
4199 *
4200 * hdd adapter pointer would point to the netdev->priv space, this function
Jeff Johnson62018292018-05-06 16:18:35 -07004201 * would retrieve the pointer, and setup the hdd adapter configuration.
Ryan Hsu07495ea2016-01-21 15:25:39 -08004202 *
4203 * Return: the pointer to hdd adapter, otherwise NULL
4204 */
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004205static struct hdd_adapter *
4206hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr,
4207 unsigned char name_assign_type, const char *name)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004208{
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004209 struct net_device *dev;
4210 struct hdd_adapter *adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07004211 struct hdd_station_ctx *sta_ctx;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304212 QDF_STATUS qdf_status;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004213
4214 /* cfg80211 initialization and registration */
4215 dev = alloc_netdev_mq(sizeof(*adapter), name,
Ryan Hsu07495ea2016-01-21 15:25:39 -08004216#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004217 name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004218#endif
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004219 (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE ?
4220 hdd_mon_mode_ether_setup : ether_setup),
4221 NUM_TX_QUEUES);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004222
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004223 if (!dev) {
4224 hdd_err("Failed to allocate new net_device '%s'", name);
4225 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004226 }
4227
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004228 adapter = netdev_priv(dev);
4229
4230 qdf_mem_zero(adapter, sizeof(*adapter));
4231 sta_ctx = &adapter->session.station;
Sourav Mohapatraa3cf12a2019-08-19 15:40:49 +05304232 qdf_mem_zero(sta_ctx->conn_info.peer_macaddr,
4233 sizeof(sta_ctx->conn_info.peer_macaddr));
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004234 adapter->dev = dev;
4235 adapter->hdd_ctx = hdd_ctx;
4236 adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Jeff Johnson912b1bb2019-03-06 10:12:36 -08004237 adapter->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004238
4239 qdf_status = qdf_event_create(&adapter->qdf_session_open_event);
4240 if (QDF_IS_STATUS_ERROR(qdf_status))
4241 goto free_net_dev;
4242
4243 qdf_status = qdf_event_create(&adapter->qdf_session_close_event);
4244 if (QDF_IS_STATUS_ERROR(qdf_status))
4245 goto free_net_dev;
4246
4247 adapter->offloads_configured = false;
4248 adapter->is_link_up_service_needed = false;
4249 adapter->disconnection_in_progress = false;
4250 adapter->send_mode_change = true;
4251
Sourav Mohapatrac320ada2019-09-03 16:15:03 +05304252 /* Cache station count initialize to zero */
4253 qdf_atomic_init(&adapter->cache_sta_count);
4254
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004255 /* Init the net_device structure */
4256 strlcpy(dev->name, name, IFNAMSIZ);
4257
4258 qdf_mem_copy(dev->dev_addr, mac_addr, sizeof(tSirMacAddr));
4259 qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr));
4260 dev->watchdog_timeo = HDD_TX_TIMEOUT;
4261
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004262 hdd_set_station_ops(adapter->dev);
4263
4264 hdd_dev_setup_destructor(dev);
4265 dev->ieee80211_ptr = &adapter->wdev;
4266 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
4267 adapter->wdev.wiphy = hdd_ctx->wiphy;
4268 adapter->wdev.netdev = dev;
4269
4270 /* set dev's parent to underlying device */
4271 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
4272 hdd_wmm_init(adapter);
4273 spin_lock_init(&adapter->pause_map_lock);
4274 adapter->start_time = qdf_system_ticks();
4275 adapter->last_time = adapter->start_time;
4276
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004277 return adapter;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004278
4279free_net_dev:
4280 free_netdev(adapter->dev);
4281
4282 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004283}
4284
Jeff Johnson9d295242017-08-29 14:39:48 -07004285static QDF_STATUS hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004286{
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004287 struct net_device *dev = adapter->dev;
4288 int ret;
4289
Dustin Brown491d54b2018-03-14 12:39:11 -07004290 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004291
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004292 if (rtnl_held) {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004293 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
4294
4295 ret = dev_alloc_name(dev, dev->name);
4296 if (ret < 0) {
4297 hdd_err(
4298 "unable to get dev name: %s, err = 0x%x",
4299 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304300 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004301 }
4302 }
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004303
4304 ret = register_netdevice(dev);
4305 if (ret) {
4306 hdd_err("register_netdevice(%s) failed, err = 0x%x",
4307 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304308 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004309 }
4310 } else {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004311 ret = register_netdev(dev);
4312 if (ret) {
4313 hdd_err("register_netdev(%s) failed, err = 0x%x",
4314 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304315 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004316 }
4317 }
4318 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
4319
Dustin Browne74003f2018-03-14 12:51:58 -07004320 hdd_exit();
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004321
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304322 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004323}
4324
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004325QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id)
Krunal Sonib51eec72017-11-20 21:53:01 -08004326{
4327 struct hdd_adapter *adapter;
4328 struct hdd_context *hdd_ctx;
4329
4330 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4331 if (!hdd_ctx) {
4332 hdd_err("Invalid HDD_CTX");
4333 return QDF_STATUS_E_FAILURE;
4334 }
4335
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004336 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnsond36fa332019-03-18 13:42:25 -07004337 if (!adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004338 hdd_err("NULL adapter");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304339 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004340 }
4341
4342 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004343 hdd_err("Invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304344 return QDF_STATUS_NOT_INITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004345 }
4346
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004347 /*
4348 * For NAN Data interface, the close session results in the final
4349 * indication to the userspace
4350 */
Rakesh Sunki3480f962016-08-29 17:29:53 -07004351 if (adapter->device_mode == QDF_NDI_MODE)
4352 hdd_ndp_session_end_handler(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004353
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004354 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
4355
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004356 /*
4357 * We can be blocked while waiting for scheduled work to be
4358 * flushed, and the adapter structure can potentially be freed, in
4359 * which case the magic will have been reset. So make sure the
4360 * magic is still good, and hence the adapter structure is still
4361 * valid, before signaling completion
4362 */
4363 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304364 qdf_event_set(&adapter->qdf_session_close_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004365
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304366 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004367}
4368
Jeff Johnson9d295242017-08-29 14:39:48 -07004369int hdd_vdev_ready(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004370{
Min Liu8c5d99e2018-09-10 17:18:44 +08004371 struct wlan_objmgr_vdev *vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004372 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004373
Min Liu8c5d99e2018-09-10 17:18:44 +08004374 vdev = hdd_objmgr_get_vdev(adapter);
4375 if (!vdev)
4376 return -EINVAL;
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004377
Min Liu8c5d99e2018-09-10 17:18:44 +08004378 status = pmo_vdev_ready(vdev);
4379 if (QDF_IS_STATUS_ERROR(status)) {
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304380 hdd_objmgr_put_vdev(vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004381 return qdf_status_to_os_return(status);
Min Liu8c5d99e2018-09-10 17:18:44 +08004382 }
4383
4384 status = ucfg_reg_11d_vdev_created_update(vdev);
4385 if (QDF_IS_STATUS_ERROR(status)) {
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304386 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08004387 return qdf_status_to_os_return(status);
4388 }
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004389
4390 if (wma_capability_enhanced_mcast_filter())
Min Liu8c5d99e2018-09-10 17:18:44 +08004391 status = ucfg_pmo_enhanced_mc_filter_enable(vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004392 else
Min Liu8c5d99e2018-09-10 17:18:44 +08004393 status = ucfg_pmo_enhanced_mc_filter_disable(vdev);
4394
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304395 hdd_objmgr_put_vdev(vdev);
Dustin Brownd28772b2017-03-17 14:16:07 -07004396
4397 return qdf_status_to_os_return(status);
4398}
4399
Jeff Johnson9d295242017-08-29 14:39:48 -07004400int hdd_vdev_destroy(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07004401{
4402 QDF_STATUS status;
Dustin Brown2da29eb2018-07-13 14:23:12 -07004403 int errno;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004404 struct hdd_context *hdd_ctx;
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004405 uint8_t vdev_id;
Min Liu8c5d99e2018-09-10 17:18:44 +08004406 struct wlan_objmgr_vdev *vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004407
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004408 vdev_id = adapter->vdev_id;
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004409 hdd_info("destroying vdev %d", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004410
4411 /* vdev created sanity check */
4412 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
Dustin Brown2da29eb2018-07-13 14:23:12 -07004413 hdd_err("vdev %u does not exist", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004414 return -EINVAL;
4415 }
Dustin Brown2da29eb2018-07-13 14:23:12 -07004416
Abhishek Singh628bb6f2019-03-26 14:52:40 +05304417 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4418
4419 /*
4420 * if this is the last active connection check & stop the
4421 * opportunistic timer first
4422 */
4423 if ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 1 &&
4424 policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
4425 policy_mgr_convert_device_mode_to_qdf_type(
4426 adapter->device_mode), NULL) == 1) ||
4427 !policy_mgr_get_connection_count(hdd_ctx->psoc))
4428 policy_mgr_check_and_stop_opportunistic_timer(hdd_ctx->psoc,
4429 adapter->vdev_id);
4430
Min Liu8c5d99e2018-09-10 17:18:44 +08004431 vdev = hdd_objmgr_get_vdev(adapter);
4432 if (!vdev)
4433 return -EINVAL;
Ashish Kumar Dhanotiya68ee2e42018-11-19 21:15:14 +05304434
4435 ucfg_pmo_del_wow_pattern(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08004436 status = ucfg_reg_11d_vdev_delete_update(vdev);
Abhishek Singh935e4772018-11-21 14:14:10 +05304437 ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304438 hdd_objmgr_put_vdev(vdev);
Yue Maf9782842017-05-08 12:49:49 -07004439
Arun Kumar Khandavallidac7a452019-10-28 11:33:54 +05304440 /* Disable serialization for vdev before sending vdev delete */
4441 wlan_ser_vdev_queue_disable(adapter->vdev);
4442
Dustin Brownd28772b2017-03-17 14:16:07 -07004443 /* close sme session (destroy vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304444 qdf_event_reset(&adapter->qdf_session_close_event);
Arun Kumar Khandavalli4f6a5bd2019-10-23 16:01:15 +05304445 status = sme_vdev_delete(hdd_ctx->mac_handle, vdev);
Dustin Brownd28772b2017-03-17 14:16:07 -07004446 if (QDF_IS_STATUS_ERROR(status)) {
Abhishek Amburecbef1442019-06-10 17:15:00 +05304447 hdd_err("failed to delete vdev; status:%d", status);
Jiachao Wu2c42c222018-01-15 18:13:19 +08004448 goto release_vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004449 }
4450
4451 /* block on a completion variable until sme session is closed */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304452 status = qdf_wait_for_event_completion(
4453 &adapter->qdf_session_close_event,
Abhishek Singh13bf0ce2018-10-24 14:26:14 +05304454 SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
Dustin Brown2da29eb2018-07-13 14:23:12 -07004455
4456 if (QDF_IS_STATUS_ERROR(status)) {
4457 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
4458
Dustin Brownd28772b2017-03-17 14:16:07 -07004459 if (adapter->device_mode == QDF_NDI_MODE)
4460 hdd_ndp_session_end_handler(adapter);
Dustin Brown2da29eb2018-07-13 14:23:12 -07004461
Jianmin Zhu387e65c2019-10-18 20:21:57 +08004462 if (status == QDF_STATUS_E_TIMEOUT) {
Abhishek Amburecbef1442019-06-10 17:15:00 +05304463 hdd_err("timed out waiting for sme vdev delete");
Jianmin Zhu387e65c2019-10-18 20:21:57 +08004464 sme_cleanup_session(hdd_ctx->mac_handle, vdev_id);
4465 } else if (adapter->qdf_session_close_event.force_set) {
Abhishek Amburecbef1442019-06-10 17:15:00 +05304466 hdd_info("SSR occurred during sme vdev delete");
Jianmin Zhu387e65c2019-10-18 20:21:57 +08004467 } else {
Abhishek Amburecbef1442019-06-10 17:15:00 +05304468 hdd_err("failed to wait for sme vdev delete; status:%u",
Dustin Brown2da29eb2018-07-13 14:23:12 -07004469 status);
Jianmin Zhu387e65c2019-10-18 20:21:57 +08004470 }
Dustin Brownd28772b2017-03-17 14:16:07 -07004471 }
Jiachao Wu2c42c222018-01-15 18:13:19 +08004472
Yue Maf9782842017-05-08 12:49:49 -07004473release_vdev:
Jiachao Wu2c42c222018-01-15 18:13:19 +08004474
Sandeep Puligillaef415362017-08-30 16:37:13 -07004475 /* do vdev logical destroy via objmgr */
Dustin Brownb277dd62018-01-26 15:17:33 -08004476 errno = hdd_objmgr_release_and_destroy_vdev(adapter);
Sandeep Puligillaef415362017-08-30 16:37:13 -07004477 if (errno) {
Dustin Brownb277dd62018-01-26 15:17:33 -08004478 hdd_err("failed to destroy objmgr vdev; errno:%d", errno);
Sandeep Puligillaef415362017-08-30 16:37:13 -07004479 return errno;
4480 }
4481
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004482 hdd_info("vdev %d destroyed successfully", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004483
4484 return 0;
4485}
4486
gaurank kathpalia6c4b50c2019-02-28 14:07:48 +05304487void
gaurank kathpalia78af1932018-10-27 20:33:10 +05304488hdd_store_nss_chains_cfg_in_vdev(struct hdd_adapter *adapter)
4489{
4490 struct wlan_mlme_nss_chains vdev_ini_cfg;
4491 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4492
gaurank kathpaliab414bce2018-11-09 18:44:46 +05304493 /* Populate the nss chain params from ini for this vdev type */
gaurank kathpalia78af1932018-10-27 20:33:10 +05304494 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
4495 adapter->device_mode,
4496 hdd_ctx->num_rf_chains);
gaurank kathpaliab414bce2018-11-09 18:44:46 +05304497
4498 /* Store the nss chain config into the vdev */
4499 sme_store_nss_chains_cfg_in_vdev(adapter->vdev, &vdev_ini_cfg);
gaurank kathpalia78af1932018-10-27 20:33:10 +05304500}
gaurank kathpalia6982d472018-10-31 21:54:15 +05304501
4502bool hdd_is_vdev_in_conn_state(struct hdd_adapter *adapter)
4503{
4504 switch (adapter->device_mode) {
4505 case QDF_STA_MODE:
4506 case QDF_P2P_CLIENT_MODE:
4507 case QDF_P2P_DEVICE_MODE:
4508 return hdd_conn_is_connected(
4509 WLAN_HDD_GET_STATION_CTX_PTR(adapter));
4510 case QDF_SAP_MODE:
4511 case QDF_P2P_GO_MODE:
4512 return (test_bit(SOFTAP_BSS_STARTED,
4513 &adapter->event_flags));
4514 default:
4515 hdd_err("Device mode %d invalid", adapter->device_mode);
4516 return 0;
4517 }
4518
4519 return 0;
4520}
4521
Arun Kumar Khandavalli4f6a5bd2019-10-23 16:01:15 +05304522static struct vdev_osif_priv *
4523hdd_init_vdev_os_priv(struct hdd_adapter *adapter)
4524{
4525 struct vdev_osif_priv *os_priv;
4526
4527 os_priv = qdf_mem_malloc(sizeof(*os_priv));
4528 if (!os_priv)
4529 return NULL;
4530
4531 /* Initialize the vdev OS private structure*/
4532 os_priv->wdev = adapter->dev->ieee80211_ptr;
4533 os_priv->legacy_osif_priv = adapter;
4534
4535 return os_priv;
4536}
4537
Arun Kumar Khandavalli42b44872019-10-21 19:02:04 +05304538int hdd_vdev_create(struct hdd_adapter *adapter)
Krunal Sonib51eec72017-11-20 21:53:01 -08004539{
4540 QDF_STATUS status;
4541 int errno;
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304542 bool bval;
Krunal Sonib51eec72017-11-20 21:53:01 -08004543 struct hdd_context *hdd_ctx;
Min Liu8c5d99e2018-09-10 17:18:44 +08004544 struct wlan_objmgr_vdev *vdev;
Arun Kumar Khandavalli4f6a5bd2019-10-23 16:01:15 +05304545 struct vdev_osif_priv *osif_priv;
4546 struct wlan_vdev_create_params vdev_params = {0};
Krunal Sonib51eec72017-11-20 21:53:01 -08004547
4548 hdd_info("creating new vdev");
Dustin Brownd28772b2017-03-17 14:16:07 -07004549
4550 /* do vdev create via objmgr */
4551 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Arun Kumar Khandavalliadd284b2019-10-23 12:27:39 +05304552 status = sme_check_for_duplicate_session(hdd_ctx->mac_handle,
4553 adapter->mac_addr.bytes);
4554 if (QDF_IS_STATUS_ERROR(status)) {
4555 hdd_err("Duplicate session is existing with same mac address");
4556 errno = qdf_status_to_os_return(status);
4557 return errno;
4558 }
Arun Kumar Khandavalli4f6a5bd2019-10-23 16:01:15 +05304559
4560 osif_priv = hdd_init_vdev_os_priv(adapter);
4561 if (!osif_priv) {
4562 hdd_err("Failed to allocate osif_priv");
4563 return -ENOMEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004564 }
Dustin Brownd28772b2017-03-17 14:16:07 -07004565
Arun Kumar Khandavalli4f6a5bd2019-10-23 16:01:15 +05304566 vdev_params.opmode = adapter->device_mode;
4567 vdev_params.osifp = osif_priv;
4568 qdf_mem_copy(vdev_params.macaddr,
4569 adapter->mac_addr.bytes,
4570 QDF_NET_MAC_ADDR_MAX_LEN);
4571
4572 vdev = sme_vdev_create(hdd_ctx->mac_handle, &vdev_params);
4573 if (!vdev) {
4574 hdd_err("failed to create vdev");
4575 return -EINVAL;
Krunal Sonib51eec72017-11-20 21:53:01 -08004576 }
Arun Kumar Khandavalli4f6a5bd2019-10-23 16:01:15 +05304577
4578 if (wlan_objmgr_vdev_try_get_ref(vdev, WLAN_HDD_ID_OBJ_MGR) !=
4579 QDF_STATUS_SUCCESS) {
4580 errno = QDF_STATUS_E_INVAL;
4581 sme_vdev_delete(hdd_ctx->mac_handle, vdev);
4582 wlan_objmgr_vdev_obj_delete(vdev);
4583 return -EINVAL;
Dustin Brownd28772b2017-03-17 14:16:07 -07004584 }
4585
Arun Kumar Khandavallibcd56342019-10-18 16:46:53 +05304586 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
Arun Kumar Khandavalli4f6a5bd2019-10-23 16:01:15 +05304587 qdf_spin_lock_bh(&adapter->vdev_lock);
4588 adapter->vdev_id = wlan_vdev_get_id(vdev);
4589 adapter->vdev = vdev;
4590 qdf_spin_unlock_bh(&adapter->vdev_lock);
4591
Dustin Brownd28772b2017-03-17 14:16:07 -07004592 /* firmware ready for component communication, raise vdev_ready event */
4593 errno = hdd_vdev_ready(adapter);
4594 if (errno) {
4595 hdd_err("failed to dispatch vdev ready event: %d", errno);
Krunal Soni4a020c72017-10-30 20:58:40 -07004596 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004597 }
4598
Naveen Rawat2b430892018-03-13 13:58:18 -07004599 if (adapter->device_mode == QDF_STA_MODE) {
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304600 bval = false;
4601 status = ucfg_mlme_get_rtt_mac_randomization(hdd_ctx->psoc,
4602 &bval);
4603 if (QDF_IS_STATUS_ERROR(status))
4604 hdd_err("unable to get RTT MAC randomization value");
4605
4606 hdd_debug("setting RTT mac randomization param: %d", bval);
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004607 errno = sme_cli_set_command(adapter->vdev_id,
Naveen Rawat2b430892018-03-13 13:58:18 -07004608 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC,
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304609 bval,
Naveen Rawat2b430892018-03-13 13:58:18 -07004610 VDEV_CMD);
4611 if (0 != errno)
4612 hdd_err("RTT mac randomization param set failed %d",
4613 errno);
4614 }
4615
Bala Venkatesh110b03e2018-07-10 16:02:08 +05304616 if (adapter->device_mode == QDF_STA_MODE ||
Min Liu8c5d99e2018-09-10 17:18:44 +08004617 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
4618 vdev = hdd_objmgr_get_vdev(adapter);
4619 if (!vdev)
4620 goto hdd_vdev_destroy_procedure;
4621 wlan_vdev_set_max_peer_count(vdev, HDD_MAX_VDEV_PEER_COUNT);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304622 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08004623 }
Bala Venkatesh110b03e2018-07-10 16:02:08 +05304624
gaurank kathpalia78af1932018-10-27 20:33:10 +05304625 hdd_store_nss_chains_cfg_in_vdev(adapter);
4626
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004627 hdd_info("vdev %d created successfully", adapter->vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004628
4629 return 0;
4630
Krunal Soni4a020c72017-10-30 20:58:40 -07004631hdd_vdev_destroy_procedure:
Dustin Brownd28772b2017-03-17 14:16:07 -07004632 QDF_BUG(!hdd_vdev_destroy(adapter));
4633
4634 return errno;
4635}
4636
Jeff Johnson9d295242017-08-29 14:39:48 -07004637QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07004638{
Jeff Johnsonb9424862017-10-30 08:49:35 -07004639 struct hdd_station_ctx *sta_ctx = &adapter->session.station;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004640 struct hdd_context *hdd_ctx;
Dustin Brownd28772b2017-03-17 14:16:07 -07004641 QDF_STATUS status;
4642 int ret_val;
Jeff Johnson16528362018-06-14 12:34:16 -07004643 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304644 bool bval = false;
Qun Zhang1b3c85c2019-08-27 16:31:49 +08004645 uint8_t enable_sifs_burst = 0;
Dustin Brownd28772b2017-03-17 14:16:07 -07004646
Dustin Brownd28772b2017-03-17 14:16:07 -07004647 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson16528362018-06-14 12:34:16 -07004648 mac_handle = hdd_ctx->mac_handle;
4649 sme_set_curr_device_mode(mac_handle, adapter->device_mode);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304650 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
4651 if (!QDF_IS_STATUS_SUCCESS(status))
4652 hdd_err("unable to get vht_enable2x2");
4653 sme_set_pdev_ht_vht_ies(mac_handle, bval);
4654
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004655 sme_set_vdev_ies_per_band(mac_handle, adapter->vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004656
Jeff Johnson7f2c5912018-03-23 11:42:28 -07004657 hdd_roam_profile_init(adapter);
4658 hdd_register_wext(adapter->dev);
4659
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -07004660 hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004661
Deepak Dhamdherea2785822016-11-17 01:17:45 -08004662 /* set fast roaming capability in sme session */
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004663 status = sme_config_fast_roaming(mac_handle, adapter->vdev_id,
Abhishek Singh1f217ec2017-12-22 11:48:27 +05304664 true);
sheenam monga67ecb072019-09-20 11:25:23 +05304665 /* Set the default operation channel freq*/
4666 sta_ctx->conn_info.chan_freq = hdd_ctx->config->operating_chan_freq;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004667
4668 /* Make the default Auth Type as OPEN */
Jeff Johnson96e33512019-02-27 15:10:21 -08004669 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004670
4671 status = hdd_init_tx_rx(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304672 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004673 hdd_err("hdd_init_tx_rx() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004674 status, status);
4675 goto error_init_txrx;
4676 }
4677
4678 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4679
4680 status = hdd_wmm_adapter_init(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304681 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004682 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004683 status, status);
4684 goto error_wmm_init;
4685 }
4686
4687 set_bit(WMM_INIT_DONE, &adapter->event_flags);
4688
Qun Zhang1b3c85c2019-08-27 16:31:49 +08004689 status = ucfg_get_enable_sifs_burst(hdd_ctx->psoc, &enable_sifs_burst);
4690 if (!QDF_IS_STATUS_SUCCESS(status))
4691 hdd_err("Failed to get sifs burst value, use default");
4692
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004693 ret_val = sme_cli_set_command(adapter->vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004694 WMI_PDEV_PARAM_BURST_ENABLE,
Qun Zhang1b3c85c2019-08-27 16:31:49 +08004695 enable_sifs_burst,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004696 PDEV_CMD);
Dustin Brownd28772b2017-03-17 14:16:07 -07004697 if (ret_val)
4698 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004699
Poddar, Siddarth4b3f7312017-11-02 17:00:20 +05304700 /*
4701 * In case of USB tethering, LRO is disabled. If SSR happened
4702 * during that time, then as part of SSR init, do not enable
4703 * the LRO again. Keep the LRO state same as before SSR.
4704 */
jitiphil377bcc12018-10-05 19:46:08 +05304705 if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
4706 cfg_dp_lro_enable) &&
4707 !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -07004708 adapter->dev->features |= NETIF_F_LRO;
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05304709
Rakshith Suresh Patkar9f5c5862019-02-04 16:23:02 +05304710 if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
4711 cfg_dp_enable_ip_tcp_udp_checksum_offload))
4712 adapter->dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
4713 adapter->dev->features |= NETIF_F_RXCSUM;
4714
4715 hdd_set_tso_flags(hdd_ctx, adapter->dev);
4716
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05304717 /* rcpi info initialization */
4718 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
4719
Abhinav Kumar523ca372019-08-30 16:28:19 +05304720 if (adapter->device_mode == QDF_STA_MODE)
4721 mlme_set_roam_trigger_bitmap(hdd_ctx->psoc, adapter->vdev_id,
4722 DEFAULT_ROAM_TRIGGER_BITMAP);
4723
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304724 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004725
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004726error_wmm_init:
4727 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4728 hdd_deinit_tx_rx(adapter);
4729error_init_txrx:
Dustin Brownd28772b2017-03-17 14:16:07 -07004730 hdd_unregister_wext(adapter->dev);
Dustin Brownd28772b2017-03-17 14:16:07 -07004731 QDF_BUG(!hdd_vdev_destroy(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004732
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004733 return status;
4734}
4735
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304736/**
Krunal Soni4a020c72017-10-30 20:58:40 -07004737 * hdd_deinit_station_mode() - De-initialize the station adapter
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304738 * @hdd_ctx: global hdd context
4739 * @adapter: HDD adapter
Jeff Johnson590e2012016-10-05 16:16:24 -07004740 * @rtnl_held: Used to indicate whether or not the caller is holding
4741 * the kernel rtnl_mutex
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304742 *
4743 * This function De-initializes the STA/P2P/OCB adapter.
4744 *
4745 * Return: None.
4746 */
Krunal Soni4a020c72017-10-30 20:58:40 -07004747static void hdd_deinit_station_mode(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004748 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004749 bool rtnl_held)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304750{
Dustin Brownfdf17c12018-03-14 12:55:34 -07004751 hdd_enter_dev(adapter->dev);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304752
Hanumanth Reddy Pothula7a657402016-09-07 20:59:18 +05304753 if (adapter->dev) {
4754 if (rtnl_held)
4755 adapter->dev->wireless_handlers = NULL;
4756 else {
4757 rtnl_lock();
4758 adapter->dev->wireless_handlers = NULL;
4759 rtnl_unlock();
4760 }
4761 }
4762
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304763 if (test_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags)) {
4764 hdd_deinit_tx_rx(adapter);
4765 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4766 }
4767
4768 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
4769 hdd_wmm_adapter_close(adapter);
4770 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
4771 }
4772
Krunal Sonib51eec72017-11-20 21:53:01 -08004773
Dustin Browne74003f2018-03-14 12:51:58 -07004774 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304775}
4776
Krunal Sonib51eec72017-11-20 21:53:01 -08004777void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
4778 struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004779 bool rtnl_held)
4780{
Dustin Brown491d54b2018-03-14 12:39:11 -07004781 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304782
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004783 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004784 case QDF_STA_MODE:
4785 case QDF_P2P_CLIENT_MODE:
4786 case QDF_P2P_DEVICE_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08004787 case QDF_IBSS_MODE:
4788 case QDF_NDI_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004789 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004790 hdd_deinit_station_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004791 break;
4792 }
4793
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004794 case QDF_SAP_MODE:
4795 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004796 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004797 hdd_deinit_ap_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004798 break;
4799 }
4800
4801 default:
4802 break;
4803 }
4804
Dustin Browne74003f2018-03-14 12:51:58 -07004805 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004806}
4807
Min Liu8c5d99e2018-09-10 17:18:44 +08004808static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
4809 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004810 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004811{
Jeff Johnson5505db82017-11-02 21:19:23 -07004812 struct net_device *dev = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004813
4814 if (adapter)
Jeff Johnson5505db82017-11-02 21:19:23 -07004815 dev = adapter->dev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004816 else {
Jeff Johnson5880d792016-08-15 13:32:30 -07004817 hdd_err("adapter is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004818 return;
4819 }
4820
Alok Kumarb64650c2018-03-23 17:05:11 +05304821 hdd_nud_deinit_tracking(adapter);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05304822 hdd_mic_deinit_work(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05304823 qdf_mutex_destroy(&adapter->disconnection_status_lock);
Nachiket Kukade5f0ce4f2018-06-15 19:47:37 +05304824 hdd_apf_context_destroy(adapter);
Min Liu8c5d99e2018-09-10 17:18:44 +08004825 qdf_spinlock_destroy(&adapter->vdev_lock);
Alok Kumarb64650c2018-03-23 17:05:11 +05304826
Sourav Mohapatra43e6dea2019-08-18 11:39:23 +05304827 if (adapter->device_mode == QDF_SAP_MODE ||
Sourav Mohapatrac320ada2019-09-03 16:15:03 +05304828 adapter->device_mode == QDF_P2P_GO_MODE) {
Sourav Mohapatra43e6dea2019-08-18 11:39:23 +05304829 hdd_sta_info_deinit(&adapter->sta_info_list);
Sourav Mohapatrac320ada2019-09-03 16:15:03 +05304830 hdd_sta_info_deinit(&adapter->cache_sta_info_list);
4831 }
Sourav Mohapatra43e6dea2019-08-18 11:39:23 +05304832
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05304833 wlan_hdd_debugfs_csr_deinit(adapter);
Arunk Khandavallica56d4b2018-11-29 15:46:00 +05304834 if (adapter->device_mode == QDF_STA_MODE)
4835 hdd_sysfs_destroy_adapter_root_obj(adapter);
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05304836
Rajeev Kumardca5f812016-02-04 17:28:06 -08004837 hdd_debugfs_exit(adapter);
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05304838
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004839 /*
4840 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
4841 * the driver is almost closed and cannot handle either control
4842 * messages or data. However, unregister_netdevice() call above will
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004843 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
4844 * to close the active connections(basically excites control path) which
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004845 * is not right. Setting this flag helps hdd_stop() to recognize that
4846 * the interface is closed and restricts any operations on that
4847 */
4848 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
4849
4850 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004851 if (rtnl_held)
Jeff Johnson5505db82017-11-02 21:19:23 -07004852 unregister_netdevice(dev);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004853 else
Jeff Johnson5505db82017-11-02 21:19:23 -07004854 unregister_netdev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004855 /*
4856 * Note that the adapter is no longer valid at this point
4857 * since the memory has been reclaimed
4858 */
4859 }
4860}
4861
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004862static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07004863 tSirMacAddr mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004864{
Jeff Johnson9d295242017-08-29 14:39:48 -07004865 struct hdd_adapter *adapter;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004866
Dustin Brown920397d2017-12-13 16:27:50 -08004867 hdd_for_each_adapter(hdd_ctx, adapter) {
4868 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07004869 mac_addr, sizeof(tSirMacAddr))) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304870 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004871 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004872 }
Dustin Brown920397d2017-12-13 16:27:50 -08004873
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304874 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004875}
Ryan Hsu07495ea2016-01-21 15:25:39 -08004876
Arun Khandavalli2358d522016-05-16 18:05:37 +05304877#ifdef CONFIG_FW_LOGS_BASED_ON_INI
4878/**
4879 * hdd_set_fw_log_params() - Set log parameters to FW
4880 * @hdd_ctx: HDD Context
4881 * @adapter: HDD Adapter
4882 *
4883 * This function set the FW Debug log level based on the INI.
4884 *
4885 * Return: None
4886 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004887static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004888 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304889{
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304890 QDF_STATUS status;
4891 uint16_t enable_fw_log_level, enable_fw_log_type;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304892 int ret;
4893
Arun Khandavallifae92942016-08-01 13:31:08 +05304894 if (QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
4895 (!hdd_ctx->config->enable_fw_log)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004896 hdd_debug("enable_fw_log not enabled in INI or in FTM mode return");
Arun Khandavalli2358d522016-05-16 18:05:37 +05304897 return;
4898 }
4899
Arun Khandavallifae92942016-08-01 13:31:08 +05304900 /* Enable FW logs based on INI configuration */
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304901 status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc,
4902 &enable_fw_log_type);
4903 if (QDF_IS_STATUS_ERROR(status))
4904 return;
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004905 ret = sme_cli_set_command(adapter->vdev_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304906 WMI_DBGLOG_TYPE,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304907 enable_fw_log_type,
Arun Khandavallifae92942016-08-01 13:31:08 +05304908 DBG_CMD);
4909 if (ret != 0)
4910 hdd_err("Failed to enable FW log type ret %d",
4911 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304912
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304913 status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc,
4914 &enable_fw_log_level);
4915 if (QDF_IS_STATUS_ERROR(status))
4916 return;
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004917 ret = sme_cli_set_command(adapter->vdev_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304918 WMI_DBGLOG_LOG_LEVEL,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304919 enable_fw_log_level,
Arun Khandavallifae92942016-08-01 13:31:08 +05304920 DBG_CMD);
4921 if (ret != 0)
4922 hdd_err("Failed to enable FW log level ret %d",
4923 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304924
lifengfaa83cb2018-11-24 01:53:56 +08004925 sme_enable_fw_module_log_level(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004926 adapter->vdev_id);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304927}
4928#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004929static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004930 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304931{
4932}
4933
4934#endif
4935
4936/**
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004937 * hdd_configure_chain_mask() - programs chain mask to firmware
4938 * @adapter: HDD adapter
4939 *
4940 * Return: 0 on success or errno on failure
4941 */
4942static int hdd_configure_chain_mask(struct hdd_adapter *adapter)
4943{
Naveen Rawat98322472018-03-06 10:29:42 -08004944 QDF_STATUS status;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004945 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Naveen Rawatdacb5032018-02-08 15:23:24 -08004946
Dustin Brown1dbefe62018-09-11 16:32:03 -07004947 status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004948 adapter->vdev_id);
gaurank kathpalia7633dfc2019-09-13 20:04:58 +05304949 if (QDF_IS_STATUS_ERROR(status))
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304950 goto error;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004951
4952 return 0;
4953
4954error:
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304955 hdd_err("WMI PDEV set param failed");
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004956 return -EINVAL;
4957}
4958
4959/**
Dundi Raviteja3b637092018-09-12 13:42:50 +05304960 * hdd_send_coex_config_params() - Send coex config params to FW
4961 * @hdd_ctx: HDD context
4962 * @adapter: Primary adapter context
4963 *
4964 * This function is used to send all coex config related params to FW
4965 *
4966 * Return: 0 on success and -EINVAL on failure
4967 */
4968static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx,
4969 struct hdd_adapter *adapter)
4970{
4971 struct coex_config_params coex_cfg_params = {0};
4972 struct wlan_fwol_coex_config config = {0};
Dustin Brown05d81302018-09-11 16:49:22 -07004973 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Dundi Raviteja3b637092018-09-12 13:42:50 +05304974 QDF_STATUS status;
4975
4976 if (!hdd_ctx) {
4977 hdd_err("hdd_ctx is invalid");
4978 goto err;
4979 }
4980
4981 if (!adapter) {
4982 hdd_err("adapter is invalid");
4983 goto err;
4984 }
4985
4986 if (!psoc) {
4987 hdd_err("HDD psoc is invalid");
4988 goto err;
4989 }
4990
4991 status = ucfg_fwol_get_coex_config_params(psoc, &config);
4992 if (QDF_IS_STATUS_ERROR(status)) {
4993 hdd_err("Unable to get coex config params");
4994 goto err;
4995 }
4996
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004997 coex_cfg_params.vdev_id = adapter->vdev_id;
Dundi Raviteja3b637092018-09-12 13:42:50 +05304998 coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER;
4999 coex_cfg_params.config_arg1 = config.max_tx_power_for_btc;
5000
5001 status = sme_send_coex_config_cmd(&coex_cfg_params);
5002 if (QDF_IS_STATUS_ERROR(status)) {
5003 hdd_err("Failed to send coex Tx power");
5004 goto err;
5005 }
5006
5007 coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI;
5008 coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold;
5009
5010 status = sme_send_coex_config_cmd(&coex_cfg_params);
5011 if (QDF_IS_STATUS_ERROR(status)) {
5012 hdd_err("Failed to send coex handover RSSI");
5013 goto err;
5014 }
5015
5016 coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE;
5017 coex_cfg_params.config_arg1 = config.btc_mode;
5018
5019 status = sme_send_coex_config_cmd(&coex_cfg_params);
5020 if (QDF_IS_STATUS_ERROR(status)) {
5021 hdd_err("Failed to send coex BTC mode");
5022 goto err;
5023 }
5024
5025 coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION;
5026 coex_cfg_params.config_arg1 = config.antenna_isolation;
5027
5028 status = sme_send_coex_config_cmd(&coex_cfg_params);
5029 if (QDF_IS_STATUS_ERROR(status)) {
5030 hdd_err("Failed to send coex antenna isolation");
5031 goto err;
5032 }
5033
5034 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD;
5035 coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold;
5036
5037 status = sme_send_coex_config_cmd(&coex_cfg_params);
5038 if (QDF_IS_STATUS_ERROR(status)) {
5039 hdd_err("Failed to send coex BT low RSSI threshold");
5040 goto err;
5041 }
5042
5043 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL;
5044 coex_cfg_params.config_arg1 = config.bt_interference_low_ll;
5045 coex_cfg_params.config_arg2 = config.bt_interference_low_ul;
5046 coex_cfg_params.config_arg3 = config.bt_interference_medium_ll;
5047 coex_cfg_params.config_arg4 = config.bt_interference_medium_ul;
5048 coex_cfg_params.config_arg5 = config.bt_interference_high_ll;
5049 coex_cfg_params.config_arg6 = config.bt_interference_high_ul;
5050
5051 status = sme_send_coex_config_cmd(&coex_cfg_params);
5052 if (QDF_IS_STATUS_ERROR(status)) {
5053 hdd_err("Failed to send coex BT interference level");
5054 goto err;
5055 }
stonezc9936cb2019-03-11 16:41:22 +08005056
5057 if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config))
5058 goto err;
5059
hqu1dd504a2019-06-04 11:24:11 +08005060 coex_cfg_params.config_type =
5061 WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN;
5062 coex_cfg_params.config_arg1 = config.bt_sco_allow_wlan_2g_scan;
5063
5064 status = sme_send_coex_config_cmd(&coex_cfg_params);
5065 if (QDF_IS_STATUS_ERROR(status)) {
5066 hdd_err("Failed to send coex BT sco allow wlan 2g scan");
5067 goto err;
5068 }
5069
Dundi Raviteja3b637092018-09-12 13:42:50 +05305070 return 0;
5071err:
5072 return -EINVAL;
5073}
5074
5075/**
Arun Khandavalli2358d522016-05-16 18:05:37 +05305076 * hdd_set_fw_params() - Set parameters to firmware
5077 * @adapter: HDD adapter
5078 *
5079 * This function Sets various parameters to fw once the
5080 * adapter is started.
5081 *
5082 * Return: 0 on success or errno on failure
5083 */
Jeff Johnson9d295242017-08-29 14:39:48 -07005084int hdd_set_fw_params(struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05305085{
5086 int ret;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05305087 uint16_t upper_brssi_thresh, lower_brssi_thresh, rts_profile;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05305088 bool enable_dtim_1chrx;
5089 QDF_STATUS status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005090 struct hdd_context *hdd_ctx;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05305091 bool bval = false;
Manikandan Mohand350c192018-11-29 14:01:12 -08005092 uint8_t max_amsdu_len, enable_tx_sch_delay;
5093 uint32_t dtim_sel_diversity, enable_secondary_rate;
Arun Khandavalli2358d522016-05-16 18:05:37 +05305094
Dustin Brownfdf17c12018-03-14 12:55:34 -07005095 hdd_enter_dev(adapter->dev);
Arun Khandavalli2358d522016-05-16 18:05:37 +05305096
5097 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
5098 if (!hdd_ctx)
5099 return -EINVAL;
5100
Dustin Brown732ab9c2017-06-15 13:24:09 -07005101 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
5102 hdd_debug("FTM Mode is active; nothing to do");
5103 return 0;
5104 }
5105
Manikandan Mohand350c192018-11-29 14:01:12 -08005106 ret = -1;
5107 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_lprx_enable(hdd_ctx->psoc,
5108 &bval))) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005109 ret = sme_cli_set_command(adapter->vdev_id,
Manikandan Mohand350c192018-11-29 14:01:12 -08005110 WMI_PDEV_PARAM_DTIM_SYNTH,
5111 bval, PDEV_CMD);
5112 }
Ashish Kumar Dhanotiyab8630ab2017-07-21 14:18:14 +05305113 if (ret) {
5114 hdd_err("Failed to set LPRx");
5115 goto error;
5116 }
5117
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +05305118 ucfg_mlme_get_dtim_selection_diversity(hdd_ctx->psoc,
5119 &dtim_sel_diversity);
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05305120
5121 ret = sme_cli_set_command(
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005122 adapter->vdev_id,
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05305123 WMI_PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION,
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +05305124 dtim_sel_diversity, PDEV_CMD);
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05305125 if (ret) {
5126 hdd_err("Failed to set DTIM_OPTIMIZED_CHAIN_SELECTION");
5127 goto error;
5128 }
5129
Manikandan Mohand350c192018-11-29 14:01:12 -08005130 ret = -1;
5131 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_tx_sch_delay(
5132 hdd_ctx->psoc, &enable_tx_sch_delay))) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005133 ret = sme_cli_set_command(adapter->vdev_id,
Manikandan Mohand350c192018-11-29 14:01:12 -08005134 WMI_PDEV_PARAM_TX_SCH_DELAY,
5135 enable_tx_sch_delay, PDEV_CMD);
5136 }
Ashish Kumar Dhanotiya48dac7d2018-03-28 14:59:50 +05305137 if (ret) {
5138 hdd_err("Failed to set WMI_PDEV_PARAM_TX_SCH_DELAY");
5139 goto error;
5140 }
5141
Manikandan Mohand350c192018-11-29 14:01:12 -08005142 ret = -1;
5143 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_secondary_rate(
5144 hdd_ctx->psoc, &enable_secondary_rate))) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005145 ret = sme_cli_set_command(adapter->vdev_id,
Manikandan Mohand350c192018-11-29 14:01:12 -08005146 WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE,
5147 enable_secondary_rate, PDEV_CMD);
5148 }
Ashish Kumar Dhanotiya959b38c2018-04-06 21:07:57 +05305149 if (ret) {
5150 hdd_err("Failed to set WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE");
5151 goto error;
5152 }
5153
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05305154 if (adapter->device_mode == QDF_STA_MODE) {
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05305155 status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc,
5156 &upper_brssi_thresh);
5157 if (QDF_IS_STATUS_ERROR(status))
5158 return -EINVAL;
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05305159
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005160 sme_set_smps_cfg(adapter->vdev_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05305161 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH,
5162 upper_brssi_thresh);
5163
5164 status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc,
5165 &lower_brssi_thresh);
5166 if (QDF_IS_STATUS_ERROR(status))
5167 return -EINVAL;
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05305168
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005169 sme_set_smps_cfg(adapter->vdev_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05305170 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH,
5171 lower_brssi_thresh);
5172
5173 status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc,
5174 &enable_dtim_1chrx);
5175 if (QDF_IS_STATUS_ERROR(status))
5176 return -EINVAL;
5177
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005178 sme_set_smps_cfg(adapter->vdev_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05305179 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE,
5180 enable_dtim_1chrx);
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05305181 }
5182
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05305183 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
5184 if (!QDF_IS_STATUS_SUCCESS(status))
5185 hdd_err("unable to get vht_enable2x2");
5186
5187 if (bval) {
Dustin Brown732ab9c2017-06-15 13:24:09 -07005188 hdd_debug("configuring 2x2 mode fw params");
5189
Vignesh Viswanathana851d752018-10-03 19:44:38 +05305190 ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005191 adapter->vdev_id);
Dustin Brown732ab9c2017-06-15 13:24:09 -07005192 if (ret) {
5193 hdd_err("WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE set failed %d",
5194 ret);
5195 goto error;
5196 }
Liangwei Dong22810e82018-03-15 03:42:12 -04005197
5198 if (hdd_configure_chain_mask(adapter))
5199 goto error;
Dustin Brown732ab9c2017-06-15 13:24:09 -07005200 } else {
Arun Khandavalli2358d522016-05-16 18:05:37 +05305201#define HDD_DTIM_1CHAIN_RX_ID 0x5
5202#define HDD_SMPS_PARAM_VALUE_S 29
Dustin Brown732ab9c2017-06-15 13:24:09 -07005203 hdd_debug("configuring 1x1 mode fw params");
5204
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07005205 /*
5206 * Disable DTIM 1 chain Rx when in 1x1,
5207 * we are passing two value
5208 * as param_id << 29 | param_value.
5209 * Below param_value = 0(disable)
5210 */
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005211 ret = sme_cli_set_command(adapter->vdev_id,
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07005212 WMI_STA_SMPS_PARAM_CMDID,
5213 HDD_DTIM_1CHAIN_RX_ID <<
5214 HDD_SMPS_PARAM_VALUE_S,
5215 VDEV_CMD);
5216 if (ret) {
5217 hdd_err("DTIM 1 chain set failed %d", ret);
5218 goto error;
5219 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05305220
Arun Khandavalli2358d522016-05-16 18:05:37 +05305221#undef HDD_DTIM_1CHAIN_RX_ID
5222#undef HDD_SMPS_PARAM_VALUE_S
Naveen Rawat269b4ed2017-12-07 06:47:32 -08005223
5224 if (hdd_configure_chain_mask(adapter))
5225 goto error;
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07005226 }
5227
Vignesh Viswanathana851d752018-10-03 19:44:38 +05305228 ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005229 adapter->vdev_id);
Dustin Brown732ab9c2017-06-15 13:24:09 -07005230 if (ret) {
5231 hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d", ret);
5232 goto error;
5233 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05305234
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05305235 status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile);
5236 if (QDF_IS_STATUS_ERROR(status))
5237 return -EINVAL;
5238
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005239 ret = sme_cli_set_command(adapter->vdev_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07005240 WMI_VDEV_PARAM_ENABLE_RTSCTS,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05305241 rts_profile,
Dustin Brown732ab9c2017-06-15 13:24:09 -07005242 VDEV_CMD);
5243 if (ret) {
5244 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
5245 goto error;
Arun Khandavalli2358d522016-05-16 18:05:37 +05305246 }
5247
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05305248 status = ucfg_mlme_get_max_amsdu_num(hdd_ctx->psoc, &max_amsdu_len);
5249 if (QDF_IS_STATUS_ERROR(status)) {
5250 hdd_err("Failed to get Max AMSDU Num");
5251 goto error;
5252 }
5253
5254 hdd_debug("SET AMSDU num %d", max_amsdu_len);
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07005255
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005256 ret = wma_cli_set_command(adapter->vdev_id,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07005257 GEN_VDEV_PARAM_AMSDU,
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05305258 max_amsdu_len,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07005259 GEN_CMD);
5260 if (ret != 0) {
5261 hdd_err("GEN_VDEV_PARAM_AMSDU set failed %d", ret);
5262 goto error;
5263 }
5264
Arun Khandavalli2358d522016-05-16 18:05:37 +05305265 hdd_set_fw_log_params(hdd_ctx, adapter);
Dundi Raviteja3b637092018-09-12 13:42:50 +05305266
5267 ret = hdd_send_coex_config_params(hdd_ctx, adapter);
5268 if (ret) {
5269 hdd_warn("Error initializing coex config params");
5270 goto error;
5271 }
5272
Dustin Browne74003f2018-03-14 12:51:58 -07005273 hdd_exit();
Dustin Brown732ab9c2017-06-15 13:24:09 -07005274
Arun Khandavalli2358d522016-05-16 18:05:37 +05305275 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05305276
Arun Khandavalli2358d522016-05-16 18:05:37 +05305277error:
5278 return -EINVAL;
5279}
5280
Ryan Hsu07495ea2016-01-21 15:25:39 -08005281/**
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305282 * hdd_init_completion() - Initialize Completion Variables
5283 * @adapter: HDD adapter
5284 *
5285 * This function Initialize the completion variables for
5286 * a particular adapter
5287 *
5288 * Return: None
5289 */
5290static void hdd_init_completion(struct hdd_adapter *adapter)
5291{
5292 init_completion(&adapter->disconnect_comp_var);
5293 init_completion(&adapter->roaming_comp_var);
5294 init_completion(&adapter->linkup_event_var);
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305295 init_completion(&adapter->sta_authorized_event);
5296 init_completion(&adapter->offchannel_tx_event);
5297 init_completion(&adapter->tx_action_cnf_event);
5298 init_completion(&adapter->ibss_peer_info_comp);
5299 init_completion(&adapter->lfr_fw_status.disable_lfr_event);
5300}
5301
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305302static void hdd_reset_locally_admin_bit(struct hdd_context *hdd_ctx,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005303 tSirMacAddr mac_addr)
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305304{
5305 int i;
5306 /*
5307 * Reset locally administered bit for dynamic_mac_list
5308 * also as while releasing the MAC address for any
5309 * interface mac will be compared with dynamic mac list
5310 */
5311 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
5312 if (!qdf_mem_cmp(
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005313 mac_addr,
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305314 &hdd_ctx->
5315 dynamic_mac_list[i].dynamic_mac.bytes[0],
5316 sizeof(struct qdf_mac_addr))) {
5317 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(
5318 hdd_ctx->
5319 dynamic_mac_list[i].dynamic_mac.bytes);
5320 break;
5321 }
5322 }
5323 /*
5324 * Reset locally administered bit if the device mode is
5325 * STA
5326 */
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005327 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305328 hdd_debug("locally administered bit reset in sta mode: "
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07005329 QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(mac_addr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305330}
5331
Dustin Brown96b98dd2019-03-06 12:39:37 -08005332static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
5333{
5334 struct hdd_adapter *adapter =
5335 container_of(work, struct hdd_adapter, scan_block_work);
5336 struct osif_vdev_sync *vdev_sync;
5337
5338 if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync))
5339 return;
5340
5341 wlan_hdd_cfg80211_scan_block(adapter);
5342
5343 osif_vdev_sync_op_stop(vdev_sync);
5344}
5345
Rachit Kankane33bf18f2019-06-20 08:05:07 +05305346static u8 hdd_get_mode_specific_interface_count(struct hdd_context *hdd_ctx,
5347 enum QDF_OPMODE mode)
5348{
5349 struct hdd_adapter *adapter = NULL;
5350 u8 intf_count = 0;
5351
5352 hdd_for_each_adapter(hdd_ctx, adapter) {
5353 if (adapter->device_mode == mode)
5354 intf_count++;
5355 }
5356 return intf_count;
5357}
5358
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305359/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08005360 * hdd_open_adapter() - open and setup the hdd adatper
5361 * @hdd_ctx: global hdd context
5362 * @session_type: type of the interface to be created
5363 * @iface_name: User-visible name of the interface
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005364 * @mac_addr: MAC address to assign to the interface
Ryan Hsu07495ea2016-01-21 15:25:39 -08005365 * @name_assign_type: the name of assign type of the netdev
5366 * @rtnl_held: the rtnl lock hold flag
5367 *
5368 * This function open and setup the hdd adpater according to the device
5369 * type request, assign the name, the mac address assigned, and then prepared
5370 * the hdd related parameters, queue, lock and ready to start.
5371 *
5372 * Return: the pointer of hdd adapter, otherwise NULL.
5373 */
Jeff Johnson9d295242017-08-29 14:39:48 -07005374struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t session_type,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005375 const char *iface_name, tSirMacAddr mac_addr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08005376 unsigned char name_assign_type,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08005377 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005378{
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305379 struct net_device *ndev = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07005380 struct hdd_adapter *adapter = NULL;
Rachit Kankane33bf18f2019-06-20 08:05:07 +05305381 u8 intf_count = 0;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305382 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005383
5384 if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
5385 /*
5386 * Max limit reached on the number of vdevs configured by the
5387 * host. Return error
5388 */
Arun Khandavallifae92942016-08-01 13:31:08 +05305389 hdd_err("Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
5390 hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005391 return NULL;
5392 }
5393
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005394 status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)mac_addr);
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05305395 if (QDF_IS_STATUS_ERROR(status)) {
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005396 /* Not received valid mac_addr */
Arun Khandavallifae92942016-08-01 13:31:08 +05305397 hdd_err("Unable to add virtual intf: Not able to get valid mac address");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005398 return NULL;
5399 }
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05305400
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005401 status = hdd_check_for_existing_macaddr(hdd_ctx, mac_addr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305402 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07005403 hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_STR
Arun Khandavallifae92942016-08-01 13:31:08 +05305404 " already exists",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07005405 QDF_MAC_ADDR_ARRAY(mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005406 return NULL;
5407 }
5408
5409 switch (session_type) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005410 case QDF_STA_MODE:
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305411 if (!hdd_ctx->config->mac_provision) {
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005412 hdd_reset_locally_admin_bit(hdd_ctx, mac_addr);
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305413 /*
5414 * After resetting locally administered bit
5415 * again check if the new mac address is already
5416 * exists.
5417 */
5418 status = hdd_check_for_existing_macaddr(hdd_ctx,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005419 mac_addr);
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305420 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07005421 hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_STR
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305422 " already exists",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07005423 QDF_MAC_ADDR_ARRAY(mac_addr));
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305424 return NULL;
5425 }
5426 }
Rachit Kankane33bf18f2019-06-20 08:05:07 +05305427 /* Check for max no of supported VDEVs before creating
5428 * another one.
5429 */
5430 intf_count = hdd_get_mode_specific_interface_count(
5431 hdd_ctx,
5432 session_type);
5433 if (CFG_TGT_DEFAULT_MAX_STA_VDEVS &&
5434 (intf_count >= CFG_TGT_DEFAULT_MAX_STA_VDEVS)) {
5435 hdd_err("Max limit reached sta vdev-current %d max %d",
5436 intf_count, CFG_TGT_DEFAULT_MAX_STA_VDEVS);
5437 return NULL;
5438 }
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05305439
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005440 /* fall through */
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005441 case QDF_P2P_CLIENT_MODE:
5442 case QDF_P2P_DEVICE_MODE:
5443 case QDF_OCB_MODE:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07005444 case QDF_NDI_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305445 case QDF_MONITOR_MODE:
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005446 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08005447 name_assign_type,
5448 iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005449
Jeff Johnsond36fa332019-03-18 13:42:25 -07005450 if (!adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05305451 hdd_err("failed to allocate adapter for session %d",
5452 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005453 return NULL;
5454 }
5455
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305456 ndev = adapter->dev;
5457
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005458 if (QDF_P2P_CLIENT_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005459 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005460 else if (QDF_P2P_DEVICE_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005461 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305462 else if (QDF_MONITOR_MODE == session_type)
5463 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005464 else
5465 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
5466
5467 adapter->device_mode = session_type;
5468
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005469
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005470 /*
5471 * Workqueue which gets scheduled in IPv4 notification
5472 * callback
5473 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005474 INIT_WORK(&adapter->ipv4_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005475 hdd_ipv4_notifier_work_queue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005476
5477#ifdef WLAN_NS_OFFLOAD
5478 /*
5479 * Workqueue which gets scheduled in IPv6
5480 * notification callback.
5481 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005482 INIT_WORK(&adapter->ipv6_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005483 hdd_ipv6_notifier_work_queue);
5484#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005485 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005486 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08005487 goto err_free_netdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005488
5489 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005490 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005491 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305492 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5493 WLAN_CONTROL_PATH);
Arun Khandavallifae92942016-08-01 13:31:08 +05305494
Alok Kumarb64650c2018-03-23 17:05:11 +05305495 hdd_nud_init_tracking(adapter);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05305496 hdd_mic_init_work(adapter);
5497
Arunk Khandavallica56d4b2018-11-29 15:46:00 +05305498 if (adapter->device_mode == QDF_STA_MODE ||
5499 adapter->device_mode == QDF_P2P_DEVICE_MODE)
5500 hdd_sysfs_create_adapter_root_obj(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305501 qdf_mutex_create(&adapter->disconnection_status_lock);
5502
Ravi Joshi1a292562017-05-18 16:28:54 -07005503 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005504
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005505 case QDF_P2P_GO_MODE:
5506 case QDF_SAP_MODE:
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005507 adapter = hdd_wlan_create_ap_dev(hdd_ctx, mac_addr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08005508 name_assign_type,
5509 (uint8_t *) iface_name);
Jeff Johnsond36fa332019-03-18 13:42:25 -07005510 if (!adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005511 hdd_err("failed to allocate adapter for session %d",
Arun Khandavallifae92942016-08-01 13:31:08 +05305512 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005513 return NULL;
5514 }
5515
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305516 ndev = adapter->dev;
5517
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005518 adapter->wdev.iftype =
5519 (session_type ==
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005520 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005521 NL80211_IFTYPE_P2P_GO;
5522 adapter->device_mode = session_type;
5523
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07005524 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005525 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005526 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08005527
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005528 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005529 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305530 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5531 WLAN_CONTROL_PATH);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305532
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05305533 hdd_mic_init_work(adapter);
5534
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305535 /*
5536 * Workqueue which gets scheduled in IPv4 notification
5537 * callback
5538 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005539 INIT_WORK(&adapter->ipv4_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305540 hdd_ipv4_notifier_work_queue);
5541
5542#ifdef WLAN_NS_OFFLOAD
5543 /*
5544 * Workqueue which gets scheduled in IPv6
5545 * notification callback.
5546 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005547 INIT_WORK(&adapter->ipv6_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305548 hdd_ipv6_notifier_work_queue);
5549#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005550 break;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305551 case QDF_FTM_MODE:
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005552 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr,
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305553 name_assign_type,
Lin Bai1c678482017-12-18 18:29:11 +08005554 iface_name);
Jeff Johnsond36fa332019-03-18 13:42:25 -07005555 if (!adapter) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305556 hdd_err("Failed to allocate adapter for FTM mode");
5557 return NULL;
5558 }
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305559
5560 ndev = adapter->dev;
5561
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305562 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
5563 adapter->device_mode = session_type;
5564 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005565 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08005566 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08005567
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305568 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005569 hdd_debug("Disabling queues");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305570 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305571 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5572 WLAN_CONTROL_PATH);
Rakshith Suresh Patkara8405f52019-09-09 17:59:10 +05305573
5574 hdd_mic_init_work(adapter);
5575
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305576 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005577 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005578 hdd_err("Invalid session type %d", session_type);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305579 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005580 return NULL;
5581 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005582
Min Liu8c5d99e2018-09-10 17:18:44 +08005583 qdf_spinlock_create(&adapter->vdev_lock);
5584
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305585 hdd_init_completion(adapter);
hqueaa33ee2017-05-04 17:56:35 +08005586 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
Min Liu9be5d4a2018-05-17 11:51:53 +08005587 qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT);
5588 qdf_mutex_create(&adapter->blocked_scan_request_q_lock);
gaurank kathpalia7aed85e2019-10-10 15:12:54 +05305589 qdf_event_create(&adapter->acs_complete_event);
hqueaa33ee2017-05-04 17:56:35 +08005590
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305591 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005592 /* Add it to the hdd's session list. */
Dustin Brown920397d2017-12-13 16:27:50 -08005593 status = hdd_add_adapter_back(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005594 }
5595
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305596 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsond36fa332019-03-18 13:42:25 -07005597 if (adapter) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005598 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
5599 adapter = NULL;
5600 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005601
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005602 return NULL;
5603 }
Nachiket Kukade5f0ce4f2018-06-15 19:47:37 +05305604 hdd_apf_context_init(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005605
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305606 if (QDF_STATUS_SUCCESS == status) {
Dustin Brown1dbefe62018-09-11 16:32:03 -07005607 policy_mgr_set_concurrency_mode(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005608 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005609
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005610 /* Adapter successfully added. Increment the vdev count */
5611 hdd_ctx->current_intf_count++;
5612
Jeff Johnson5880d792016-08-15 13:32:30 -07005613 hdd_debug("current_intf_count=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005614 hdd_ctx->current_intf_count);
5615
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08005616 hdd_check_and_restart_sap_with_non_dfs_acs();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005617 }
5618
Rajeev Kumardca5f812016-02-04 17:28:06 -08005619 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
Mahesh Kumar Kalikot Veetil80dda9a2017-07-17 11:38:03 -07005620 hdd_err("Interface %s wow debug_fs init failed",
5621 netdev_name(adapter->dev));
5622
5623 hdd_info("%s interface created. iftype: %d", netdev_name(adapter->dev),
5624 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005625
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05305626 if (adapter->device_mode == QDF_STA_MODE)
5627 wlan_hdd_debugfs_csr_init(adapter);
5628
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005629 return adapter;
5630
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005631err_free_netdev:
Jeff Johnson1e851a12017-10-28 14:36:12 -07005632 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305633
5634 if (ndev)
5635 free_netdev(ndev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005636
5637 return NULL;
5638}
5639
Dustin Brown728d65a2018-10-02 16:27:52 -07005640static void __hdd_close_adapter(struct hdd_context *hdd_ctx,
5641 struct hdd_adapter *adapter,
5642 bool rtnl_held)
5643{
5644 qdf_list_destroy(&adapter->blocked_scan_request_q);
5645 qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock);
5646 policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
gaurank kathpalia7aed85e2019-10-10 15:12:54 +05305647 qdf_event_destroy(&adapter->acs_complete_event);
Dustin Brown728d65a2018-10-02 16:27:52 -07005648 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
5649
5650 if (hdd_ctx->current_intf_count != 0)
5651 hdd_ctx->current_intf_count--;
5652}
5653
5654void hdd_close_adapter(struct hdd_context *hdd_ctx,
5655 struct hdd_adapter *adapter,
5656 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005657{
Dustin Brown920397d2017-12-13 16:27:50 -08005658 /*
Dustin Brown728d65a2018-10-02 16:27:52 -07005659 * Stop the global bus bandwidth timer while touching the adapter list
5660 * to avoid bad memory access by the timer handler.
Dustin Brown920397d2017-12-13 16:27:50 -08005661 */
Dustin Brown920397d2017-12-13 16:27:50 -08005662 hdd_bus_bw_compute_timer_stop(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005663
Dustin Brown920397d2017-12-13 16:27:50 -08005664 hdd_remove_adapter(hdd_ctx, adapter);
Dustin Brown728d65a2018-10-02 16:27:52 -07005665 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005666
Dustin Brown920397d2017-12-13 16:27:50 -08005667 /* conditionally restart the bw timer */
5668 hdd_bus_bw_compute_timer_try_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005669}
5670
Dustin Brown728d65a2018-10-02 16:27:52 -07005671void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005672{
Dustin Brown920397d2017-12-13 16:27:50 -08005673 struct hdd_adapter *adapter;
Dustin Brown2c5e0482019-02-05 16:14:43 -08005674 struct osif_vdev_sync *vdev_sync;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005675
Dustin Brown491d54b2018-03-14 12:39:11 -07005676 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005677
Dustin Brown728d65a2018-10-02 16:27:52 -07005678 while (QDF_IS_STATUS_SUCCESS(hdd_remove_front_adapter(hdd_ctx,
5679 &adapter))) {
Dustin Brown2c5e0482019-02-05 16:14:43 -08005680 vdev_sync = osif_vdev_sync_unregister(adapter->dev);
Dustin Brown693b5352019-01-17 10:00:31 -08005681 if (vdev_sync)
Dustin Brown2c5e0482019-02-05 16:14:43 -08005682 osif_vdev_sync_wait_for_ops(vdev_sync);
Dustin Brown693b5352019-01-17 10:00:31 -08005683
Dustin Brown728d65a2018-10-02 16:27:52 -07005684 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
5685 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
Dustin Brown693b5352019-01-17 10:00:31 -08005686
5687 if (vdev_sync)
Dustin Brown2c5e0482019-02-05 16:14:43 -08005688 osif_vdev_sync_destroy(vdev_sync);
Dustin Brown728d65a2018-10-02 16:27:52 -07005689 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005690
Dustin Browne74003f2018-03-14 12:51:58 -07005691 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005692}
5693
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005694void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005695{
Anurag Chouhan6d760662016-02-20 16:05:43 +05305696 struct qdf_mac_addr *bssid = NULL;
Jeff Johnsonc565af12019-03-10 21:09:47 -07005697 tSirUpdateIE update_ie;
Jeff Johnson16528362018-06-14 12:34:16 -07005698 mac_handle_t mac_handle;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005699
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005700 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005701 case QDF_STA_MODE:
5702 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005703 {
Jeff Johnsond377dce2017-10-04 10:32:42 -07005704 struct hdd_station_ctx *sta_ctx =
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005705 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnsone04b6992019-02-27 14:06:55 -08005706 bssid = &sta_ctx->conn_info.bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005707 break;
5708 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005709 case QDF_SAP_MODE:
5710 case QDF_P2P_GO_MODE:
5711 case QDF_IBSS_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005712 {
Jeff Johnson1e851a12017-10-28 14:36:12 -07005713 bssid = &adapter->mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005714 break;
5715 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005716 case QDF_FTM_MODE:
5717 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005718 default:
5719 /*
5720 * wlan_hdd_reset_prob_rspies should not have been called
5721 * for these kind of devices
5722 */
Jeff Johnson5880d792016-08-15 13:32:30 -07005723 hdd_err("Unexpected request for the current device type %d",
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005724 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005725 return;
5726 }
5727
Jeff Johnsonc565af12019-03-10 21:09:47 -07005728 qdf_copy_macaddr(&update_ie.bssid, bssid);
Abhishek Singh5a2c42f2019-11-19 11:39:23 +05305729 update_ie.vdev_id = adapter->vdev_id;
Jeff Johnsonc565af12019-03-10 21:09:47 -07005730 update_ie.ieBufferlength = 0;
5731 update_ie.pAdditionIEBuffer = NULL;
5732 update_ie.append = true;
5733 update_ie.notify = false;
Jeff Johnson16528362018-06-14 12:34:16 -07005734 mac_handle = hdd_adapter_get_mac_handle(adapter);
5735 if (sme_update_add_ie(mac_handle,
Jeff Johnsonc565af12019-03-10 21:09:47 -07005736 &update_ie,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305737 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005738 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005739 }
5740}
5741
Sravan Goudfb8c84f2019-10-07 12:46:18 +05305742/**
5743 * hdd_ipa_ap_disconnect_evt() - Indicate wlan ipa ap disconnect event
5744 * @hdd_ctx: hdd context
5745 * @adapter: hdd adapter
5746 *
5747 * Return: None
5748 */
5749static inline
5750void hdd_ipa_ap_disconnect_evt(struct hdd_context *hdd_ctx,
5751 struct hdd_adapter *adapter)
5752{
5753 if (ucfg_ipa_is_enabled()) {
5754 ucfg_ipa_uc_disconnect_ap(hdd_ctx->pdev,
5755 adapter->dev);
5756 ucfg_ipa_cleanup_dev_iface(hdd_ctx->pdev,
5757 adapter->dev);
5758 }
5759}
5760
Dustin Browndb2a8be2017-12-20 11:49:56 -08005761QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
5762 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005763{
Dustin Brownd747ecd2018-10-26 16:32:22 -07005764 QDF_STATUS status = QDF_STATUS_SUCCESS;
5765 struct hdd_station_ctx *sta_ctx;
Dustin Brownb4260d52019-01-24 11:53:08 -08005766 struct sap_context *sap_ctx;
Jeff Johnson025618c2018-03-18 14:41:00 -07005767 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005768 union iwreq_data wrqu;
Jeff Johnsonc565af12019-03-10 21:09:47 -07005769 tSirUpdateIE update_ie;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005770 unsigned long rc;
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07005771 struct sap_config *sap_config;
Jeff Johnson16528362018-06-14 12:34:16 -07005772 mac_handle_t mac_handle;
Min Liu8c5d99e2018-09-10 17:18:44 +08005773 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005774
Dustin Brown491d54b2018-03-14 12:39:11 -07005775 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005776
Jeff Johnson912b1bb2019-03-06 10:12:36 -08005777 if (adapter->vdev_id != WLAN_UMAC_VDEV_ID_MAX)
Dustin Browne7e71d32018-05-11 16:00:08 -07005778 wlan_hdd_cfg80211_deregister_frames(adapter);
5779
Alok Kumarb64650c2018-03-23 17:05:11 +05305780 hdd_nud_ignore_tracking(adapter, true);
5781 hdd_nud_reset_tracking(adapter);
Alok Kumar016a1ac2018-09-16 09:55:50 +05305782 hdd_nud_flush_work(adapter);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05305783 hdd_mic_flush_work(adapter);
hangtian9c47aaf2018-11-26 17:59:39 +08005784 hdd_stop_tsf_sync(adapter);
bings6b7c21b2019-07-31 13:57:31 +08005785 cds_flush_work(&adapter->scan_block_work);
5786 wlan_hdd_cfg80211_scan_block(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305787
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005788 hdd_debug("Disabling queues");
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305789 wlan_hdd_netif_queue_control(adapter,
5790 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5791 WLAN_CONTROL_PATH);
Jeff Johnson16528362018-06-14 12:34:16 -07005792
5793 mac_handle = hdd_ctx->mac_handle;
5794
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005795 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005796 case QDF_STA_MODE:
5797 case QDF_P2P_CLIENT_MODE:
5798 case QDF_IBSS_MODE:
5799 case QDF_P2P_DEVICE_MODE:
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005800 case QDF_NDI_MODE:
Dustin Brownd747ecd2018-10-26 16:32:22 -07005801 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5802
5803 if (adapter->device_mode == QDF_NDI_MODE ||
5804 hdd_conn_is_connected(sta_ctx) ||
5805 hdd_is_connecting(sta_ctx)) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005806 INIT_COMPLETION(adapter->disconnect_comp_var);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005807
Jeff Johnson025618c2018-03-18 14:41:00 -07005808 roam_profile = hdd_roam_profile(adapter);
5809 /* For NDI do not use roam_profile */
Dustin Brownd747ecd2018-10-26 16:32:22 -07005810 if (adapter->device_mode == QDF_NDI_MODE)
5811 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005812 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005813 adapter->vdev_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005814 eCSR_DISCONNECT_REASON_NDI_DELETE);
Jeff Johnson025618c2018-03-18 14:41:00 -07005815 else if (roam_profile->BSSType ==
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005816 eCSR_BSS_TYPE_START_IBSS)
Dustin Brownd747ecd2018-10-26 16:32:22 -07005817 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005818 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005819 adapter->vdev_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005820 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Vevek Venkatesane81bca82019-08-12 22:25:15 +05305821 else if (adapter->device_mode == QDF_STA_MODE) {
5822 rc = wlan_hdd_disconnect(
5823 adapter,
5824 eCSR_DISCONNECT_REASON_DEAUTH);
5825 if (rc != 0 && ucfg_ipa_is_enabled()) {
5826 hdd_err("STA disconnect failed");
5827 ucfg_ipa_uc_cleanup_sta(hdd_ctx->pdev,
5828 adapter->dev);
5829 }
5830 } else {
Dustin Brownd747ecd2018-10-26 16:32:22 -07005831 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005832 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005833 adapter->vdev_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005834 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Vevek Venkatesane81bca82019-08-12 22:25:15 +05305835 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005836 /* success implies disconnect is queued */
5837 if (QDF_IS_STATUS_SUCCESS(status) &&
5838 adapter->device_mode != QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005839 rc = wait_for_completion_timeout(
5840 &adapter->disconnect_comp_var,
5841 msecs_to_jiffies
Abhishek Singhd1f21c72019-01-21 15:16:34 +05305842 (SME_DISCONNECT_TIMEOUT));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005843 if (!rc)
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005844 hdd_warn("disconn_comp_var wait fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005845 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005846 if (QDF_IS_STATUS_ERROR(status))
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005847 hdd_warn("failed to post disconnect");
Dustin Brownd747ecd2018-10-26 16:32:22 -07005848
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005849 memset(&wrqu, '\0', sizeof(wrqu));
5850 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
5851 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
5852 wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu,
5853 NULL);
Sachin Ahuja988fd102016-09-15 17:16:25 +05305854 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005855
Dustin Brownd747ecd2018-10-26 16:32:22 -07005856 wlan_hdd_scan_abort(adapter);
Wu Gao4a1ec8c2018-07-23 19:18:40 +08005857 wlan_hdd_cleanup_actionframe(adapter);
Abhishek Singh1e94d7a2015-11-30 17:26:54 +05305858 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05305859 hdd_clear_fils_connection_info(adapter);
Ashish Kumar Dhanotiya36510832019-02-20 22:13:25 +05305860
Liangwei Donga44d55b2019-03-20 03:22:08 -04005861 status = wlan_hdd_flush_pmksa_cache(adapter);
Ashish Kumar Dhanotiya36510832019-02-20 22:13:25 +05305862 if (QDF_IS_STATUS_ERROR(status))
5863 hdd_err("Cannot flush PMKIDCache");
5864
Visweswara Tanukub5a61242019-03-26 12:24:13 +05305865 hdd_deregister_hl_netdev_fc_timer(adapter);
5866
Dustin Brownd747ecd2018-10-26 16:32:22 -07005867 hdd_deregister_tx_flow_control(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005868
5869#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005870 cancel_work_sync(&adapter->ipv4_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005871#ifdef WLAN_NS_OFFLOAD
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005872 cancel_work_sync(&adapter->ipv6_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005873#endif
5874#endif
5875
Min Liu8c5d99e2018-09-10 17:18:44 +08005876 if (adapter->device_mode == QDF_STA_MODE) {
5877 struct wlan_objmgr_vdev *vdev;
5878
5879 vdev = hdd_objmgr_get_vdev(adapter);
5880 if (vdev) {
5881 wlan_cfg80211_sched_scan_stop(vdev);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05305882 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08005883 }
5884 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08005885
Pragaspathi Thilagaraje6f37e02019-01-04 12:24:33 +05305886 /*
5887 * During vdev destroy, if any STA is in connecting state the
5888 * roam command will be in active queue and thus vdev destroy is
5889 * queued in pending queue. In case STA tries to connect to
5890 * multiple BSSID and fails to connect, due to auth/assoc
5891 * timeouts it may take more than vdev destroy time to get
5892 * completed. On vdev destroy timeout vdev is moved to logically
5893 * deleted state. Once connection is completed, vdev destroy is
5894 * activated and to release the self-peer ref count it try to
5895 * get the ref of the vdev, which fails as vdev is logically
5896 * deleted and this leads to peer ref leak. So before vdev
5897 * destroy is queued abort any STA ongoing connection to avoid
5898 * vdev destroy timeout.
5899 */
5900 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags))
5901 hdd_abort_ongoing_sta_connection(hdd_ctx);
Dustin Browndb2a8be2017-12-20 11:49:56 -08005902
Himanshu Agarwalb229a142017-12-21 10:16:45 +05305903 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005904 break;
5905
Rajeev Kumar3b906202018-02-01 10:55:14 -08005906 case QDF_MONITOR_MODE:
5907 wlan_hdd_scan_abort(adapter);
Visweswara Tanukub5a61242019-03-26 12:24:13 +05305908 hdd_deregister_hl_netdev_fc_timer(adapter);
Rajeev Kumar3b906202018-02-01 10:55:14 -08005909 hdd_deregister_tx_flow_control(adapter);
Jinwei Chenbdd977f2019-06-14 15:09:30 +08005910 sme_delete_mon_session(mac_handle, adapter->vdev_id);
Rajeev Kumar3b906202018-02-01 10:55:14 -08005911 hdd_vdev_destroy(adapter);
5912 break;
5913
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005914 case QDF_SAP_MODE:
wadesongf9b15ed2017-12-14 14:12:32 +08005915 wlan_hdd_scan_abort(adapter);
gaurank kathpaliab7a9f702019-02-15 18:09:58 +05305916 /* Diassociate with all the peers before stop ap post */
5917 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))
5918 wlan_hdd_del_station(adapter);
Arunk Khandavalli96c122f2017-10-17 11:49:36 +05305919 sap_config = &adapter->session.ap.sap_config;
Dustin Brownd747ecd2018-10-26 16:32:22 -07005920 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
5921
Dustin Brown07901ec2018-09-07 11:02:41 -07005922 ucfg_ipa_flush(hdd_ctx->pdev);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005923
Dustin Brownb4260d52019-01-24 11:53:08 -08005924 /* don't flush pre-cac destroy if we are destroying pre-cac */
5925 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
Alan Chenc2d4b1c2019-10-28 17:28:35 -07005926 if (!wlan_sap_is_pre_cac_context(sap_ctx) &&
5927 (hdd_ctx->sap_pre_cac_work.fn))
Liangwei Dongad89c762018-06-01 01:56:23 -04005928 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
Dustin Brownb4260d52019-01-24 11:53:08 -08005929
Jeff Johnson46807cd2018-04-29 21:32:22 -07005930 /* fallthrough */
Dustin Browna5cf8e02017-10-19 16:04:19 -07005931
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005932 case QDF_P2P_GO_MODE:
Krunal Soni22208392017-09-29 18:10:34 -07005933 cds_flush_work(&adapter->sap_stop_bss_work);
gaurank kathpalia7aed85e2019-10-10 15:12:54 +05305934 if (qdf_atomic_read(&adapter->session.ap.acs_in_progress)) {
5935 hdd_info("ACS in progress, wait for complete");
5936 qdf_wait_for_event_completion(
5937 &adapter->acs_complete_event,
5938 ACS_COMPLETE_TIMEOUT);
5939 }
Dustin Browna5cf8e02017-10-19 16:04:19 -07005940 wlan_hdd_undo_acs(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005941
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005942 if (adapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005943 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5944
Visweswara Tanukub5a61242019-03-26 12:24:13 +05305945 hdd_deregister_hl_netdev_fc_timer(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005946 hdd_deregister_tx_flow_control(adapter);
Kapil Guptac1224bf2017-06-22 21:22:40 +05305947 hdd_destroy_acs_timer(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005948
Pragaspathi Thilagaraje6f37e02019-01-04 12:24:33 +05305949 /**
5950 * During vdev destroy, If any STA is in connecting state the
5951 * roam command will be in active queue and thus vdev destroy is
5952 * queued in pending queue. In case STA is tries to connected to
5953 * multiple BSSID and fails to connect, due to auth/assoc
5954 * timeouts it may take more than vdev destroy time to get
5955 * completes. If vdev destroy timeout vdev is moved to logically
5956 * deleted state. Once connection is completed, vdev destroy is
5957 * activated and to release the self-peer ref count it try to
5958 * get the ref of the vdev, which fails as vdev is logically
5959 * deleted and this leads to peer ref leak. So before vdev
5960 * destroy is queued abort any STA ongoing connection to avoid
5961 * vdev destroy timeout.
5962 */
5963 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags))
5964 hdd_abort_ongoing_sta_connection(hdd_ctx);
5965
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005966 mutex_lock(&hdd_ctx->sap_lock);
5967 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005968 status = wlansap_stop_bss(
5969 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005970
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305971 if (QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonca2530c2017-09-30 18:25:40 -07005972 struct hdd_hostapd_state *hostapd_state =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005973 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +05305974 qdf_event_reset(&hostapd_state->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305975 qdf_stop_bss_event);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005976 status = qdf_wait_for_event_completion(
Nachiket Kukade0396b732017-11-14 16:35:16 +05305977 &hostapd_state->qdf_stop_bss_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +05305978 SME_CMD_STOP_BSS_TIMEOUT);
Sravan Goudfb8c84f2019-10-07 12:46:18 +05305979 if (QDF_IS_STATUS_ERROR(status)) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005980 hdd_err("failure waiting for wlansap_stop_bss %d",
Dustin Brownd747ecd2018-10-26 16:32:22 -07005981 status);
Sravan Goudfb8c84f2019-10-07 12:46:18 +05305982 hdd_ipa_ap_disconnect_evt(hdd_ctx,
5983 adapter);
5984 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005985 } else {
Jeff Johnson5880d792016-08-15 13:32:30 -07005986 hdd_err("failure in wlansap_stop_bss");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005987 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005988
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005989 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -07005990 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005991 adapter->device_mode,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005992 adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07005993 hdd_green_ap_start_state_mc(hdd_ctx,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305994 adapter->device_mode,
5995 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005996
Jeff Johnsonc565af12019-03-10 21:09:47 -07005997 qdf_copy_macaddr(&update_ie.bssid,
Jeff Johnson1e851a12017-10-28 14:36:12 -07005998 &adapter->mac_addr);
Abhishek Singh5a2c42f2019-11-19 11:39:23 +05305999 update_ie.vdev_id = adapter->vdev_id;
Jeff Johnsonc565af12019-03-10 21:09:47 -07006000 update_ie.ieBufferlength = 0;
6001 update_ie.pAdditionIEBuffer = NULL;
6002 update_ie.append = false;
6003 update_ie.notify = false;
Dustin Brownd747ecd2018-10-26 16:32:22 -07006004
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006005 /* Probe bcn reset */
Jeff Johnsonc565af12019-03-10 21:09:47 -07006006 status = sme_update_add_ie(mac_handle, &update_ie,
Dustin Brownd747ecd2018-10-26 16:32:22 -07006007 eUPDATE_IE_PROBE_BCN);
6008 if (status == QDF_STATUS_E_FAILURE)
6009 hdd_err("Could not pass PROBE_RSP_BCN to PE");
6010
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006011 /* Assoc resp reset */
Jeff Johnsonc565af12019-03-10 21:09:47 -07006012 status = sme_update_add_ie(mac_handle, &update_ie,
Dustin Brownd747ecd2018-10-26 16:32:22 -07006013 eUPDATE_IE_ASSOC_RESP);
6014 if (status == QDF_STATUS_E_FAILURE)
6015 hdd_err("Could not pass ASSOC_RSP to PE");
6016
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006017 /* Reset WNI_CFG_PROBE_RSP Flags */
6018 wlan_hdd_reset_prob_rspies(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006019 }
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08006020 clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
Jeff Johnsonb9424862017-10-30 08:49:35 -07006021 qdf_mem_free(adapter->session.ap.beacon);
6022 adapter->session.ap.beacon = NULL;
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08006023
Sourav Mohapatrac320ada2019-09-03 16:15:03 +05306024 /* Clear all the cached sta info */
6025 hdd_clear_cached_sta_info(&adapter->cache_sta_info_list);
6026
Ajit Pal Singh747b6802017-05-24 15:42:03 +05306027 /*
6028 * If Do_Not_Break_Stream was enabled clear avoid channel list.
6029 */
Min Liu8c5d99e2018-09-10 17:18:44 +08006030 vdev = hdd_objmgr_get_vdev(adapter);
6031 if (vdev) {
6032 if (policy_mgr_is_dnsc_set(vdev))
6033 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05306034 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08006035 }
Ajit Pal Singh747b6802017-05-24 15:42:03 +05306036
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05306037#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07006038 cancel_work_sync(&adapter->ipv4_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05306039#ifdef WLAN_NS_OFFLOAD
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07006040 cancel_work_sync(&adapter->ipv6_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05306041#endif
6042#endif
Dustin Browndb2a8be2017-12-20 11:49:56 -08006043
6044 hdd_vdev_destroy(adapter);
6045
Krunal Sonib51eec72017-11-20 21:53:01 -08006046 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006047 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006048 case QDF_OCB_MODE:
Dustin Brownd747ecd2018-10-26 16:32:22 -07006049 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Krishna Kumaar Natarajane58b4092017-01-25 15:47:35 -08006050 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
Dustin Brownd747ecd2018-10-26 16:32:22 -07006051 cds_get_context(QDF_MODULE_ID_TXRX),
Sourav Mohapatraffbd0272019-07-31 14:18:25 +05306052 sta_ctx->conn_info.peer_macaddr[0]);
Visweswara Tanukub5a61242019-03-26 12:24:13 +05306053 hdd_deregister_hl_netdev_fc_timer(adapter);
Zhang Qian79d0d132018-02-05 13:40:16 +08006054 hdd_deregister_tx_flow_control(adapter);
6055 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006056 break;
6057 default:
6058 break;
6059 }
6060
Dustin Brown04348372017-12-14 16:13:39 -08006061 if (adapter->scan_info.default_scan_ies) {
6062 qdf_mem_free(adapter->scan_info.default_scan_ies);
6063 adapter->scan_info.default_scan_ies = NULL;
Abhishek Singh74d06cf2019-09-06 09:23:22 +05306064 adapter->scan_info.default_scan_ies_len = 0;
Dustin Brown04348372017-12-14 16:13:39 -08006065 }
6066
Dustin Browne74003f2018-03-14 12:51:58 -07006067 hdd_exit();
Dustin Brownd747ecd2018-10-26 16:32:22 -07006068
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306069 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006070}
6071
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306072/**
6073 * hdd_deinit_all_adapters - deinit all adapters
6074 * @hdd_ctx: HDD context
6075 * @rtnl_held: True if RTNL lock held
6076 *
6077 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006078void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306079{
Jeff Johnson9d295242017-08-29 14:39:48 -07006080 struct hdd_adapter *adapter;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306081
Dustin Brown491d54b2018-03-14 12:39:11 -07006082 hdd_enter();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306083
Dustin Brown920397d2017-12-13 16:27:50 -08006084 hdd_for_each_adapter(hdd_ctx, adapter)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306085 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306086
Dustin Browne74003f2018-03-14 12:51:58 -07006087 hdd_exit();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306088}
6089
Dustin Browndb2a8be2017-12-20 11:49:56 -08006090QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006091{
Jeff Johnson9d295242017-08-29 14:39:48 -07006092 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006093
Dustin Brown491d54b2018-03-14 12:39:11 -07006094 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006095
Alan Chenc2d4b1c2019-10-28 17:28:35 -07006096 if (hdd_ctx->sap_pre_cac_work.fn)
6097 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05306098
Dustin Brown920397d2017-12-13 16:27:50 -08006099 hdd_for_each_adapter(hdd_ctx, adapter)
Dustin Browndb2a8be2017-12-20 11:49:56 -08006100 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006101
Dustin Browne74003f2018-03-14 12:51:58 -07006102 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006103
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306104 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006105}
6106
Paul Zhang84fa9382017-11-10 21:18:21 +08006107static void hdd_reset_scan_operation(struct hdd_context *hdd_ctx,
6108 struct hdd_adapter *adapter)
6109{
6110 switch (adapter->device_mode) {
6111 case QDF_STA_MODE:
6112 case QDF_P2P_CLIENT_MODE:
6113 case QDF_IBSS_MODE:
6114 case QDF_P2P_DEVICE_MODE:
6115 case QDF_NDI_MODE:
6116 wlan_hdd_scan_abort(adapter);
6117 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Min Liu8c5d99e2018-09-10 17:18:44 +08006118 if (adapter->device_mode == QDF_STA_MODE) {
6119 struct wlan_objmgr_vdev *vdev;
6120
6121 vdev = hdd_objmgr_get_vdev(adapter);
6122 if (vdev) {
6123 wlan_cfg80211_sched_scan_stop(vdev);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05306124 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08006125 }
6126 }
Paul Zhang84fa9382017-11-10 21:18:21 +08006127 break;
6128 case QDF_P2P_GO_MODE:
6129 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
6130 break;
6131 case QDF_SAP_MODE:
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05306132 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Paul Zhang84fa9382017-11-10 21:18:21 +08006133 break;
6134 default:
6135 break;
6136 }
6137}
6138
Ke Huangc067b8d2018-05-21 15:50:13 +08006139#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
6140/**
6141 * hdd_adapter_abort_tx_flow() - Abort the tx flow control
6142 * @pAdapter: pointer to hdd_adapter_t
6143 *
6144 * Resume tx and stop the tx flow control timer if the tx is paused
6145 * and the flow control timer is running. This function is called by
6146 * SSR to avoid the inconsistency of tx status before and after SSR.
6147 *
6148 * Return: void
6149 */
6150static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
6151{
6152 if (adapter->hdd_stats.tx_rx_stats.is_txflow_paused &&
6153 QDF_TIMER_STATE_RUNNING ==
6154 qdf_mc_timer_get_current_state(
6155 &adapter->tx_flow_control_timer)) {
6156 hdd_tx_resume_timer_expired_handler(adapter);
6157 qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
6158 }
6159}
6160#endif
6161
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006162QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006163{
Jeff Johnson9d295242017-08-29 14:39:48 -07006164 struct hdd_adapter *adapter;
Jeff Johnsond377dce2017-10-04 10:32:42 -07006165 struct hdd_station_ctx *sta_ctx;
Jeff Johnson2d044612019-02-26 20:08:43 -08006166 struct qdf_mac_addr peer_macaddr;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05306167 bool value;
Min Liu8c5d99e2018-09-10 17:18:44 +08006168 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006169
Dustin Brown491d54b2018-03-14 12:39:11 -07006170 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006171
Alan Chen285bbc72019-10-03 12:57:15 -07006172 /* do not flush work if it is not created */
6173 if (hdd_ctx->sap_pre_cac_work.fn)
6174 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05306175
Dustin Brown920397d2017-12-13 16:27:50 -08006176 hdd_for_each_adapter(hdd_ctx, adapter) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07006177 hdd_info("[SSR] reset adapter with device mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07006178 qdf_opmode_str(adapter->device_mode),
Dustin Brown5e89ef82018-03-14 11:50:23 -07006179 adapter->device_mode);
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05306180
Ke Huangc067b8d2018-05-21 15:50:13 +08006181#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
6182 hdd_adapter_abort_tx_flow(adapter);
6183#endif
6184
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05306185 if ((adapter->device_mode == QDF_STA_MODE) ||
Paul Zhang679025e2018-03-08 22:39:44 +08006186 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05306187 /* Stop tdls timers */
Min Liu8c5d99e2018-09-10 17:18:44 +08006188 vdev = hdd_objmgr_get_vdev(adapter);
6189 if (vdev) {
6190 hdd_notify_tdls_reset_adapter(vdev);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05306191 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08006192 }
Paul Zhang679025e2018-03-08 22:39:44 +08006193 adapter->session.station.hdd_reassoc_scenario = false;
6194 }
Dustin Brown05d81302018-09-11 16:49:22 -07006195 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05306196 if (value &&
Arun Khandavallicc544b32017-01-30 19:52:16 +05306197 adapter->device_mode == QDF_SAP_MODE) {
6198 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05306199 WLAN_STOP_ALL_NETIF_QUEUE,
Arun Khandavallicc544b32017-01-30 19:52:16 +05306200 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08006201 } else {
Arun Khandavallicc544b32017-01-30 19:52:16 +05306202 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05306203 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006204 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08006205 }
Yeshwanth Sriram Guntukae6e60f82019-11-08 17:22:00 +05306206
6207 if ((adapter->device_mode == QDF_P2P_GO_MODE ||
6208 adapter->device_mode == QDF_SAP_MODE) &&
6209 test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
6210 hdd_sap_indicate_disconnect_for_sta(adapter);
6211 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
6212 }
6213
Nijun Gong104ccc72018-08-07 10:43:56 +08006214 /*
6215 * Clear fc flag if it was set before SSR to avoid TX queues
6216 * permanently stopped after SSR.
6217 * Here WLAN_START_ALL_NETIF_QUEUE will actually not start any
6218 * queue since it's blocked by reason WLAN_CONTROL_PATH.
6219 */
6220 if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL))
6221 wlan_hdd_netif_queue_control(adapter,
6222 WLAN_START_ALL_NETIF_QUEUE,
6223 WLAN_DATA_FLOW_CONTROL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006224
Paul Zhang84fa9382017-11-10 21:18:21 +08006225 hdd_reset_scan_operation(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006226
6227 hdd_deinit_tx_rx(adapter);
Dustin Brown1dbefe62018-09-11 16:32:03 -07006228 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08006229 adapter->device_mode, adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07006230 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05306231 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006232 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
6233 hdd_wmm_adapter_close(adapter);
6234 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
6235 }
6236
Vignesh Viswanathan2eb18742017-09-08 11:18:59 +05306237 if (adapter->device_mode == QDF_STA_MODE)
6238 hdd_clear_fils_connection_info(adapter);
6239
Wu Gao3545e642017-07-14 19:24:41 +08006240 if (adapter->device_mode == QDF_SAP_MODE) {
Jingxiang Geec113592018-08-09 15:40:39 +08006241 wlansap_cleanup_cac_timer(
6242 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Wu Gao3545e642017-07-14 19:24:41 +08006243 /*
6244 * If adapter is SAP, set session ID to invalid
6245 * since SAP session will be cleanup during SSR.
6246 */
Wu Gao36717432016-11-21 15:09:48 +08006247 wlansap_set_invalid_session(
6248 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Wu Gao3545e642017-07-14 19:24:41 +08006249 }
6250
Abhishek Singh8f4aa182019-03-06 10:29:24 +05306251 /* Release vdev ref count to avoid vdev object leak */
6252 if (adapter->device_mode == QDF_P2P_GO_MODE ||
6253 adapter->device_mode == QDF_SAP_MODE)
6254 wlansap_release_vdev_ref(
6255 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
6256
Yue Ma42654682018-01-11 16:55:24 -08006257 /* Delete connection peers if any to avoid peer object leaks */
Yue Mad5b4b9f2017-05-26 16:23:40 -07006258 if (adapter->device_mode == QDF_STA_MODE ||
6259 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
Jeff Johnsond377dce2017-10-04 10:32:42 -07006260 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnson2d044612019-02-26 20:08:43 -08006261 qdf_copy_macaddr(&peer_macaddr,
Jeff Johnsone04b6992019-02-27 14:06:55 -08006262 &sta_ctx->conn_info.bssid);
Yue Mad5b4b9f2017-05-26 16:23:40 -07006263
Yue Mad5b4b9f2017-05-26 16:23:40 -07006264 }
6265
Alok Kumarb64650c2018-03-23 17:05:11 +05306266 hdd_nud_ignore_tracking(adapter, true);
Alok Kumar016a1ac2018-09-16 09:55:50 +05306267 hdd_nud_reset_tracking(adapter);
6268 hdd_nud_flush_work(adapter);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05306269 hdd_mic_flush_work(adapter);
Ashish Kumar Dhanotiyadc3900f2019-01-11 20:42:04 +05306270
6271 if (adapter->device_mode != QDF_SAP_MODE &&
6272 adapter->device_mode != QDF_P2P_GO_MODE &&
6273 adapter->device_mode != QDF_FTM_MODE)
6274 hdd_set_disconnect_status(adapter, false);
6275
hangtian9c47aaf2018-11-26 17:59:39 +08006276 hdd_stop_tsf_sync(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05306277
Tiger Yu94a5a5c2018-03-09 21:22:26 +08006278 hdd_softap_deinit_tx_rx(adapter);
Sourav Mohapatra43e6dea2019-08-18 11:39:23 +05306279 if (adapter->device_mode == QDF_SAP_MODE ||
Sourav Mohapatrac320ada2019-09-03 16:15:03 +05306280 adapter->device_mode == QDF_P2P_GO_MODE) {
Sourav Mohapatra934409a2019-10-22 09:34:21 +05306281 /* Clear all the cached sta info */
6282 hdd_clear_cached_sta_info(
6283 &adapter->cache_sta_info_list);
Sourav Mohapatra43e6dea2019-08-18 11:39:23 +05306284 hdd_sta_info_deinit(&adapter->sta_info_list);
Sourav Mohapatrac320ada2019-09-03 16:15:03 +05306285 hdd_sta_info_deinit(&adapter->cache_sta_info_list);
6286 }
Sourav Mohapatra43e6dea2019-08-18 11:39:23 +05306287
Visweswara Tanukub5a61242019-03-26 12:24:13 +05306288 hdd_deregister_hl_netdev_fc_timer(adapter);
Tiger Yu8c387702018-07-06 16:56:42 +08006289 hdd_deregister_tx_flow_control(adapter);
Tiger Yu94a5a5c2018-03-09 21:22:26 +08006290
Yue Maf9782842017-05-08 12:49:49 -07006291 /* Destroy vdev which will be recreated during reinit. */
6292 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006293 }
6294
Dustin Browne74003f2018-03-14 12:51:58 -07006295 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006296
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306297 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006298}
6299
Dustin Brown4c663222018-10-23 14:19:36 -07006300bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05306301{
Dustin Brown920397d2017-12-13 16:27:50 -08006302 struct hdd_adapter *adapter;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05306303
Dustin Brown4c663222018-10-23 14:19:36 -07006304 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
Arun Khandavalliba479c42017-07-26 21:29:40 +05306305 hdd_info("FTM mode, don't close the module");
Dustin Brown4c663222018-10-23 14:19:36 -07006306 return true;
Arun Khandavalliba479c42017-07-26 21:29:40 +05306307 }
6308
Dustin Brown920397d2017-12-13 16:27:50 -08006309 hdd_for_each_adapter(hdd_ctx, adapter) {
6310 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
Dustin Brown4c663222018-10-23 14:19:36 -07006311 test_bit(SME_SESSION_OPENED, &adapter->event_flags))
6312 return true;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05306313 }
6314
Dustin Brown4c663222018-10-23 14:19:36 -07006315 return false;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05306316}
6317
yeshwanth sriram guntukaea63f632017-08-30 19:31:56 +05306318bool hdd_is_interface_up(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05306319{
6320 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
6321 return true;
6322 else
6323 return false;
6324}
6325
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306326#if defined CFG80211_CONNECT_BSS || \
6327 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306328#if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306329 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306330/**
6331 * hdd_convert_timeout_reason() - Convert to kernel specific enum
6332 * @timeout_reason: reason for connect timeout
6333 *
6334 * This function is used to convert host timeout
6335 * reason enum to kernel specific enum.
6336 *
6337 * Return: nl timeout enum
6338 */
6339static enum nl80211_timeout_reason hdd_convert_timeout_reason(
6340 tSirResultCodes timeout_reason)
6341{
6342 switch (timeout_reason) {
6343 case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
6344 return NL80211_TIMEOUT_SCAN;
6345 case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
6346 return NL80211_TIMEOUT_AUTH;
6347 case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
6348 return NL80211_TIMEOUT_ASSOC;
6349 default:
6350 return NL80211_TIMEOUT_UNSPECIFIED;
6351 }
6352}
6353
6354/**
6355 * hdd_cfg80211_connect_timeout() - API to send connection timeout reason
6356 * @dev: network device
6357 * @bssid: bssid to which we want to associate
6358 * @timeout_reason: reason for connect timeout
6359 *
6360 * This API is used to send connection timeout reason to supplicant
6361 *
6362 * Return: void
6363 */
6364static void hdd_cfg80211_connect_timeout(struct net_device *dev,
6365 const u8 *bssid,
6366 tSirResultCodes timeout_reason)
6367{
6368 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006369
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306370 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
6371
6372 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL,
6373 nl_timeout_reason);
6374}
6375
6376/**
6377 * __hdd_connect_bss() - API to send connection status to supplicant
6378 * @dev: network device
6379 * @bssid: bssid to which we want to associate
6380 * @req_ie: Request Information Element
6381 * @req_ie_len: len of the req IE
6382 * @resp_ie: Response IE
6383 * @resp_ie_len: len of ht response IE
6384 * @status: status
6385 * @gfp: Kernel Flag
6386 * @timeout_reason: reason for connect timeout
6387 *
6388 * Return: void
6389 */
6390static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6391 struct cfg80211_bss *bss, const u8 *req_ie,
6392 size_t req_ie_len, const u8 *resp_ie,
6393 size_t resp_ie_len, int status, gfp_t gfp,
6394 tSirResultCodes timeout_reason)
6395{
6396 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006397
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306398 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
6399
6400 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
6401 resp_ie, resp_ie_len, status, gfp,
6402 nl_timeout_reason);
6403}
6404#else
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306405#if defined CFG80211_CONNECT_TIMEOUT || \
6406 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306407static void hdd_cfg80211_connect_timeout(struct net_device *dev,
6408 const u8 *bssid,
6409 tSirResultCodes timeout_reason)
6410{
6411 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL);
6412}
6413#endif
6414
6415static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6416 struct cfg80211_bss *bss, const u8 *req_ie,
6417 size_t req_ie_len, const u8 *resp_ie,
6418 size_t resp_ie_len, int status, gfp_t gfp,
6419 tSirResultCodes timeout_reason)
6420{
6421 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
6422 resp_ie, resp_ie_len, status, gfp);
6423}
6424#endif
6425
Abhishek Singha84d3952016-09-13 13:45:05 +05306426/**
6427 * hdd_connect_bss() - API to send connection status to supplicant
6428 * @dev: network device
6429 * @bssid: bssid to which we want to associate
6430 * @req_ie: Request Information Element
6431 * @req_ie_len: len of the req IE
6432 * @resp_ie: Response IE
6433 * @resp_ie_len: len of ht response IE
6434 * @status: status
6435 * @gfp: Kernel Flag
6436 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306437 * @timeout_reason: reason for connect timeout
Abhishek Singha84d3952016-09-13 13:45:05 +05306438 *
6439 * The API is a wrapper to send connection status to supplicant
6440 *
6441 * Return: Void
6442 */
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306443#if defined CFG80211_CONNECT_TIMEOUT || \
6444 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
Abhishek Singha84d3952016-09-13 13:45:05 +05306445static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6446 struct cfg80211_bss *bss, const u8 *req_ie,
6447 size_t req_ie_len, const u8 *resp_ie,
6448 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306449 bool connect_timeout,
6450 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05306451{
6452 if (connect_timeout)
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306453 hdd_cfg80211_connect_timeout(dev, bssid, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05306454 else
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306455 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
6456 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05306457}
6458#else
6459static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6460 struct cfg80211_bss *bss, const u8 *req_ie,
6461 size_t req_ie_len, const u8 *resp_ie,
6462 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306463 bool connect_timeout,
6464 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05306465{
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306466 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
6467 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05306468}
6469#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05306470
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306471#if defined(WLAN_FEATURE_FILS_SK)
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306472#if (defined(CFG80211_CONNECT_DONE) || \
6473 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))) && \
6474 (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0))
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306475#if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
6476 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306477/**
6478 * hdd_populate_fils_params() - Populate FILS keys to connect response
6479 * @fils_params: connect response to supplicant
6480 * @fils_kek: FILS kek
6481 * @fils_kek_len: FILS kek length
6482 * @pmk: FILS PMK
6483 * @pmk_len: FILS PMK length
6484 * @pmkid: PMKID
6485 * @fils_seq_num: FILS Seq number
6486 *
6487 * Return: None
6488 */
6489static void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6490 *fils_params, const uint8_t *fils_kek,
6491 size_t fils_kek_len, const uint8_t *pmk,
6492 size_t pmk_len, const uint8_t *pmkid,
6493 uint16_t fils_seq_num)
6494{
6495 /* Increament seq number to be used for next FILS */
6496 fils_params->fils_erp_next_seq_num = fils_seq_num + 1;
6497 fils_params->update_erp_next_seq_num = true;
6498 fils_params->fils_kek = fils_kek;
6499 fils_params->fils_kek_len = fils_kek_len;
6500 fils_params->pmk = pmk;
6501 fils_params->pmk_len = pmk_len;
6502 fils_params->pmkid = pmkid;
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306503 hdd_debug("FILS erp_next_seq_num:%d",
6504 fils_params->fils_erp_next_seq_num);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306505}
6506#else
6507static inline void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6508 *fils_params, const uint8_t
6509 *fils_kek, size_t fils_kek_len,
6510 const uint8_t *pmk, size_t pmk_len,
6511 const uint8_t *pmkid,
6512 uint16_t fils_seq_num)
6513{ }
6514#endif
6515
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306516#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
6517/**
6518 * hdd_populate_fils_params() - Populate FILS keys to connect response
6519 * @fils_params: connect response to supplicant
6520 * @fils_kek: FILS kek
6521 * @fils_kek_len: FILS kek length
6522 * @pmk: FILS PMK
6523 * @pmk_len: FILS PMK length
6524 * @pmkid: PMKID
6525 * @fils_seq_num: FILS Seq number
6526 *
6527 * Return: None
6528 */
6529static void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6530 *fils_params, const uint8_t *fils_kek,
6531 size_t fils_kek_len, const uint8_t *pmk,
6532 size_t pmk_len, const uint8_t *pmkid,
6533 uint16_t fils_seq_num)
6534{
6535 /* Increament seq number to be used for next FILS */
6536 fils_params->fils.erp_next_seq_num = fils_seq_num + 1;
6537 fils_params->fils.update_erp_next_seq_num = true;
6538 fils_params->fils.kek = fils_kek;
6539 fils_params->fils.kek_len = fils_kek_len;
6540 fils_params->fils.pmk = pmk;
6541 fils_params->fils.pmk_len = pmk_len;
6542 fils_params->fils.pmkid = pmkid;
6543 hdd_debug("FILS erp_next_seq_num:%d",
6544 fils_params->fils.erp_next_seq_num);
6545}
6546#endif /* CFG80211_CONNECT_DONE */
6547
6548#if defined(CFG80211_CONNECT_DONE) || \
6549 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
6550
Jeff Johnson172237b2017-11-07 15:32:59 -08006551void hdd_update_hlp_info(struct net_device *dev,
6552 struct csr_roam_info *roam_info)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306553{
6554 struct sk_buff *skb;
6555 uint16_t skb_len;
6556 struct llc_snap_hdr_t *llc_hdr;
6557 QDF_STATUS status;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306558 uint8_t *hlp_data;
6559 uint16_t hlp_data_len;
6560 struct fils_join_rsp_params *roam_fils_params
6561 = roam_info->fils_join_rsp;
Jeff Johnsona1382382019-03-31 11:08:27 -07006562 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306563
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306564 if (!roam_fils_params) {
6565 hdd_err("FILS Roam Param NULL");
6566 return;
6567 }
6568
Srinivas Girigowda3cc8e912017-11-28 18:11:57 -08006569 if (!roam_fils_params->hlp_data_len) {
Jianmin Zhucc6b3d02019-03-07 14:19:34 +08006570 hdd_debug("FILS HLP Data NULL, len %d",
6571 roam_fils_params->hlp_data_len);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306572 return;
6573 }
6574
6575 hlp_data = roam_fils_params->hlp_data;
6576 hlp_data_len = roam_fils_params->hlp_data_len;
6577
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306578 /* Calculate skb length */
6579 skb_len = (2 * ETH_ALEN) + hlp_data_len;
6580 skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false);
Jeff Johnsond36fa332019-03-18 13:42:25 -07006581 if (!skb) {
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306582 hdd_err("HLP packet nbuf alloc fails");
6583 return;
6584 }
6585
6586 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->dst_mac.bytes,
6587 QDF_MAC_ADDR_SIZE);
6588 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->src_mac.bytes,
6589 QDF_MAC_ADDR_SIZE);
6590
6591 llc_hdr = (struct llc_snap_hdr_t *) hlp_data;
6592 if (IS_SNAP(llc_hdr)) {
6593 hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
6594 hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
6595 }
6596
6597 qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len);
6598
6599 /*
6600 * This HLP packet is formed from HLP info encapsulated
6601 * in assoc response frame which is AEAD encrypted.
6602 * Hence, this checksum validation can be set unnecessary.
6603 * i.e. network layer need not worry about checksum.
6604 */
6605 skb->ip_summed = CHECKSUM_UNNECESSARY;
6606
Jeff Johnsona1382382019-03-31 11:08:27 -07006607 status = hdd_rx_packet_cbk(adapter, skb);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306608 if (QDF_IS_STATUS_ERROR(status)) {
6609 hdd_err("Sending HLP packet fails");
6610 return;
6611 }
6612 hdd_debug("send HLP packet to netif successfully");
6613}
6614
6615/**
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306616 * hdd_connect_done() - Wrapper API to call cfg80211_connect_done
6617 * @dev: network device
6618 * @bssid: bssid to which we want to associate
6619 * @bss: cfg80211 bss info
6620 * @roam_info: information about connected bss
6621 * @req_ie: Request Information Element
6622 * @req_ie_len: len of the req IE
6623 * @resp_ie: Response IE
6624 * @resp_ie_len: len of ht response IE
6625 * @status: status
6626 * @gfp: allocation flags
6627 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
6628 * @timeout_reason: reason for connect timeout
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306629 *
6630 * This API is used as wrapper to send FILS key/sequence number
6631 * params etc. to supplicant in case of FILS connection
6632 *
6633 * Return: None
6634 */
6635static void hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006636 struct cfg80211_bss *bss,
6637 struct csr_roam_info *roam_info,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306638 const u8 *req_ie, size_t req_ie_len,
6639 const u8 *resp_ie, size_t resp_ie_len, u16 status,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006640 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306641 tSirResultCodes timeout_reason)
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306642{
6643 struct cfg80211_connect_resp_params fils_params;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306644 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6645 struct fils_join_rsp_params *roam_fils_params =
6646 roam_info->fils_join_rsp;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006647
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306648 qdf_mem_zero(&fils_params, sizeof(fils_params));
6649
6650 if (!roam_fils_params) {
6651 fils_params.status = WLAN_STATUS_UNSPECIFIED_FAILURE;
6652 } else {
6653 fils_params.status = status;
6654 fils_params.bssid = bssid;
Srinivas Girigowdae975f532018-01-05 14:03:05 -08006655 fils_params.timeout_reason =
6656 hdd_convert_timeout_reason(timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306657 fils_params.req_ie = req_ie;
6658 fils_params.req_ie_len = req_ie_len;
6659 fils_params.resp_ie = resp_ie;
6660 fils_params.resp_ie_len = resp_ie_len;
6661 fils_params.bss = bss;
6662 hdd_populate_fils_params(&fils_params, roam_fils_params->kek,
6663 roam_fils_params->kek_len,
6664 roam_fils_params->fils_pmk,
6665 roam_fils_params->fils_pmk_len,
6666 roam_fils_params->fils_pmkid,
6667 roam_info->fils_seq_num);
Sridhar Selvaraje5260442017-08-19 10:12:03 +05306668 hdd_save_gtk_params(adapter, roam_info, false);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306669 }
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306670 hdd_debug("FILS indicate connect status %d", fils_params.status);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306671
6672 cfg80211_connect_done(dev, &fils_params, gfp);
6673
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306674 if (roam_fils_params && roam_fils_params->hlp_data_len)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306675 hdd_update_hlp_info(dev, roam_info);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306676
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306677 /* Clear all the FILS key info */
6678 if (roam_fils_params && roam_fils_params->fils_pmk)
6679 qdf_mem_free(roam_fils_params->fils_pmk);
6680 if (roam_fils_params)
6681 qdf_mem_free(roam_fils_params);
6682 roam_info->fils_join_rsp = NULL;
6683}
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306684#else /* CFG80211_CONNECT_DONE */
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006685static inline void
6686hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006687 struct cfg80211_bss *bss, struct csr_roam_info *roam_info,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006688 const u8 *req_ie, size_t req_ie_len,
6689 const u8 *resp_ie, size_t resp_ie_len, u16 status,
6690 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306691 tSirResultCodes timeout_reason)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306692{ }
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306693#endif
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306694#endif /* WLAN_FEATURE_FILS_SK */
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306695
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306696#if defined(WLAN_FEATURE_FILS_SK) && \
6697 (defined(CFG80211_CONNECT_DONE) || \
6698 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306699/**
6700 * hdd_fils_update_connect_results() - API to send fils connection status to
6701 * supplicant.
6702 * @dev: network device
6703 * @bssid: bssid to which we want to associate
6704 * @bss: cfg80211 bss info
6705 * @roam_info: information about connected bss
6706 * @req_ie: Request Information Element
6707 * @req_ie_len: len of the req IE
6708 * @resp_ie: Response IE
6709 * @resp_ie_len: len of ht response IE
6710 * @status: status
6711 * @gfp: allocation flags
6712 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
6713 * @timeout_reason: reason for connect timeout
6714 *
6715 * The API is a wrapper to send connection status to supplicant
6716 *
6717 * Return: 0 if success else failure
6718 */
6719static int hdd_fils_update_connect_results(struct net_device *dev,
6720 const u8 *bssid,
6721 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08006722 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306723 size_t req_ie_len, const u8 *resp_ie,
6724 size_t resp_ie_len, u16 status, gfp_t gfp,
6725 bool connect_timeout,
6726 tSirResultCodes timeout_reason)
6727{
Dustin Brown491d54b2018-03-14 12:39:11 -07006728 hdd_enter();
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306729 if (!roam_info || !roam_info->is_fils_connection)
6730 return -EINVAL;
6731
6732 hdd_connect_done(dev, bssid, bss, roam_info, req_ie, req_ie_len,
6733 resp_ie, resp_ie_len, status, gfp, connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306734 timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306735 return 0;
6736}
6737#else
6738static inline int hdd_fils_update_connect_results(struct net_device *dev,
6739 const u8 *bssid,
6740 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08006741 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306742 size_t req_ie_len, const u8 *resp_ie,
6743 size_t resp_ie_len, u16 status, gfp_t gfp,
6744 bool connect_timeout,
6745 tSirResultCodes timeout_reason)
6746{
6747 return -EINVAL;
6748}
6749#endif
6750
Anurag Chouhanc4092922016-09-08 15:56:11 +05306751/**
6752 * hdd_connect_result() - API to send connection status to supplicant
6753 * @dev: network device
6754 * @bssid: bssid to which we want to associate
6755 * @roam_info: information about connected bss
6756 * @req_ie: Request Information Element
6757 * @req_ie_len: len of the req IE
6758 * @resp_ie: Response IE
6759 * @resp_ie_len: len of ht response IE
6760 * @status: status
6761 * @gfp: Kernel Flag
Abhishek Singha84d3952016-09-13 13:45:05 +05306762 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306763 * @timeout_reason: reason for connect timeout
Anurag Chouhanc4092922016-09-08 15:56:11 +05306764 *
6765 * The API is a wrapper to send connection status to supplicant
6766 * and allow runtime suspend
6767 *
6768 * Return: Void
6769 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05306770void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006771 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306772 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05306773 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306774 bool connect_timeout,
6775 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05306776{
Jeff Johnsona1382382019-03-31 11:08:27 -07006777 struct hdd_adapter *adapter = netdev_priv(dev);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306778 struct cfg80211_bss *bss = NULL;
Jeff Johnsona1382382019-03-31 11:08:27 -07006779 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306780
6781 if (WLAN_STATUS_SUCCESS == status) {
6782 struct ieee80211_channel *chan;
Anurag Chouhanc4092922016-09-08 15:56:11 +05306783
Will Huang65d64252019-07-16 17:57:42 +08006784 chan = ieee80211_get_channel(adapter->wdev.wiphy,
6785 roam_info->bss_desc->chan_freq);
Jeff Johnsona1382382019-03-31 11:08:27 -07006786 bss = wlan_cfg80211_get_bss(adapter->wdev.wiphy, chan, bssid,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306787 roam_info->u.pConnectedProfile->SSID.ssId,
6788 roam_info->u.pConnectedProfile->SSID.length);
6789 }
Komal Seelama89be8d2016-09-29 11:09:26 +05306790
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306791 if (hdd_fils_update_connect_results(dev, bssid, bss,
6792 roam_info, req_ie, req_ie_len, resp_ie,
6793 resp_ie_len, status, gfp, connect_timeout,
6794 timeout_reason) != 0) {
6795 hdd_connect_bss(dev, bssid, bss, req_ie,
6796 req_ie_len, resp_ie, resp_ie_len,
6797 status, gfp, connect_timeout, timeout_reason);
6798 }
Komal Seelama89be8d2016-09-29 11:09:26 +05306799
Jingxiang Geb49aa302018-01-17 20:54:15 +08006800 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07006801 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306802}
6803#else
6804void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006805 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306806 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05306807 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306808 bool connect_timeout,
6809 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05306810{
Jeff Johnsona1382382019-03-31 11:08:27 -07006811 struct hdd_adapter *adapter = netdev_priv(dev);
6812 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Komal Seelama89be8d2016-09-29 11:09:26 +05306813
Anurag Chouhanc4092922016-09-08 15:56:11 +05306814 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
6815 resp_ie, resp_ie_len, status, gfp);
Prashanth Bhatta87b6dc02017-01-19 15:17:58 -08006816
Jingxiang Geb49aa302018-01-17 20:54:15 +08006817 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07006818 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306819}
6820#endif
6821
Nirav Shah73713f72018-05-17 14:50:41 +05306822#ifdef FEATURE_MONITOR_MODE_SUPPORT
Jeff Johnsond9952752018-04-18 12:15:35 -07006823int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
6824 uint32_t bandwidth)
6825{
6826 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6827 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
6828 struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info;
6829 QDF_STATUS status;
Jeff Johnsond9952752018-04-18 12:15:35 -07006830 struct qdf_mac_addr bssid;
6831 struct csr_roam_profile roam_profile;
6832 struct ch_params ch_params;
6833
Abhishek Singh9fee5182019-11-01 11:39:38 +05306834 if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE) {
6835 hdd_err("Not supported, device is not in monitor mode");
Jeff Johnsond9952752018-04-18 12:15:35 -07006836 return -EINVAL;
6837 }
6838
Visweswara Tanuku006313a2018-04-12 12:26:34 +05306839 /* Validate Channel */
6840 if (!WLAN_REG_IS_24GHZ_CH(chan) && !WLAN_REG_IS_5GHZ_CH(chan)) {
6841 hdd_err("Channel %d Not supported", chan);
6842 return -EINVAL;
6843 }
6844
6845 if (WLAN_REG_IS_24GHZ_CH(chan)) {
6846 if (bandwidth == CH_WIDTH_80MHZ) {
6847 hdd_err("BW80 not possible in 2.4GHz band");
6848 return -EINVAL;
6849 }
6850 if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 14) &&
6851 (bandwidth != CH_WIDTH_MAX)) {
6852 hdd_err("Only BW20 possible on channel 14");
6853 return -EINVAL;
6854 }
6855 }
6856
6857 if (WLAN_REG_IS_5GHZ_CH(chan)) {
6858 if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 165) &&
6859 (bandwidth != CH_WIDTH_MAX)) {
6860 hdd_err("Only BW20 possible on channel 165");
6861 return -EINVAL;
6862 }
6863 }
6864
Jeff Johnsond9952752018-04-18 12:15:35 -07006865 hdd_debug("Set monitor mode Channel %d", chan);
6866 qdf_mem_zero(&roam_profile, sizeof(roam_profile));
wadesong24c869a2019-07-19 17:38:59 +08006867 roam_profile.ChannelInfo.freq_list = &ch_info->freq;
Jeff Johnsond9952752018-04-18 12:15:35 -07006868 roam_profile.ChannelInfo.numOfChannels = 1;
6869 roam_profile.phyMode = ch_info->phy_mode;
6870 roam_profile.ch_params.ch_width = bandwidth;
Manikandan Mohan5c1e9ae2019-10-23 15:45:35 -07006871 hdd_select_cbmode(adapter, wlan_chan_to_freq(chan),
6872 &roam_profile.ch_params);
Abhishek Singh9fee5182019-11-01 11:39:38 +05306873
Jeff Johnsond9952752018-04-18 12:15:35 -07006874 qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
6875 QDF_MAC_ADDR_SIZE);
6876
6877 ch_params.ch_width = bandwidth;
Dustin Brown07901ec2018-09-07 11:02:41 -07006878 wlan_reg_set_channel_params(hdd_ctx->pdev, chan, 0, &ch_params);
Jeff Johnsond9952752018-04-18 12:15:35 -07006879 if (ch_params.ch_width == CH_WIDTH_INVALID) {
6880 hdd_err("Invalid capture channel or bandwidth for a country");
6881 return -EINVAL;
6882 }
6883 if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan,
6884 POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
6885 hdd_err("Failed to change hw mode");
6886 return -EINVAL;
6887 }
6888
Jeff Johnson16528362018-06-14 12:34:16 -07006889 status = sme_roam_channel_change_req(hdd_ctx->mac_handle,
6890 bssid, &ch_params,
Jeff Johnsond9952752018-04-18 12:15:35 -07006891 &roam_profile);
6892 if (status) {
6893 hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
6894 status);
6895 }
6896
Paul Zhang9d117c82019-07-25 15:55:11 +08006897 adapter->mon_chan_freq = wlan_reg_chan_to_freq(hdd_ctx->pdev, chan);
Jeff Johnsond9952752018-04-18 12:15:35 -07006898 adapter->mon_bandwidth = bandwidth;
6899 return qdf_status_to_os_return(status);
6900}
Nirav Shah73713f72018-05-17 14:50:41 +05306901#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05306902
Wu Gaodf929f12018-05-25 18:12:25 +08006903#ifdef MSM_PLATFORM
6904/**
6905 * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO
6906 * @adapter: pointer to adapter
6907 *
6908 * This function calls cfg80211 API to stop P2P GO
6909 *
6910 * Return: None
6911 */
6912static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
6913{
6914 hdd_debug("[SSR] send stop ap to supplicant");
6915 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
6916}
6917
6918static inline void hdd_delete_sta(struct hdd_adapter *adapter)
6919{
6920}
6921#else
6922static inline void hdd_stop_p2p_go(struct hdd_adapter *adapter)
6923{
6924}
6925
6926/**
6927 * hdd_delete_sta() - call cfg80211 API to delete STA
6928 * @adapter: pointer to adapter
6929 *
6930 * This function calls cfg80211 API to delete STA
6931 *
6932 * Return: None
6933 */
6934static void hdd_delete_sta(struct hdd_adapter *adapter)
6935{
6936 struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
6937
6938 hdd_debug("[SSR] send restart supplicant");
6939 /* event supplicant to restart */
6940 cfg80211_del_sta(adapter->dev,
6941 (const u8 *)&bcast_mac.bytes[0],
6942 GFP_KERNEL);
6943}
6944#endif
6945
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006946QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006947{
Jeff Johnson9d295242017-08-29 14:39:48 -07006948 struct hdd_adapter *adapter;
Jeff Johnsone7951512019-02-27 10:02:51 -08006949 eConnectionState conn_state;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05306950 bool value;
Paul Zhang9d117c82019-07-25 15:55:11 +08006951 uint8_t chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006952
Dustin Brown491d54b2018-03-14 12:39:11 -07006953 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006954
Dustin Brown920397d2017-12-13 16:27:50 -08006955 hdd_for_each_adapter(hdd_ctx, adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05306956 if (!hdd_is_interface_up(adapter))
Dustin Brown920397d2017-12-13 16:27:50 -08006957 continue;
Arun Khandavallifae92942016-08-01 13:31:08 +05306958
Yue Ma42654682018-01-11 16:55:24 -08006959 hdd_debug("[SSR] start adapter with device mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07006960 qdf_opmode_str(adapter->device_mode),
Yue Ma42654682018-01-11 16:55:24 -08006961 adapter->device_mode);
6962
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006963 hdd_wmm_init(adapter);
6964
6965 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006966 case QDF_STA_MODE:
6967 case QDF_P2P_CLIENT_MODE:
6968 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006969
Jeff Johnsone7951512019-02-27 10:02:51 -08006970 conn_state = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
6971 ->conn_info.conn_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006972
Krunal Sonib51eec72017-11-20 21:53:01 -08006973 hdd_start_station_adapter(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006974 /* Open the gates for HDD to receive Wext commands */
Jeff Johnsonc72c5732017-10-28 12:49:37 -07006975 adapter->is_link_up_service_needed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006976
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006977 /* Indicate disconnect event to supplicant
6978 * if associated previously
6979 */
Jeff Johnsone7951512019-02-27 10:02:51 -08006980 if (eConnectionState_Associated == conn_state ||
6981 eConnectionState_IbssConnected == conn_state ||
6982 eConnectionState_NotConnected == conn_state ||
6983 eConnectionState_IbssDisconnected == conn_state ||
6984 eConnectionState_Disconnecting == conn_state) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006985 union iwreq_data wrqu;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006986
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006987 memset(&wrqu, '\0', sizeof(wrqu));
6988 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6989 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
6990 wireless_send_event(adapter->dev, SIOCGIWAP,
6991 &wrqu, NULL);
Jeff Johnsonb9424862017-10-30 08:49:35 -07006992 adapter->session.station.
Jeff Johnson690fe952017-10-25 11:48:39 -07006993 hdd_reassoc_scenario = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006994
6995 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05306996 wlan_hdd_cfg80211_indicate_disconnect(
6997 adapter->dev, false,
Srinivas Dasarid4e87252019-07-01 15:35:52 +05306998 WLAN_REASON_UNSPECIFIED,
6999 NULL, 0);
Jeff Johnsone7951512019-02-27 10:02:51 -08007000 } else if (eConnectionState_Connecting == conn_state) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007001 /*
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007002 * Indicate connect failure to supplicant if we
7003 * were in the process of connecting
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007004 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05307005 hdd_connect_result(adapter->dev, NULL, NULL,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05307006 NULL, 0, NULL, 0,
7007 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007008 GFP_KERNEL, false, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007009 }
7010
7011 hdd_register_tx_flow_control(adapter,
7012 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08007013 hdd_tx_resume_cb,
7014 hdd_tx_flow_control_is_pause);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007015
Visweswara Tanukub5a61242019-03-26 12:24:13 +05307016 hdd_register_hl_netdev_fc_timer(
7017 adapter,
7018 hdd_tx_resume_timer_expired_handler);
7019
Arunk Khandavalli40943af2017-05-15 19:25:34 +05307020 hdd_lpass_notify_start(hdd_ctx, adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05307021 hdd_nud_ignore_tracking(adapter, false);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05307022 hdd_mic_enable_work(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007023 break;
7024
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007025 case QDF_SAP_MODE:
Dustin Brown05d81302018-09-11 16:49:22 -07007026 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05307027 &value);
7028 if (value)
Krunal Sonib51eec72017-11-20 21:53:01 -08007029 hdd_start_ap_adapter(adapter);
Arun Khandavallicc544b32017-01-30 19:52:16 +05307030
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05307031 hdd_mic_enable_work(adapter);
7032
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007033 break;
7034
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007035 case QDF_P2P_GO_MODE:
Wu Gaodf929f12018-05-25 18:12:25 +08007036 hdd_delete_sta(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007037 break;
Arunk Khandavalli062fb032017-10-04 12:18:15 +05307038 case QDF_MONITOR_MODE:
Paul Zhang9d117c82019-07-25 15:55:11 +08007039 chan = wlan_reg_freq_to_chan(hdd_ctx->pdev,
7040 adapter->mon_chan_freq);
Krunal Sonib51eec72017-11-20 21:53:01 -08007041 hdd_start_station_adapter(adapter);
Arunk Khandavalli062fb032017-10-04 12:18:15 +05307042 hdd_set_mon_rx_cb(adapter->dev);
Paul Zhang9d117c82019-07-25 15:55:11 +08007043 wlan_hdd_set_mon_chan(adapter, chan,
Arunk Khandavalli062fb032017-10-04 12:18:15 +05307044 adapter->mon_bandwidth);
7045 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007046 default:
7047 break;
7048 }
Krunal Soni9c2ee032017-07-18 13:49:54 -07007049 /*
7050 * Action frame registered in one adapter which will
7051 * applicable to all interfaces
7052 */
7053 wlan_hdd_cfg80211_register_frames(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007054 }
7055
Wu Gaodf929f12018-05-25 18:12:25 +08007056 hdd_for_each_adapter(hdd_ctx, adapter) {
7057 if (!hdd_is_interface_up(adapter))
7058 continue;
7059
7060 if (adapter->device_mode == QDF_P2P_GO_MODE)
7061 hdd_stop_p2p_go(adapter);
7062 }
7063
Dustin Browne74003f2018-03-14 12:51:58 -07007064 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007065
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307066 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007067}
7068
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007069QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08007070 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007071{
Anurag Chouhanffb21542016-02-17 14:33:03 +05307072 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08007073 qdf_list_node_t *node;
7074
7075 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007076
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007077 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007078 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007079 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007080
7081 if (QDF_IS_STATUS_ERROR(status))
7082 return status;
7083
7084 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
7085
7086 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007087}
7088
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007089QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08007090 struct hdd_adapter *current_adapter,
7091 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007092{
Anurag Chouhanffb21542016-02-17 14:33:03 +05307093 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08007094 qdf_list_node_t *node;
7095
7096 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007097
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007098 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Jeff Johnson19fc8e42017-10-30 19:53:49 -07007099 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
Dustin Brown920397d2017-12-13 16:27:50 -08007100 &current_adapter->node,
7101 &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007102 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007103
7104 if (QDF_IS_STATUS_ERROR(status))
7105 return status;
7106
7107 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
7108
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007109 return status;
7110}
7111
Sourav Mohapatraf43b3082019-11-06 13:58:09 +05307112QDF_STATUS hdd_get_front_adapter_no_lock(struct hdd_context *hdd_ctx,
7113 struct hdd_adapter **out_adapter)
7114{
7115 QDF_STATUS status;
7116 qdf_list_node_t *node;
7117
7118 *out_adapter = NULL;
7119
7120 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
7121
7122 if (QDF_IS_STATUS_ERROR(status))
7123 return status;
7124
7125 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
7126
7127 return QDF_STATUS_SUCCESS;
7128}
7129
7130QDF_STATUS hdd_get_next_adapter_no_lock(struct hdd_context *hdd_ctx,
7131 struct hdd_adapter *current_adapter,
7132 struct hdd_adapter **out_adapter)
7133{
7134 QDF_STATUS status;
7135 qdf_list_node_t *node;
7136
7137 if (!current_adapter)
7138 return QDF_STATUS_E_INVAL;
7139
7140 *out_adapter = NULL;
7141
7142 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
7143 &current_adapter->node,
7144 &node);
7145
7146 if (QDF_IS_STATUS_ERROR(status))
7147 return status;
7148
7149 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
7150
7151 return status;
7152}
7153
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007154QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08007155 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007156{
Anurag Chouhanffb21542016-02-17 14:33:03 +05307157 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007158
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007159 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007160 status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007161 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007162
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007163 return status;
7164}
7165
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007166QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08007167 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007168{
Anurag Chouhanffb21542016-02-17 14:33:03 +05307169 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08007170 qdf_list_node_t *node;
7171
7172 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007173
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007174 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007175 status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007176 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007177
7178 if (QDF_IS_STATUS_ERROR(status))
7179 return status;
7180
7181 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
7182
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007183 return status;
7184}
7185
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007186QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08007187 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007188{
Anurag Chouhanffb21542016-02-17 14:33:03 +05307189 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007190
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007191 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007192 status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007193 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007194
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007195 return status;
7196}
7197
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007198QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08007199 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007200{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307201 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007202
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007203 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007204 status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007205 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007206
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007207 return status;
7208}
7209
Alan Chen18cb4832019-11-15 16:40:17 -08007210QDF_STATUS hdd_adapter_iterate(hdd_adapter_iterate_cb cb, void *context)
7211{
7212 struct hdd_context *hdd_ctx;
7213 struct hdd_adapter *cache[HDD_MAX_ADAPTERS];
7214 struct hdd_adapter *adapter;
7215 uint32_t n_cache = 0;
7216 QDF_STATUS ret = QDF_STATUS_SUCCESS;
7217 QDF_STATUS status;
7218 int i;
7219
7220 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
7221 if (unlikely(!hdd_ctx)) {
7222 hdd_err("HDD context is Null");
7223 return QDF_STATUS_E_FAILURE;
7224 }
7225
7226 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
7227 for (hdd_get_front_adapter_no_lock(hdd_ctx, &adapter); adapter;
7228 hdd_get_next_adapter_no_lock(hdd_ctx, adapter, &adapter)) {
7229 cache[n_cache++] = adapter;
7230 }
7231 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
7232
7233 for (i = 0; i < n_cache - 1; i++) {
7234 adapter = hdd_adapter_get_by_reference(hdd_ctx, cache[i]);
7235 if (!adapter) {
7236 /*
7237 * detected remove while iterating
7238 * concurrency failure
7239 */
7240 ret = QDF_STATUS_E_FAILURE;
7241 continue;
7242 }
7243
7244 status = cb(adapter, context);
7245 hdd_adapter_put(adapter);
7246 if (status != QDF_STATUS_SUCCESS)
7247 return status;
7248 }
7249
7250 return ret;
7251}
7252
Liangwei Dong3abfe8f2018-09-20 02:25:44 -04007253struct hdd_adapter *hdd_get_adapter_by_rand_macaddr(
7254 struct hdd_context *hdd_ctx, tSirMacAddr mac_addr)
7255{
7256 struct hdd_adapter *adapter;
7257
7258 hdd_for_each_adapter(hdd_ctx, adapter) {
7259 if ((adapter->device_mode == QDF_STA_MODE ||
7260 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
7261 adapter->device_mode == QDF_P2P_DEVICE_MODE) &&
7262 ucfg_p2p_check_random_mac(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08007263 adapter->vdev_id, mac_addr))
Liangwei Dong3abfe8f2018-09-20 02:25:44 -04007264 return adapter;
7265 }
7266
7267 return NULL;
7268}
7269
Jeff Johnson9d295242017-08-29 14:39:48 -07007270struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07007271 tSirMacAddr mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007272{
Jeff Johnson9d295242017-08-29 14:39:48 -07007273 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007274
Dustin Brown920397d2017-12-13 16:27:50 -08007275 hdd_for_each_adapter(hdd_ctx, adapter) {
7276 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07007277 mac_addr, sizeof(tSirMacAddr)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007278 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007279 }
7280
7281 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007282}
7283
Jeff Johnson9d295242017-08-29 14:39:48 -07007284struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
Jeff Johnson55d2ab42019-03-06 11:43:49 -08007285 uint32_t vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007286{
Jeff Johnson9d295242017-08-29 14:39:48 -07007287 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007288
Dustin Brown920397d2017-12-13 16:27:50 -08007289 hdd_for_each_adapter(hdd_ctx, adapter) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08007290 if (adapter->vdev_id == vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007291 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007292 }
7293
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007294 return NULL;
7295}
7296
Alan Chendd4e7e32019-11-12 12:07:02 -08007297struct hdd_adapter *hdd_adapter_get_by_reference(struct hdd_context *hdd_ctx,
7298 struct hdd_adapter *reference)
7299{
7300 struct hdd_adapter *adapter;
7301
7302 hdd_for_each_adapter(hdd_ctx, adapter) {
7303 if (adapter == reference) {
7304 dev_hold(adapter->dev);
7305 break;
7306 }
7307 }
7308
7309 return adapter;
7310}
7311
7312void hdd_adapter_put(struct hdd_adapter *adapter)
7313{
7314 dev_put(adapter->dev);
7315}
7316
Jeff Johnson9d295242017-08-29 14:39:48 -07007317struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
Naveen Rawat4edb6822017-04-12 10:09:17 -07007318 const char *iface_name)
7319{
Jeff Johnson9d295242017-08-29 14:39:48 -07007320 struct hdd_adapter *adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07007321
Dustin Brown920397d2017-12-13 16:27:50 -08007322 hdd_for_each_adapter(hdd_ctx, adapter) {
7323 if (!qdf_str_cmp(adapter->dev->name, iface_name))
Naveen Rawat4edb6822017-04-12 10:09:17 -07007324 return adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07007325 }
Dustin Brown920397d2017-12-13 16:27:50 -08007326
Naveen Rawat4edb6822017-04-12 10:09:17 -07007327 return NULL;
7328}
7329
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007330/**
7331 * hdd_get_adapter() - to get adapter matching the mode
7332 * @hdd_ctx: hdd context
7333 * @mode: adapter mode
7334 *
7335 * This routine will return the pointer to adapter matching
7336 * with the passed mode.
7337 *
7338 * Return: pointer to adapter or null
7339 */
Jeff Johnson9d295242017-08-29 14:39:48 -07007340struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08007341 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007342{
Jeff Johnson9d295242017-08-29 14:39:48 -07007343 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007344
Dustin Brown920397d2017-12-13 16:27:50 -08007345 hdd_for_each_adapter(hdd_ctx, adapter) {
7346 if (adapter->device_mode == mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007347 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007348 }
7349
7350 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007351}
7352
Jeff Johnson55d2ab42019-03-06 11:43:49 -08007353enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id)
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05307354{
7355 struct hdd_context *hdd_ctx;
7356 struct hdd_adapter *adapter;
7357
7358 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
7359 if (!hdd_ctx) {
7360 hdd_err("Invalid HDD context");
7361 return QDF_MAX_NO_OF_MODE;
7362 }
7363
Jeff Johnson55d2ab42019-03-06 11:43:49 -08007364 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05307365 if (!adapter) {
7366 hdd_err("Invalid HDD adapter");
7367 return QDF_MAX_NO_OF_MODE;
7368 }
7369
7370 return adapter->device_mode;
7371}
7372
wadesonga8940a22019-11-11 16:58:16 +08007373uint32_t hdd_get_operating_chan_freq(struct hdd_context *hdd_ctx,
7374 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007375{
Jeff Johnson9d295242017-08-29 14:39:48 -07007376 struct hdd_adapter *adapter;
wadesonga8940a22019-11-11 16:58:16 +08007377 uint32_t oper_chan_freq = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007378
Dustin Brown920397d2017-12-13 16:27:50 -08007379 hdd_for_each_adapter(hdd_ctx, adapter) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007380 if (mode == adapter->device_mode) {
wadesonga8940a22019-11-11 16:58:16 +08007381 oper_chan_freq =
Jingxiang Geae80dc62019-08-13 17:32:22 +08007382 hdd_get_adapter_home_channel(adapter);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007383 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007384 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007385 }
Dustin Brown920397d2017-12-13 16:27:50 -08007386
wadesonga8940a22019-11-11 16:58:16 +08007387 return oper_chan_freq;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007388}
7389
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007390static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007391 hdd_ctx)
7392{
Jeff Johnson9d295242017-08-29 14:39:48 -07007393 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007394
Dustin Brown491d54b2018-03-14 12:39:11 -07007395 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007396
Dustin Brown920397d2017-12-13 16:27:50 -08007397 hdd_for_each_adapter(hdd_ctx, adapter) {
7398 if (adapter->device_mode == QDF_STA_MODE ||
7399 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
7400 adapter->device_mode == QDF_IBSS_MODE ||
7401 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
7402 adapter->device_mode == QDF_SAP_MODE ||
7403 adapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007404 hdd_unregister_wext(adapter->dev);
7405 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007406 }
7407
Dustin Browne74003f2018-03-14 12:51:58 -07007408 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007409
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307410 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007411}
7412
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007413QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007414{
Jeff Johnson9d295242017-08-29 14:39:48 -07007415 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007416
Dustin Brown491d54b2018-03-14 12:39:11 -07007417 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007418
Dustin Brown920397d2017-12-13 16:27:50 -08007419 hdd_for_each_adapter(hdd_ctx, adapter) {
7420 if (adapter->device_mode == QDF_STA_MODE ||
7421 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
7422 adapter->device_mode == QDF_IBSS_MODE ||
7423 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
7424 adapter->device_mode == QDF_SAP_MODE ||
7425 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brown07901ec2018-09-07 11:02:41 -07007426 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08007427 adapter->vdev_id, INVALID_SCAN_ID,
Vignesh Viswanathan19611c82018-01-16 16:20:40 +05307428 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007429 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007430 }
7431
Dustin Browne74003f2018-03-14 12:51:58 -07007432 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007433
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307434 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007435}
7436
Dustin Brownf27bce82016-11-03 12:52:27 -07007437/**
7438 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
7439 * adapters
7440 * @hdd_ctx: The HDD context containing the adapters to operate on
7441 *
7442 * return: QDF_STATUS_SUCCESS
7443 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007444static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
Dustin Brownf27bce82016-11-03 12:52:27 -07007445{
Jeff Johnson9d295242017-08-29 14:39:48 -07007446 struct hdd_adapter *adapter;
Dustin Brownf27bce82016-11-03 12:52:27 -07007447 int err;
7448
Dustin Brown491d54b2018-03-14 12:39:11 -07007449 hdd_enter();
Dustin Brownf27bce82016-11-03 12:52:27 -07007450
Dustin Brown920397d2017-12-13 16:27:50 -08007451 hdd_for_each_adapter(hdd_ctx, adapter) {
7452 if (adapter->device_mode == QDF_STA_MODE ||
7453 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
7454 adapter->device_mode == QDF_IBSS_MODE ||
7455 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
7456 adapter->device_mode == QDF_SAP_MODE ||
7457 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brownf27bce82016-11-03 12:52:27 -07007458 err = wlan_hdd_sched_scan_stop(adapter->dev);
7459 if (err)
7460 hdd_err("Unable to stop scheduled scan");
7461 }
Dustin Brownf27bce82016-11-03 12:52:27 -07007462 }
7463
Dustin Browne74003f2018-03-14 12:51:58 -07007464 hdd_exit();
Dustin Brownf27bce82016-11-03 12:52:27 -07007465
7466 return QDF_STATUS_SUCCESS;
7467}
7468
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007469#ifdef WLAN_NS_OFFLOAD
7470/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007471 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007472 * @hdd_ctx: Pointer to hdd context
7473 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007474 * Unregister for IPv6 address change notifications.
7475 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007476 * Return: None
7477 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007478static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007479{
7480 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007481}
7482
7483/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007484 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007485 * @hdd_ctx: Pointer to hdd context
7486 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007487 * Register for IPv6 address change notifications.
7488 *
7489 * Return: 0 on success and errno on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007490 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007491static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007492{
7493 int ret;
7494
7495 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
7496 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007497 if (ret) {
7498 hdd_err("Failed to register IPv6 notifier: %d", ret);
7499 goto out;
7500 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007501
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007502 hdd_debug("Registered IPv6 notifier");
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007503out:
7504 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007505}
7506#else
7507/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007508 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007509 * @hdd_ctx: Pointer to hdd context
7510 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007511 * Unregister for IPv6 address change notifications.
7512 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007513 * Return: None
7514 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007515static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007516{
7517}
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007518
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007519/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007520 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007521 * @hdd_ctx: Pointer to hdd context
7522 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007523 * Register for IPv6 address change notifications.
7524 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007525 * Return: None
7526 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007527static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007528{
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007529 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007530}
7531#endif
7532
Alok Kumarb64650c2018-03-23 17:05:11 +05307533void hdd_set_disconnect_status(struct hdd_adapter *adapter, bool status)
7534{
7535 qdf_mutex_acquire(&adapter->disconnection_status_lock);
7536 adapter->disconnection_in_progress = status;
7537 qdf_mutex_release(&adapter->disconnection_status_lock);
7538 hdd_debug("setting disconnection status: %d", status);
7539}
7540
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007541/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007542 * hdd_register_notifiers - Register netdev notifiers.
7543 * @hdd_ctx: HDD context
7544 *
7545 * Register netdev notifiers like IPv4 and IPv6.
7546 *
7547 * Return: 0 on success and errno on failure
7548 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007549static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007550{
7551 int ret;
7552
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007553 ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
7554 if (ret)
Arun Khandavalli08479ba2017-08-07 19:56:23 +05307555 goto out;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007556
7557 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
7558 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
7559 if (ret) {
7560 hdd_err("Failed to register IPv4 notifier: %d", ret);
7561 goto unregister_ip6_notifier;
7562 }
7563
Alok Kumarb64650c2018-03-23 17:05:11 +05307564 ret = hdd_nud_register_netevent_notifier(hdd_ctx);
7565 if (ret) {
7566 hdd_err("Failed to register netevent notifier: %d",
7567 ret);
7568 goto unregister_inetaddr_notifier;
7569 }
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007570 return 0;
7571
Alok Kumarb64650c2018-03-23 17:05:11 +05307572unregister_inetaddr_notifier:
7573 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007574unregister_ip6_notifier:
7575 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007576out:
7577 return ret;
7578
7579}
7580
7581/**
7582 * hdd_unregister_notifiers - Unregister netdev notifiers.
7583 * @hdd_ctx: HDD context
7584 *
7585 * Unregister netdev notifiers like IPv4 and IPv6.
7586 *
7587 * Return: None.
7588 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007589void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007590{
Alok Kumarb64650c2018-03-23 17:05:11 +05307591 hdd_nud_unregister_netevent_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007592 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
7593
7594 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007595}
7596
7597/**
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007598 * hdd_exit_netlink_services - Exit netlink services
7599 * @hdd_ctx: HDD context
7600 *
7601 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
7602 * nl service.
7603 *
7604 * Return: None.
7605 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007606static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007607{
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307608 spectral_scan_deactivate_service();
7609 cnss_diag_deactivate_service();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007610 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007611 ptt_sock_deactivate_svc();
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307612 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007613
7614 nl_srv_exit();
7615}
7616
7617/**
7618 * hdd_init_netlink_services- Init netlink services
7619 * @hdd_ctx: HDD context
7620 *
7621 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
7622 * nl service.
7623 *
7624 * Return: 0 on success and errno on failure.
7625 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007626static int hdd_init_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007627{
7628 int ret;
7629
Ryan Hsuceddceb2016-04-28 10:20:14 -07007630 ret = wlan_hdd_nl_init(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007631 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007632 hdd_err("nl_srv_init failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007633 goto out;
7634 }
Ryan Hsuceddceb2016-04-28 10:20:14 -07007635 cds_set_radio_index(hdd_ctx->radio_index);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007636
Naveen Rawat910726a2017-03-06 11:42:51 -08007637 ret = hdd_activate_wifi_pos(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007638 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007639 hdd_err("hdd_activate_wifi_pos failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007640 goto err_nl_srv;
7641 }
7642
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307643 ptt_sock_activate_svc();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007644
7645 ret = hdd_open_cesium_nl_sock();
Ryan Hsu5e2e2052016-04-28 10:19:38 -07007646 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007647 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007648
7649 ret = cnss_diag_activate_service();
7650 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007651 hdd_err("cnss_diag_activate_service failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007652 goto err_close_cesium;
7653 }
7654
Dustin Brown01520852019-02-27 12:14:16 -08007655 spectral_scan_activate_service(hdd_ctx);
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -08007656
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007657 return 0;
7658
7659err_close_cesium:
7660 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007661 ptt_sock_deactivate_svc();
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307662 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007663err_nl_srv:
7664 nl_srv_exit();
7665out:
7666 return ret;
7667}
7668
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007669/**
7670 * hdd_rx_wake_lock_destroy() - Destroy RX wakelock
7671 * @hdd_ctx: HDD context.
7672 *
7673 * Destroy RX wakelock.
7674 *
7675 * Return: None.
7676 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007677static void hdd_rx_wake_lock_destroy(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007678{
7679 qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
7680}
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007681
7682/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007683 * hdd_rx_wake_lock_create() - Create RX wakelock
7684 * @hdd_ctx: HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007685 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007686 * Create RX wakelock.
7687 *
7688 * Return: None.
7689 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007690static void hdd_rx_wake_lock_create(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007691{
7692 qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
7693}
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007694
7695/**
Houston Hoffman160db392016-10-10 17:37:51 -07007696 * hdd_context_deinit() - Deinitialize HDD context
7697 * @hdd_ctx: HDD context.
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007698 *
Houston Hoffman160db392016-10-10 17:37:51 -07007699 * Deinitialize HDD context along with all the feature specific contexts but
7700 * do not free hdd context itself. Caller of this API is supposed to free
7701 * HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007702 *
Houston Hoffman160db392016-10-10 17:37:51 -07007703 * return: 0 on success and errno on failure.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007704 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007705static int hdd_context_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007706{
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05307707 qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock);
7708
Houston Hoffman160db392016-10-10 17:37:51 -07007709 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007710
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007711 hdd_sap_context_destroy(hdd_ctx);
7712
7713 hdd_rx_wake_lock_destroy(hdd_ctx);
7714
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007715 hdd_scan_context_destroy(hdd_ctx);
7716
Jeff Johnson19fc8e42017-10-30 19:53:49 -07007717 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007718
Houston Hoffman160db392016-10-10 17:37:51 -07007719 return 0;
7720}
7721
Dustin Brown623e7e32018-09-05 14:27:50 -07007722void hdd_context_destroy(struct hdd_context *hdd_ctx)
Houston Hoffman160db392016-10-10 17:37:51 -07007723{
Rajeev Kumar493a31b2017-09-29 14:01:24 -07007724 cds_set_context(QDF_MODULE_ID_HDD, NULL);
Arunk Khandavalli3d267b42017-05-02 18:58:59 +05307725
Dustin Brown623e7e32018-09-05 14:27:50 -07007726 hdd_exit_netlink_services(hdd_ctx);
Hanumantha Reddy Pothula00c74f62016-11-24 20:13:32 +05307727
Houston Hoffman160db392016-10-10 17:37:51 -07007728 hdd_context_deinit(hdd_ctx);
7729
Dustin Browndb2df2e2018-10-31 15:29:24 -07007730 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
7731
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307732 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007733 hdd_ctx->config = NULL;
Dustin Brown84f46ea2018-02-15 11:57:36 -08007734 cfg_release();
7735
Min Liu47104042019-04-09 17:49:21 +08007736 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007737 wiphy_free(hdd_ctx->wiphy);
7738}
7739
7740/**
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05307741 * wlan_destroy_bug_report_lock() - Destroy bug report lock
7742 *
7743 * This function is used to destroy bug report lock
7744 *
7745 * Return: None
7746 */
7747static void wlan_destroy_bug_report_lock(void)
7748{
Jeff Johnson2b6982c2018-05-29 14:56:11 -07007749 struct cds_context *p_cds_context;
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05307750
7751 p_cds_context = cds_get_global_context();
7752 if (!p_cds_context) {
7753 hdd_err("cds context is NULL");
7754 return;
7755 }
7756
7757 qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
7758}
7759
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +05307760#ifdef DISABLE_CHANNEL_LIST
7761static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
7762{
7763 qdf_mutex_destroy(&hdd_ctx->cache_channel_lock);
7764}
7765#else
7766static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
7767{
7768}
7769#endif
7770
Dustin Brown92bd8382018-10-31 15:49:46 -07007771void hdd_wlan_exit(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007772{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007773 struct wiphy *wiphy = hdd_ctx->wiphy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007774
Dustin Brown491d54b2018-03-14 12:39:11 -07007775 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007776
Arun Kumar Khandavallideda5a82019-03-11 15:32:19 +05307777 hdd_debugfs_mws_coex_info_deinit(hdd_ctx);
Dustin Brown4c663222018-10-23 14:19:36 -07007778 hdd_psoc_idle_timer_stop(hdd_ctx);
Dustin Brown6470aba2018-09-05 09:49:58 -07007779
Arun Khandavallifae92942016-08-01 13:31:08 +05307780 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007781
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007782 /*
7783 * Powersave Offload Case
7784 * Disable Idle Power Save Mode
7785 */
7786 hdd_set_idle_ps_config(hdd_ctx, false);
Sandeep Puligilla8fa28fd2017-11-02 12:19:33 -07007787 /* clear the scan queue in all the scenarios */
Dustin Brown07901ec2018-09-07 11:02:41 -07007788 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007789
Dustin Brownf688ea12019-03-19 17:02:32 -07007790 if (hdd_ctx->driver_status != DRIVER_MODULES_CLOSED) {
Arun Khandavallifae92942016-08-01 13:31:08 +05307791 hdd_unregister_wext_all_adapters(hdd_ctx);
7792 /*
7793 * Cancel any outstanding scan requests. We are about to close
7794 * all of our adapters, but an adapter structure is what SME
7795 * passes back to our callback function. Hence if there
7796 * are any outstanding scan requests then there is a
7797 * race condition between when the adapter is closed and
7798 * when the callback is invoked. We try to resolve that
7799 * race condition here by canceling any outstanding scans
7800 * before we close the adapters.
7801 * Note that the scans may be cancelled in an asynchronous
7802 * manner, so ideally there needs to be some kind of
7803 * synchronization. Rather than introduce a new
7804 * synchronization here, we will utilize the fact that we are
7805 * about to Request Full Power, and since that is synchronized,
7806 * the expectation is that by the time Request Full Power has
7807 * completed, all scans will be cancelled
7808 */
7809 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Dustin Brownf27bce82016-11-03 12:52:27 -07007810 hdd_abort_sched_scan_all_adapters(hdd_ctx);
Dustin Browndb2a8be2017-12-20 11:49:56 -08007811 hdd_stop_all_adapters(hdd_ctx);
bings29c99862017-11-01 13:54:13 +08007812 hdd_deinit_all_adapters(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007813 }
7814
Arun Khandavalli08479ba2017-08-07 19:56:23 +05307815 unregister_netdevice_notifier(&hdd_netdev_notifier);
7816
Rachit Kankane30807332018-06-27 18:39:36 +05307817 qdf_dp_trace_deinit();
7818
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07007819 hdd_wlan_stop_modules(hdd_ctx, false);
Hanumanth Reddy Pothula709a6362016-10-18 18:19:44 +05307820
Dustin Brown86d196b2018-08-02 11:51:49 -07007821 hdd_bus_bandwidth_deinit(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -08007822 hdd_driver_memdump_deinit();
7823
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +05307824 qdf_nbuf_deinit_replenish_timer();
7825
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05307826 if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) {
7827 hdd_info("Release wakelock for monitor mode!");
7828 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
7829 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
7830 }
7831
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307832 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307833 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +05307834 wlan_hdd_cache_chann_mutex_destroy(hdd_ctx);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307835
Naveen Rawate02f8f52018-04-05 11:58:04 -07007836 osif_request_manager_deinit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007837
Dustin Brownd005ad82018-01-19 10:32:13 -08007838 hdd_close_all_adapters(hdd_ctx, false);
7839
Manishekar Chandrasekaranf7a1dad2016-06-23 06:43:47 +05307840 wlansap_global_deinit();
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05307841 /*
7842 * If there is re_init failure wiphy would have already de-registered
7843 * check the wiphy status before un-registering again
7844 */
Ashish Kumar Dhanotiyae16feb72017-03-31 19:39:37 +05307845 if (wiphy && wiphy->registered) {
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05307846 wiphy_unregister(wiphy);
7847 wlan_hdd_cfg80211_deinit(wiphy);
7848 hdd_lpass_notify_stop(hdd_ctx);
7849 }
Yuanyuan Liu3e918e52016-08-17 15:41:35 -07007850
Arun Khandavallifae92942016-08-01 13:31:08 +05307851 hdd_exit_netlink_services(hdd_ctx);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05307852#ifdef FEATURE_WLAN_CH_AVOID
7853 mutex_destroy(&hdd_ctx->avoid_freq_lock);
7854#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007855}
7856
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007857/**
7858 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
7859 * @state: state
7860 *
7861 * This function notifies FW with modem power status
7862 *
7863 * Return: 0 if successful, error number otherwise
7864 */
7865int hdd_wlan_notify_modem_power_state(int state)
7866{
7867 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307868 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007869 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -07007870 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007871
Anurag Chouhan6d760662016-02-20 16:05:43 +05307872 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007873 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307874 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007875 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307876
Jeff Johnson16528362018-06-14 12:34:16 -07007877 mac_handle = hdd_ctx->mac_handle;
7878 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007879 return -EINVAL;
7880
Jeff Johnson16528362018-06-14 12:34:16 -07007881 qdf_status = sme_notify_modem_power_state(mac_handle, state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307882 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007883 hdd_err("Fail to send notification with modem power state %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007884 state);
7885 return -EINVAL;
7886 }
7887 return 0;
7888}
7889
7890/**
7891 *
7892 * hdd_post_cds_enable_config() - HDD post cds start config helper
7893 * @adapter - Pointer to the HDD
7894 *
7895 * Return: None
7896 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007897QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007898{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307899 QDF_STATUS qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007900
7901 /*
7902 * Send ready indication to the HDD. This will kick off the MAC
7903 * into a 'running' state and should kick off an initial scan.
7904 */
Jeff Johnson16528362018-06-14 12:34:16 -07007905 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307906 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007907 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
7908 qdf_ret_status, qdf_ret_status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307909 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007910 }
7911
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307912 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007913}
7914
Sourav Mohapatra92ea8d62018-02-05 10:03:10 +05307915struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx)
7916{
7917 struct hdd_adapter *adapter;
7918
7919 hdd_for_each_adapter(hdd_ctx, adapter) {
7920 if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC)
7921 return adapter;
7922 }
7923
7924 return NULL;
7925}
7926
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05307927/**
7928 * hdd_rx_mic_error_ind() - MIC error indication handler
7929 * @scn_handle: pdev handle from osif layer
7930 * @info: mic failure information
7931 *
7932 * This function indicates the Mic failure to the supplicant
7933 *
7934 * Return: None
7935 */
7936static void
7937hdd_rx_mic_error_ind(void *scn_handle,
7938 struct cdp_rx_mic_err_info *mic_failure_info)
7939{
7940 struct wiphy *wiphy;
7941 struct pdev_osif_priv *pdev_priv;
7942 struct hdd_context *hdd_ctx;
7943 struct hdd_adapter *adapter;
7944 struct hdd_mic_error_info *hdd_mic_info;
7945 struct wlan_objmgr_pdev *pdev;
7946
7947 pdev = (struct wlan_objmgr_pdev *)scn_handle;
7948 pdev_priv = wlan_pdev_get_ospriv(pdev);
7949 wiphy = pdev_priv->wiphy;
7950 hdd_ctx = wiphy_priv(wiphy);
7951
7952 if (wlan_hdd_validate_context(hdd_ctx))
7953 return;
7954
7955 adapter = hdd_get_adapter_by_vdev(hdd_ctx, mic_failure_info->vdev_id);
7956 if (hdd_validate_adapter(adapter))
7957 return;
7958
7959 hdd_mic_info = qdf_mem_malloc(sizeof(*hdd_mic_info));
7960 if (!hdd_mic_info)
7961 return;
7962
7963 qdf_copy_macaddr(&hdd_mic_info->ta_mac_addr,
7964 &mic_failure_info->ta_mac_addr);
7965 hdd_mic_info->multicast = mic_failure_info->multicast;
7966 hdd_mic_info->key_id = mic_failure_info->key_id;
7967 qdf_mem_copy(&hdd_mic_info->tsc, &mic_failure_info->tsc,
7968 SIR_CIPHER_SEQ_CTR_SIZE);
7969 hdd_mic_info->vdev_id = mic_failure_info->vdev_id;
7970
7971 qdf_spin_lock_bh(&adapter->mic_work.lock);
7972 if (adapter->mic_work.status != MIC_INITIALIZED) {
7973 qdf_spin_unlock_bh(&adapter->mic_work.lock);
7974 qdf_mem_free(hdd_mic_info);
7975 return;
7976 }
7977 /*
7978 * Store mic error info pointer in adapter
7979 * for freeing up the alocated memory in case
7980 * the work scheduled below is flushed or deinitialized.
7981 */
7982 adapter->mic_work.status = MIC_SCHEDULED;
7983 adapter->mic_work.info = hdd_mic_info;
7984 qdf_sched_work(0, &adapter->mic_work.work);
7985 qdf_spin_unlock_bh(&adapter->mic_work.lock);
7986}
7987
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007988/* wake lock APIs for HDD */
7989void hdd_prevent_suspend(uint32_t reason)
7990{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05307991 qdf_wake_lock_acquire(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007992}
7993
7994void hdd_allow_suspend(uint32_t reason)
7995{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05307996 qdf_wake_lock_release(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007997}
7998
7999void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
8000{
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05308001 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
8002 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008003}
8004
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008005/* Initialize channel list in sme based on the country code */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008006QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008007{
Jeff Johnson16528362018-06-14 12:34:16 -07008008 return sme_init_chan_list(hdd_ctx->mac_handle,
Amar Singhal6f8592b2017-04-26 14:31:58 -07008009 hdd_ctx->reg.alpha2,
8010 hdd_ctx->reg.cc_src);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008011}
8012
8013/**
8014 * hdd_is_5g_supported() - check if hardware supports 5GHz
8015 * @hdd_ctx: Pointer to the hdd context
8016 *
8017 * HDD function to know if hardware supports 5GHz
8018 *
8019 * Return: true if hardware supports 5GHz
8020 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008021bool hdd_is_5g_supported(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008022{
Amar Singhal58b45ef2017-08-01 13:43:54 -07008023 if (!hdd_ctx)
zdingf54169a2016-10-12 17:08:45 +08008024 return true;
8025
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08008026 if (hdd_ctx->curr_band != BAND_2G)
zdingf54169a2016-10-12 17:08:45 +08008027 return true;
8028 else
8029 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008030}
8031
Ashish Kumar Dhanotiya34507e02019-06-12 12:53:59 +05308032bool hdd_is_2g_supported(struct hdd_context *hdd_ctx)
8033{
8034 if (!hdd_ctx)
8035 return false;
8036
8037 if (hdd_ctx->curr_band != BAND_5G)
8038 return true;
8039 else
8040 return false;
8041}
8042
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008043static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008044{
8045 struct wiphy *wiphy;
Amar Singhale4f28ee2015-10-21 14:36:56 -07008046 int ret_val;
Wu Gaoed616a12019-01-16 15:19:21 +08008047 uint32_t channel_bonding_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008048
8049 wiphy = hdd_ctx->wiphy;
8050
8051 /*
8052 * The channel information in
8053 * wiphy needs to be initialized before wiphy registration
8054 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07008055 ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
8056 if (ret_val) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008057 hdd_err("regulatory init failed");
Amar Singhale4f28ee2015-10-21 14:36:56 -07008058 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008059 }
8060
8061#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
8062 wiphy->wowlan = &wowlan_support_reg_init;
8063#else
8064 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
8065 WIPHY_WOWLAN_MAGIC_PKT |
8066 WIPHY_WOWLAN_DISCONNECT |
8067 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
8068 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
8069 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
8070 WIPHY_WOWLAN_4WAY_HANDSHAKE |
8071 WIPHY_WOWLAN_RFKILL_RELEASE;
8072
8073 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
8074 WOW_MAX_FILTERS_PER_LIST);
8075 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
8076 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
8077#endif
Wu Gaoed616a12019-01-16 15:19:21 +08008078 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
8079 &channel_bonding_mode);
Liangwei Dong0da14262018-07-03 03:30:23 -04008080 if (hdd_ctx->obss_scan_offload) {
8081 hdd_debug("wmi_service_obss_scan supported");
Wu Gaoed616a12019-01-16 15:19:21 +08008082 } else if (channel_bonding_mode) {
Liangwei Dong0da14262018-07-03 03:30:23 -04008083 hdd_debug("enable wpa_supp obss_scan");
8084 wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN;
8085 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008086
8087 /* registration of wiphy dev with cfg80211 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07008088 ret_val = wlan_hdd_cfg80211_register(wiphy);
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05308089 if (0 > ret_val) {
Amar Singhale4f28ee2015-10-21 14:36:56 -07008090 hdd_err("wiphy registration failed");
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05308091 return ret_val;
8092 }
Amar Singhalac26de22018-06-22 12:53:06 -07008093
Kiran Kumar Lokere0508af92018-04-23 18:38:32 -07008094 /* Check the kernel version for upstream commit aced43ce780dc5 that
8095 * has support for processing user cell_base hints when wiphy is
8096 * self managed or check the backport flag for the same.
8097 */
Amar Singhalac26de22018-06-22 12:53:06 -07008098#if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
8099 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
Kiran Kumar Lokere0508af92018-04-23 18:38:32 -07008100 hdd_send_wiphy_regd_sync_event(hdd_ctx);
8101#endif
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05308102
Amar Singhal2d812012018-02-03 15:06:47 +08008103 pld_increment_driver_load_cnt(hdd_ctx->parent_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008104
Amar Singhale4f28ee2015-10-21 14:36:56 -07008105 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008106}
8107
Tiger Yu8b119e92019-04-09 13:55:07 +08008108#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
Mohit Khannaca4173b2017-09-12 21:52:19 -07008109/**
8110 * hdd_display_periodic_stats() - Function to display periodic stats
8111 * @hdd_ctx - handle to hdd context
8112 * @bool data_in_interval - true, if data detected in bw time interval
8113 *
8114 * The periodicity is determined by hdd_ctx->config->periodic_stats_disp_time.
8115 * Stats show up in wlan driver logs.
8116 *
8117 * Returns: None
8118 */
Mohit Khanna70322002018-05-15 19:21:32 -07008119static void hdd_display_periodic_stats(struct hdd_context *hdd_ctx,
8120 bool data_in_interval)
Mohit Khannaca4173b2017-09-12 21:52:19 -07008121{
Mohit Khanna70322002018-05-15 19:21:32 -07008122 static uint32_t counter;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008123 static bool data_in_time_period;
8124 ol_txrx_pdev_handle pdev;
Mohit Khanna81418772018-10-30 14:14:46 -07008125 ol_txrx_soc_handle soc;
Arif Hussaincca60432018-12-03 19:45:12 -08008126 uint32_t periodic_stats_disp_time = 0;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008127
Arif Hussaincca60432018-12-03 19:45:12 -08008128 ucfg_mlme_stats_get_periodic_display_time(hdd_ctx->psoc,
8129 &periodic_stats_disp_time);
8130 if (!periodic_stats_disp_time)
Mohit Khannaca4173b2017-09-12 21:52:19 -07008131 return;
8132
Mohit Khanna81418772018-10-30 14:14:46 -07008133 soc = cds_get_context(QDF_MODULE_ID_SOC);
8134 if (!soc) {
8135 hdd_err("soc is NULL");
8136 return;
8137 }
8138
Mohit Khannaca4173b2017-09-12 21:52:19 -07008139 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
8140 if (!pdev) {
8141 hdd_err("pdev is NULL");
8142 return;
8143 }
8144
8145 counter++;
8146 if (data_in_interval)
8147 data_in_time_period = data_in_interval;
8148
jitiphil869b9f72018-09-25 17:14:01 +05308149 if (counter * hdd_ctx->config->bus_bw_compute_interval >=
Arif Hussaincca60432018-12-03 19:45:12 -08008150 periodic_stats_disp_time * 1000) {
Mohit Khannaca4173b2017-09-12 21:52:19 -07008151 if (data_in_time_period) {
Mohit Khanna70322002018-05-15 19:21:32 -07008152 wlan_hdd_display_txrx_stats(hdd_ctx);
Mohit Khannac9649652018-11-28 18:10:28 -08008153 dp_txrx_ext_dump_stats(soc, CDP_DP_RX_THREAD_STATS);
Mohit Khanna81418772018-10-30 14:14:46 -07008154 cdp_display_stats(soc,
Mohit Khanna70322002018-05-15 19:21:32 -07008155 CDP_RX_RING_STATS,
8156 QDF_STATS_VERBOSITY_LEVEL_LOW);
Mohit Khanna81418772018-10-30 14:14:46 -07008157 cdp_display_stats(soc,
Mohit Khannaca4173b2017-09-12 21:52:19 -07008158 CDP_TXRX_PATH_STATS,
8159 QDF_STATS_VERBOSITY_LEVEL_LOW);
Nirav Shahaa34cbb2019-07-03 10:32:04 +05308160 cdp_display_stats(soc,
8161 CDP_DUMP_TX_FLOW_POOL_INFO,
8162 QDF_STATS_VERBOSITY_LEVEL_LOW);
Mohit Khannaca4173b2017-09-12 21:52:19 -07008163 wlan_hdd_display_netif_queue_history
8164 (hdd_ctx, QDF_STATS_VERBOSITY_LEVEL_LOW);
8165 qdf_dp_trace_dump_stats();
8166 }
8167 counter = 0;
8168 data_in_time_period = false;
8169 }
8170}
8171
Ravi Joshie2331e82015-07-01 18:18:54 -07008172/**
Tang Yingying5a4ccf22018-03-30 15:58:27 +08008173 * hdd_clear_rps_cpu_mask - clear RPS CPU mask for interfaces
8174 * @hdd_ctx: pointer to struct hdd_context
8175 *
8176 * Return: none
8177 */
8178static void hdd_clear_rps_cpu_mask(struct hdd_context *hdd_ctx)
8179{
8180 struct hdd_adapter *adapter;
8181
8182 hdd_for_each_adapter(hdd_ctx, adapter)
8183 hdd_send_rps_disable_ind(adapter);
8184}
8185
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008186#ifdef CLD_PM_QOS
8187#define PLD_REMOVE_PM_QOS(x)
8188#define PLD_REQUEST_PM_QOS(x, y)
8189/**
8190 * hdd_pm_qos_update_cpu_mask() - Prepare CPU mask for PM_qos voting
8191 * @mask: return variable of cpumask for the TPUT
8192 * @high_throughput: only update high cores mask for high TPUT
8193 *
8194 * Return: none
8195 */
8196static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask,
8197 bool high_throughput)
8198{
8199 cpumask_set_cpu(0, mask);
8200 cpumask_set_cpu(1, mask);
8201 cpumask_set_cpu(2, mask);
8202 cpumask_set_cpu(3, mask);
8203
8204 if (high_throughput) {
8205 /* For high TPUT include GOLD mask also */
8206 cpumask_set_cpu(4, mask);
8207 cpumask_set_cpu(5, mask);
8208 cpumask_set_cpu(6, mask);
8209 }
8210}
8211
8212/**
8213 * hdd_pm_qos_update_request() - API to request for pm_qos
8214 * @hdd_ctx: handle to hdd context
8215 * @pm_qos_cpu_mask: cpu_mask to apply
8216 *
8217 * Return: none
8218 */
8219static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
8220 cpumask_t *pm_qos_cpu_mask)
8221{
8222 cpumask_copy(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask);
Mahesh Kumar Kalikot Veetil798fddc2019-10-10 22:59:33 -07008223
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008224 /* Latency value to be read from INI */
Mahesh Kumar Kalikot Veetil798fddc2019-10-10 22:59:33 -07008225 if (cpumask_empty(pm_qos_cpu_mask))
8226 pm_qos_update_request(&hdd_ctx->pm_qos_req,
8227 PM_QOS_DEFAULT_VALUE);
8228 else
8229 pm_qos_update_request(&hdd_ctx->pm_qos_req, 1);
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008230}
8231
8232#ifdef CONFIG_SMP
8233/**
8234 * hdd_update_pm_qos_affine_cores() - Update PM_qos request for AFFINE_CORES
8235 * @hdd_ctx: handle to hdd context
8236 *
8237 * Return: none
8238 */
8239static inline void hdd_update_pm_qos_affine_cores(struct hdd_context *hdd_ctx)
8240{
8241 hdd_ctx->pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES;
Nisha Menon33030f82019-10-28 16:24:21 -07008242 qdf_cpumask_clear(&hdd_ctx->pm_qos_req.cpus_affine);
8243 hdd_pm_qos_update_cpu_mask(&hdd_ctx->pm_qos_req.cpus_affine, false);
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008244}
8245#else
8246static inline void hdd_update_pm_qos_affine_cores(struct hdd_context *hdd_ctx)
8247{
8248}
8249#endif
8250static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
8251{
8252 hdd_update_pm_qos_affine_cores(hdd_ctx);
8253 pm_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
8254 PM_QOS_DEFAULT_VALUE);
Nisha Menon33030f82019-10-28 16:24:21 -07008255 hdd_info("Set cpu_mask %*pb for affine_cores",
8256 cpumask_pr_args(&hdd_ctx->pm_qos_req.cpus_affine));
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008257}
8258
8259static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
8260{
8261 pm_qos_remove_request(&hdd_ctx->pm_qos_req);
8262}
8263#else
8264#define PLD_REMOVE_PM_QOS(x) pld_remove_pm_qos(x)
8265#define PLD_REQUEST_PM_QOS(x, y) pld_request_pm_qos(x, y)
8266
8267static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
8268{
8269}
8270
8271static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
8272{
8273}
8274
8275static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask,
8276 bool high_throughput)
8277{
8278}
8279
8280static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
8281 cpumask_t *pm_qos_cpu_mask)
8282{
8283}
8284#endif
8285
Tang Yingying5a4ccf22018-03-30 15:58:27 +08008286/**
Yuanyuan Liu13738502016-04-06 17:41:37 -07008287 * hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
Ravi Joshie2331e82015-07-01 18:18:54 -07008288 * @hdd_ctx - handle to hdd context
8289 * @tx_packets - transmit packet count
8290 * @rx_packets - receive packet count
8291 *
8292 * The function controls the bus bandwidth and dynamic control of
8293 * tcp delayed ack configuration
8294 *
8295 * Returns: None
8296 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07008297
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008298static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07008299 const uint64_t tx_packets,
8300 const uint64_t rx_packets)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008301{
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008302 uint16_t index = 0;
8303 bool vote_level_change = false;
8304 bool rx_level_change = false;
8305 bool tx_level_change = false;
8306 bool rxthread_high_tput_req = false;
8307 bool dptrace_high_tput_req;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008308 u64 total_pkts = tx_packets + rx_packets;
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008309 uint64_t avg_tx = 0, avg_rx = 0;
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008310 uint64_t no_rx_offload_pkts = 0, avg_no_rx_offload_pkts = 0;
8311 uint64_t rx_offload_pkts = 0, avg_rx_offload_pkts = 0;
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008312 uint64_t no_tx_offload_pkts = 0, avg_no_tx_offload_pkts = 0;
8313 uint64_t tx_offload_pkts = 0, avg_tx_offload_pkts = 0;
Mahesh Kumar Kalikot Veetil64a88692019-07-03 13:57:34 -07008314 enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_IDLE;
Mohit Khannac3da7062017-02-08 21:08:56 -08008315 static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
Mohit Khannae71e2262015-11-10 09:37:24 -08008316 enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
Ravi Joshib89e7f72016-09-07 13:43:15 -07008317 uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count;
Jinwei Chen0dc383e2019-08-23 00:43:04 +08008318 uint32_t bus_low_cnt_threshold = hdd_ctx->config->bus_low_cnt_threshold;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008319 cpumask_t pm_qos_cpu_mask;
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008320 bool is_rx_pm_qos_high = false;
8321 bool is_tx_pm_qos_high = false;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008322
8323 cpumask_clear(&pm_qos_cpu_mask);
Srinivas Girigowda50335342018-09-07 15:21:01 -07008324
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008325 if (total_pkts > hdd_ctx->config->bus_bw_very_high_threshold)
8326 next_vote_level = PLD_BUS_WIDTH_VERY_HIGH;
8327 else if (total_pkts > hdd_ctx->config->bus_bw_high_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07008328 next_vote_level = PLD_BUS_WIDTH_HIGH;
jitiphil869b9f72018-09-25 17:14:01 +05308329 else if (total_pkts > hdd_ctx->config->bus_bw_medium_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07008330 next_vote_level = PLD_BUS_WIDTH_MEDIUM;
jitiphil869b9f72018-09-25 17:14:01 +05308331 else if (total_pkts > hdd_ctx->config->bus_bw_low_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07008332 next_vote_level = PLD_BUS_WIDTH_LOW;
Yue Mad6478e42015-10-20 18:49:24 -07008333 else
Mahesh Kumar Kalikot Veetil64a88692019-07-03 13:57:34 -07008334 next_vote_level = PLD_BUS_WIDTH_IDLE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008335
Mohit Khannaf7562c32018-07-05 17:42:36 -07008336 dptrace_high_tput_req =
Mahesh Kumar Kalikot Veetil64a88692019-07-03 13:57:34 -07008337 next_vote_level > PLD_BUS_WIDTH_IDLE ? true : false;
Mohit Khannaf7562c32018-07-05 17:42:36 -07008338
Jinwei Chen0dc383e2019-08-23 00:43:04 +08008339 if (next_vote_level == PLD_BUS_WIDTH_LOW) {
8340 if (++hdd_ctx->bus_low_vote_cnt >= bus_low_cnt_threshold)
8341 qdf_atomic_set(&hdd_ctx->low_tput_gro_enable, 1);
8342 } else {
8343 hdd_ctx->bus_low_vote_cnt = 0;
8344 qdf_atomic_set(&hdd_ctx->low_tput_gro_enable, 0);
8345 }
8346
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008347 if (hdd_ctx->cur_vote_level != next_vote_level) {
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008348 hdd_debug("BW Vote level %d, tx_packets: %lld, rx_packets: %lld",
8349 next_vote_level, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008350 hdd_ctx->cur_vote_level = next_vote_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008351 vote_level_change = true;
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008352
Yuanyuan Liu13738502016-04-06 17:41:37 -07008353 pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level);
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008354
Tang Yingying5a4ccf22018-03-30 15:58:27 +08008355 if ((next_vote_level == PLD_BUS_WIDTH_LOW) ||
Mahesh Kumar Kalikot Veetil64a88692019-07-03 13:57:34 -07008356 (next_vote_level == PLD_BUS_WIDTH_IDLE)) {
Nirav Shahffc6a092016-06-09 16:09:08 +05308357 if (hdd_ctx->hbw_requested) {
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008358 PLD_REMOVE_PM_QOS(hdd_ctx->parent_dev);
Nirav Shahffc6a092016-06-09 16:09:08 +05308359 hdd_ctx->hbw_requested = false;
8360 }
Tang Yingying5a4ccf22018-03-30 15:58:27 +08008361 if (hdd_ctx->dynamic_rps)
8362 hdd_clear_rps_cpu_mask(hdd_ctx);
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07008363 } else {
Nirav Shahffc6a092016-06-09 16:09:08 +05308364 if (!hdd_ctx->hbw_requested) {
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008365 PLD_REQUEST_PM_QOS(hdd_ctx->parent_dev, 1);
Nirav Shahffc6a092016-06-09 16:09:08 +05308366 hdd_ctx->hbw_requested = true;
8367 }
Tang Yingying5a4ccf22018-03-30 15:58:27 +08008368 if (hdd_ctx->dynamic_rps)
8369 hdd_set_rps_cpu_mask(hdd_ctx);
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07008370 }
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008371
Manjunathappa Prakashcb6df762018-05-29 18:54:58 -07008372 if (hdd_ctx->config->napi_cpu_affinity_mask)
8373 hdd_napi_apply_throughput_policy(hdd_ctx,
8374 tx_packets,
8375 rx_packets);
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008376
jitiphil869b9f72018-09-25 17:14:01 +05308377 if (rx_packets < hdd_ctx->config->bus_bw_low_threshold)
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008378 hdd_disable_rx_ol_for_low_tput(hdd_ctx, true);
8379 else
8380 hdd_disable_rx_ol_for_low_tput(hdd_ctx, false);
Venkata Sharath Chandra Manchalaf0296dd2019-09-19 13:50:02 -07008381
8382 if (hdd_ctx->is_pktlog_enabled) {
8383 if (next_vote_level >= PLD_BUS_WIDTH_HIGH)
8384 hdd_pktlog_enable_disable(hdd_ctx, false,
8385 0, 0);
8386 else
8387 hdd_pktlog_enable_disable(hdd_ctx, true,
8388 0, 0);
8389 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008390 }
Mohit Khannae71e2262015-11-10 09:37:24 -08008391
Mohit Khannaf7562c32018-07-05 17:42:36 -07008392 qdf_dp_trace_apply_tput_policy(dptrace_high_tput_req);
8393
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008394 /*
8395 * Includes tcp+udp, if perf core is required for tcp, then
8396 * perf core is also required for udp.
8397 */
8398 no_rx_offload_pkts = hdd_ctx->no_rx_offload_pkt_cnt;
8399 hdd_ctx->no_rx_offload_pkt_cnt = 0;
8400 rx_offload_pkts = rx_packets - no_rx_offload_pkts;
Mohit Khannae71e2262015-11-10 09:37:24 -08008401
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008402 avg_no_rx_offload_pkts = (no_rx_offload_pkts +
8403 hdd_ctx->prev_no_rx_offload_pkts) / 2;
8404 hdd_ctx->prev_no_rx_offload_pkts = no_rx_offload_pkts;
Mohit Khannab1dd1e82017-02-04 15:14:38 -08008405
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008406 avg_rx_offload_pkts = (rx_offload_pkts +
8407 hdd_ctx->prev_rx_offload_pkts) / 2;
8408 hdd_ctx->prev_rx_offload_pkts = rx_offload_pkts;
8409
8410 avg_rx = avg_no_rx_offload_pkts + avg_rx_offload_pkts;
8411 /*
8412 * Takes care to set Rx_thread affinity for below case
8413 * 1)LRO/GRO not supported ROME case
8414 * 2)when rx_ol is disabled in cases like concurrency etc
8415 * 3)For UDP cases
8416 */
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008417 if (avg_no_rx_offload_pkts > hdd_ctx->config->bus_bw_high_threshold) {
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008418 rxthread_high_tput_req = true;
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008419 is_rx_pm_qos_high = true;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008420 } else {
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008421 rxthread_high_tput_req = false;
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008422 is_rx_pm_qos_high = false;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008423 }
8424
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008425 hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, is_rx_pm_qos_high);
Poddar, Siddarth47c23402017-10-25 12:17:39 +05308426
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008427 if (cds_sched_handle_throughput_req(rxthread_high_tput_req))
8428 hdd_warn("Rx thread high_tput(%d) affinity request failed",
8429 rxthread_high_tput_req);
8430
8431 /* fine-tuning parameters for RX Flows */
jitiphil869b9f72018-09-25 17:14:01 +05308432 if (avg_rx > hdd_ctx->config->tcp_delack_thres_high) {
Ravi Joshifed83572016-10-07 16:20:37 -07008433 if ((hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH) &&
8434 (++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt)) {
8435 next_rx_level = WLAN_SVC_TP_HIGH;
8436 }
Ravi Joshib89e7f72016-09-07 13:43:15 -07008437 } else {
Ravi Joshib89e7f72016-09-07 13:43:15 -07008438 hdd_ctx->rx_high_ind_cnt = 0;
Mohit Khannac3da7062017-02-08 21:08:56 -08008439 next_rx_level = WLAN_SVC_TP_LOW;
Ravi Joshib89e7f72016-09-07 13:43:15 -07008440 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008441
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008442 if (hdd_ctx->cur_rx_level != next_rx_level) {
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07008443 struct wlan_rx_tp_data rx_tp_data = {0};
8444
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008445 hdd_ctx->cur_rx_level = next_rx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008446 rx_level_change = true;
Ravi Joshie2331e82015-07-01 18:18:54 -07008447 /* Send throughput indication only if it is enabled.
8448 * Disabling tcp_del_ack will revert the tcp stack behavior
8449 * to default delayed ack. Note that this will disable the
8450 * dynamic delayed ack mechanism across the system
8451 */
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008452 if (hdd_ctx->en_tcp_delack_no_lro) {
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07008453 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008454 }
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07008455
Mohit Khanna6272fb682017-04-13 09:34:36 -07008456 if (hdd_ctx->config->enable_tcp_adv_win_scale)
8457 rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
8458
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07008459 rx_tp_data.level = next_rx_level;
Alok Kumar2fad6442018-11-08 19:19:28 +05308460 wlan_hdd_update_tcp_rx_param(hdd_ctx, &rx_tp_data);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008461 }
8462
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008463 no_tx_offload_pkts = hdd_ctx->no_tx_offload_pkt_cnt;
8464 hdd_ctx->no_tx_offload_pkt_cnt = 0;
8465 tx_offload_pkts = tx_packets - no_tx_offload_pkts;
8466
8467 avg_no_tx_offload_pkts = (no_tx_offload_pkts +
8468 hdd_ctx->prev_no_tx_offload_pkts) / 2;
8469 hdd_ctx->prev_no_tx_offload_pkts = no_tx_offload_pkts;
8470
8471 avg_tx_offload_pkts = (tx_offload_pkts +
8472 hdd_ctx->prev_tx_offload_pkts) / 2;
8473 hdd_ctx->prev_tx_offload_pkts = tx_offload_pkts;
8474
8475 avg_tx = avg_no_tx_offload_pkts + avg_tx_offload_pkts;
8476
Mohit Khannae71e2262015-11-10 09:37:24 -08008477 /* fine-tuning parameters for TX Flows */
Mohit Khannae71e2262015-11-10 09:37:24 -08008478 hdd_ctx->prev_tx = tx_packets;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008479
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008480 if (avg_no_tx_offload_pkts > hdd_ctx->config->bus_bw_high_threshold)
8481 is_tx_pm_qos_high = true;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008482 else
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008483 is_tx_pm_qos_high = false;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008484
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008485 hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, is_tx_pm_qos_high);
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008486
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008487 if (avg_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
Mohit Khannae71e2262015-11-10 09:37:24 -08008488 next_tx_level = WLAN_SVC_TP_HIGH;
8489 else
8490 next_tx_level = WLAN_SVC_TP_LOW;
8491
Prakash Manjunathappae73e3b52018-02-27 18:56:22 -08008492 if ((hdd_ctx->config->enable_tcp_limit_output) &&
8493 (hdd_ctx->cur_tx_level != next_tx_level)) {
Alok Kumar2fad6442018-11-08 19:19:28 +05308494 struct wlan_tx_tp_data tx_tp_data = {0};
Mohit Khannae71e2262015-11-10 09:37:24 -08008495 hdd_ctx->cur_tx_level = next_tx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008496 tx_level_change = true;
Alok Kumar2fad6442018-11-08 19:19:28 +05308497 tx_tp_data.level = next_tx_level;
8498 tx_tp_data.tcp_limit_output = true;
8499 wlan_hdd_update_tcp_tx_param(hdd_ctx, &tx_tp_data);
Mohit Khannae71e2262015-11-10 09:37:24 -08008500 }
8501
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008502 index = hdd_ctx->hdd_txrx_hist_idx;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008503 if (vote_level_change || tx_level_change || rx_level_change) {
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008504 /* Clear all the mask if no silver/gold vote is required */
Mohit Khanna58a898b2019-07-31 19:13:02 -07008505 if (next_vote_level < PLD_BUS_WIDTH_HIGH) {
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008506 is_rx_pm_qos_high = false;
8507 is_tx_pm_qos_high = false;
8508 cpumask_clear(&pm_qos_cpu_mask);
8509 }
8510
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008511 hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level;
8512 hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level;
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008513 hdd_ctx->hdd_txrx_hist[index].is_rx_pm_qos_high =
8514 is_rx_pm_qos_high;
8515 hdd_ctx->hdd_txrx_hist[index].is_tx_pm_qos_high =
8516 is_tx_pm_qos_high;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008517 hdd_ctx->hdd_txrx_hist[index].next_vote_level = next_vote_level;
8518 hdd_ctx->hdd_txrx_hist[index].interval_rx = rx_packets;
8519 hdd_ctx->hdd_txrx_hist[index].interval_tx = tx_packets;
8520 hdd_ctx->hdd_txrx_hist[index].qtime = qdf_get_log_timestamp();
8521 hdd_ctx->hdd_txrx_hist_idx++;
8522 hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008523
8524 /* Clear all the mask if no silver/gold vote is required */
8525 if (next_vote_level < PLD_BUS_WIDTH_MEDIUM)
8526 cpumask_clear(&pm_qos_cpu_mask);
8527
8528 hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask);
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008529 }
Mohit Khannaca4173b2017-09-12 21:52:19 -07008530
8531 hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008532}
8533
Tiger Yue40e7832019-04-25 10:46:53 +08008534#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK
8535/**
8536 * hdd_set_driver_del_ack_enable() - set driver delayed ack enabled flag
8537 * @vdev_id: vdev id
8538 * @hdd_ctx: handle to hdd context
8539 * @rx_packets: receive packet count
8540 *
8541 * Return: none
8542 */
8543static inline
8544void hdd_set_driver_del_ack_enable(uint16_t vdev_id,
8545 struct hdd_context *hdd_ctx,
8546 uint64_t rx_packets)
8547{
8548 struct hdd_config *cfg = hdd_ctx->config;
8549
8550 cdp_vdev_set_driver_del_ack_enable(cds_get_context(QDF_MODULE_ID_SOC),
8551 vdev_id, rx_packets,
8552 cfg->bus_bw_compute_interval,
8553 cfg->del_ack_threshold_high,
8554 cfg->del_ack_threshold_low);
8555}
8556#else
8557static inline
8558void hdd_set_driver_del_ack_enable(uint16_t vdev_id,
8559 struct hdd_context *hdd_ctx,
8560 uint64_t rx_packets)
8561{
8562}
8563#endif
8564
Sravan Kumar Kairam761ae632019-09-11 21:27:16 +05308565#ifdef WDI3_STATS_UPDATE
8566static inline
8567void hdd_ipa_set_perf_level(struct hdd_context *hdd_ctx,
8568 uint64_t *tx_pkts, uint64_t *rx_pkts,
8569 uint32_t *ipa_tx_pkts, uint32_t *ipa_rx_pkts)
8570{
8571}
8572#else
8573static void hdd_ipa_set_perf_level(struct hdd_context *hdd_ctx,
8574 uint64_t *tx_pkts, uint64_t *rx_pkts,
8575 uint32_t *ipa_tx_pkts, uint32_t *ipa_rx_pkts)
8576{
8577 if (ucfg_ipa_is_fw_wdi_activated(hdd_ctx->pdev)) {
8578 ucfg_ipa_uc_stat_query(hdd_ctx->pdev, ipa_tx_pkts,
8579 ipa_rx_pkts);
8580 *tx_pkts += *ipa_tx_pkts;
8581 *rx_pkts += *ipa_rx_pkts;
8582
8583 ucfg_ipa_set_perf_level(hdd_ctx->pdev, *tx_pkts, *rx_pkts);
8584 ucfg_ipa_uc_stat_request(hdd_ctx->pdev, 2);
8585 }
8586}
8587#endif
8588
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008589#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
Dustin Browna20bad52019-03-05 12:03:30 -08008590static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008591{
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05308592 struct hdd_adapter *adapter = NULL, *con_sap_adapter = NULL;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308593 uint64_t tx_packets = 0, rx_packets = 0;
Himanshu Agarwala6cedee2016-06-08 14:50:00 +05308594 uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
8595 uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008596 uint64_t total_tx = 0, total_rx = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308597 A_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008598 bool connected = false;
8599 uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
Sravan Goud01588142019-09-30 18:27:28 +05308600 uint64_t sta_tx_bytes = 0, sap_tx_bytes = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008601
Prashanth Bhattaab004382016-10-11 16:08:11 -07008602 if (wlan_hdd_validate_context(hdd_ctx))
Dustin Browna20bad52019-03-05 12:03:30 -08008603 goto stop_work;
Prashanth Bhattaab004382016-10-11 16:08:11 -07008604
Jeff Johnson214671b2017-10-30 19:45:23 -07008605 if (hdd_ctx->is_wiphy_suspended)
Dustin Browna20bad52019-03-05 12:03:30 -08008606 return;
Jingxiang Gec64e1932017-08-22 14:38:59 +08008607
Dustin Brown920397d2017-12-13 16:27:50 -08008608 hdd_for_each_adapter(hdd_ctx, adapter) {
Manjeet Singh01327cc2016-09-03 12:14:25 +05308609 /*
8610 * Validate magic so we don't end up accessing
8611 * an invalid adapter.
8612 */
8613 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
8614 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008615
Krunal Soni9b04c9b2016-03-10 13:08:05 -08008616 if ((adapter->device_mode == QDF_STA_MODE ||
8617 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
Jeff Johnsone7951512019-02-27 10:02:51 -08008618 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.conn_state
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008619 != eConnectionState_Associated) {
8620
8621 continue;
8622 }
8623
Krunal Soni9b04c9b2016-03-10 13:08:05 -08008624 if ((adapter->device_mode == QDF_SAP_MODE ||
8625 adapter->device_mode == QDF_P2P_GO_MODE) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -07008626 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008627
8628 continue;
8629 }
8630
8631 tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets,
8632 adapter->prev_tx_packets);
8633 rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets,
8634 adapter->prev_rx_packets);
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308635
8636 if (adapter->device_mode == QDF_SAP_MODE ||
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +05308637 adapter->device_mode == QDF_P2P_GO_MODE ||
8638 adapter->device_mode == QDF_IBSS_MODE ||
8639 adapter->device_mode == QDF_NDI_MODE) {
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308640
Dhanashri Atrea8f82f22017-01-23 12:58:24 -08008641 ret = cdp_get_intra_bss_fwd_pkts_count(
8642 cds_get_context(QDF_MODULE_ID_SOC),
Jeff Johnson5a6fc962019-02-04 14:20:25 -08008643 adapter->vdev_id,
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308644 &fwd_tx_packets, &fwd_rx_packets);
8645 if (ret == A_OK) {
8646 fwd_tx_packets_diff += HDD_BW_GET_DIFF(
8647 fwd_tx_packets,
8648 adapter->prev_fwd_tx_packets);
8649 fwd_rx_packets_diff += HDD_BW_GET_DIFF(
8650 fwd_tx_packets,
8651 adapter->prev_fwd_rx_packets);
8652 }
8653 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008654
Sravan Kumar Kairam3bc886d2019-08-22 23:46:27 +05308655 if (adapter->device_mode == QDF_SAP_MODE) {
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05308656 con_sap_adapter = adapter;
Sravan Kumar Kairam3bc886d2019-08-22 23:46:27 +05308657 sap_tx_bytes = adapter->stats.tx_bytes;
8658 }
8659
8660 if (adapter->device_mode == QDF_STA_MODE)
8661 sta_tx_bytes = adapter->stats.tx_bytes;
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05308662
Tiger Yue40e7832019-04-25 10:46:53 +08008663 hdd_set_driver_del_ack_enable(adapter->vdev_id, hdd_ctx,
8664 rx_packets);
8665
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008666 total_rx += adapter->stats.rx_packets;
8667 total_tx += adapter->stats.tx_packets;
8668
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +05308669 qdf_spin_lock_bh(&hdd_ctx->bus_bw_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008670 adapter->prev_tx_packets = adapter->stats.tx_packets;
8671 adapter->prev_rx_packets = adapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308672 adapter->prev_fwd_tx_packets = fwd_tx_packets;
8673 adapter->prev_fwd_rx_packets = fwd_rx_packets;
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +05308674 qdf_spin_unlock_bh(&hdd_ctx->bus_bw_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008675 connected = true;
8676 }
8677
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008678 if (!connected) {
Jeff Johnson760350b2016-08-15 14:01:52 -07008679 hdd_err("bus bandwidth timer running in disconnected state");
Dustin Browna20bad52019-03-05 12:03:30 -08008680 goto stop_work;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008681 }
8682
Yun Parka29974a2018-04-09 12:05:49 -07008683 /* add intra bss forwarded tx and rx packets */
8684 tx_packets += fwd_tx_packets_diff;
8685 rx_packets += fwd_rx_packets_diff;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008686
Sravan Kumar Kairam3bc886d2019-08-22 23:46:27 +05308687 /* Send embedded Tx packet bytes on STA & SAP interface to IPA driver */
8688 ucfg_ipa_update_tx_stats(hdd_ctx->pdev, sta_tx_bytes, sap_tx_bytes);
8689
Sravan Kumar Kairam761ae632019-09-11 21:27:16 +05308690 hdd_ipa_set_perf_level(hdd_ctx, &tx_packets, &rx_packets,
8691 &ipa_tx_packets, &ipa_rx_packets);
8692 if (con_sap_adapter) {
8693 con_sap_adapter->stats.tx_packets += ipa_tx_packets;
8694 con_sap_adapter->stats.rx_packets += ipa_rx_packets;
Yun Parka29974a2018-04-09 12:05:49 -07008695 }
8696
8697 hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008698
Dustin Browna20bad52019-03-05 12:03:30 -08008699 return;
8700
8701stop_work:
8702 qdf_periodic_work_stop_async(&hdd_ctx->bus_bw_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008703}
Prashanth Bhattaab004382016-10-11 16:08:11 -07008704
Dustin Browna20bad52019-03-05 12:03:30 -08008705static void hdd_bus_bw_work_handler(void *context)
Rajeev Kumarb2b5e692018-08-31 15:12:40 -07008706{
Dustin Brown3fdaaf62019-03-18 14:00:16 -07008707 struct hdd_context *hdd_ctx = context;
8708 struct qdf_op_sync *op_sync;
Dustin Browna20bad52019-03-05 12:03:30 -08008709
Dustin Brown3fdaaf62019-03-18 14:00:16 -07008710 if (qdf_op_protect(&op_sync))
8711 return;
8712
8713 __hdd_bus_bw_work_handler(hdd_ctx);
8714
8715 qdf_op_unprotect(op_sync);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05308716}
8717
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008718int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07008719{
Dustin Browna20bad52019-03-05 12:03:30 -08008720 QDF_STATUS status;
8721
Dustin Brown35008ba2018-08-23 14:34:21 -07008722 hdd_enter();
8723
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +05308724 qdf_spinlock_create(&hdd_ctx->bus_bw_lock);
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008725
8726 hdd_pm_qos_add_request(hdd_ctx);
8727
Dustin Browna20bad52019-03-05 12:03:30 -08008728 status = qdf_periodic_work_create(&hdd_ctx->bus_bw_work,
8729 hdd_bus_bw_work_handler,
Dustin Brown3fdaaf62019-03-18 14:00:16 -07008730 hdd_ctx);
Dustin Brown35008ba2018-08-23 14:34:21 -07008731
8732 hdd_exit();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008733
Dustin Browna20bad52019-03-05 12:03:30 -08008734 return qdf_status_to_os_return(status);
Prashanth Bhattaab004382016-10-11 16:08:11 -07008735}
8736
Dustin Brown86d196b2018-08-02 11:51:49 -07008737void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07008738{
Dustin Brown35008ba2018-08-23 14:34:21 -07008739 hdd_enter();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008740
Dustin Browna20bad52019-03-05 12:03:30 -08008741 QDF_BUG(!qdf_periodic_work_stop_sync(&hdd_ctx->bus_bw_work));
8742 qdf_periodic_work_destroy(&hdd_ctx->bus_bw_work);
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +05308743 qdf_spinlock_destroy(&hdd_ctx->bus_bw_lock);
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008744 hdd_pm_qos_remove_request(hdd_ctx);
Dustin Brown35008ba2018-08-23 14:34:21 -07008745
8746 hdd_exit();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008747}
Tiger Yu8b119e92019-04-09 13:55:07 +08008748#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008749
Nirav Shahda008342016-05-17 18:50:40 +05308750static uint8_t *convert_level_to_string(uint32_t level)
8751{
8752 switch (level) {
8753 /* initialize the wlan sub system */
8754 case WLAN_SVC_TP_NONE:
8755 return "NONE";
8756 case WLAN_SVC_TP_LOW:
8757 return "LOW";
8758 case WLAN_SVC_TP_MEDIUM:
8759 return "MED";
8760 case WLAN_SVC_TP_HIGH:
8761 return "HIGH";
8762 default:
8763 return "INVAL";
8764 }
8765}
8766
Nirav Shahed34b212016-04-25 10:59:16 +05308767
8768/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008769 * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram
8770 * @hdd_ctx: hdd context
8771 *
8772 * Return: none
8773 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008774void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008775{
8776 int i;
8777
Tiger Yu8b119e92019-04-09 13:55:07 +08008778#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308779 hdd_nofl_debug("BW compute Interval: %d ms",
8780 hdd_ctx->config->bus_bw_compute_interval);
8781 hdd_nofl_debug("BW TH - Very High: %d High: %d Med: %d Low: %d",
8782 hdd_ctx->config->bus_bw_very_high_threshold,
8783 hdd_ctx->config->bus_bw_high_threshold,
8784 hdd_ctx->config->bus_bw_medium_threshold,
8785 hdd_ctx->config->bus_bw_low_threshold);
8786 hdd_nofl_debug("Enable TCP DEL ACK: %d",
8787 hdd_ctx->en_tcp_delack_no_lro);
8788 hdd_nofl_debug("TCP DEL High TH: %d TCP DEL Low TH: %d",
8789 hdd_ctx->config->tcp_delack_thres_high,
8790 hdd_ctx->config->tcp_delack_thres_low);
8791 hdd_nofl_debug("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_limit)",
8792 hdd_ctx->config->tcp_tx_high_tput_thres);
Tiger Yu8b119e92019-04-09 13:55:07 +08008793#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008794
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308795 hdd_nofl_debug("Total entries: %d Current index: %d",
8796 NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
Nirav Shahda008342016-05-17 18:50:40 +05308797
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008798 hdd_nofl_debug("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level, Rx:Tx pm_qos");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008799
8800 for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008801 /* using hdd_log to avoid printing function name */
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008802 if (hdd_ctx->hdd_txrx_hist[i].qtime > 0)
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008803 hdd_nofl_debug("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s, %s:%s",
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308804 i, hdd_ctx->hdd_txrx_hist[i].qtime,
8805 hdd_ctx->hdd_txrx_hist[i].interval_rx,
8806 hdd_ctx->hdd_txrx_hist[i].interval_tx,
8807 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008808 hdd_ctx->hdd_txrx_hist[i].
8809 next_vote_level),
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308810 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008811 hdd_ctx->hdd_txrx_hist[i].
8812 next_rx_level),
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308813 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008814 hdd_ctx->hdd_txrx_hist[i].
Manjunathappa Prakash35af2e22019-07-30 20:23:34 -07008815 next_tx_level),
8816 hdd_ctx->hdd_txrx_hist[i].is_rx_pm_qos_high ?
8817 "HIGH" : "LOW",
8818 hdd_ctx->hdd_txrx_hist[i].is_tx_pm_qos_high ?
8819 "HIGH" : "LOW");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008820 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008821}
8822
8823/**
8824 * wlan_hdd_clear_tx_rx_histogram() - clear tx rx histogram
8825 * @hdd_ctx: hdd context
8826 *
8827 * Return: none
8828 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008829void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008830{
8831 hdd_ctx->hdd_txrx_hist_idx = 0;
Nirav Shahed34b212016-04-25 10:59:16 +05308832 qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
8833 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008834}
8835
Mohit Khannaca4173b2017-09-12 21:52:19 -07008836/* length of the netif queue log needed per adapter */
8837#define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
8838
8839/**
8840 *
8841 * hdd_display_netif_queue_history_compact() - display compact netifq history
8842 * @hdd_ctx: hdd context
8843 *
8844 * Return: none
8845 */
8846static void
8847hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
8848{
8849 int adapter_num = 0;
8850 int i;
8851 int bytes_written;
8852 u32 tbytes;
8853 qdf_time_t total, pause, unpause, curr_time, delta;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008854 char temp_str[20 * WLAN_REASON_TYPE_MAX];
jiadbdefb252018-01-03 14:27:06 +08008855 char *comb_log_str;
8856 uint32_t comb_log_str_size;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008857 struct hdd_adapter *adapter = NULL;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008858
Dustin Brownad06be62019-02-04 14:52:56 -08008859 comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * WLAN_MAX_VDEVS) + 1;
jiadbdefb252018-01-03 14:27:06 +08008860 comb_log_str = qdf_mem_malloc(comb_log_str_size);
Min Liu74a1a502018-10-10 19:59:07 +08008861 if (!comb_log_str)
jiadbdefb252018-01-03 14:27:06 +08008862 return;
jiadbdefb252018-01-03 14:27:06 +08008863
Mohit Khannaca4173b2017-09-12 21:52:19 -07008864 bytes_written = 0;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008865
Dustin Brown920397d2017-12-13 16:27:50 -08008866 hdd_for_each_adapter(hdd_ctx, adapter) {
Mohit Khannaca4173b2017-09-12 21:52:19 -07008867 curr_time = qdf_system_ticks();
8868 total = curr_time - adapter->start_time;
8869 delta = curr_time - adapter->last_time;
8870
8871 if (adapter->pause_map) {
8872 pause = adapter->total_pause_time + delta;
8873 unpause = adapter->total_unpause_time;
8874 } else {
8875 unpause = adapter->total_unpause_time + delta;
8876 pause = adapter->total_pause_time;
8877 }
8878
8879 tbytes = 0;
hangtian127c9532019-01-12 13:29:07 +08008880 qdf_mem_zero(temp_str, sizeof(temp_str));
Mohit Khannaca4173b2017-09-12 21:52:19 -07008881 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
8882 if (adapter->queue_oper_stats[i].pause_count == 0)
8883 continue;
8884 tbytes +=
8885 snprintf(
8886 &temp_str[tbytes],
8887 (tbytes >= sizeof(temp_str) ?
8888 0 : sizeof(temp_str) - tbytes),
8889 "%d(%d,%d) ",
8890 i,
8891 adapter->queue_oper_stats[i].
8892 pause_count,
8893 adapter->queue_oper_stats[i].
8894 unpause_count);
8895 }
8896 if (tbytes >= sizeof(temp_str))
8897 hdd_warn("log truncated");
8898
8899 bytes_written += snprintf(&comb_log_str[bytes_written],
jiadbdefb252018-01-03 14:27:06 +08008900 bytes_written >= comb_log_str_size ? 0 :
8901 comb_log_str_size - bytes_written,
Mohit Khannaca4173b2017-09-12 21:52:19 -07008902 "[%d %d] (%d) %u/%ums %s|",
Jeff Johnson5a6fc962019-02-04 14:20:25 -08008903 adapter->vdev_id, adapter->device_mode,
Mohit Khannaca4173b2017-09-12 21:52:19 -07008904 adapter->pause_map,
8905 qdf_system_ticks_to_msecs(pause),
8906 qdf_system_ticks_to_msecs(total),
8907 temp_str);
8908
Mohit Khannaca4173b2017-09-12 21:52:19 -07008909 adapter_num++;
8910 }
8911
8912 /* using QDF_TRACE to avoid printing function name */
8913 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
8914 "STATS |%s", comb_log_str);
8915
jiadbdefb252018-01-03 14:27:06 +08008916 if (bytes_written >= comb_log_str_size)
Mohit Khannaca4173b2017-09-12 21:52:19 -07008917 hdd_warn("log string truncated");
jiadbdefb252018-01-03 14:27:06 +08008918
8919 qdf_mem_free(comb_log_str);
Mohit Khannaca4173b2017-09-12 21:52:19 -07008920}
8921
Mohit Khannaf7e7b342019-04-08 11:54:21 -07008922/* Max size of a single netdev tx queue state string. e.g. "1: 0x1" */
8923#define HDD_NETDEV_TX_Q_STATE_STRLEN 15
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008924/**
Srinivas Girigowdab841da72017-03-25 18:04:39 -07008925 * wlan_hdd_display_netif_queue_history() - display netif queue history
Jeff Johnson58adbcf2017-09-03 08:53:31 -07008926 * @hdd_ctx: hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008927 *
8928 * Return: none
8929 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07008930void
8931wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
8932 enum qdf_stats_verbosity_level verb_lvl)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008933{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008934 int i;
Mohit Khannaf7e7b342019-04-08 11:54:21 -07008935 struct hdd_adapter *adapter = NULL;
Nirav Shahda008342016-05-17 18:50:40 +05308936 qdf_time_t total, pause, unpause, curr_time, delta;
Mohit Khannaf7e7b342019-04-08 11:54:21 -07008937 struct hdd_netif_queue_history *q_hist_ptr;
8938 char q_status_buf[NUM_TX_QUEUES * HDD_NETDEV_TX_Q_STATE_STRLEN] = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008939
Mohit Khannaca4173b2017-09-12 21:52:19 -07008940 if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
8941 hdd_display_netif_queue_history_compact(hdd_ctx);
8942 return;
8943 }
8944
Dustin Brown920397d2017-12-13 16:27:50 -08008945 hdd_for_each_adapter(hdd_ctx, adapter) {
Mohit Khannaf7e7b342019-04-08 11:54:21 -07008946 if (adapter->vdev_id == CDP_INVALID_VDEV_ID)
8947 continue;
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308948 hdd_nofl_debug("Netif queue operation statistics:");
8949 hdd_nofl_debug("vdev_id %d device mode %d",
8950 adapter->vdev_id, adapter->device_mode);
8951 hdd_nofl_debug("Current pause_map %x", adapter->pause_map);
Nirav Shah617cff92016-04-25 10:24:24 +05308952 curr_time = qdf_system_ticks();
8953 total = curr_time - adapter->start_time;
Nirav Shahda008342016-05-17 18:50:40 +05308954 delta = curr_time - adapter->last_time;
Nirav Shah617cff92016-04-25 10:24:24 +05308955 if (adapter->pause_map) {
Nirav Shahda008342016-05-17 18:50:40 +05308956 pause = adapter->total_pause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05308957 unpause = adapter->total_unpause_time;
8958 } else {
Nirav Shahda008342016-05-17 18:50:40 +05308959 unpause = adapter->total_unpause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05308960 pause = adapter->total_pause_time;
8961 }
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308962 hdd_nofl_debug("Total: %ums Pause: %ums Unpause: %ums",
8963 qdf_system_ticks_to_msecs(total),
8964 qdf_system_ticks_to_msecs(pause),
8965 qdf_system_ticks_to_msecs(unpause));
8966 hdd_nofl_debug("reason_type: pause_cnt: unpause_cnt: pause_time");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008967
Nirav Shahda008342016-05-17 18:50:40 +05308968 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
8969 qdf_time_t pause_delta = 0;
8970
8971 if (adapter->pause_map & (1 << i))
8972 pause_delta = delta;
8973
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008974 /* using hdd_log to avoid printing function name */
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308975 hdd_nofl_debug("%s: %d: %d: %ums",
8976 hdd_reason_type_to_string(i),
8977 adapter->queue_oper_stats[i].pause_count,
8978 adapter->queue_oper_stats[i].
Nirav Shahe6194ac2018-07-13 11:04:41 +05308979 unpause_count,
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308980 qdf_system_ticks_to_msecs(
8981 adapter->queue_oper_stats[i].
Nirav Shahe6194ac2018-07-13 11:04:41 +05308982 total_pause_time + pause_delta));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008983 }
8984
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308985 hdd_nofl_debug("Netif queue operation history: Total entries: %d current index %d(-1) time %u",
8986 WLAN_HDD_MAX_HISTORY_ENTRY,
8987 adapter->history_index,
8988 qdf_system_ticks_to_msecs(qdf_system_ticks()));
Nirav Shahda008342016-05-17 18:50:40 +05308989
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308990 hdd_nofl_debug("%2s%20s%50s%30s%10s %s",
8991 "#", "time(ms)", "action_type", "reason_type",
8992 "pause_map", "netdev-queue-status");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008993
8994 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008995 /* using hdd_log to avoid printing function name */
8996 if (adapter->queue_oper_history[i].time == 0)
8997 continue;
Mohit Khannaf7e7b342019-04-08 11:54:21 -07008998 q_hist_ptr = &adapter->queue_oper_history[i];
8999 wlan_hdd_dump_queue_history_state(q_hist_ptr,
9000 q_status_buf,
9001 sizeof(q_status_buf));
Rakesh Pillai70f1f542019-09-10 20:26:54 +05309002 hdd_nofl_debug("%2d%20u%50s%30s%10x %s",
9003 i, qdf_system_ticks_to_msecs(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009004 adapter->queue_oper_history[i].time),
Rakesh Pillai70f1f542019-09-10 20:26:54 +05309005 hdd_action_type_to_string(
Nirav Shahe6194ac2018-07-13 11:04:41 +05309006 adapter->queue_oper_history[i].
9007 netif_action),
Rakesh Pillai70f1f542019-09-10 20:26:54 +05309008 hdd_reason_type_to_string(
Nirav Shahe6194ac2018-07-13 11:04:41 +05309009 adapter->queue_oper_history[i].
9010 netif_reason),
Rakesh Pillai70f1f542019-09-10 20:26:54 +05309011 adapter->queue_oper_history[i].pause_map,
9012 q_status_buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009013 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009014 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009015}
9016
9017/**
9018 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
9019 * @hdd_ctx: hdd context
9020 *
9021 * Return: none
9022 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009023void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009024{
Jeff Johnson9d295242017-08-29 14:39:48 -07009025 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009026
Dustin Brown920397d2017-12-13 16:27:50 -08009027 hdd_for_each_adapter(hdd_ctx, adapter) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05309028 qdf_mem_zero(adapter->queue_oper_stats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009029 sizeof(adapter->queue_oper_stats));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05309030 qdf_mem_zero(adapter->queue_oper_history,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009031 sizeof(adapter->queue_oper_history));
Nirav Shah617cff92016-04-25 10:24:24 +05309032 adapter->history_index = 0;
9033 adapter->start_time = adapter->last_time = qdf_system_ticks();
9034 adapter->total_pause_time = 0;
9035 adapter->total_unpause_time = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009036 }
9037}
9038
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009039#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
9040/**
9041 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
9042 * @hdd_ctx: hdd global context
9043 *
9044 * Return: none
9045 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009046static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009047{
9048 uint8_t i;
9049
9050 mutex_init(&hdd_ctx->op_ctx.op_lock);
9051 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
9052 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
9053 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
9054 }
9055}
9056#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009057static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009058{
9059}
9060#endif
9061
Yingying Tang95409972016-10-20 15:16:15 +08009062#ifdef WLAN_FEATURE_WOW_PULSE
9063/**
9064 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07009065 * @hdd_ctx: struct hdd_context structure pointer
Yingying Tang95409972016-10-20 15:16:15 +08009066 * @enable: enable or disable this behaviour
9067 *
9068 * Return: int
9069 */
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07009070static int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08009071{
Yingying Tang95409972016-10-20 15:16:15 +08009072 struct wow_pulse_mode wow_pulse_set_info;
9073 QDF_STATUS status;
9074
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009075 hdd_debug("wow pulse enable flag is %d", enable);
Yingying Tang95409972016-10-20 15:16:15 +08009076
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07009077 if (!ucfg_pmo_is_wow_pulse_enabled(hdd_ctx->psoc))
Yingying Tang95409972016-10-20 15:16:15 +08009078 return 0;
9079
9080 /* prepare the request to send to SME */
9081 if (enable == true) {
9082 wow_pulse_set_info.wow_pulse_enable = true;
9083 wow_pulse_set_info.wow_pulse_pin =
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07009084 ucfg_pmo_get_wow_pulse_pin(hdd_ctx->psoc);
Wu Gao66454f12018-09-26 19:55:41 +08009085
Yingying Tang95409972016-10-20 15:16:15 +08009086 wow_pulse_set_info.wow_pulse_interval_high =
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07009087 ucfg_pmo_get_wow_pulse_interval_high(hdd_ctx->psoc);
Wu Gao66454f12018-09-26 19:55:41 +08009088
9089 wow_pulse_set_info.wow_pulse_interval_low =
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07009090 ucfg_pmo_get_wow_pulse_interval_low(hdd_ctx->psoc);
Yingying Tang95409972016-10-20 15:16:15 +08009091 } else {
9092 wow_pulse_set_info.wow_pulse_enable = false;
9093 wow_pulse_set_info.wow_pulse_pin = 0;
9094 wow_pulse_set_info.wow_pulse_interval_low = 0;
9095 wow_pulse_set_info.wow_pulse_interval_high = 0;
9096 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009097 hdd_debug("enable %d pin %d low %d high %d",
Yingying Tang95409972016-10-20 15:16:15 +08009098 wow_pulse_set_info.wow_pulse_enable,
9099 wow_pulse_set_info.wow_pulse_pin,
9100 wow_pulse_set_info.wow_pulse_interval_low,
9101 wow_pulse_set_info.wow_pulse_interval_high);
9102
9103 status = sme_set_wow_pulse(&wow_pulse_set_info);
9104 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009105 hdd_debug("sme_set_wow_pulse failure!");
Yingying Tang95409972016-10-20 15:16:15 +08009106 return -EIO;
9107 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009108 hdd_debug("sme_set_wow_pulse success!");
Yingying Tang95409972016-10-20 15:16:15 +08009109 return 0;
9110}
9111#else
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07009112static inline int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08009113{
9114 return 0;
9115}
9116#endif
9117
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009118#ifdef WLAN_FEATURE_FASTPATH
jitiphil377bcc12018-10-05 19:46:08 +05309119
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009120/**
9121 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
9122 * @hdd_cfg: hdd config
9123 * @context: lower layer context
9124 *
9125 * Return: none
9126 */
jitiphil377bcc12018-10-05 19:46:08 +05309127void hdd_enable_fastpath(struct hdd_context *hdd_ctx,
9128 void *context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009129{
jitiphil377bcc12018-10-05 19:46:08 +05309130 if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009131 hif_enable_fastpath(context);
9132}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009133#endif
9134
Yuanyuan Liu13738502016-04-06 17:41:37 -07009135#if defined(FEATURE_WLAN_CH_AVOID)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009136/**
9137 * hdd_set_thermal_level_cb() - set thermal level callback function
Jeff Johnson0e963082018-07-04 19:39:20 -07009138 * @hdd_handle: opaque handle for the hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009139 * @level: thermal level
9140 *
9141 * Change IPA data path to SW path when the thermal throttle level greater
9142 * than 0, and restore the original data path when throttle level is 0
9143 *
9144 * Return: none
9145 */
Jeff Johnson0e963082018-07-04 19:39:20 -07009146static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009147{
Jeff Johnson0e963082018-07-04 19:39:20 -07009148 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009149
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009150 /* Change IPA to SW path when throttle level greater than 0 */
9151 if (level > THROTTLE_LEVEL_0)
Dustin Brown07901ec2018-09-07 11:02:41 -07009152 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009153 else
9154 /* restore original concurrency mode */
Dustin Brown07901ec2018-09-07 11:02:41 -07009155 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009156}
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05309157#else
9158/**
9159 * hdd_set_thermal_level_cb() - set thermal level callback function
9160 * @hdd_handle: opaque handle for the hdd context
9161 * @level: thermal level
9162 *
9163 * Change IPA data path to SW path when the thermal throttle level greater
9164 * than 0, and restore the original data path when throttle level is 0
9165 *
9166 * Return: none
9167 */
9168static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
9169{
9170}
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05309171#endif
9172
9173/**
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08009174 * hdd_switch_sap_channel() - Move SAP to the given channel
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309175 * @adapter: AP adapter
9176 * @channel: Channel
Min Liu2fef5792018-01-19 17:59:42 +08009177 * @forced: Force to switch channel, ignore SCC/MCC check
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309178 *
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08009179 * Moves the SAP interface by invoking the function which
9180 * executes the callback to perform channel switch using (E)CSA.
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309181 *
9182 * Return: None
9183 */
Min Liu2fef5792018-01-19 17:59:42 +08009184void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel,
9185 bool forced)
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309186{
Jeff Johnson87251032017-08-29 13:31:11 -07009187 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009188 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -07009189 mac_handle_t mac_handle;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309190
9191 if (!adapter) {
9192 hdd_err("invalid adapter");
9193 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009194 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309195
9196 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
9197
Jeff Johnson16528362018-06-14 12:34:16 -07009198 mac_handle = hdd_adapter_get_mac_handle(adapter);
9199 if (!mac_handle) {
9200 hdd_err("invalid MAC handle");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309201 return;
9202 }
9203
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08009204 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9205
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009206 hdd_debug("chan:%d width:%d",
Jeff Johnson91df29d2017-10-27 19:29:50 -07009207 channel, hdd_ap_ctx->sap_config.ch_width_orig);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309208
Manikandan Mohan7fdb0252019-08-14 16:49:02 -07009209 policy_mgr_change_sap_channel_with_csa(
9210 hdd_ctx->psoc, adapter->vdev_id,
9211 wlan_chan_to_freq(channel),
Min Liu2fef5792018-01-19 17:59:42 +08009212 hdd_ap_ctx->sap_config.ch_width_orig, forced);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009213}
Kapil Gupta8878ad92017-02-13 11:56:04 +05309214
Jeff Johnson9d295242017-08-29 14:39:48 -07009215int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
Kapil Gupta8878ad92017-02-13 11:56:04 +05309216{
9217 struct hdd_external_acs_timer_context *timer_context;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05309218 int status;
9219 QDF_STATUS qdf_status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05309220
9221 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
9222
9223 if (QDF_TIMER_STATE_RUNNING ==
Jeff Johnsonb9424862017-10-30 08:49:35 -07009224 qdf_mc_timer_get_current_state(&adapter->session.
Kapil Gupta8878ad92017-02-13 11:56:04 +05309225 ap.vendor_acs_timer)) {
Jeff Johnsonb9424862017-10-30 08:49:35 -07009226 qdf_mc_timer_stop(&adapter->session.ap.vendor_acs_timer);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309227 }
9228 timer_context = (struct hdd_external_acs_timer_context *)
Jeff Johnsonb9424862017-10-30 08:49:35 -07009229 adapter->session.ap.vendor_acs_timer.user_data;
Kapil Gupta8878ad92017-02-13 11:56:04 +05309230 timer_context->reason = reason;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05309231 qdf_status =
Jeff Johnsonb9424862017-10-30 08:49:35 -07009232 qdf_mc_timer_start(&adapter->session.ap.vendor_acs_timer,
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05309233 WLAN_VENDOR_ACS_WAIT_TIME);
9234 if (qdf_status != QDF_STATUS_SUCCESS) {
9235 hdd_err("failed to start external acs timer");
9236 return -ENOSPC;
9237 }
9238 /* Update config to application */
9239 status = hdd_cfg80211_update_acs_config(adapter, reason);
Dustin Brown5e89ef82018-03-14 11:50:23 -07009240 hdd_info("Updated ACS config to nl with reason %d", reason);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309241
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05309242 return status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05309243}
9244
Nirav Shaheb017be2018-02-15 11:20:58 +05309245#if defined(FEATURE_WLAN_CH_AVOID)
Agrawal Ashish467dde42016-09-08 18:44:22 +05309246/**
hqu54e6ba12019-08-01 21:11:12 +08009247 * hdd_store_sap_restart_channel() - store sap restart channel
9248 * @restart_chan: restart channel
9249 * @restart_chan_store: pointer to restart channel store
9250 *
9251 * The function will store new sap restart channel.
9252 *
9253 * Return - none
9254 */
9255static void
9256hdd_store_sap_restart_channel(uint8_t restart_chan, uint8_t *restart_chan_store)
9257{
9258 uint8_t i;
9259
9260 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
9261 if (*(restart_chan_store + i) == restart_chan)
9262 return;
9263
9264 if (*(restart_chan_store + i))
9265 continue;
9266
9267 *(restart_chan_store + i) = restart_chan;
9268 return;
9269 }
9270}
9271
9272/**
Agrawal Ashish467dde42016-09-08 18:44:22 +05309273 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
9274 * @hdd_ctx: hdd context pointer
9275 *
9276 * hdd_unsafe_channel_restart_sap check all unsafe channel list
9277 * and if ACS is enabled, driver will ask userspace to restart the
9278 * sap. User space on LTE coex indication restart driver.
9279 *
9280 * Return - none
9281 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009282void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
Agrawal Ashish467dde42016-09-08 18:44:22 +05309283{
Dustin Brown920397d2017-12-13 16:27:50 -08009284 struct hdd_adapter *adapter;
Agrawal Ashish467dde42016-09-08 18:44:22 +05309285 uint32_t i;
9286 bool found = false;
hqu54e6ba12019-08-01 21:11:12 +08009287 uint8_t restart_chan_store[SAP_MAX_NUM_SESSION] = {0};
Will Huang4b097f52019-08-29 10:51:56 -07009288 uint8_t restart_chan, ap_chan;
Krunal Sonidf29bc42018-11-15 13:26:29 -08009289 uint8_t scc_on_lte_coex = 0;
gaurank kathpaliaaa252b52019-10-30 15:29:04 +05309290 uint32_t restart_freq;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309291 bool value;
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07009292 QDF_STATUS status;
9293 bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE);
9294 bool is_vendor_acs_support =
9295 cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009296
Dustin Brown920397d2017-12-13 16:27:50 -08009297 hdd_for_each_adapter(hdd_ctxt, adapter) {
9298 if (!(adapter->device_mode == QDF_SAP_MODE &&
9299 adapter->session.ap.sap_config.acs_cfg.acs_mode)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009300 hdd_debug("skip device mode:%d acs:%d",
Dustin Brown920397d2017-12-13 16:27:50 -08009301 adapter->device_mode,
9302 adapter->session.ap.sap_config.
9303 acs_cfg.acs_mode);
9304 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05309305 }
9306
Will Huang4b097f52019-08-29 10:51:56 -07009307 ap_chan = wlan_reg_freq_to_chan(
9308 hdd_ctxt->pdev,
9309 adapter->session.ap.operating_chan_freq);
Agrawal Ashish467dde42016-09-08 18:44:22 +05309310 found = false;
Krunal Sonidf29bc42018-11-15 13:26:29 -08009311 status =
9312 ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctxt->psoc,
9313 &scc_on_lte_coex);
9314 if (!QDF_IS_STATUS_SUCCESS(status))
9315 hdd_err("can't get scc on lte coex chnl, use def");
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07009316 /*
9317 * If STA+SAP is doing SCC & g_sta_sap_scc_on_lte_coex_chan
9318 * is set, no need to move SAP.
9319 */
Manikandan Mohan956b69e2019-02-14 13:08:14 -08009320 if ((policy_mgr_is_sta_sap_scc(
Manikandan Mohana0bbb512019-08-15 11:39:26 -07009321 hdd_ctxt->psoc,
9322 adapter->session.ap.operating_chan_freq) &&
9323 scc_on_lte_coex) ||
9324 policy_mgr_nan_sap_scc_on_unsafe_ch_chk(
9325 hdd_ctxt->psoc,
9326 adapter->session.ap.operating_chan_freq)) {
Manikandan Mohan956b69e2019-02-14 13:08:14 -08009327 hdd_debug("SAP allowed in unsafe SCC channel");
9328 } else {
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07009329 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
Will Huang4b097f52019-08-29 10:51:56 -07009330 if (ap_chan ==
9331 hdd_ctxt->unsafe_channel_list[i]) {
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07009332 found = true;
9333 hdd_debug("operating ch:%d is unsafe",
Will Huang4b097f52019-08-29 10:51:56 -07009334 ap_chan);
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07009335 break;
9336 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05309337 }
9338 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05309339 if (!found) {
hqu54e6ba12019-08-01 21:11:12 +08009340 hdd_store_sap_restart_channel(
Will Huang4b097f52019-08-29 10:51:56 -07009341 ap_chan,
hqu54e6ba12019-08-01 21:11:12 +08009342 restart_chan_store);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009343 hdd_debug("ch:%d is safe. no need to change channel",
Will Huang4b097f52019-08-29 10:51:56 -07009344 ap_chan);
Dustin Brown920397d2017-12-13 16:27:50 -08009345 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05309346 }
9347
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07009348 status = ucfg_mlme_get_acs_support_for_dfs_ltecoex(
9349 hdd_ctxt->psoc,
9350 &is_acs_support_for_dfs_ltecoex);
9351 if (!QDF_IS_STATUS_SUCCESS(status))
9352 hdd_err("get_acs_support_for_dfs_ltecoex failed,set def");
9353
9354 status = ucfg_mlme_get_vendor_acs_support(
9355 hdd_ctxt->psoc,
9356 &is_vendor_acs_support);
9357 if (!QDF_IS_STATUS_SUCCESS(status))
9358 hdd_err("get_vendor_acs_support failed, set default");
9359
9360 if (is_vendor_acs_support && is_acs_support_for_dfs_ltecoex) {
Dustin Brown920397d2017-12-13 16:27:50 -08009361 hdd_update_acs_timer_reason(adapter,
Kapil Gupta8878ad92017-02-13 11:56:04 +05309362 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
Dustin Brown920397d2017-12-13 16:27:50 -08009363 continue;
hqu54e6ba12019-08-01 21:11:12 +08009364 }
9365
9366 restart_chan = 0;
9367 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
9368 if (!restart_chan_store[i])
9369 continue;
9370
9371 if (policy_mgr_is_force_scc(hdd_ctxt->psoc) &&
9372 WLAN_REG_IS_SAME_BAND_CHANNELS(
Will Huang4b097f52019-08-29 10:51:56 -07009373 restart_chan_store[i],
9374 ap_chan)) {
hqu54e6ba12019-08-01 21:11:12 +08009375 restart_chan = restart_chan_store[i];
9376 break;
9377 }
9378 }
gaurank kathpaliaaa252b52019-10-30 15:29:04 +05309379 if (!restart_chan) {
9380 restart_freq =
bings6c4672b2019-03-19 16:00:19 +08009381 wlansap_get_safe_channel_from_pcl_and_acs_range(
9382 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
gaurank kathpaliaaa252b52019-10-30 15:29:04 +05309383 restart_chan = wlan_reg_freq_to_chan(hdd_ctxt->pdev,
9384 restart_freq);
9385 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05309386 if (!restart_chan) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009387 hdd_err("fail to restart SAP");
Agrawal Ashish467dde42016-09-08 18:44:22 +05309388 } else {
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08009389 /*
9390 * SAP restart due to unsafe channel. While
9391 * restarting the SAP, make sure to clear
9392 * acs_channel, channel to reset to
9393 * 0. Otherwise these settings will override
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05309394 * the ACS while restart.
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08009395 */
Rajeev Kumar Sirasanagandlae83ac292019-09-19 16:35:26 +05309396 hdd_ctxt->acs_policy.acs_chan_freq =
9397 AUTO_CHANNEL_SELECT;
Dustin Brown05d81302018-09-11 16:49:22 -07009398 ucfg_mlme_get_sap_internal_restart(hdd_ctxt->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309399 &value);
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +05309400 if (value) {
9401 wlan_hdd_set_sap_csa_reason(hdd_ctxt->psoc,
9402 adapter->vdev_id,
9403 CSA_REASON_UNSAFE_CHANNEL);
Min Liu2fef5792018-01-19 17:59:42 +08009404 hdd_switch_sap_channel(adapter, restart_chan,
9405 true);
Will Huangc3fb27d2019-08-16 16:34:25 +08009406 return;
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +05309407 }
hqu1d1b9222019-06-11 20:00:55 +08009408 else {
9409 hdd_debug("sending coex indication");
9410 wlan_hdd_send_svc_nlink_msg(
9411 hdd_ctxt->radio_index,
9412 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Liangwei Dong6663d162017-07-10 03:29:36 -04009413 return;
hqu1d1b9222019-06-11 20:00:55 +08009414 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05309415 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05309416 }
9417}
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05309418
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009419/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009420 * hdd_init_channel_avoidance() - Initialize channel avoidance
9421 * @hdd_ctx: HDD global context
9422 *
9423 * Initialize the channel avoidance logic by retrieving the unsafe
Yuanyuan Liu13738502016-04-06 17:41:37 -07009424 * channel list from the platform driver and plumbing the data
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009425 * down to the lower layers. Then subscribe to subsequent channel
9426 * avoidance events.
9427 *
9428 * Return: None
9429 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009430static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009431{
9432 uint16_t unsafe_channel_count;
9433 int index;
9434
Yuanyuan Liu13738502016-04-06 17:41:37 -07009435 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
9436 hdd_ctx->unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009437 &(hdd_ctx->unsafe_channel_count),
Amar Singhalb8d4f152016-02-10 10:21:43 -08009438 sizeof(uint16_t) * NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009439
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009440 hdd_debug("num of unsafe channels is %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009441 hdd_ctx->unsafe_channel_count);
9442
Anurag Chouhan6d760662016-02-20 16:05:43 +05309443 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
Amar Singhalb8d4f152016-02-10 10:21:43 -08009444 (uint16_t)NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009445
9446 for (index = 0; index < unsafe_channel_count; index++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009447 hdd_debug("channel %d is not safe",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009448 hdd_ctx->unsafe_channel_list[index]);
9449
9450 }
9451
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009452}
Dustin Brown676a2322017-08-15 13:16:13 -07009453
Jeff Johnson9d295242017-08-29 14:39:48 -07009454static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009455 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07009456{
9457 uint8_t restart_chan;
gaurank kathpaliaaa252b52019-10-30 15:29:04 +05309458 uint32_t restart_freq;
Dustin Brown676a2322017-08-15 13:16:13 -07009459
gaurank kathpaliaaa252b52019-10-30 15:29:04 +05309460 restart_freq = wlansap_get_safe_channel_from_pcl_and_acs_range(
bings6c4672b2019-03-19 16:00:19 +08009461 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
gaurank kathpaliaaa252b52019-10-30 15:29:04 +05309462
9463 restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev,
9464 restart_freq);
9465
Dustin Brown676a2322017-08-15 13:16:13 -07009466 if (!restart_chan) {
9467 hdd_alert("fail to restart SAP");
9468 return;
9469 }
9470
9471 /* SAP restart due to unsafe channel. While restarting
9472 * the SAP, make sure to clear acs_channel, channel to
9473 * reset to 0. Otherwise these settings will override
9474 * the ACS while restart.
9475 */
Rajeev Kumar Sirasanagandlae83ac292019-09-19 16:35:26 +05309476 hdd_ctx->acs_policy.acs_chan_freq = AUTO_CHANNEL_SELECT;
Dustin Brown676a2322017-08-15 13:16:13 -07009477
9478 hdd_debug("sending coex indication");
9479
9480 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
9481 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +05309482 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->vdev_id,
9483 CSA_REASON_LTE_COEX);
Min Liu2fef5792018-01-19 17:59:42 +08009484 hdd_switch_sap_channel(adapter, restart_chan, true);
Dustin Brown676a2322017-08-15 13:16:13 -07009485}
Liangwei Dong6e1a2092017-08-30 16:29:06 +08009486
9487int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
9488 uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count)
9489{
9490 uint32_t size;
9491 uint16_t *unsafe_list;
9492 uint16_t chan_count;
9493
9494 if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count)
9495 return -EINVAL;
9496
9497 chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count,
9498 NUM_CHANNELS);
9499 if (chan_count) {
9500 size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]);
9501 unsafe_list = qdf_mem_malloc(size);
Min Liu74a1a502018-10-10 19:59:07 +08009502 if (!unsafe_list)
Liangwei Dong6e1a2092017-08-30 16:29:06 +08009503 return -ENOMEM;
Liangwei Dong6e1a2092017-08-30 16:29:06 +08009504 qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size);
9505 } else {
9506 unsafe_list = NULL;
9507 }
9508
9509 *local_unsafe_list = unsafe_list;
9510 *local_unsafe_list_count = chan_count;
9511
9512 return 0;
9513}
9514
9515bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
9516 uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count)
9517{
9518 int i, j;
9519
9520 if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count)
9521 return true;
9522 if (local_unsafe_list_count == 0)
9523 return false;
9524 for (i = 0; i < local_unsafe_list_count; i++) {
9525 for (j = 0; j < local_unsafe_list_count; j++)
9526 if (local_unsafe_list[i] ==
9527 hdd_ctx->unsafe_channel_list[j])
9528 break;
9529 if (j >= local_unsafe_list_count)
9530 break;
9531 }
9532 if (i >= local_unsafe_list_count) {
9533 hdd_info("unsafe chan list same");
9534 return false;
9535 }
9536
9537 return true;
9538}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009539#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009540static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009541{
9542}
Dustin Brown676a2322017-08-15 13:16:13 -07009543
Jeff Johnson9d295242017-08-29 14:39:48 -07009544static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009545 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07009546{
9547 hdd_debug("Channel avoidance is not enabled; Abort SAP restart");
9548}
Yuanyuan Liu13738502016-04-06 17:41:37 -07009549#endif /* defined(FEATURE_WLAN_CH_AVOID) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009550
Sourav Mohapatraf43b3082019-11-06 13:58:09 +05309551QDF_STATUS
9552wlan_hdd_get_adapter_by_vdev_id_from_objmgr(struct hdd_context *hdd_ctx,
9553 struct hdd_adapter **adapter,
9554 struct wlan_objmgr_vdev *vdev)
9555{
9556 *adapter = NULL;
9557 if (!hdd_ctx)
9558 return QDF_STATUS_E_INVAL;
9559
9560 if (!vdev || !vdev->vdev_nif.osdev) {
9561 hdd_err("null vdev object");
9562 return QDF_STATUS_E_INVAL;
9563 }
9564
9565 *adapter = vdev->vdev_nif.osdev->legacy_osif_priv;
9566
9567 return QDF_STATUS_SUCCESS;
9568}
9569
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009570/**
Rajeev Kumard004abc2016-02-17 12:09:56 -08009571 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
9572 * user space
9573 * @frame_ind: Management frame data to be informed.
9574 *
9575 * This function is used to indicate management frame to
9576 * user space
9577 *
9578 * Return: None
9579 *
9580 */
9581void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
9582{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009583 struct hdd_context *hdd_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07009584 struct hdd_adapter *adapter = NULL;
Sourav Mohapatraf43b3082019-11-06 13:58:09 +05309585 int i, num_adapters;
9586 uint8_t vdev_id[WLAN_MAX_VDEVS];
Pragaspathi Thilagaraj28ffc042018-07-18 15:19:36 +05309587 struct ieee80211_mgmt *mgmt =
9588 (struct ieee80211_mgmt *)frame_ind->frameBuf;
Sourav Mohapatraf43b3082019-11-06 13:58:09 +05309589 QDF_STATUS status;
9590 struct wlan_objmgr_vdev *vdev;
Rajeev Kumard004abc2016-02-17 12:09:56 -08009591
Dustin Browne7e71d32018-05-11 16:00:08 -07009592 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
9593 if (wlan_hdd_validate_context(hdd_ctx))
Rajeev Kumard004abc2016-02-17 12:09:56 -08009594 return;
9595
Pragaspathi Thilagaraj28ffc042018-07-18 15:19:36 +05309596 if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) {
9597 hdd_err(" Invalid frame length");
9598 return;
9599 }
9600
Rajeev Kumard004abc2016-02-17 12:09:56 -08009601 if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
Dustin Brownad06be62019-02-04 14:52:56 -08009602 for (i = 0; i < WLAN_MAX_VDEVS; i++) {
Rajeev Kumard004abc2016-02-17 12:09:56 -08009603 adapter =
Jeff Johnson55d2ab42019-03-06 11:43:49 -08009604 hdd_get_adapter_by_vdev(hdd_ctx, i);
Rajeev Kumard004abc2016-02-17 12:09:56 -08009605 if (adapter)
9606 break;
9607 }
Wu Gaoa0230a62018-01-04 20:56:57 +08009608 } else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) {
Sourav Mohapatraf43b3082019-11-06 13:58:09 +05309609 num_adapters = 0;
9610 hdd_for_each_adapter_dev_held(hdd_ctx, adapter) {
9611 vdev_id[num_adapters] = adapter->vdev_id;
9612 num_adapters++;
9613 /* dev_put has to be done here */
9614 dev_put(adapter->dev);
Wu Gaoa0230a62018-01-04 20:56:57 +08009615 }
Sourav Mohapatraf43b3082019-11-06 13:58:09 +05309616
9617 adapter = NULL;
9618
9619 for (i = 0; i < num_adapters; i++) {
9620 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(
9621 hdd_ctx->psoc,
9622 vdev_id[i],
9623 WLAN_OSIF_ID);
9624
9625 if (!vdev)
9626 continue;
9627
9628 status = wlan_hdd_get_adapter_by_vdev_id_from_objmgr(
9629 hdd_ctx, &adapter, vdev);
9630
9631 if (QDF_IS_STATUS_ERROR(status) || !adapter) {
9632 wlan_objmgr_vdev_release_ref(vdev,
9633 WLAN_OSIF_ID);
9634 continue;
9635 }
9636
9637 hdd_indicate_mgmt_frame_to_user(adapter,
9638 frame_ind->frame_len,
9639 frame_ind->frameBuf,
9640 frame_ind->frameType,
9641 frame_ind->rx_freq,
9642 frame_ind->rxRssi,
9643 frame_ind->rx_flags);
9644 wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
9645 }
9646
Wu Gaoa0230a62018-01-04 20:56:57 +08009647 adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08009648 } else {
Jeff Johnson55d2ab42019-03-06 11:43:49 -08009649 adapter = hdd_get_adapter_by_vdev(hdd_ctx,
9650 frame_ind->sessionId);
Rajeev Kumard004abc2016-02-17 12:09:56 -08009651 }
9652
Jeff Johnsond36fa332019-03-18 13:42:25 -07009653 if ((adapter) &&
Rajeev Kumard004abc2016-02-17 12:09:56 -08009654 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
Rajeev Kumard097ea12019-10-10 16:56:54 -07009655 hdd_indicate_mgmt_frame_to_user(adapter,
Rajeev Kumard004abc2016-02-17 12:09:56 -08009656 frame_ind->frame_len,
9657 frame_ind->frameBuf,
9658 frame_ind->frameType,
Ashish Kumar Dhanotiyaca5d9222019-08-29 18:56:32 +05309659 frame_ind->rx_freq,
Srinivas Dasariea1c1332019-02-18 12:43:23 +05309660 frame_ind->rxRssi,
9661 frame_ind->rx_flags);
Rajeev Kumard004abc2016-02-17 12:09:56 -08009662}
9663
Kapil Gupta8878ad92017-02-13 11:56:04 +05309664void hdd_acs_response_timeout_handler(void *context)
9665{
9666 struct hdd_external_acs_timer_context *timer_context =
9667 (struct hdd_external_acs_timer_context *)context;
Jeff Johnson9d295242017-08-29 14:39:48 -07009668 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009669 struct hdd_context *hdd_ctx;
Kapil Gupta8878ad92017-02-13 11:56:04 +05309670 uint8_t reason;
9671
Dustin Brown491d54b2018-03-14 12:39:11 -07009672 hdd_enter();
Kapil Gupta8878ad92017-02-13 11:56:04 +05309673 if (!timer_context) {
9674 hdd_err("invlaid timer context");
9675 return;
9676 }
9677 adapter = timer_context->adapter;
9678 reason = timer_context->reason;
9679
9680
9681 if ((!adapter) ||
9682 (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
9683 hdd_err("invalid adapter or adapter has invalid magic");
9684 return;
9685 }
9686 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9687 if (wlan_hdd_validate_context(hdd_ctx))
9688 return;
9689
9690 if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags))
9691 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
9692 else
9693 return;
9694
9695 hdd_err("ACS timeout happened for %s reason %d",
9696 adapter->dev->name, reason);
Jeff Johnson16528362018-06-14 12:34:16 -07009697
Kapil Gupta8878ad92017-02-13 11:56:04 +05309698 switch (reason) {
9699 /* SAP init case */
9700 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
9701 wlan_sap_set_vendor_acs(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
9702 false);
9703 wlan_hdd_cfg80211_start_acs(adapter);
9704 break;
9705 /* DFS detected on current channel */
9706 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
9707 wlan_sap_update_next_channel(
9708 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 0, 0);
Jeff Johnson16528362018-06-14 12:34:16 -07009709 sme_update_new_channel_event(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08009710 adapter->vdev_id);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309711 break;
9712 /* LTE coex event on current channel */
9713 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
9714 hdd_lte_coex_restart_sap(adapter, hdd_ctx);
9715 break;
9716 default:
9717 hdd_info("invalid reason for timer invoke");
9718
9719 }
9720}
9721
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009722/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009723 * hdd_override_ini_config - Override INI config
9724 * @hdd_ctx: HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009725 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009726 * Override INI config based on module parameter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009727 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009728 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009729 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009730static void hdd_override_ini_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009731{
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309732 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009733
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009734 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
gaurank kathpalia97c070b2019-01-07 17:23:06 +05309735 ucfg_scan_cfg_set_dfs_chan_scan_allowed(hdd_ctx->psoc,
9736 enable_dfs_chan_scan);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009737 hdd_debug("Module enable_dfs_chan_scan set to %d",
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009738 enable_dfs_chan_scan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009739 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009740 if (0 == enable_11d || 1 == enable_11d) {
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309741 status = ucfg_mlme_set_11d_enabled(hdd_ctx->psoc, enable_11d);
9742 if (!QDF_IS_STATUS_SUCCESS(status))
9743 hdd_err("Failed to set 11d_enable flag");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009744 }
Leo Chang11545d62016-10-17 14:53:50 -07009745
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +05309746 if (hdd_ctx->config->action_oui_enable && !ucfg_action_oui_enabled()) {
9747 hdd_ctx->config->action_oui_enable = 0;
Sourav Mohapatra58841062018-11-19 16:33:27 +05309748 hdd_err("Ignore action oui ini, since no action_oui component");
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +05309749 }
Will Huang14b120f2019-01-14 17:26:14 +08009750
9751 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
9752 hdd_override_all_ps(hdd_ctx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009753}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009754
Ashish Kumar Dhanotiya12f68212018-09-04 22:00:14 +05309755#ifdef ENABLE_MTRACE_LOG
9756static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
9757{
9758 uint8_t module_id = 0;
9759 int qdf_print_idx = -1;
9760
9761 qdf_print_idx = qdf_get_pidx();
9762 for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++)
9763 qdf_print_set_category_verbose(
9764 qdf_print_idx,
9765 module_id, QDF_TRACE_LEVEL_TRACE,
9766 hdd_ctx->config->enable_mtrace);
9767}
9768#else
9769static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
9770{
9771}
9772
9773#endif
9774
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009775/**
Wu Gao8dd9f502019-04-26 15:04:28 +08009776 * hdd_log_level_to_bitmask() - user space log level to host log bitmask
9777 * @user_log_level: user space log level
9778 *
9779 * Convert log level from user space to host log level bitmask.
9780 *
9781 * Return: Bitmask of log levels to be enabled
9782 */
9783static uint32_t hdd_log_level_to_bitmask(enum host_log_level user_log_level)
9784{
9785 QDF_TRACE_LEVEL host_trace_level;
9786 uint32_t bitmask;
9787
9788 switch (user_log_level) {
9789 case HOST_LOG_LEVEL_NONE:
9790 host_trace_level = QDF_TRACE_LEVEL_NONE;
9791 break;
9792 case HOST_LOG_LEVEL_FATAL:
9793 host_trace_level = QDF_TRACE_LEVEL_FATAL;
9794 break;
9795 case HOST_LOG_LEVEL_ERROR:
9796 host_trace_level = QDF_TRACE_LEVEL_ERROR;
9797 break;
9798 case HOST_LOG_LEVEL_WARN:
9799 host_trace_level = QDF_TRACE_LEVEL_WARN;
9800 break;
9801 case HOST_LOG_LEVEL_INFO:
9802 host_trace_level = QDF_TRACE_LEVEL_INFO_LOW;
9803 break;
9804 case HOST_LOG_LEVEL_DEBUG:
9805 host_trace_level = QDF_TRACE_LEVEL_DEBUG;
9806 break;
9807 case HOST_LOG_LEVEL_TRACE:
9808 host_trace_level = QDF_TRACE_LEVEL_TRACE;
9809 break;
9810 default:
9811 host_trace_level = QDF_TRACE_LEVEL_TRACE;
9812 break;
9813 }
9814
9815 bitmask = (1 << (host_trace_level + 1)) - 1;
9816
9817 return bitmask;
9818}
9819
9820/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009821 * hdd_set_trace_level_for_each - Set trace level for each INI config
9822 * @hdd_ctx - HDD context
9823 *
9824 * Set trace level for each module based on INI config.
9825 *
9826 * Return: None
9827 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009828static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009829{
Wu Gao8dd9f502019-04-26 15:04:28 +08009830 uint8_t host_module_log[QDF_MODULE_ID_MAX * 2];
9831 qdf_size_t host_module_log_num = 0;
9832 QDF_MODULE_ID module_id;
9833 uint32_t bitmask;
9834 uint32_t i;
9835
Wu Gaobc6eaa12018-11-30 14:17:45 +08009836 hdd_qdf_trace_enable(QDF_MODULE_ID_DP, 0x7f);
Wu Gao8dd9f502019-04-26 15:04:28 +08009837
9838 qdf_uint8_array_parse(cfg_get(hdd_ctx->psoc,
9839 CFG_ENABLE_HOST_MODULE_LOG_LEVEL),
9840 host_module_log,
9841 QDF_MODULE_ID_MAX * 2,
9842 &host_module_log_num);
9843
9844 for (i = 0; i + 1 < host_module_log_num; i += 2) {
9845 module_id = host_module_log[i];
9846 bitmask = hdd_log_level_to_bitmask(host_module_log[i + 1]);
9847 if (module_id < QDF_MODULE_ID_MAX &&
9848 module_id >= QDF_MODULE_ID_MIN)
9849 hdd_qdf_trace_enable(module_id, bitmask);
9850 }
Kiran Kumar Lokere798de7e2017-03-30 14:01:12 -07009851
Ashish Kumar Dhanotiya12f68212018-09-04 22:00:14 +05309852 hdd_set_mtrace_for_each(hdd_ctx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009853}
9854
9855/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009856 * hdd_context_init() - Initialize HDD context
9857 * @hdd_ctx: HDD context.
9858 *
9859 * Initialize HDD context along with all the feature specific contexts.
9860 *
9861 * return: 0 on success and errno on failure.
9862 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009863static int hdd_context_init(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009864{
9865 int ret;
9866
9867 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
Dustin Brownad06be62019-02-04 14:52:56 -08009868 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009869
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009870 init_completion(&hdd_ctx->mc_sus_event_var);
9871 init_completion(&hdd_ctx->ready_to_suspend);
9872
9873 qdf_spinlock_create(&hdd_ctx->connection_status_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009874 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05309875
Dustin Brownbee82832018-07-23 10:10:51 -07009876 qdf_list_create(&hdd_ctx->hdd_adapters, 0);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009877
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009878 ret = hdd_scan_context_init(hdd_ctx);
9879 if (ret)
9880 goto list_destroy;
9881
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009882 hdd_rx_wake_lock_create(hdd_ctx);
9883
9884 ret = hdd_sap_context_init(hdd_ctx);
9885 if (ret)
9886 goto scan_destroy;
9887
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009888 wlan_hdd_cfg80211_extscan_init(hdd_ctx);
9889
9890 hdd_init_offloaded_packets_ctx(hdd_ctx);
9891
9892 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
9893 hdd_ctx->config);
9894 if (ret)
Wu Gao02bd75b2017-10-13 18:34:02 +08009895 goto sap_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009896
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05309897 qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock,
9898 "monitor_mode_wakelock");
9899
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009900 return 0;
9901
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009902sap_destroy:
9903 hdd_sap_context_destroy(hdd_ctx);
9904
9905scan_destroy:
9906 hdd_scan_context_destroy(hdd_ctx);
9907 hdd_rx_wake_lock_destroy(hdd_ctx);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009908list_destroy:
Jeff Johnson19fc8e42017-10-30 19:53:49 -07009909 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Sandeep Puligillad0004212017-02-26 18:34:56 -08009910
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009911 return ret;
9912}
9913
Dustin Brown4c663222018-10-23 14:19:36 -07009914void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx)
9915{
9916 uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time;
9917 enum wake_lock_reason reason =
9918 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER;
9919
Rajeev Kumar7b7bb3f2018-12-20 12:09:54 -08009920 if (!timeout_ms) {
9921 hdd_info("psoc idle timer is disabled");
9922 return;
9923 }
9924
Dustin Brown4c663222018-10-23 14:19:36 -07009925 hdd_debug("Starting psoc idle timer");
Alan Chen5b19c212019-07-19 10:44:42 -07009926 timeout_ms += HDD_PSOC_IDLE_SHUTDOWN_SUSPEND_DELAY;
Dustin Brown8d8ab302019-03-05 16:19:36 -08009927 qdf_delayed_work_start(&hdd_ctx->psoc_idle_timeout_work, timeout_ms);
Dustin Brown4c663222018-10-23 14:19:36 -07009928 hdd_prevent_suspend_timeout(timeout_ms, reason);
9929}
9930
9931void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx)
9932{
Dustin Brown8d8ab302019-03-05 16:19:36 -08009933 qdf_delayed_work_stop_sync(&hdd_ctx->psoc_idle_timeout_work);
Dustin Brown4c663222018-10-23 14:19:36 -07009934 hdd_debug("Stopped psoc idle timer");
9935}
9936
Sourav Mohapatra698d6f62019-01-29 14:49:52 +05309937
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009938/**
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009939 * __hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc
Dustin Brown3ecc8782018-09-19 16:37:13 -07009940 * @hdd_ctx: the hdd context which should be shutdown
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309941 *
Dustin Brown3ecc8782018-09-19 16:37:13 -07009942 * When no interfaces are "up" on a psoc, an idle shutdown timer is started.
9943 * If no interfaces are brought up before the timer expires, we do an
9944 * "idle shutdown," cutting power to the physical SoC to save power. This is
9945 * done completely transparently from the perspective of userspace.
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309946 *
Dustin Brown3ecc8782018-09-19 16:37:13 -07009947 * Return: None
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309948 */
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009949static int __hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309950{
Dustin Brown363b4792019-02-05 16:11:55 -08009951 struct osif_psoc_sync *psoc_sync;
Dustin Browncfcb5762019-01-31 15:43:45 -08009952 int errno;
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309953
Dustin Brown491d54b2018-03-14 12:39:11 -07009954 hdd_enter();
Dustin Brown3ecc8782018-09-19 16:37:13 -07009955
Dustin Brown363b4792019-02-05 16:11:55 -08009956 errno = osif_psoc_sync_trans_start(hdd_ctx->parent_dev, &psoc_sync);
Dustin Browncfcb5762019-01-31 15:43:45 -08009957 if (errno) {
9958 hdd_info("psoc busy, abort idle shutdown; errno:%d", errno);
9959 goto exit;
Dustin Brown3ecc8782018-09-19 16:37:13 -07009960 }
9961
Dustin Brown363b4792019-02-05 16:11:55 -08009962 osif_psoc_sync_wait_for_ops(psoc_sync);
Dustin Browncfcb5762019-01-31 15:43:45 -08009963
Alan Chend841bcc2019-08-30 12:17:22 -07009964 errno = hdd_wlan_stop_modules(hdd_ctx, false);
Dustin Brown3ecc8782018-09-19 16:37:13 -07009965
Dustin Brown363b4792019-02-05 16:11:55 -08009966 osif_psoc_sync_trans_stop(psoc_sync);
Dustin Brown3ecc8782018-09-19 16:37:13 -07009967
Dustin Browncfcb5762019-01-31 15:43:45 -08009968exit:
Dustin Browne74003f2018-03-14 12:51:58 -07009969 hdd_exit();
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009970 return errno;
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309971}
9972
Rajeev Kumar588a2542019-04-08 10:57:19 -07009973static int __hdd_mode_change_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
9974{
9975 is_mode_change_psoc_idle_shutdown = false;
9976 return hdd_wlan_stop_modules(hdd_ctx, true);
9977}
9978
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009979int hdd_psoc_idle_shutdown(struct device *dev)
9980{
Alan Chen6a5eb932019-08-12 17:08:22 -07009981 int ret;
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009982 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
9983
Rajeev Kumard62104a2019-05-31 12:04:27 -07009984 if (!hdd_ctx) {
9985 hdd_err_rl("hdd ctx is null");
9986 return -EINVAL;
9987 }
9988
Rajeev Kumar588a2542019-04-08 10:57:19 -07009989 if (is_mode_change_psoc_idle_shutdown)
Alan Chen6a5eb932019-08-12 17:08:22 -07009990 ret = __hdd_mode_change_psoc_idle_shutdown(hdd_ctx);
Rajeev Kumar588a2542019-04-08 10:57:19 -07009991 else
Alan Chen6a5eb932019-08-12 17:08:22 -07009992 ret = __hdd_psoc_idle_shutdown(hdd_ctx);
9993
Alan Chen6a5eb932019-08-12 17:08:22 -07009994 return ret;
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009995}
9996
9997static int __hdd_psoc_idle_restart(struct hdd_context *hdd_ctx)
9998{
Alan Chene523cd92019-07-15 16:45:09 -07009999 int ret;
10000
Alan Chen0f29e972019-09-04 12:04:22 -070010001 ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev);
10002 if (ret)
10003 return ret;
Alan Chene523cd92019-07-15 16:45:09 -070010004
10005 ret = hdd_wlan_start_modules(hdd_ctx, false);
10006
10007 hdd_soc_idle_restart_unlock();
10008
10009 return ret;
Rajeev Kumar473f9af2019-04-05 14:25:56 -070010010}
10011
10012int hdd_psoc_idle_restart(struct device *dev)
10013{
10014 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
10015
Rajeev Kumard62104a2019-05-31 12:04:27 -070010016 if (!hdd_ctx) {
10017 hdd_err_rl("hdd ctx is null");
10018 return -EINVAL;
10019 }
10020
Rajeev Kumar473f9af2019-04-05 14:25:56 -070010021 return __hdd_psoc_idle_restart(hdd_ctx);
10022}
10023
10024int hdd_trigger_psoc_idle_restart(struct hdd_context *hdd_ctx)
Dustin Brown3ecc8782018-09-19 16:37:13 -070010025{
Jingxiang Geccd7fdc2019-06-21 16:04:55 +080010026 int ret;
10027
Dustin Brown693b5352019-01-17 10:00:31 -080010028 QDF_BUG(rtnl_is_locked());
Dustin Brown3ecc8782018-09-19 16:37:13 -070010029
Rajeev Kumar473f9af2019-04-05 14:25:56 -070010030 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
10031 hdd_psoc_idle_timer_stop(hdd_ctx);
10032 hdd_info("Driver modules already Enabled");
10033 return 0;
10034 }
10035
Alan Chen0f29e972019-09-04 12:04:22 -070010036 ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev);
10037 if (ret)
10038 return ret;
Jingxiang Geccd7fdc2019-06-21 16:04:55 +080010039 ret = pld_idle_restart(hdd_ctx->parent_dev, hdd_psoc_idle_restart);
Alan Chene523cd92019-07-15 16:45:09 -070010040 hdd_soc_idle_restart_unlock();
Rajeev Kumar473f9af2019-04-05 14:25:56 -070010041
Jingxiang Geccd7fdc2019-06-21 16:04:55 +080010042 return ret;
Dustin Brown3ecc8782018-09-19 16:37:13 -070010043}
10044
10045/**
10046 * hdd_psoc_idle_timeout_callback() - Handler for psoc idle timeout
10047 * @priv: pointer to hdd context
10048 *
10049 * Return: None
10050 */
10051static void hdd_psoc_idle_timeout_callback(void *priv)
10052{
Alan Chen5b19c212019-07-19 10:44:42 -070010053 int ret;
Dustin Brown3ecc8782018-09-19 16:37:13 -070010054 struct hdd_context *hdd_ctx = priv;
10055
10056 if (wlan_hdd_validate_context(hdd_ctx))
10057 return;
10058
Rajeev Kumar473f9af2019-04-05 14:25:56 -070010059 hdd_info("Psoc idle timeout elapsed; starting psoc shutdown");
10060
Alan Chen5b19c212019-07-19 10:44:42 -070010061 ret = pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown);
10062 if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) {
10063 hdd_debug("System suspend in progress. Restart idle shutdown timer");
10064 hdd_psoc_idle_timer_start(hdd_ctx);
10065 }
Alan Chen50582ca2019-09-12 15:45:21 -070010066
10067 /* Clear the recovery flag for PCIe discrete soc after idle shutdown*/
10068 if (PLD_BUS_TYPE_PCIE == pld_get_bus_type(hdd_ctx->parent_dev))
10069 cds_set_recovery_in_progress(false);
Dustin Brown3ecc8782018-09-19 16:37:13 -070010070}
10071
Nirav Shaheb017be2018-02-15 11:20:58 +053010072#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10073static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
10074{
10075 wlan_logging_set_log_to_console(hdd_ctx->config->
10076 wlan_logging_to_console);
10077 wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable);
10078}
10079#else
10080static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
10081{ }
10082#endif
10083
Dundi Raviteja8e338282018-09-25 17:16:04 +053010084#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
10085static void hdd_init_wlan_logging_params(struct hdd_config *config,
10086 struct wlan_objmgr_psoc *psoc)
10087{
10088 config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT);
10089
10090 config->wlan_logging_to_console =
10091 cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT);
Hangtian Zhuc7642602019-09-11 17:47:43 +080010092 config->host_log_custom_nl_proto =
10093 cfg_get(psoc, CFG_HOST_LOG_CUSTOM_NETLINK_PROTO);
Dundi Raviteja8e338282018-09-25 17:16:04 +053010094}
10095#else
10096static void hdd_init_wlan_logging_params(struct hdd_config *config,
10097 struct wlan_objmgr_psoc *psoc)
10098{
10099}
10100#endif
10101
10102#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
10103static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
10104 struct wlan_objmgr_psoc *psoc)
10105{
10106 config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN);
10107}
10108#else
10109static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
10110 struct wlan_objmgr_psoc *psoc)
10111{
10112}
10113#endif
10114
10115#ifndef REMOVE_PKT_LOG
10116static void hdd_init_packet_log(struct hdd_config *config,
10117 struct wlan_objmgr_psoc *psoc)
10118{
10119 config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG);
10120}
10121#else
10122static void hdd_init_packet_log(struct hdd_config *config,
10123 struct wlan_objmgr_psoc *psoc)
10124{
10125}
10126#endif
10127
Sandeep Puligilla43b6d1a2018-12-03 09:16:13 -080010128#ifdef ENABLE_MTRACE_LOG
10129static void hdd_init_mtrace_log(struct hdd_config *config,
10130 struct wlan_objmgr_psoc *psoc)
10131{
10132 config->enable_mtrace = cfg_get(psoc, CFG_ENABLE_MTRACE);
10133}
10134#else
10135static void hdd_init_mtrace_log(struct hdd_config *config,
10136 struct wlan_objmgr_psoc *psoc)
10137{
10138}
10139#endif
10140
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +053010141#ifdef FEATURE_RUNTIME_PM
10142static void hdd_init_runtime_pm(struct hdd_config *config,
10143 struct wlan_objmgr_psoc *psoc)
10144{
10145 config->runtime_pm = cfg_get(psoc, CFG_ENABLE_RUNTIME_PM);
10146}
10147#else
10148static void hdd_init_runtime_pm(struct hdd_config *config,
10149 struct wlan_objmgr_psoc *psoc)
10150
10151{
10152}
10153#endif
10154
10155#ifdef FEATURE_WLAN_DYNAMIC_CVM
10156static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
10157 struct wlan_objmgr_psoc *psoc)
10158{
10159 config->vc_mode_cfg_bitmap = cfg_get(psoc, CFG_VC_MODE_BITMAP);
10160}
10161#else
10162static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
10163 struct wlan_objmgr_psoc *psoc)
10164{
10165}
10166#endif
10167
gaurank kathpalia566c81b2019-02-20 14:31:45 +053010168#ifdef DHCP_SERVER_OFFLOAD
10169static void
10170hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx)
10171{
10172 uint8_t num_entries;
10173
10174 hdd_ctx->config->dhcp_server_ip.is_dhcp_server_ip_valid = true;
10175 hdd_string_to_u8_array(cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME),
10176 hdd_ctx->config->dhcp_server_ip.dhcp_server_ip,
10177 &num_entries, IPADDR_NUM_ENTRIES);
10178
10179 if (num_entries != IPADDR_NUM_ENTRIES) {
10180 hdd_err("Incorrect IP address (%s) assigned for DHCP server!",
10181 cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME));
10182 hdd_config->dhcp_server_ip.is_dhcp_server_ip_valid = false;
10183 }
10184}
10185#else
10186static void
10187hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx)
10188{
10189}
10190#endif
10191
Dundi Raviteja8e338282018-09-25 17:16:04 +053010192/**
10193 * hdd_cfg_params_init() - Initialize hdd params in hdd_config strucuture
10194 * @hdd_ctx - Pointer to HDD context
10195 *
10196 * Return: None
10197 */
10198static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
10199{
10200 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
10201 struct hdd_config *config = hdd_ctx->config;
Dundi Raviteja8e338282018-09-25 17:16:04 +053010202 if (!psoc) {
10203 hdd_err("Invalid psoc");
10204 return;
10205 }
10206
10207 if (!config) {
10208 hdd_err("Invalid hdd config");
10209 return;
10210 }
10211
gaurank kathpalia43c52622019-02-11 12:30:05 +053010212 config->dot11Mode = cfg_get(psoc, CFG_HDD_DOT11_MODE);
Dundi Raviteja8e338282018-09-25 17:16:04 +053010213 config->bug_on_reinit_failure = cfg_get(psoc,
10214 CFG_BUG_ON_REINIT_FAILURE);
10215
10216 config->is_ramdump_enabled = cfg_get(psoc,
10217 CFG_ENABLE_RAMDUMP_COLLECTION);
10218
10219 config->iface_change_wait_time = cfg_get(psoc,
10220 CFG_INTERFACE_CHANGE_WAIT);
10221
10222 config->multicast_host_fw_msgs = cfg_get(psoc,
10223 CFG_MULTICAST_HOST_FW_MSGS);
10224
10225 config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL);
Dundi Raviteja8e338282018-09-25 17:16:04 +053010226 config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT);
10227 config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG);
sheenam monga67ecb072019-09-20 11:25:23 +053010228 config->operating_chan_freq = cfg_get(psoc, CFG_OPERATING_FREQUENCY);
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +053010229 config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE);
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +053010230 qdf_str_lcopy(config->enable_concurrent_sta,
10231 cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA),
10232 CFG_CONCURRENT_IFACE_MAX_LEN);
10233 qdf_str_lcopy(config->dbs_scan_selection,
10234 cfg_get(psoc, CFG_DBS_SCAN_SELECTION),
10235 CFG_DBS_SCAN_PARAM_LENGTH);
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +053010236 config->inform_bss_rssi_raw = cfg_get(psoc, CFG_INFORM_BSS_RSSI_RAW);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010237 config->mac_provision = cfg_get(psoc, CFG_ENABLE_MAC_PROVISION);
10238 config->provisioned_intf_pool =
10239 cfg_get(psoc, CFG_PROVISION_INTERFACE_POOL);
10240 config->derived_intf_pool = cfg_get(psoc, CFG_DERIVED_INTERFACE_POOL);
Sourav Mohapatra58841062018-11-19 16:33:27 +053010241 config->action_oui_enable = cfg_get(psoc, CFG_ENABLE_ACTION_OUI);
Jeff Johnson15a88ac2019-03-11 14:35:25 -070010242 config->advertise_concurrent_operation =
Sandeep Puligilladc6d68a2019-01-04 16:57:12 -080010243 cfg_get(psoc,
10244 CFG_ADVERTISE_CONCURRENT_OPERATION);
Sourav Mohapatra58841062018-11-19 16:33:27 +053010245 qdf_str_lcopy(config->action_oui_str[0],
10246 cfg_get(psoc, CFG_ACTION_OUI_CONNECT_1X1),
10247 ACTION_OUI_MAX_STR_LEN);
10248 qdf_str_lcopy(config->action_oui_str[1],
10249 cfg_get(psoc, CFG_ACTION_OUI_ITO_EXTENSION),
10250 ACTION_OUI_MAX_STR_LEN);
10251 qdf_str_lcopy(config->action_oui_str[2],
10252 cfg_get(psoc, CFG_ACTION_OUI_CCKM_1X1),
10253 ACTION_OUI_MAX_STR_LEN);
10254 qdf_str_lcopy(config->action_oui_str[3],
10255 cfg_get(psoc, CFG_ACTION_OUI_ITO_ALTERNATE),
10256 ACTION_OUI_MAX_STR_LEN);
10257 qdf_str_lcopy(config->action_oui_str[4],
10258 cfg_get(psoc, CFG_ACTION_OUI_SWITCH_TO_11N_MODE),
10259 ACTION_OUI_MAX_STR_LEN);
10260 qdf_str_lcopy(config->action_oui_str[5],
10261 cfg_get(psoc,
10262 CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN),
10263 ACTION_OUI_MAX_STR_LEN);
Rajeev Kumar Sirasanagandlad7987f12018-12-08 23:24:04 +053010264 qdf_str_lcopy(config->action_oui_str[6],
10265 cfg_get(psoc,
10266 CFG_ACTION_OUI_DISABLE_AGGRESSIVE_TX),
10267 ACTION_OUI_MAX_STR_LEN);
Yeshwanth Sriram Guntuka22ed8002019-05-07 15:08:09 +053010268 qdf_str_lcopy(config->action_oui_str[ACTION_OUI_FORCE_MAX_NSS],
10269 cfg_get(psoc, CFG_ACTION_OUI_FORCE_MAX_NSS),
Paul Zhangd34b5752019-10-09 11:22:32 +080010270 ACTION_OUI_MAX_STR_LEN);
10271 qdf_str_lcopy(config->action_oui_str
10272 [ACTION_OUI_DISABLE_AGGRESSIVE_EDCA],
10273 cfg_get(psoc,
10274 CFG_ACTION_OUI_DISABLE_AGGRESSIVE_EDCA),
10275 ACTION_OUI_MAX_STR_LEN);
Sourav Mohapatra9e014cf2018-12-11 09:39:33 +053010276 config->enable_rtt_support = cfg_get(psoc, CFG_ENABLE_RTT_SUPPORT);
Sandeep Puligillaefeb4a92019-01-08 00:06:51 -080010277 config->is_unit_test_framework_enabled =
10278 cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK);
Ashish Kumar Dhanotiyad63d6862019-03-14 18:54:10 +053010279 config->disable_channel = cfg_get(psoc, CFG_ENABLE_DISABLE_CHANNEL);
Ashish Kumar Dhanotiya95498182019-04-29 13:59:20 +053010280 config->sar_version = cfg_get(psoc, CFG_SAR_VERSION);
Rajeev Kumar3a7c3402019-05-02 16:02:20 -070010281 config->is_wow_disabled = cfg_get(psoc, CFG_WOW_DISABLE);
Dundi Raviteja8e338282018-09-25 17:16:04 +053010282
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +053010283 hdd_init_vc_mode_cfg_bitmap(config, psoc);
10284 hdd_init_runtime_pm(config, psoc);
Dundi Raviteja8e338282018-09-25 17:16:04 +053010285 hdd_init_wlan_auto_shutdown(config, psoc);
10286 hdd_init_wlan_logging_params(config, psoc);
10287 hdd_init_packet_log(config, psoc);
Sandeep Puligilla43b6d1a2018-12-03 09:16:13 -080010288 hdd_init_mtrace_log(config, psoc);
gaurank kathpalia566c81b2019-02-20 14:31:45 +053010289 hdd_init_dhcp_server_ip(hdd_ctx);
jitiphil869b9f72018-09-25 17:14:01 +053010290 hdd_dp_cfg_update(psoc, hdd_ctx);
Dundi Raviteja8e338282018-09-25 17:16:04 +053010291}
10292
Dustin Brown623e7e32018-09-05 14:27:50 -070010293struct hdd_context *hdd_context_create(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010294{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010295 QDF_STATUS status;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010296 int ret = 0;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010297 struct hdd_context *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010298
Dustin Brown491d54b2018-03-14 12:39:11 -070010299 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010300
Dustin Brown92bd8382018-10-31 15:49:46 -070010301 hdd_ctx = hdd_cfg80211_wiphy_alloc();
10302 if (!hdd_ctx) {
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010303 ret = -ENOMEM;
10304 goto err_out;
10305 }
10306
Dustin Brown8d8ab302019-03-05 16:19:36 -080010307 status = qdf_delayed_work_create(&hdd_ctx->psoc_idle_timeout_work,
10308 hdd_psoc_idle_timeout_callback,
10309 hdd_ctx);
10310 if (QDF_IS_STATUS_ERROR(status)) {
10311 ret = qdf_status_to_os_return(status);
10312 goto wiphy_dealloc;
10313 }
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +053010314
Prashanth Bhatta527fd752016-04-28 12:35:23 -070010315 hdd_ctx->parent_dev = dev;
Jeff Johnson995fd512019-03-06 08:45:10 -080010316 hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010317
Anurag Chouhan600c3a02016-03-01 10:33:54 +053010318 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
Min Liu74a1a502018-10-10 19:59:07 +080010319 if (!hdd_ctx->config) {
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010320 ret = -ENOMEM;
10321 goto err_free_hdd_context;
10322 }
10323
Dustin Brown84f46ea2018-02-15 11:57:36 -080010324 status = cfg_parse(WLAN_INI_FILE);
nakul kachhwahaed09dc92019-05-21 14:20:06 +053010325 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Brown84f46ea2018-02-15 11:57:36 -080010326 hdd_err("Failed to parse cfg %s; status:%d\n",
10327 WLAN_INI_FILE, status);
nakul kachhwahaed09dc92019-05-21 14:20:06 +053010328 ret = qdf_status_to_os_return(status);
10329 goto err_free_config;
10330 }
Dustin Brown84f46ea2018-02-15 11:57:36 -080010331
Dundi Ravitejafb9357a2018-09-25 12:16:03 +053010332 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID);
10333 if (ret) {
Dundi Raviteja8e338282018-09-25 17:16:04 +053010334 QDF_DEBUG_PANIC("Psoc creation fails!");
nakul kachhwahaed09dc92019-05-21 14:20:06 +053010335 goto err_release_store;
Dundi Ravitejafb9357a2018-09-25 12:16:03 +053010336 }
10337
Dundi Raviteja8e338282018-09-25 17:16:04 +053010338 hdd_cfg_params_init(hdd_ctx);
10339
Dustin Brown4bbd5462019-03-22 11:18:13 -070010340 /* apply multiplier config, if not already set via module parameter */
10341 if (qdf_timer_get_multiplier() == 1)
10342 qdf_timer_set_multiplier(cfg_get(hdd_ctx->psoc,
10343 CFG_TIMER_MULTIPLIER));
Dustin Browna9a84522019-02-04 12:25:40 -080010344 hdd_debug("set timer multiplier: %u", qdf_timer_get_multiplier());
Dustin Brown7f939932017-05-18 15:02:17 -070010345
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010346 cds_set_fatal_event(cfg_get(hdd_ctx->psoc,
10347 CFG_ENABLE_FATAL_EVENT_TRIGGER));
Abhishek Singh5ea86532016-04-27 14:10:53 +053010348
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010349 hdd_override_ini_config(hdd_ctx);
10350
Prashanth Bhatta527fd752016-04-28 12:35:23 -070010351 ret = hdd_context_init(hdd_ctx);
10352
10353 if (ret)
Dundi Ravitejafb9357a2018-09-25 12:16:03 +053010354 goto err_hdd_objmgr_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -070010355
Nirav Shah6aeecf92019-02-13 14:05:03 +053010356 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE ||
10357 hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010358 goto skip_multicast_logging;
10359
10360 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -070010361 ret = hdd_init_netlink_services(hdd_ctx);
10362 if (ret)
Jingxiang Ge645300a2019-11-15 12:30:27 +080010363 goto err_deinit_hdd_context;
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -070010364
Nirav Shaheb017be2018-02-15 11:20:58 +053010365 hdd_set_wlan_logging(hdd_ctx);
Nirav Shahed34b212016-04-25 10:59:16 +053010366
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010367skip_multicast_logging:
10368 hdd_set_trace_level_for_each(hdd_ctx);
10369
Rajeev Kumar493a31b2017-09-29 14:01:24 -070010370 cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx);
10371
Dustin Browne74003f2018-03-14 12:51:58 -070010372 hdd_exit();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -070010373
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010374 return hdd_ctx;
10375
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -070010376err_deinit_hdd_context:
10377 hdd_context_deinit(hdd_ctx);
10378
Dundi Ravitejafb9357a2018-09-25 12:16:03 +053010379err_hdd_objmgr_destroy:
10380 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
10381
nakul kachhwahaed09dc92019-05-21 14:20:06 +053010382err_release_store:
10383 cfg_release();
10384
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010385err_free_config:
Anurag Chouhan600c3a02016-03-01 10:33:54 +053010386 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010387
10388err_free_hdd_context:
Dustin Brown8d8ab302019-03-05 16:19:36 -080010389 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
10390
10391wiphy_dealloc:
Rajeev Kumarfa55a692018-01-09 14:12:41 -080010392 wiphy_free(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010393
10394err_out:
10395 return ERR_PTR(ret);
10396}
10397
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010398/**
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010399 * hdd_start_station_adapter()- Start the Station Adapter
10400 * @adapter: HDD adapter
10401 *
10402 * This function initializes the adapter for the station mode.
10403 *
10404 * Return: 0 on success or errno on failure.
10405 */
Jeff Johnson9d295242017-08-29 14:39:48 -070010406int hdd_start_station_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010407{
10408 QDF_STATUS status;
Paul Zhang1ef2b7c2019-10-31 16:09:55 +080010409 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Krunal Sonib51eec72017-11-20 21:53:01 -080010410 int ret;
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010411
Dustin Brownfdf17c12018-03-14 12:55:34 -070010412 hdd_enter_dev(adapter->dev);
Krunal Sonib51eec72017-11-20 21:53:01 -080010413 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
10414 hdd_err("session is already opened, %d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -080010415 adapter->vdev_id);
Krunal Sonib51eec72017-11-20 21:53:01 -080010416 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
10417 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010418
Arun Kumar Khandavalli42b44872019-10-21 19:02:04 +053010419 ret = hdd_vdev_create(adapter);
Krunal Sonib51eec72017-11-20 21:53:01 -080010420 if (ret) {
10421 hdd_err("failed to create vdev: %d", ret);
10422 return ret;
10423 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010424 status = hdd_init_station_mode(adapter);
10425
10426 if (QDF_STATUS_SUCCESS != status) {
10427 hdd_err("Error Initializing station mode: %d", status);
10428 return qdf_status_to_os_return(status);
10429 }
10430
Arun Khandavallifae92942016-08-01 13:31:08 +053010431 hdd_register_tx_flow_control(adapter,
10432 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +080010433 hdd_tx_resume_cb,
10434 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +053010435
Visweswara Tanukub5a61242019-03-26 12:24:13 +053010436 hdd_register_hl_netdev_fc_timer(adapter,
10437 hdd_tx_resume_timer_expired_handler);
10438
Paul Zhang1ef2b7c2019-10-31 16:09:55 +080010439 status = sme_set_wlm_latency_level(hdd_ctx->mac_handle,
10440 adapter->vdev_id,
10441 adapter->latency_level);
10442 if (QDF_IS_STATUS_ERROR(status))
10443 hdd_warn("set latency level failed, %u", status);
10444
Dustin Browne74003f2018-03-14 12:51:58 -070010445 hdd_exit();
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053010446
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010447 return 0;
10448}
10449
10450/**
10451 * hdd_start_ap_adapter()- Start AP Adapter
10452 * @adapter: HDD adapter
10453 *
10454 * This function initializes the adapter for the AP mode.
10455 *
10456 * Return: 0 on success errno on failure.
10457 */
Jeff Johnson9d295242017-08-29 14:39:48 -070010458int hdd_start_ap_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010459{
10460 QDF_STATUS status;
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -080010461 bool is_ssr = false;
Krunal Sonib51eec72017-11-20 21:53:01 -080010462 int ret;
Naveen Rawat1af09392018-01-03 17:28:21 -080010463 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Arif Hussainbd5194c2018-11-27 19:01:15 -080010464 uint32_t fine_time_meas_cap = 0;
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010465
Dustin Brown491d54b2018-03-14 12:39:11 -070010466 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010467
Krunal Sonib51eec72017-11-20 21:53:01 -080010468 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
10469 hdd_err("session is already opened, %d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -080010470 adapter->vdev_id);
Krunal Sonib51eec72017-11-20 21:53:01 -080010471 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
10472 }
10473 /*
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -080010474 * In SSR case no need to create new sap context.
10475 * Otherwise create sap context first and then create
10476 * vdev as while creating the vdev, driver needs to
10477 * register SAP callback and that callback uses sap context
Krunal Sonib51eec72017-11-20 21:53:01 -080010478 */
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -080010479 if (adapter->session.ap.sap_context) {
10480 is_ssr = true;
10481 } else if (!hdd_sap_create_ctx(adapter)) {
Krunal Sonib51eec72017-11-20 21:53:01 -080010482 hdd_err("sap creation failed");
10483 return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
10484 }
10485
Arun Kumar Khandavalli42b44872019-10-21 19:02:04 +053010486 ret = hdd_vdev_create(adapter);
Krunal Sonib51eec72017-11-20 21:53:01 -080010487 if (ret) {
10488 hdd_err("failed to create vdev, status:%d", ret);
10489 hdd_sap_destroy_ctx(adapter);
10490 return ret;
10491 }
Naveen Rawat1af09392018-01-03 17:28:21 -080010492
Arif Hussainbd5194c2018-11-27 19:01:15 -080010493 if (adapter->device_mode == QDF_SAP_MODE) {
10494 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
10495 &fine_time_meas_cap);
Jeff Johnson5a6fc962019-02-04 14:20:25 -080010496 sme_cli_set_command(adapter->vdev_id,
Naveen Rawat1af09392018-01-03 17:28:21 -080010497 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE,
Arif Hussainbd5194c2018-11-27 19:01:15 -080010498 (bool)(fine_time_meas_cap & WMI_FW_AP_RTT_RESPR),
Naveen Rawat1af09392018-01-03 17:28:21 -080010499 VDEV_CMD);
Arif Hussainbd5194c2018-11-27 19:01:15 -080010500 }
Naveen Rawat1af09392018-01-03 17:28:21 -080010501
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -080010502 status = hdd_init_ap_mode(adapter, is_ssr);
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010503
10504 if (QDF_STATUS_SUCCESS != status) {
10505 hdd_err("Error Initializing the AP mode: %d", status);
10506 return qdf_status_to_os_return(status);
10507 }
10508
Arun Khandavallifae92942016-08-01 13:31:08 +053010509 hdd_register_tx_flow_control(adapter,
10510 hdd_softap_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +080010511 hdd_softap_tx_resume_cb,
10512 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +053010513
Visweswara Tanukub5a61242019-03-26 12:24:13 +053010514 hdd_register_hl_netdev_fc_timer(adapter,
10515 hdd_tx_resume_timer_expired_handler);
10516
Dustin Browne74003f2018-03-14 12:51:58 -070010517 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010518 return 0;
10519}
10520
hangtianb9c91362019-06-07 10:39:38 +080010521#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010522/**
10523 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
10524 * @cds_cfg: CDS Configuration
10525 * @hdd_ctx: Pointer to hdd context
10526 *
10527 * Return: none
10528 */
10529static inline void hdd_txrx_populate_cds_config(struct cds_config_info
10530 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010531 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010532{
10533 cds_cfg->tx_flow_stop_queue_th =
jitiphil47c3d9a2018-11-08 18:30:55 +053010534 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010535 cds_cfg->tx_flow_start_queue_offset =
jitiphil47c3d9a2018-11-08 18:30:55 +053010536 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
Mohit Khanna70322002018-05-15 19:21:32 -070010537 /* configuration for DP RX Threads */
10538 cds_cfg->enable_dp_rx_threads = hdd_ctx->enable_dp_rx_threads;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010539}
hangtianb9c91362019-06-07 10:39:38 +080010540#else
10541static inline void hdd_txrx_populate_cds_config(struct cds_config_info
10542 *cds_cfg,
10543 struct hdd_context *hdd_ctx)
10544{
10545}
10546#endif
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010547
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010548/**
10549 * hdd_update_cds_config() - API to update cds configuration parameters
10550 * @hdd_ctx: HDD Context
10551 *
10552 * Return: 0 for Success, errno on failure
10553 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010554static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010555{
10556 struct cds_config_info *cds_cfg;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053010557 int value;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053010558 uint8_t band_capability;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010559 uint8_t ito_repeat_count;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053010560 bool crash_inject;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010561 bool self_recovery;
10562 bool fw_timeout_crash;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053010563 QDF_STATUS status;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010564
Min Liu74a1a502018-10-10 19:59:07 +080010565 cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg));
10566 if (!cds_cfg)
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010567 return -ENOMEM;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010568
Srinivas Girigowda35b00312017-06-27 21:52:03 -070010569 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
Bala Venkatesh46e29032018-11-14 18:24:55 +053010570 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
10571 &cds_cfg->sta_maxlimod_dtim);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010572
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010573 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
Vignesh Viswanathana851d752018-10-03 19:44:38 +053010574 if (QDF_IS_STATUS_ERROR(status)) {
10575 hdd_err("Failed to get crash inject ini config");
10576 goto exit;
10577 }
10578
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010579 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
10580 if (QDF_IS_STATUS_ERROR(status)) {
10581 hdd_err("Failed to get self recovery ini config");
10582 goto exit;
10583 }
10584
10585 status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc,
10586 &fw_timeout_crash);
10587 if (QDF_IS_STATUS_ERROR(status)) {
10588 hdd_err("Failed to get fw timeout crash ini config");
10589 goto exit;
10590 }
10591
10592 status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc,
10593 &ito_repeat_count);
10594 if (QDF_IS_STATUS_ERROR(status)) {
10595 hdd_err("Failed to get ITO repeat count ini config");
10596 goto exit;
10597 }
10598
Vignesh Viswanathana851d752018-10-03 19:44:38 +053010599 cds_cfg->force_target_assert_enabled = crash_inject;
SaidiReddy Yenugacc733af2016-11-09 17:45:42 +053010600
Dustin Brown05d81302018-09-11 16:49:22 -070010601 ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053010602 cds_cfg->ap_maxoffload_peers = value;
Dustin Brown05d81302018-09-11 16:49:22 -070010603 ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053010604 &value);
10605 cds_cfg->ap_maxoffload_reorderbuffs = value;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010606
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010607 cds_cfg->reorder_offload =
jitiphil47c3d9a2018-11-08 18:30:55 +053010608 cfg_get(hdd_ctx->psoc, CFG_DP_REORDER_OFFLOAD_SUPPORT);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010609
10610 /* IPA micro controller data path offload resource config item */
Sravan Kumar Kairam5214f652018-03-13 09:52:31 +053010611 cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled();
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010612
Jeff Johnsone2ba3cd2017-10-30 20:02:09 -070010613 cds_cfg->enable_rxthread = hdd_ctx->enable_rxthread;
Dustin Brown05d81302018-09-11 16:49:22 -070010614 ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053010615 cds_cfg->max_station = value;
Naveen Rawat64e477e2016-05-20 10:34:56 -070010616 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
Orhan K AKYILDIZ30e8cbc2017-08-11 18:00:28 -070010617 cds_cfg->max_msdus_per_rxinorderind =
jitiphil8e15ea62018-11-16 18:05:34 +053010618 cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND);
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010619 cds_cfg->self_recovery_enabled = self_recovery;
10620 cds_cfg->fw_timeout_crash = fw_timeout_crash;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010621
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010622 cds_cfg->ito_repeat_count = ito_repeat_count;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053010623
10624 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
10625 if (QDF_IS_STATUS_ERROR(status))
10626 goto exit;
10627
10628 cds_cfg->bandcapability = band_capability;
Rachit Kankane0106e382018-05-16 18:59:28 +053010629 cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs;
Jiani Liu6d3b6a12019-05-08 15:15:06 +080010630 cds_cfg->enable_tx_compl_tsf64 =
10631 hdd_tsf_is_tsf64_tx_set(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010632 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
Jeff Johnson9078bdc2016-09-23 17:18:11 -070010633 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010634 cds_init_ini_config(cds_cfg);
10635 return 0;
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +053010636
10637exit:
10638 qdf_mem_free(cds_cfg);
10639 return -EINVAL;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010640}
10641
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010642/**
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080010643 * hdd_update_user_config() - API to update user configuration
10644 * parameters to obj mgr which are used by multiple components
10645 * @hdd_ctx: HDD Context
10646 *
10647 * Return: 0 for Success, errno on failure
10648 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010649static int hdd_update_user_config(struct hdd_context *hdd_ctx)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080010650{
10651 struct wlan_objmgr_psoc_user_config *user_config;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053010652 uint8_t band_capability;
10653 QDF_STATUS status;
Abhinav Kumard4d6eb72018-12-04 20:30:37 +053010654 bool value = false;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053010655
10656 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
10657 if (QDF_IS_STATUS_ERROR(status))
10658 return -EIO;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080010659
10660 user_config = qdf_mem_malloc(sizeof(*user_config));
Min Liu74a1a502018-10-10 19:59:07 +080010661 if (!user_config)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080010662 return -ENOMEM;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080010663
10664 user_config->dot11_mode = hdd_ctx->config->dot11Mode;
Abhinav Kumard4d6eb72018-12-04 20:30:37 +053010665 status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value);
10666 if (!QDF_IS_STATUS_SUCCESS(status))
10667 hdd_err("Invalid 11d_enable flag");
10668 user_config->is_11d_support_enabled = value;
10669
10670 value = false;
10671 status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value);
10672 if (!QDF_IS_STATUS_SUCCESS(status))
10673 hdd_err("Invalid 11h_enable flag");
10674 user_config->is_11h_support_enabled = value;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053010675 user_config->band_capability = band_capability;
Dustin Brown1dbefe62018-09-11 16:32:03 -070010676 wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080010677
10678 qdf_mem_free(user_config);
10679 return 0;
10680}
10681
10682/**
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010683 * hdd_init_thermal_info - Initialize thermal level
10684 * @hdd_ctx: HDD context
10685 *
10686 * Initialize thermal level at SME layer and set the thermal level callback
10687 * which would be called when a configured thermal threshold is hit.
10688 *
10689 * Return: 0 on success and errno on failure
10690 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010691static int hdd_init_thermal_info(struct hdd_context *hdd_ctx)
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010692{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010693 QDF_STATUS status;
Manikandan Mohan9045e2e2018-11-26 16:44:19 -080010694 mac_handle_t mac_handle = hdd_ctx->mac_handle;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010695
Manikandan Mohan9045e2e2018-11-26 16:44:19 -080010696 status = sme_init_thermal_info(mac_handle);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010697
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010698 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanc5548422016-02-24 18:33:27 +053010699 return qdf_status_to_os_return(status);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010700
Jeff Johnson16528362018-06-14 12:34:16 -070010701 sme_add_set_thermal_level_callback(mac_handle,
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010702 hdd_set_thermal_level_cb);
10703
10704 return 0;
10705
10706}
10707
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010708#if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
10709/**
10710 * hdd_hold_rtnl_lock - Hold RTNL lock
10711 *
10712 * Hold RTNL lock
10713 *
10714 * Return: True if held and false otherwise
10715 */
10716static inline bool hdd_hold_rtnl_lock(void)
10717{
10718 rtnl_lock();
10719 return true;
10720}
10721
10722/**
10723 * hdd_release_rtnl_lock - Release RTNL lock
10724 *
10725 * Release RTNL lock
10726 *
10727 * Return: None
10728 */
10729static inline void hdd_release_rtnl_lock(void)
10730{
10731 rtnl_unlock();
10732}
10733#else
10734static inline bool hdd_hold_rtnl_lock(void) { return false; }
10735static inline void hdd_release_rtnl_lock(void) { }
10736#endif
10737
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010738#if !defined(REMOVE_PKT_LOG)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010739
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010740/* MAX iwpriv command support */
10741#define PKTLOG_SET_BUFF_SIZE 3
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010742#define PKTLOG_CLEAR_BUFF 4
Venkata Sharath Chandra Manchala27e44902019-01-28 11:29:18 -080010743/* Set Maximum pktlog file size to 64MB */
10744#define MAX_PKTLOG_SIZE 64
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010745
10746/**
10747 * hdd_pktlog_set_buff_size() - set pktlog buffer size
10748 * @hdd_ctx: hdd context
10749 * @set_value2: pktlog buffer size value
10750 *
10751 *
10752 * Return: 0 for success or error.
10753 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010754static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010755{
10756 struct sir_wifi_start_log start_log = { 0 };
10757 QDF_STATUS status;
10758
10759 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10760 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
10761 start_log.ini_triggered = cds_is_packet_log_enabled();
10762 start_log.user_triggered = 1;
10763 start_log.size = set_value2;
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010764 start_log.is_pktlog_buff_clear = false;
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010765
Jeff Johnson16528362018-06-14 12:34:16 -070010766 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010767 if (!QDF_IS_STATUS_SUCCESS(status)) {
10768 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010769 hdd_exit();
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010770 return -EINVAL;
10771 }
10772
10773 return 0;
10774}
10775
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010776/**
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010777 * hdd_pktlog_clear_buff() - clear pktlog buffer
10778 * @hdd_ctx: hdd context
10779 *
10780 * Return: 0 for success or error.
10781 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010782static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010783{
10784 struct sir_wifi_start_log start_log;
10785 QDF_STATUS status;
10786
10787 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10788 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
10789 start_log.ini_triggered = cds_is_packet_log_enabled();
10790 start_log.user_triggered = 1;
10791 start_log.size = 0;
10792 start_log.is_pktlog_buff_clear = true;
10793
Jeff Johnson16528362018-06-14 12:34:16 -070010794 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010795 if (!QDF_IS_STATUS_SUCCESS(status)) {
10796 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010797 hdd_exit();
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010798 return -EINVAL;
10799 }
10800
10801 return 0;
10802}
10803
10804
10805/**
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010806 * hdd_process_pktlog_command() - process pktlog command
10807 * @hdd_ctx: hdd context
10808 * @set_value: value set by user
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010809 * @set_value2: pktlog buffer size value
10810 *
10811 * This function process pktlog command.
10812 * set_value2 only matters when set_value is 3 (set buff size)
10813 * otherwise we ignore it.
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010814 *
10815 * Return: 0 for success or error.
10816 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010817int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010818 int set_value2)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010819{
10820 int ret;
10821 bool enable;
10822 uint8_t user_triggered = 0;
10823
10824 ret = wlan_hdd_validate_context(hdd_ctx);
10825 if (0 != ret)
10826 return ret;
10827
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010828 hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010829
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010830 if (set_value > PKTLOG_CLEAR_BUFF) {
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010831 hdd_err("invalid pktlog value %d", set_value);
10832 return -EINVAL;
10833 }
10834
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010835 if (set_value == PKTLOG_SET_BUFF_SIZE) {
10836 if (set_value2 <= 0) {
10837 hdd_err("invalid pktlog size %d", set_value2);
10838 return -EINVAL;
10839 } else if (set_value2 > MAX_PKTLOG_SIZE) {
Venkata Sharath Chandra Manchala27e44902019-01-28 11:29:18 -080010840 hdd_err_rl("Pktlog size is large. max value is %uMB.",
10841 MAX_PKTLOG_SIZE);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010842 return -EINVAL;
10843 }
10844 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010845 } else if (set_value == PKTLOG_CLEAR_BUFF) {
10846 return hdd_pktlog_clear_buff(hdd_ctx);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010847 }
10848
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010849 /*
10850 * set_value = 0 then disable packetlog
10851 * set_value = 1 enable packetlog forcefully
10852 * set_vlaue = 2 then disable packetlog if disabled through ini or
10853 * enable packetlog with AUTO type.
10854 */
10855 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
10856 true : false;
10857
10858 if (1 == set_value) {
10859 enable = true;
10860 user_triggered = 1;
10861 }
10862
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010863 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010864}
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070010865
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010866/**
10867 * hdd_pktlog_enable_disable() - Enable/Disable packet logging
10868 * @hdd_ctx: HDD context
Venkata Sharath Chandra Manchalaf0296dd2019-09-19 13:50:02 -070010869 * @enable_disable_flag: Flag to enable/disable
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010870 * @user_triggered: triggered through iwpriv
10871 * @size: buffer size to be used for packetlog
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010872 *
10873 * Return: 0 on success; error number otherwise
10874 */
Venkata Sharath Chandra Manchalaf0296dd2019-09-19 13:50:02 -070010875int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx,
10876 bool enable_disable_flag,
10877 uint8_t user_triggered, int size)
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010878{
10879 struct sir_wifi_start_log start_log;
10880 QDF_STATUS status;
10881
Venkata Sharath Chandra Manchalaf0296dd2019-09-19 13:50:02 -070010882 if (hdd_ctx->is_pktlog_enabled && enable_disable_flag)
10883 return 0;
10884
10885 if ((!hdd_ctx->is_pktlog_enabled) && (!enable_disable_flag))
10886 return 0;
10887
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010888 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10889 start_log.verbose_level =
Venkata Sharath Chandra Manchalaf0296dd2019-09-19 13:50:02 -070010890 enable_disable_flag ?
10891 WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010892 start_log.ini_triggered = cds_is_packet_log_enabled();
10893 start_log.user_triggered = user_triggered;
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010894 start_log.size = size;
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010895 start_log.is_pktlog_buff_clear = false;
Poddar, Siddartheefe3482016-09-21 18:12:59 +053010896 /*
10897 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
10898 * commands. Host uses this flag to decide whether to send pktlog
10899 * disable command to fw without sending pktlog enable command
10900 * previously. For eg, If vendor sends pktlog disable command without
10901 * sending pktlog enable command, then host discards the packet
10902 * but for iwpriv command, host will send it to fw.
10903 */
10904 start_log.is_iwpriv_command = 1;
Venkata Sharath Chandra Manchalaf0296dd2019-09-19 13:50:02 -070010905
Jeff Johnson16528362018-06-14 12:34:16 -070010906 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010907 if (!QDF_IS_STATUS_SUCCESS(status)) {
10908 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010909 hdd_exit();
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010910 return -EINVAL;
10911 }
10912
Venkata Sharath Chandra Manchalaf0296dd2019-09-19 13:50:02 -070010913 hdd_ctx->is_pktlog_enabled = enable_disable_flag;
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053010914
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010915 return 0;
10916}
10917#endif /* REMOVE_PKT_LOG */
10918
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010919void hdd_free_mac_address_lists(struct hdd_context *hdd_ctx)
10920{
10921 hdd_debug("Resetting MAC address lists");
hangtian127c9532019-01-12 13:29:07 +080010922 qdf_mem_zero(hdd_ctx->provisioned_mac_addr,
10923 sizeof(hdd_ctx->provisioned_mac_addr));
10924 qdf_mem_zero(hdd_ctx->derived_mac_addr,
10925 sizeof(hdd_ctx->derived_mac_addr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010926 hdd_ctx->num_provisioned_addr = 0;
10927 hdd_ctx->num_derived_addr = 0;
10928 hdd_ctx->provisioned_intf_addr_mask = 0;
10929 hdd_ctx->derived_intf_addr_mask = 0;
10930}
10931
Komal Seelam92fff912016-03-24 11:51:41 +053010932/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010933 * hdd_get_platform_wlan_mac_buff() - API to query platform driver
10934 * for MAC address
Komal Seelam92fff912016-03-24 11:51:41 +053010935 * @dev: Device Pointer
10936 * @num: Number of Valid Mac address
10937 *
10938 * Return: Pointer to MAC address buffer
10939 */
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010940static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
10941 uint32_t *num)
Komal Seelam92fff912016-03-24 11:51:41 +053010942{
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010943 return pld_get_wlan_mac_address(dev, num);
Komal Seelam92fff912016-03-24 11:51:41 +053010944}
Komal Seelam92fff912016-03-24 11:51:41 +053010945
10946/**
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010947 * hdd_get_platform_wlan_derived_mac_buff() - API to query platform driver
10948 * for derived MAC address
10949 * @dev: Device Pointer
10950 * @num: Number of Valid Mac address
10951 *
10952 * Return: Pointer to MAC address buffer
10953 */
10954static uint8_t *hdd_get_platform_wlan_derived_mac_buff(struct device *dev,
10955 uint32_t *num)
10956{
10957 return pld_get_wlan_derived_mac_address(dev, num);
10958}
10959
10960/**
Komal Seelam92fff912016-03-24 11:51:41 +053010961 * hdd_populate_random_mac_addr() - API to populate random mac addresses
10962 * @hdd_ctx: HDD Context
10963 * @num: Number of random mac addresses needed
10964 *
10965 * Generate random addresses using bit manipulation on the base mac address
10966 *
10967 * Return: None
10968 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010969void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
Komal Seelam92fff912016-03-24 11:51:41 +053010970{
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010971 uint32_t idx = hdd_ctx->num_derived_addr;
Komal Seelam92fff912016-03-24 11:51:41 +053010972 uint32_t iter;
Komal Seelam92fff912016-03-24 11:51:41 +053010973 uint8_t *buf = NULL;
10974 uint8_t macaddr_b3, tmp_br3;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010975 /*
10976 * Consider first provisioned mac address as source address to derive
10977 * remaining addresses
10978 */
Komal Seelam92fff912016-03-24 11:51:41 +053010979
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010980 uint8_t *src = hdd_ctx->provisioned_mac_addr[0].bytes;
10981
10982 for (iter = 0; iter < num; ++iter, ++idx) {
10983 buf = hdd_ctx->derived_mac_addr[idx].bytes;
Komal Seelam92fff912016-03-24 11:51:41 +053010984 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
10985 macaddr_b3 = buf[3];
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010986 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + idx) &
Komal Seelam92fff912016-03-24 11:51:41 +053010987 INTF_MACADDR_MASK;
10988 macaddr_b3 += tmp_br3;
10989 macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
10990 buf[0] |= 0x02;
10991 buf[3] = macaddr_b3;
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070010992 hdd_debug(QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(buf));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010993 hdd_ctx->num_derived_addr++;
Komal Seelam92fff912016-03-24 11:51:41 +053010994 }
10995}
10996
10997/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010998 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
Komal Seelam92fff912016-03-24 11:51:41 +053010999 * @hdd_ctx: HDD Context
11000 *
11001 * API to get mac addresses from platform driver and update the driver
11002 * structures and configure FW with the base mac address.
11003 * Return: int
11004 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011005static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +053011006{
11007 uint32_t no_of_mac_addr, iter;
11008 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
11009 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
11010 uint8_t *addr, *buf;
11011 struct device *dev = hdd_ctx->parent_dev;
Komal Seelam92fff912016-03-24 11:51:41 +053011012 tSirMacAddr mac_addr;
11013 QDF_STATUS status;
11014
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080011015 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
Komal Seelam92fff912016-03-24 11:51:41 +053011016
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011017 if (no_of_mac_addr == 0 || !addr) {
11018 hdd_debug("No mac configured from platform driver");
Komal Seelam92fff912016-03-24 11:51:41 +053011019 return -EINVAL;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011020 }
11021
11022 hdd_free_mac_address_lists(hdd_ctx);
Komal Seelam92fff912016-03-24 11:51:41 +053011023
11024 if (no_of_mac_addr > max_mac_addr)
11025 no_of_mac_addr = max_mac_addr;
11026
11027 qdf_mem_copy(&mac_addr, addr, mac_addr_size);
11028
11029 for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011030 buf = hdd_ctx->provisioned_mac_addr[iter].bytes;
Komal Seelam92fff912016-03-24 11:51:41 +053011031 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070011032 hdd_info("provisioned MAC Addr [%d]" QDF_MAC_ADDR_STR, iter,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070011033 QDF_MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +053011034 }
11035
Komal Seelam92fff912016-03-24 11:51:41 +053011036
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011037 hdd_ctx->num_provisioned_addr = no_of_mac_addr;
Srinivas Girigowdab841da72017-03-25 18:04:39 -070011038
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011039 if (hdd_ctx->config->mac_provision) {
11040 addr = hdd_get_platform_wlan_derived_mac_buff(dev,
11041 &no_of_mac_addr);
11042
11043 if (no_of_mac_addr == 0 || !addr)
11044 hdd_warn("No derived address from platform driver");
11045 else if (no_of_mac_addr >
11046 (max_mac_addr - hdd_ctx->num_provisioned_addr))
11047 no_of_mac_addr = (max_mac_addr -
11048 hdd_ctx->num_provisioned_addr);
11049
11050 for (iter = 0; iter < no_of_mac_addr; ++iter,
11051 addr += mac_addr_size) {
11052 buf = hdd_ctx->derived_mac_addr[iter].bytes;
11053 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070011054 hdd_debug("derived MAC Addr [%d]" QDF_MAC_ADDR_STR, iter,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070011055 QDF_MAC_ADDR_ARRAY(buf));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011056 }
11057 hdd_ctx->num_derived_addr = no_of_mac_addr;
11058 }
11059
11060 no_of_mac_addr = hdd_ctx->num_provisioned_addr +
11061 hdd_ctx->num_derived_addr;
Komal Seelam92fff912016-03-24 11:51:41 +053011062 if (no_of_mac_addr < max_mac_addr)
11063 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
11064 no_of_mac_addr);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011065
11066 status = sme_set_custom_mac_addr(mac_addr);
11067 if (!QDF_IS_STATUS_SUCCESS(status))
11068 return -EAGAIN;
11069
Komal Seelam92fff912016-03-24 11:51:41 +053011070 return 0;
11071}
11072
11073/**
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070011074 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
11075 * @hdd_ctx: HDD Context
11076 *
11077 * Update MAC address to FW. If MAC address passed by FW is invalid, host
11078 * will generate its own MAC and update it to FW.
11079 *
11080 * Return: 0 for success
11081 * Non-zero error code for failure
11082 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011083static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070011084{
Jeff Johnson374c0852019-03-10 19:02:07 -070011085 tSirMacAddr custom_mac_addr;
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070011086 QDF_STATUS status;
11087
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011088 if (hdd_ctx->num_provisioned_addr)
Jeff Johnson374c0852019-03-10 19:02:07 -070011089 qdf_mem_copy(&custom_mac_addr,
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011090 &hdd_ctx->provisioned_mac_addr[0].bytes[0],
11091 sizeof(tSirMacAddr));
11092 else
Jeff Johnson374c0852019-03-10 19:02:07 -070011093 qdf_mem_copy(&custom_mac_addr,
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011094 &hdd_ctx->derived_mac_addr[0].bytes[0],
11095 sizeof(tSirMacAddr));
Jeff Johnson374c0852019-03-10 19:02:07 -070011096 status = sme_set_custom_mac_addr(custom_mac_addr);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070011097 if (!QDF_IS_STATUS_SUCCESS(status))
11098 return -EAGAIN;
11099 return 0;
11100}
11101
11102/**
Komal Seelam92fff912016-03-24 11:51:41 +053011103 * hdd_initialize_mac_address() - API to get wlan mac addresses
11104 * @hdd_ctx: HDD Context
11105 *
11106 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
11107 * is provisioned with mac addresses, driver uses it, else it will use
11108 * wlan_mac.bin to update HW MAC addresses.
11109 *
11110 * Return: None
11111 */
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011112static int hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +053011113{
11114 QDF_STATUS status;
11115 int ret;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011116 bool update_mac_addr_to_fw = true;
Komal Seelam92fff912016-03-24 11:51:41 +053011117
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080011118 ret = hdd_platform_wlan_mac(hdd_ctx);
Jingxiang Gec2ac79b2019-09-20 09:42:45 +080011119 if (!ret) {
Dustin Brown7e761c72018-07-31 13:50:17 -070011120 hdd_info("using MAC address from platform driver");
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011121 return ret;
Jingxiang Gec2ac79b2019-09-20 09:42:45 +080011122 } else if (hdd_ctx->config->mac_provision) {
11123 hdd_err("getting MAC address from platform driver failed");
11124 return ret;
Dustin Brown7e761c72018-07-31 13:50:17 -070011125 }
Komal Seelam92fff912016-03-24 11:51:41 +053011126
11127 status = hdd_update_mac_config(hdd_ctx);
Dustin Brown7e761c72018-07-31 13:50:17 -070011128 if (QDF_IS_STATUS_SUCCESS(status)) {
11129 hdd_info("using MAC address from wlan_mac.bin");
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011130 return 0;
Dustin Brown7e761c72018-07-31 13:50:17 -070011131 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070011132
Dustin Brown7e761c72018-07-31 13:50:17 -070011133 hdd_info("using default MAC address");
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070011134
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011135 /* Use fw provided MAC */
11136 if (!qdf_is_macaddr_zero(&hdd_ctx->hw_macaddr)) {
11137 hdd_update_macaddr(hdd_ctx, hdd_ctx->hw_macaddr, false);
11138 update_mac_addr_to_fw = false;
11139 return 0;
11140 } else if (hdd_generate_macaddr_auto(hdd_ctx) != 0) {
11141 struct qdf_mac_addr mac_addr;
11142
11143 hdd_err("MAC failure from device serial no.");
Jeff Johnson51a80522018-12-11 20:19:44 -080011144 qdf_get_random_bytes(&mac_addr, sizeof(mac_addr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011145 /*
11146 * Reset multicast bit (bit-0) and set
11147 * locally-administered bit
11148 */
11149 mac_addr.bytes[0] = 0x2;
11150 hdd_update_macaddr(hdd_ctx, mac_addr, true);
11151 }
11152
11153 if (update_mac_addr_to_fw) {
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070011154 ret = hdd_update_mac_addr_to_fw(hdd_ctx);
Dustin Brown7e761c72018-07-31 13:50:17 -070011155 if (ret)
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -080011156 hdd_err("MAC address out-of-sync, ret:%d", ret);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070011157 }
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011158 return ret;
Komal Seelam92fff912016-03-24 11:51:41 +053011159}
11160
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011161static int hdd_set_smart_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011162{
11163 int vdev_id = 0;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053011164 QDF_STATUS status;
11165 bool smart_chainmask_enabled;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011166 int param_id = WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011167 int vpdev = PDEV_CMD;
11168 int ret;
11169
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053011170 status = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc,
11171 &smart_chainmask_enabled);
11172 if (QDF_IS_STATUS_ERROR(status))
11173 return -EINVAL;
11174
11175 ret = sme_cli_set_command(vdev_id, param_id,
11176 (int)smart_chainmask_enabled, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011177 if (ret)
11178 hdd_err("WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME failed %d", ret);
11179
11180 return ret;
11181}
11182
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011183static int hdd_set_alternative_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011184{
11185 int vdev_id = 0;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011186 QDF_STATUS status;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011187 int param_id = WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011188 bool alternative_chainmask_enabled;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011189 int vpdev = PDEV_CMD;
11190 int ret;
11191
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011192 status = ucfg_get_alternative_chainmask_enabled(
11193 hdd_ctx->psoc,
11194 &alternative_chainmask_enabled);
11195 if (QDF_IS_STATUS_ERROR(status))
11196 return -EINVAL;
11197
11198 ret = sme_cli_set_command(vdev_id, param_id,
11199 (int)alternative_chainmask_enabled, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011200 if (ret)
11201 hdd_err("WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME failed %d",
11202 ret);
11203
11204 return ret;
11205}
11206
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011207static int hdd_set_ani_enabled(struct hdd_context *hdd_ctx)
Jeff Johnson12a744b2017-04-04 08:19:37 -070011208{
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011209 QDF_STATUS status;
Jeff Johnson12a744b2017-04-04 08:19:37 -070011210 int vdev_id = 0;
11211 int param_id = WMI_PDEV_PARAM_ANI_ENABLE;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011212 bool value;
Jeff Johnson12a744b2017-04-04 08:19:37 -070011213 int vpdev = PDEV_CMD;
11214 int ret;
11215
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011216 status = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &value);
11217 if (QDF_IS_STATUS_ERROR(status))
11218 return -EINVAL;
11219
11220 ret = sme_cli_set_command(vdev_id, param_id, (int)value, vpdev);
Jeff Johnson12a744b2017-04-04 08:19:37 -070011221 if (ret)
11222 hdd_err("WMI_PDEV_PARAM_ANI_ENABLE failed %d", ret);
11223
11224 return ret;
11225}
11226
Jeff Johnson89c66ff2016-04-22 15:21:37 -070011227/**
Prashanth Bhatta07998752016-04-28 12:35:33 -070011228 * hdd_pre_enable_configure() - Configurations prior to cds_enable
11229 * @hdd_ctx: HDD context
11230 *
11231 * Pre configurations to be done at lower layer before calling cds enable.
11232 *
11233 * Return: 0 on success and errno on failure.
11234 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011235static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
Prashanth Bhatta07998752016-04-28 12:35:33 -070011236{
11237 int ret;
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011238 uint8_t val = 0;
Prashanth Bhatta07998752016-04-28 12:35:33 -070011239 QDF_STATUS status;
Leo Changfdb45c32016-10-28 11:09:23 -070011240 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prashanth Bhatta07998752016-04-28 12:35:33 -070011241
Leo Changfdb45c32016-10-28 11:09:23 -070011242 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
Ajit Pal Singh5d269612018-04-19 16:29:12 +053011243 /* Register HL netdev flow control callback */
Rakesh Pillai6a36b0a2019-09-06 16:30:05 +053011244 cdp_hl_fc_register(soc, OL_TXRX_PDEV_ID, wlan_hdd_txrx_pause_cb);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +053011245 /* Register rx mic error indication handler */
11246 cdp_register_rx_mic_error_ind_handler(soc, hdd_rx_mic_error_ind);
Prashanth Bhatta07998752016-04-28 12:35:33 -070011247
11248 /*
11249 * Note that the cds_pre_enable() sequence triggers the cfg download.
11250 * The cfg download must occur before we update the SME config
11251 * since the SME config operation must access the cfg database
11252 */
11253 status = hdd_set_sme_config(hdd_ctx);
11254
11255 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011256 hdd_err("Failed hdd_set_sme_config: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -070011257 ret = qdf_status_to_os_return(status);
11258 goto out;
11259 }
11260
Tushnim Bhattacharyyaba8ee932017-03-23 09:27:40 -070011261 status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
11262 if (QDF_STATUS_SUCCESS != status) {
11263 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
11264 ret = qdf_status_to_os_return(status);
11265 goto out;
11266 }
11267
Dustin Brown1dbefe62018-09-11 16:32:03 -070011268 status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val);
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011269 if (QDF_STATUS_SUCCESS != status) {
11270 hdd_err("Get tx_chainmask_1ss from mlme failed");
11271 ret = qdf_status_to_os_return(status);
11272 goto out;
11273 }
11274 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, val,
Prashanth Bhatta07998752016-04-28 12:35:33 -070011275 PDEV_CMD);
11276 if (0 != ret) {
11277 hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret);
11278 goto out;
11279 }
11280
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011281 ret = hdd_set_smart_chainmask_enabled(hdd_ctx);
11282 if (ret)
11283 goto out;
11284
11285 ret = hdd_set_alternative_chainmask_enabled(hdd_ctx);
11286 if (ret)
11287 goto out;
11288
Jeff Johnson12a744b2017-04-04 08:19:37 -070011289 ret = hdd_set_ani_enabled(hdd_ctx);
11290 if (ret)
11291 goto out;
11292
Prashanth Bhatta07998752016-04-28 12:35:33 -070011293 status = hdd_set_sme_chan_list(hdd_ctx);
11294 if (status != QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011295 hdd_err("Failed to init channel list: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -070011296 ret = qdf_status_to_os_return(status);
11297 goto out;
11298 }
11299
Krunal Sonidf0f8742016-09-26 14:56:31 -070011300 if (!hdd_update_config_cfg(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011301 hdd_err("config update failed");
Prashanth Bhatta07998752016-04-28 12:35:33 -070011302 ret = -EINVAL;
11303 goto out;
11304 }
Prashanth Bhatta07998752016-04-28 12:35:33 -070011305 hdd_init_channel_avoidance(hdd_ctx);
11306
11307out:
11308 return ret;
11309}
11310
Rachit Kankane026e77a2018-07-31 16:21:09 +053011311#ifdef FEATURE_P2P_LISTEN_OFFLOAD
Prashanth Bhatta07998752016-04-28 12:35:33 -070011312/**
Peng Xu8fdaa492016-06-22 10:20:47 -070011313 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070011314 * @context: context registered with sme_register_p2p_lo_event(). HDD
11315 * always registers a hdd context pointer
11316 * @evt:event structure pointer
Peng Xu8fdaa492016-06-22 10:20:47 -070011317 *
11318 * This is the p2p listen offload stop event handler, it sends vendor
11319 * event back to supplicant to notify the stop reason.
11320 *
11321 * Return: None
11322 */
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070011323static void wlan_hdd_p2p_lo_event_callback(void *context,
11324 struct sir_p2p_lo_event *evt)
Peng Xu8fdaa492016-06-22 10:20:47 -070011325{
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070011326 struct hdd_context *hdd_ctx = context;
Peng Xu8fdaa492016-06-22 10:20:47 -070011327 struct sk_buff *vendor_event;
Jeff Johnson9d295242017-08-29 14:39:48 -070011328 struct hdd_adapter *adapter;
Peng Xu8fdaa492016-06-22 10:20:47 -070011329
Dustin Brown491d54b2018-03-14 12:39:11 -070011330 hdd_enter();
Peng Xu8fdaa492016-06-22 10:20:47 -070011331
Jeff Johnsond36fa332019-03-18 13:42:25 -070011332 if (!hdd_ctx) {
Peng Xu8fdaa492016-06-22 10:20:47 -070011333 hdd_err("Invalid HDD context pointer");
11334 return;
11335 }
11336
Peng Xu5c682812017-08-06 07:39:13 -070011337 adapter = hdd_get_adapter_by_vdev(hdd_ctx, evt->vdev_id);
11338 if (!adapter) {
11339 hdd_err("Cannot find adapter by vdev_id = %d",
11340 evt->vdev_id);
11341 return;
11342 }
11343
Peng Xu8fdaa492016-06-22 10:20:47 -070011344 vendor_event =
11345 cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
Peng Xu5c682812017-08-06 07:39:13 -070011346 &(adapter->wdev), sizeof(uint32_t) + NLMSG_HDRLEN,
Peng Xu8fdaa492016-06-22 10:20:47 -070011347 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX,
11348 GFP_KERNEL);
11349
11350 if (!vendor_event) {
11351 hdd_err("cfg80211_vendor_event_alloc failed");
11352 return;
11353 }
11354
11355 if (nla_put_u32(vendor_event,
11356 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
11357 evt->reason_code)) {
11358 hdd_err("nla put failed");
11359 kfree_skb(vendor_event);
11360 return;
11361 }
11362
11363 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Peng Xu5c682812017-08-06 07:39:13 -070011364 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
11365 evt->vdev_id);
Peng Xu8fdaa492016-06-22 10:20:47 -070011366}
Rachit Kankane026e77a2018-07-31 16:21:09 +053011367#else
11368static void wlan_hdd_p2p_lo_event_callback(void *context,
11369 struct sir_p2p_lo_event *evt)
11370{
11371}
11372#endif
Peng Xu8fdaa492016-06-22 10:20:47 -070011373
Rachit Kankanef6834c42018-08-02 18:47:50 +053011374#ifdef FEATURE_WLAN_DYNAMIC_CVM
11375static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
11376{
11377 return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap);
11378}
11379#else
11380static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
11381{
11382 return QDF_STATUS_SUCCESS;
11383}
11384#endif
11385
Peng Xu8fdaa492016-06-22 10:20:47 -070011386/**
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053011387 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
11388 * @hdd_ctx: HDD context
11389 *
11390 * This function sends the adaptive dwell time config configuration to the
11391 * firmware via WMA
11392 *
11393 * Return: 0 - success, < 0 - failure
11394 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011395static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053011396{
11397 QDF_STATUS status;
11398 struct adaptive_dwelltime_params dwelltime_params;
11399
Harprit Chhabadad59ae762019-01-08 16:40:43 -080011400 status = ucfg_fwol_get_all_adaptive_dwelltime_params(hdd_ctx->psoc,
11401 &dwelltime_params);
11402 status = ucfg_fwol_set_adaptive_dwelltime_config(&dwelltime_params);
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053011403
11404 hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
11405 if (!QDF_IS_STATUS_SUCCESS(status)) {
11406 hdd_err("Failed to send Adaptive Dwelltime configuration!");
11407 return -EAGAIN;
11408 }
11409 return 0;
11410}
11411
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011412int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011413{
11414 QDF_STATUS status;
11415 struct wmi_dbs_scan_sel_params dbs_scan_params;
11416 uint32_t i = 0;
11417 uint8_t count = 0, numentries = 0;
Krunal Sonidf29bc42018-11-15 13:26:29 -080011418 uint8_t dual_mac_feature;
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011419 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
11420 * CDS_DBS_SCAN_CLIENTS_MAX];
11421
Krunal Sonidf29bc42018-11-15 13:26:29 -080011422 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
11423 &dual_mac_feature);
11424
11425 if (status != QDF_STATUS_SUCCESS) {
11426 hdd_err("can't get dual mac feature flag");
11427 return -EINVAL;
11428 }
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011429 /* check if DBS is enabled or supported */
Krunal Sonidf29bc42018-11-15 13:26:29 -080011430 if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) ||
11431 (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN))
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011432 return -EINVAL;
11433
11434 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
11435 dbs_scan_config, &numentries,
11436 (CDS_DBS_SCAN_PARAM_PER_CLIENT
11437 * CDS_DBS_SCAN_CLIENTS_MAX));
11438
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011439 if (!numentries) {
Dustin Brown6a8d39b2018-08-14 15:27:26 -070011440 hdd_debug("Do not send scan_selection_config");
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011441 return 0;
11442 }
11443
11444 /* hdd_set_fw_log_params */
11445 dbs_scan_params.num_clients = 0;
11446 while (count < (numentries - 2)) {
11447 dbs_scan_params.module_id[i] = dbs_scan_config[count];
11448 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
11449 dbs_scan_params.num_non_dbs_scans[i] =
11450 dbs_scan_config[count + 2];
11451 dbs_scan_params.num_clients++;
11452 hdd_debug("module:%d NDS:%d NNDS:%d",
11453 dbs_scan_params.module_id[i],
11454 dbs_scan_params.num_dbs_scans[i],
11455 dbs_scan_params.num_non_dbs_scans[i]);
11456 count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
11457 i++;
11458 }
11459
11460 dbs_scan_params.pdev_id = 0;
11461
11462 hdd_debug("clients:%d pdev:%d",
11463 dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
11464
Jeff Johnson16528362018-06-14 12:34:16 -070011465 status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle,
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011466 &dbs_scan_params);
11467 hdd_debug("Sending DBS Scan Selection Configuration to fw");
11468 if (!QDF_IS_STATUS_SUCCESS(status)) {
11469 hdd_err("Failed to send DBS Scan selection configuration!");
11470 return -EAGAIN;
11471 }
11472 return 0;
11473}
11474
Arun Khandavallid4349a92016-07-25 11:10:43 +053011475#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
11476/**
11477 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
11478 * @hdd_ctx: HDD context
11479 *
11480 * Set auto shutdown callback to get indications from firmware to indicate
11481 * userspace to shutdown WLAN after a configured amount of inactivity.
11482 *
11483 * Return: 0 on success and errno on failure.
11484 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011485static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053011486{
11487 QDF_STATUS status;
11488
Dundi Raviteja8e338282018-09-25 17:16:04 +053011489 if (!hdd_ctx->config->wlan_auto_shutdown)
Arun Khandavallid4349a92016-07-25 11:10:43 +053011490 return 0;
11491
Jeff Johnson16528362018-06-14 12:34:16 -070011492 status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle,
Arun Khandavallid4349a92016-07-25 11:10:43 +053011493 wlan_hdd_auto_shutdown_cb);
11494 if (status != QDF_STATUS_SUCCESS)
11495 hdd_err("Auto shutdown feature could not be enabled: %d",
11496 status);
11497
11498 return qdf_status_to_os_return(status);
11499}
11500#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011501static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053011502{
11503 return 0;
11504}
11505#endif
11506
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011507#ifdef MWS_COEX
11508/**
11509 * hdd_set_mws_coex() - Set MWS coex configurations
11510 * @hdd_ctx: HDD context
11511 *
11512 * This function sends MWS-COEX 4G quick FTDM and
11513 * MWS-COEX 5G-NR power limit to FW
11514 *
11515 * Return: 0 on success and errno on failure.
11516 */
11517static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
11518{
11519 int ret = 0;
lifengdb340e72018-11-20 00:50:20 +080011520 uint32_t mws_coex_4g_quick_tdm = 0, mws_coex_5g_nr_pwr_limit = 0;
11521
11522 ucfg_mlme_get_mws_coex_4g_quick_tdm(hdd_ctx->psoc,
11523 &mws_coex_4g_quick_tdm);
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011524
11525 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM,
lifengdb340e72018-11-20 00:50:20 +080011526 mws_coex_4g_quick_tdm,
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011527 PDEV_CMD);
11528 if (ret) {
11529 hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy");
11530 return ret;
11531 }
11532
lifengdb340e72018-11-20 00:50:20 +080011533 ucfg_mlme_get_mws_coex_5g_nr_pwr_limit(hdd_ctx->psoc,
11534 &mws_coex_5g_nr_pwr_limit);
11535
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011536 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT,
lifengdb340e72018-11-20 00:50:20 +080011537 mws_coex_5g_nr_pwr_limit,
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011538 PDEV_CMD);
11539 if (ret) {
11540 hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy");
11541 return ret;
11542 }
lifengdb340e72018-11-20 00:50:20 +080011543
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011544 return ret;
11545}
11546#else
11547static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
11548{
11549 return 0;
11550}
11551#endif
11552
Arun Khandavallid4349a92016-07-25 11:10:43 +053011553/**
11554 * hdd_features_init() - Init features
11555 * @hdd_ctx: HDD context
Arun Khandavallid4349a92016-07-25 11:10:43 +053011556 *
11557 * Initialize features and their feature context after WLAN firmware is up.
11558 *
11559 * Return: 0 on success and errno on failure.
11560 */
Dustin Browne7e71d32018-05-11 16:00:08 -070011561static int hdd_features_init(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053011562{
Jeff Johnson19ce8d02019-02-08 22:56:23 -080011563 struct tx_power_limit hddtxlimit;
Arun Khandavallid4349a92016-07-25 11:10:43 +053011564 QDF_STATUS status;
11565 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -070011566 mac_handle_t mac_handle;
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070011567 struct hdd_config *cfg;
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +053011568 bool b_cts2self, is_imps_enabled;
Arun Khandavallid4349a92016-07-25 11:10:43 +053011569
Dustin Brown491d54b2018-03-14 12:39:11 -070011570 hdd_enter();
Arun Khandavallid4349a92016-07-25 11:10:43 +053011571
Dustin Brownad698ae2018-09-05 17:19:30 -070011572 ret = hdd_update_country_code(hdd_ctx);
11573 if (ret) {
11574 hdd_err("Failed to update country code; errno:%d", ret);
11575 return -EINVAL;
11576 }
11577
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011578 ret = hdd_init_mws_coex(hdd_ctx);
11579 if (ret)
11580 hdd_warn("Error initializing mws-coex");
11581
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070011582 cfg = hdd_ctx->config;
Arun Khandavallid4349a92016-07-25 11:10:43 +053011583 /* FW capabilities received, Set the Dot11 mode */
Jeff Johnson16528362018-06-14 12:34:16 -070011584 mac_handle = hdd_ctx->mac_handle;
11585 sme_setdef_dot11mode(mac_handle);
Arun Khandavallid4349a92016-07-25 11:10:43 +053011586
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +053011587 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
11588 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
Arun Khandavallid4349a92016-07-25 11:10:43 +053011589
Poddar, Siddarth37033032017-10-11 15:47:40 +053011590 /* Send Enable/Disable data stall detection cmd to FW */
11591 sme_cli_set_command(0, WMI_PDEV_PARAM_DATA_STALL_DETECT_ENABLE,
jitiphil377bcc12018-10-05 19:46:08 +053011592 cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
11593 cfg_dp_enable_data_stall), PDEV_CMD);
Poddar, Siddarth37033032017-10-11 15:47:40 +053011594
Dustin Brown1dbefe62018-09-11 16:32:03 -070011595 ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self);
Wu Gao93816212018-08-31 16:49:54 +080011596 if (b_cts2self)
Jeff Johnson16528362018-06-14 12:34:16 -070011597 sme_set_cts2self_for_p2p_go(mac_handle);
Agrawal Ashish642ec9b2017-02-22 14:45:30 +053011598
Rachit Kankanef6834c42018-08-02 18:47:50 +053011599 if (hdd_set_vc_mode_config(hdd_ctx))
Nachiket Kukade8983cf62017-10-12 18:14:48 +053011600 hdd_warn("Error in setting Voltage Corner mode config to FW");
11601
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070011602 if (hdd_rx_ol_init(hdd_ctx))
11603 hdd_err("Unable to initialize Rx LRO/GRO in fw");
Arun Khandavallid4349a92016-07-25 11:10:43 +053011604
11605 if (hdd_adaptive_dwelltime_init(hdd_ctx))
11606 hdd_err("Unable to send adaptive dwelltime setting to FW");
11607
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011608 if (hdd_dbs_scan_selection_init(hdd_ctx))
11609 hdd_err("Unable to send DBS scan selection setting to FW");
11610
Arun Khandavallid4349a92016-07-25 11:10:43 +053011611 ret = hdd_init_thermal_info(hdd_ctx);
11612 if (ret) {
11613 hdd_err("Error while initializing thermal information");
Dustin Browne7e71d32018-05-11 16:00:08 -070011614 return ret;
Arun Khandavallid4349a92016-07-25 11:10:43 +053011615 }
11616
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053011617 /**
11618 * In case of SSR/PDR, if pktlog was enabled manually before
Rakshith Suresh Patkar6d955262019-03-13 16:51:50 +053011619 * SSR/PDR, then enable it again automatically after Wlan
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053011620 * device up.
Rakshith Suresh Patkar6d955262019-03-13 16:51:50 +053011621 * During SSR/PDR, pktlog will be disabled as part of
11622 * hdd_features_deinit if pktlog is enabled in ini.
11623 * Re-enable pktlog in SSR case, if pktlog is enabled in ini.
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053011624 */
Rakshith Suresh Patkar6d955262019-03-13 16:51:50 +053011625 if (cds_is_packet_log_enabled() ||
11626 (cds_is_driver_recovering() && hdd_ctx->is_pktlog_enabled))
Alok Kumar5a75b9d2018-08-31 10:55:43 +053011627 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
Poddar, Siddarth66a46592017-02-22 11:44:44 +053011628
gaurank kathpalia3d2e3852018-10-03 22:03:23 +053011629 hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G);
11630 hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G);
Jeff Johnson16528362018-06-14 12:34:16 -070011631 status = sme_txpower_limit(mac_handle, &hddtxlimit);
Arun Khandavallid4349a92016-07-25 11:10:43 +053011632 if (!QDF_IS_STATUS_SUCCESS(status))
11633 hdd_err("Error setting txlimit in sme: %d", status);
11634
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011635 wlan_hdd_tsf_init(hdd_ctx);
Arun Khandavallid4349a92016-07-25 11:10:43 +053011636
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053011637 status = sme_enable_disable_chanavoidind_event(mac_handle, 0);
11638 if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) {
11639 hdd_err("Failed to disable Chan Avoidance Indication");
Sourav Mohapatra674925f2018-04-16 11:16:58 +053011640 return -EINVAL;
Selvaraj, Sridhar371f55e2017-02-21 10:36:15 +053011641 }
Arun Khandavallid4349a92016-07-25 11:10:43 +053011642
11643 /* register P2P Listen Offload event callback */
11644 if (wma_is_p2p_lo_capable())
Jeff Johnson16528362018-06-14 12:34:16 -070011645 sme_register_p2p_lo_event(mac_handle, hdd_ctx,
11646 wlan_hdd_p2p_lo_event_callback);
Arun Khandavallid4349a92016-07-25 11:10:43 +053011647
11648 ret = hdd_set_auto_shutdown_cb(hdd_ctx);
11649
11650 if (ret)
Sourav Mohapatra674925f2018-04-16 11:16:58 +053011651 return -EINVAL;
Arun Khandavallid4349a92016-07-25 11:10:43 +053011652
Dustin Brown11638b72018-01-25 17:37:25 +053011653 wlan_hdd_init_chan_info(hdd_ctx);
Varun Reddy Yeturu3c9f89c2018-04-18 19:10:34 -070011654 wlan_hdd_twt_init(hdd_ctx);
Dustin Brown11638b72018-01-25 17:37:25 +053011655
Dustin Browne74003f2018-03-14 12:51:58 -070011656 hdd_exit();
Arun Khandavallid4349a92016-07-25 11:10:43 +053011657 return 0;
Arun Khandavallid4349a92016-07-25 11:10:43 +053011658}
11659
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011660/**
11661 * hdd_features_deinit() - Deinit features
11662 * @hdd_ctx: HDD context
11663 *
11664 * De-Initialize features and their feature context.
11665 *
11666 * Return: none.
11667 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011668static void hdd_features_deinit(struct hdd_context *hdd_ctx)
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011669{
Varun Reddy Yeturu3c9f89c2018-04-18 19:10:34 -070011670 wlan_hdd_twt_deinit(hdd_ctx);
Dustin Brown11638b72018-01-25 17:37:25 +053011671 wlan_hdd_deinit_chan_info(hdd_ctx);
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011672 wlan_hdd_tsf_deinit(hdd_ctx);
jitiphil4e3bef42018-11-14 14:31:13 +053011673 if (cds_is_packet_log_enabled())
11674 hdd_pktlog_enable_disable(hdd_ctx, false, 0, 0);
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011675}
11676
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011677/**
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070011678 * hdd_register_bcn_cb() - register scan beacon callback
11679 * @hdd_ctx - Pointer to the HDD context
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011680 *
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070011681 * Return: QDF_STATUS
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011682 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011683static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011684{
11685 QDF_STATUS status;
11686
Dustin Brown1dbefe62018-09-11 16:32:03 -070011687 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011688 wlan_cfg80211_inform_bss_frame,
11689 SCAN_CB_TYPE_INFORM_BCN);
11690 if (!QDF_IS_STATUS_SUCCESS(status)) {
Abhishek Singh5ffe9de2019-03-05 15:42:43 +053011691 hdd_err("failed to register SCAN_CB_TYPE_INFORM_BCN with status code %08d [x%08x]",
11692 status, status);
11693 return status;
11694 }
11695
11696 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
11697 wlan_cfg80211_unlink_bss_list,
11698 SCAN_CB_TYPE_UNLINK_BSS);
11699 if (!QDF_IS_STATUS_SUCCESS(status)) {
11700 hdd_err("failed to refister SCAN_CB_TYPE_FLUSH_BSS with status code %08d [x%08x]",
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011701 status, status);
11702 return status;
11703 }
11704
11705 return QDF_STATUS_SUCCESS;
11706}
Arun Khandavallid4349a92016-07-25 11:10:43 +053011707
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053011708/**
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070011709 * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active
11710 * @vdev_id: vdev_id, corresponds to flow_pool
11711 *
11712 * Return: none.
11713 */
11714static void hdd_v2_flow_pool_map(int vdev_id)
11715{
11716 QDF_STATUS status;
11717
11718 status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC),
Rakesh Pillaia889ffa2019-07-03 19:29:52 +053011719 OL_TXRX_PDEV_ID,
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070011720 vdev_id);
11721 /*
11722 * For Adrastea flow control v2 is based on FW MAP events,
11723 * so this above callback is not implemented.
11724 * Hence this is not actual failure. Dont return failure
11725 */
11726 if ((status != QDF_STATUS_SUCCESS) &&
11727 (status != QDF_STATUS_E_INVAL)) {
11728 hdd_err("vdev_id: %d, failed to create flow pool status %d",
11729 vdev_id, status);
11730 }
11731}
11732
11733/**
11734 * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active
11735 * @vdev_id: vdev_id, corresponds to flow_pool
11736 *
11737 * Return: none.
11738 */
11739static void hdd_v2_flow_pool_unmap(int vdev_id)
11740{
11741 cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC),
Rakesh Pillaia889ffa2019-07-03 19:29:52 +053011742 OL_TXRX_PDEV_ID, vdev_id);
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070011743}
11744
11745/**
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011746 * hdd_action_oui_config() - Configure action_oui strings
11747 * @hdd_ctx: pointer to hdd context
11748 *
11749 * This is a HDD wrapper function which invokes ucfg api
11750 * of action_oui component to parse action oui strings.
11751 *
11752 * Return: None
11753 */
11754static void hdd_action_oui_config(struct hdd_context *hdd_ctx)
11755{
11756 QDF_STATUS status;
11757 uint32_t id;
11758 uint8_t *str;
11759
11760 if (!hdd_ctx->config->action_oui_enable)
11761 return;
11762
11763 for (id = 0; id < ACTION_OUI_MAXIMUM_ID; id++) {
11764 str = hdd_ctx->config->action_oui_str[id];
11765 if (!qdf_str_len(str))
11766 continue;
11767
Dustin Brown1dbefe62018-09-11 16:32:03 -070011768 status = ucfg_action_oui_parse(hdd_ctx->psoc, str, id);
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011769 if (!QDF_IS_STATUS_SUCCESS(status))
11770 hdd_err("Failed to parse action_oui str: %u", id);
11771 }
11772}
11773
11774/**
11775 * hdd_action_oui_send() - Send action_oui extensions to firmware
11776 * @hdd_ctx: pointer to hdd context
11777 *
11778 * This is a HDD wrapper function which invokes ucfg api
11779 * of action_oui component to send action oui extensions to firmware.
11780 *
11781 * Return: None
11782 */
11783static void hdd_action_oui_send(struct hdd_context *hdd_ctx)
11784{
11785 QDF_STATUS status;
11786
11787 if (!hdd_ctx->config->action_oui_enable)
11788 return;
11789
Dustin Brown1dbefe62018-09-11 16:32:03 -070011790 status = ucfg_action_oui_send(hdd_ctx->psoc);
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011791 if (!QDF_IS_STATUS_SUCCESS(status))
11792 hdd_err("Failed to send one or all action_ouis");
11793}
11794
Jeff Johnson0187c622019-01-04 06:39:44 -080011795static void hdd_hastings_bt_war_initialize(struct hdd_context *hdd_ctx)
11796{
11797 if (hdd_ctx->config->iface_change_wait_time)
11798 hdd_hastings_bt_war_disable_fw(hdd_ctx);
11799 else
11800 hdd_hastings_bt_war_enable_fw(hdd_ctx);
11801}
11802
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011803/**
Arun Khandavallifae92942016-08-01 13:31:08 +053011804 * hdd_configure_cds() - Configure cds modules
11805 * @hdd_ctx: HDD context
11806 * @adapter: Primary adapter context
11807 *
11808 * Enable Cds modules after WLAN firmware is up.
11809 *
11810 * Return: 0 on success and errno on failure.
11811 */
Dustin Browne7e71d32018-05-11 16:00:08 -070011812int hdd_configure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053011813{
11814 int ret;
11815 QDF_STATUS status;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011816 int set_value;
Jeff Johnson16528362018-06-14 12:34:16 -070011817 mac_handle_t mac_handle;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011818 bool enable_rts_sifsbursting;
11819 uint8_t enable_phy_reg_retention;
Krunal Sonidf29bc42018-11-15 13:26:29 -080011820 uint8_t max_mpdus_inampdu, is_force_1x1 = 0;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011821 uint32_t num_abg_tx_chains = 0;
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011822 uint16_t num_11b_tx_chains = 0;
11823 uint16_t num_11ag_tx_chains = 0;
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070011824 struct policy_mgr_dp_cbacks dp_cbs = {0};
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053011825 bool value;
Wu Gao66454f12018-09-26 19:55:41 +080011826 enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053011827 bool bval = false;
Varuneshwar Petlozuf8766672019-07-02 15:50:42 +053011828 qdf_device_t qdf_ctx;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011829
Jeff Johnson16528362018-06-14 12:34:16 -070011830 mac_handle = hdd_ctx->mac_handle;
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011831
11832 hdd_action_oui_send(hdd_ctx);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011833 status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1);
11834 if (status != QDF_STATUS_SUCCESS) {
11835 hdd_err("Failed to get force 1x1 value");
11836 goto out;
11837 }
11838 if (is_force_1x1)
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011839 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_SET_IOT_PATTERN,
11840 1, PDEV_CMD);
11841 /* set chip power save failure detected callback */
Jeff Johnson16528362018-06-14 12:34:16 -070011842 sme_set_chip_pwr_save_fail_cb(mac_handle,
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011843 hdd_chip_pwr_save_fail_detected_cb);
11844
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011845 status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc,
11846 &max_mpdus_inampdu);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011847 if (status) {
11848 hdd_err("Failed to get max mpdus in ampdu value");
11849 goto out;
11850 }
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011851
11852 if (max_mpdus_inampdu) {
11853 set_value = max_mpdus_inampdu;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011854 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU,
11855 set_value, PDEV_CMD);
11856 }
11857
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011858 status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc,
11859 &enable_rts_sifsbursting);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011860 if (status) {
11861 hdd_err("Failed to get rts sifs bursting value");
11862 goto out;
11863 }
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011864
11865 if (enable_rts_sifsbursting) {
11866 set_value = enable_rts_sifsbursting;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011867 sme_cli_set_command(0,
11868 (int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING,
11869 set_value, PDEV_CMD);
11870 }
11871
Dustin Brown05d81302018-09-11 16:49:22 -070011872 ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053011873 if (value) {
11874 set_value = value;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011875 sme_cli_set_command(0,
11876 (int)WMI_PDEV_PARAM_PEER_STATS_INFO_ENABLE,
11877 set_value, PDEV_CMD);
11878 }
11879
Dustin Brown1dbefe62018-09-11 16:32:03 -070011880 status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc,
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011881 &num_11b_tx_chains);
11882 if (status != QDF_STATUS_SUCCESS) {
11883 hdd_err("Failed to get num_11b_tx_chains");
11884 goto out;
11885 }
11886
Dustin Brown1dbefe62018-09-11 16:32:03 -070011887 status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc,
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011888 &num_11ag_tx_chains);
11889 if (status != QDF_STATUS_SUCCESS) {
11890 hdd_err("Failed to get num_11ag_tx_chains");
11891 goto out;
11892 }
11893
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053011894 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
11895 if (!QDF_IS_STATUS_SUCCESS(status))
11896 hdd_err("unable to get vht_enable2x2");
11897
11898 if (!bval) {
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011899 if (num_11b_tx_chains > 1)
11900 num_11b_tx_chains = 1;
11901 if (num_11ag_tx_chains > 1)
11902 num_11ag_tx_chains = 1;
11903 }
11904 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
11905 num_11b_tx_chains);
11906 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
11907 num_11ag_tx_chains);
11908 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM,
11909 num_abg_tx_chains, PDEV_CMD);
Arun Khandavallifae92942016-08-01 13:31:08 +053011910
Paul Zhang02526cd2018-09-20 17:47:46 +080011911 if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc))
11912 ucfg_reg_program_default_cc(hdd_ctx->pdev,
11913 hdd_ctx->reg.reg_domain);
11914
Arun Khandavallifae92942016-08-01 13:31:08 +053011915 ret = hdd_pre_enable_configure(hdd_ctx);
11916 if (ret) {
11917 hdd_err("Failed to pre-configure cds");
11918 goto out;
11919 }
11920
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080011921 /* Always get latest IPA resources allocated from cds_open and configure
11922 * IPA module before configuring them to FW. Sequence required as crash
11923 * observed otherwise.
11924 */
Varuneshwar Petlozuf8766672019-07-02 15:50:42 +053011925
11926 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
11927 if (!qdf_ctx) {
11928 hdd_err("QDF device context is NULL");
11929 goto out;
11930 }
11931
11932 if (ucfg_ipa_uc_ol_init(hdd_ctx->pdev, qdf_ctx)) {
Manikandan Mohan2e803a02017-02-14 14:57:53 -080011933 hdd_err("Failed to setup pipes");
11934 goto out;
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080011935 }
11936
Arun Khandavallifae92942016-08-01 13:31:08 +053011937 /*
11938 * Start CDS which starts up the SME/MAC/HAL modules and everything
11939 * else
11940 */
Dustin Brown1dbefe62018-09-11 16:32:03 -070011941 status = cds_enable(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053011942
11943 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011944 hdd_err("cds_enable failed");
Arun Khandavallifae92942016-08-01 13:31:08 +053011945 goto out;
11946 }
11947
11948 status = hdd_post_cds_enable_config(hdd_ctx);
11949 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011950 hdd_err("hdd_post_cds_enable_config failed");
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011951 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053011952 }
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011953 status = hdd_register_bcn_cb(hdd_ctx);
11954 if (!QDF_IS_STATUS_SUCCESS(status)) {
Paul Zhange03cf4c2018-01-19 18:33:22 +080011955 hdd_err("hdd_register_bcn_cb failed");
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011956 goto cds_disable;
11957 }
Arun Khandavallifae92942016-08-01 13:31:08 +053011958
Dustin Browne7e71d32018-05-11 16:00:08 -070011959 ret = hdd_features_init(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053011960 if (ret)
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011961 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053011962
Mohit Khanna81418772018-10-30 14:14:46 -070011963 /* Donot disable rx offload on concurrency for lithium based targets */
11964 if (!(hdd_ctx->target_type == TARGET_TYPE_QCA6290 ||
Manjunathappa Prakash458f6fe2019-05-13 18:33:01 -070011965 hdd_ctx->target_type == TARGET_TYPE_QCA6390 ||
11966 hdd_ctx->target_type == TARGET_TYPE_QCA6490))
Mohit Khanna81418772018-10-30 14:14:46 -070011967 if (hdd_ctx->ol_enable)
11968 dp_cbs.hdd_disable_rx_ol_in_concurrency =
11969 hdd_disable_rx_ol_in_concurrency;
Yun Parkff6a16a2017-09-26 16:38:18 -070011970 dp_cbs.hdd_set_rx_mode_rps_cb = hdd_set_rx_mode_rps;
jiadbb47e132018-03-30 16:28:30 +080011971 dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070011972 dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map;
11973 dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap;
Dustin Brown1dbefe62018-09-11 16:32:03 -070011974 status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs);
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011975 if (!QDF_IS_STATUS_SUCCESS(status)) {
Yun Parkff6a16a2017-09-26 16:38:18 -070011976 hdd_debug("Failed to register DP cb with Policy Manager");
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011977 goto cds_disable;
11978 }
Dustin Brown1dbefe62018-09-11 16:32:03 -070011979 status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc,
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011980 wlan_hdd_send_mode_change_event);
11981 if (!QDF_IS_STATUS_SUCCESS(status)) {
11982 hdd_debug("Failed to register mode change cb with Policy Manager");
11983 goto cds_disable;
11984 }
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011985
Jeff Johnson8bb61112018-03-31 13:33:54 -070011986 if (hdd_green_ap_enable_egap(hdd_ctx))
Nachiket Kukadefbd1afc2017-07-12 17:41:54 +053011987 hdd_debug("enhance green ap is not enabled");
11988
Nachiket Kukadedd302662017-07-13 17:31:44 +053011989 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
11990 hdd_debug("Failed to set wow pulse");
11991
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053011992 sme_cli_set_command(0, WMI_PDEV_PARAM_GCMP_SUPPORT_ENABLE,
Manikandan Mohan66df7fc2019-01-08 17:57:05 -080011993 ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc), PDEV_CMD);
Wu Gao66454f12018-09-26 19:55:41 +080011994
11995 auto_power_fail_mode =
11996 ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc);
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +053011997 sme_cli_set_command(0, WMI_PDEV_AUTO_DETECT_POWER_FAILURE,
Wu Gao66454f12018-09-26 19:55:41 +080011998 auto_power_fail_mode, PDEV_CMD);
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +053011999
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053012000 status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc,
12001 &enable_phy_reg_retention);
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053012002
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053012003 if (QDF_IS_STATUS_ERROR(status))
12004 return -EINVAL;
12005
12006 if (enable_phy_reg_retention)
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053012007 wma_cli_set_command(0, WMI_PDEV_PARAM_FAST_PWR_TRANSITION,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053012008 enable_phy_reg_retention, PDEV_CMD);
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053012009
Jeff Johnson0187c622019-01-04 06:39:44 -080012010 hdd_hastings_bt_war_initialize(hdd_ctx);
12011
Arun Khandavallifae92942016-08-01 13:31:08 +053012012 return 0;
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070012013
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070012014cds_disable:
Dustin Brown1dbefe62018-09-11 16:32:03 -070012015 cds_disable(hdd_ctx->psoc);
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070012016
Arun Khandavallifae92942016-08-01 13:31:08 +053012017out:
12018 return -EINVAL;
12019}
12020
12021/**
12022 * hdd_deconfigure_cds() -De-Configure cds
12023 * @hdd_ctx: HDD context
12024 *
12025 * Deconfigure Cds modules before WLAN firmware is down.
12026 *
12027 * Return: 0 on success and errno on failure.
12028 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012029static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053012030{
12031 QDF_STATUS qdf_status;
Houston Hoffman6640cf32016-10-10 16:44:29 -070012032 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053012033
Dustin Brown491d54b2018-03-14 12:39:11 -070012034 hdd_enter();
Yu Wangf5d5b5f2017-05-25 22:38:32 +080012035
12036 /* De-init features */
12037 hdd_features_deinit(hdd_ctx);
12038
Dustin Brown1dbefe62018-09-11 16:32:03 -070012039 qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc);
Srinivas Girigowdad2412882018-09-07 15:42:04 -070012040 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053012041 hdd_debug("Failed to deregister mode change cb with Policy Manager");
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053012042
Dustin Brown1dbefe62018-09-11 16:32:03 -070012043 qdf_status = cds_disable(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053012044 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
12045 hdd_err("Failed to Disable the CDS Modules! :%d",
12046 qdf_status);
Houston Hoffman6640cf32016-10-10 16:44:29 -070012047 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053012048 }
12049
Dustin Brown07901ec2018-09-07 11:02:41 -070012050 if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) {
Sravan Kumar Kairam71121712017-04-15 00:34:42 +053012051 hdd_err("Failed to disconnect pipes");
12052 ret = -EINVAL;
12053 }
12054
Dustin Browne74003f2018-03-14 12:51:58 -070012055 hdd_exit();
Houston Hoffman6640cf32016-10-10 16:44:29 -070012056 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053012057}
12058
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070012059#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
12060static void hdd_deregister_policy_manager_callback(
12061 struct wlan_objmgr_psoc *psoc)
12062{
12063 if (QDF_STATUS_SUCCESS !=
12064 policy_mgr_deregister_hdd_cb(psoc)) {
12065 hdd_err("HDD callback deregister with policy manager failed");
12066 }
12067}
12068#else
12069static void hdd_deregister_policy_manager_callback(
12070 struct wlan_objmgr_psoc *psoc)
12071{
12072}
12073#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053012074
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012075int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
Arun Khandavallifae92942016-08-01 13:31:08 +053012076{
12077 void *hif_ctx;
12078 qdf_device_t qdf_ctx;
12079 QDF_STATUS qdf_status;
Dustin Brown4bc0a622017-12-06 15:56:50 -080012080 bool is_recovery_stop = cds_is_driver_recovering();
Sourav Mohapatra808e3d42018-07-04 09:34:23 +053012081 int ret = 0;
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053012082 int debugfs_threads;
Arunk Khandavallia6305a32018-01-25 11:19:18 +053012083 struct target_psoc_info *tgt_hdl;
Arun Khandavallifae92942016-08-01 13:31:08 +053012084
Dustin Brown491d54b2018-03-14 12:39:11 -070012085 hdd_enter();
Arun Khandavallifae92942016-08-01 13:31:08 +053012086 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
12087 if (!qdf_ctx) {
12088 hdd_err("QDF device context NULL");
12089 return -EINVAL;
12090 }
12091
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070012092 cds_set_module_stop_in_progress(true);
Arun Khandavallifae92942016-08-01 13:31:08 +053012093
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053012094 debugfs_threads = hdd_return_debugfs_threads_count();
Dustin Brown70111822017-03-30 15:31:40 -070012095
Dustin Brown3fdaaf62019-03-18 14:00:16 -070012096 if (debugfs_threads > 0 || hdd_ctx->is_wiphy_suspended) {
12097 hdd_warn("Debugfs threads %d, wiphy suspend %d",
12098 debugfs_threads, hdd_ctx->is_wiphy_suspended);
Dustin Brown70111822017-03-30 15:31:40 -070012099
Sourav Mohapatra808e3d42018-07-04 09:34:23 +053012100 if (IS_IDLE_STOP && !ftm_mode) {
Dustin Brown4c663222018-10-23 14:19:36 -070012101 hdd_psoc_idle_timer_start(hdd_ctx);
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070012102 cds_set_module_stop_in_progress(false);
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070012103
Manjunathappa Prakashf065fcd2019-08-06 16:47:08 -070012104 hdd_bus_bw_compute_timer_stop(hdd_ctx);
Alan Chend841bcc2019-08-30 12:17:22 -070012105 return -EAGAIN;
Dustin Brown70111822017-03-30 15:31:40 -070012106 }
Rajeev Kumar86177c22017-03-16 19:44:39 -070012107 }
12108
Liangwei Dong857cb842019-04-28 04:55:17 -040012109 hdd_deregister_policy_manager_callback(hdd_ctx->psoc);
12110
Kabilan Kannan6edafeb2017-11-16 16:34:34 -080012111 /* free user wowl patterns */
12112 hdd_free_user_wowl_ptrns();
12113
Arun Khandavallifae92942016-08-01 13:31:08 +053012114 switch (hdd_ctx->driver_status) {
12115 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070012116 hdd_debug("Modules not initialized just return");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053012117 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053012118 case DRIVER_MODULES_CLOSED:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070012119 hdd_debug("Modules already closed");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053012120 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053012121 case DRIVER_MODULES_ENABLED:
Dustin Brown1a20b082018-08-03 17:27:15 -070012122 hdd_info("Wlan transitioning (CLOSED <- ENABLED)");
12123
Nirav Shah6aeecf92019-02-13 14:05:03 +053012124 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE ||
12125 hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
Dustin Brown1a20b082018-08-03 17:27:15 -070012126 break;
Dustin Brown550f6d22017-12-14 15:44:01 -080012127
Jingxiang Ge645300a2019-11-15 12:30:27 +080012128 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
12129
Lin Bai56386f52019-08-08 13:58:23 +080012130 hdd_skip_acs_scan_timer_deinit(hdd_ctx);
12131
Komal Seelamf2136bb2016-09-28 18:30:44 +053012132 hdd_disable_power_management();
Arun Khandavallifae92942016-08-01 13:31:08 +053012133 if (hdd_deconfigure_cds(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012134 hdd_err("Failed to de-configure CDS");
Arun Khandavallifae92942016-08-01 13:31:08 +053012135 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053012136 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053012137 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012138 hdd_debug("successfully Disabled the CDS modules!");
Dustin Brown550f6d22017-12-14 15:44:01 -080012139
Arun Khandavallifae92942016-08-01 13:31:08 +053012140 break;
12141 default:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070012142 QDF_DEBUG_PANIC("Unknown driver state:%d",
Arun Khandavallifae92942016-08-01 13:31:08 +053012143 hdd_ctx->driver_status);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053012144 ret = -EINVAL;
12145 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053012146 }
12147
Arunk Khandavalli890f6d92018-10-30 20:18:28 +053012148 hdd_sysfs_destroy_powerstats_interface();
Amar Singhal18081642018-01-26 16:04:13 -080012149 hdd_sysfs_destroy_version_interface();
Arunk Khandavalli890f6d92018-10-30 20:18:28 +053012150 hdd_sysfs_destroy_driver_root_obj();
Dustin Brown550f6d22017-12-14 15:44:01 -080012151 hdd_debug("Closing CDS modules!");
Amar Singhal18081642018-01-26 16:04:13 -080012152
Nirav Shah6aeecf92019-02-13 14:05:03 +053012153 if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) {
12154 qdf_status = cds_post_disable();
12155 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
12156 hdd_err("Failed to process post CDS disable! :%d",
12157 qdf_status);
12158 ret = -EINVAL;
12159 QDF_ASSERT(0);
12160 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070012161
Nirav Shah6aeecf92019-02-13 14:05:03 +053012162 /* De-register the SME callbacks */
12163 hdd_deregister_cb(hdd_ctx);
Sourav Mohapatra674925f2018-04-16 11:16:58 +053012164
Nirav Shah6aeecf92019-02-13 14:05:03 +053012165 hdd_runtime_suspend_context_deinit(hdd_ctx);
psimhadeea0a12017-12-18 14:50:02 -080012166
Nirav Shah6aeecf92019-02-13 14:05:03 +053012167 qdf_status = cds_dp_close(hdd_ctx->psoc);
12168 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
12169 hdd_warn("Failed to stop CDS DP: %d", qdf_status);
12170 ret = -EINVAL;
12171 QDF_ASSERT(0);
12172 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070012173
Nirav Shah6aeecf92019-02-13 14:05:03 +053012174 qdf_status = cds_close(hdd_ctx->psoc);
12175 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
12176 hdd_warn("Failed to stop CDS: %d", qdf_status);
12177 ret = -EINVAL;
12178 QDF_ASSERT(0);
12179 }
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053012180
Nirav Shah6aeecf92019-02-13 14:05:03 +053012181 qdf_status = wbuff_module_deinit();
12182 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
12183 hdd_err("WBUFF de-init unsuccessful; status: %d",
12184 qdf_status);
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053012185
Nirav Shah6aeecf92019-02-13 14:05:03 +053012186 hdd_component_pdev_close(hdd_ctx->pdev);
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053012187
Nirav Shah6aeecf92019-02-13 14:05:03 +053012188 hdd_component_psoc_close(hdd_ctx->psoc);
12189 dispatcher_pdev_close(hdd_ctx->pdev);
12190 ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
12191 if (ret) {
12192 hdd_err("Failed to destroy pdev; errno:%d", ret);
12193 QDF_ASSERT(0);
12194 }
Liangwei Dong50a64a72018-01-11 01:17:00 -050012195 }
12196
12197 /*
12198 * Reset total mac phy during module stop such that during
12199 * next module start same psoc is used to populate new service
12200 * ready data
12201 */
Dustin Brown1dbefe62018-09-11 16:32:03 -070012202 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
Arunk Khandavallia6305a32018-01-25 11:19:18 +053012203 if (tgt_hdl)
12204 target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0);
12205
Liangwei Dong50a64a72018-01-11 01:17:00 -050012206
Arun Khandavallifae92942016-08-01 13:31:08 +053012207 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
12208 if (!hif_ctx) {
12209 hdd_err("Hif context is Null");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053012210 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053012211 }
12212
Arunk Khandavalli4b404332017-09-26 12:46:00 +053012213 if (hdd_ctx->target_hw_name) {
12214 qdf_mem_free(hdd_ctx->target_hw_name);
12215 hdd_ctx->target_hw_name = NULL;
12216 }
12217
Lin Bai7bae1032019-04-30 12:29:36 +080012218 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
Visweswara Tanukuc949ad22019-03-20 13:00:30 +053012219 epping_disable();
12220 epping_close();
12221 }
12222
Sravan Kumar Kairam27296782017-04-21 22:04:18 +053012223 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053012224
12225 ol_cds_free();
12226
Dustin Brownc2a156e2018-10-25 16:56:27 -070012227 if (IS_IDLE_STOP) {
Arun Khandavallifae92942016-08-01 13:31:08 +053012228 ret = pld_power_off(qdf_ctx->dev);
12229 if (ret)
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070012230 hdd_err("Failed to power down device; errno:%d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053012231 }
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070012232
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012233 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
12234 wlan_hdd_free_cache_channels(hdd_ctx);
Ashish Kumar Dhanotiya64b3fa92019-07-23 15:50:10 +053012235 hdd_driver_mem_cleanup();
Arunk Khandavalli847969d2017-09-25 15:15:36 +053012236
Sourav Mohapatra9036f652019-04-02 15:02:59 +053012237 /* Free the resources allocated while storing SAR config. These needs
12238 * to be freed only in the case when it is not SSR. As in the case of
12239 * SSR, the values needs to be intact so that it can be restored during
12240 * reinit path.
12241 */
12242 if (!is_recovery_stop)
12243 wlan_hdd_free_sar_config(hdd_ctx);
12244
Jingxiang Ge3de02752019-01-29 15:47:03 +080012245 hdd_sap_destroy_ctx_all(hdd_ctx, is_recovery_stop);
12246
Dustin Brown29533f22018-07-24 13:11:56 -070012247 hdd_check_for_leaks(hdd_ctx, is_recovery_stop);
Dustin Brown26b3d042017-12-21 11:13:27 -080012248 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -080012249
Arunk Khandavalli847969d2017-09-25 15:15:36 +053012250 /* Once the firmware sequence is completed reset this flag */
12251 hdd_ctx->imps_enabled = false;
Arun Khandavallifae92942016-08-01 13:31:08 +053012252 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -080012253 hdd_info("Wlan transitioned (now CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +053012254
Kai Liueabb1df2018-11-08 14:58:54 +080012255 pld_request_bus_bandwidth(hdd_ctx->parent_dev, PLD_BUS_WIDTH_NONE);
Manjunathappa Prakashf065fcd2019-08-06 16:47:08 -070012256 hdd_bus_bw_compute_timer_stop(hdd_ctx);
Kai Liueabb1df2018-11-08 14:58:54 +080012257
Arun Khandavallia172c3e2016-08-26 17:33:13 +053012258done:
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070012259 cds_set_module_stop_in_progress(false);
Dustin Brown4bc0a622017-12-06 15:56:50 -080012260
Dustin Browne74003f2018-03-14 12:51:58 -070012261 hdd_exit();
Arun Khandavallifae92942016-08-01 13:31:08 +053012262
Arun Khandavallia172c3e2016-08-26 17:33:13 +053012263 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053012264}
12265
Wen Gong3f003382018-05-14 14:26:37 +080012266#ifdef WLAN_FEATURE_MEMDUMP_ENABLE
Arun Khandavallifae92942016-08-01 13:31:08 +053012267/**
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012268 * hdd_state_info_dump() - prints state information of hdd layer
12269 * @buf: buffer pointer
12270 * @size: size of buffer to be filled
12271 *
12272 * This function is used to dump state information of hdd layer
12273 *
12274 * Return: None
12275 */
12276static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
12277{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012278 struct hdd_context *hdd_ctx;
Jeff Johnson40dae4e2017-08-29 14:00:25 -070012279 struct hdd_station_ctx *hdd_sta_ctx;
Jeff Johnson9d295242017-08-29 14:39:48 -070012280 struct hdd_adapter *adapter;
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012281 uint16_t len = 0;
12282 char *buf = *buf_ptr;
12283
12284 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12285 if (!hdd_ctx) {
12286 hdd_err("Failed to get hdd context ");
12287 return;
12288 }
12289
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012290 hdd_debug("size of buffer: %d", *size);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012291
12292 len += scnprintf(buf + len, *size - len,
Jeff Johnson214671b2017-10-30 19:45:23 -070012293 "\n is_wiphy_suspended %d", hdd_ctx->is_wiphy_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012294 len += scnprintf(buf + len, *size - len,
Rajeev Kumareada0d02016-12-08 17:44:17 -080012295 "\n is_scheduler_suspended %d",
12296 hdd_ctx->is_scheduler_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012297
Dustin Brown920397d2017-12-13 16:27:50 -080012298 hdd_for_each_adapter(hdd_ctx, adapter) {
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012299 if (adapter->dev)
12300 len += scnprintf(buf + len, *size - len,
12301 "\n device name: %s", adapter->dev->name);
wadesong42968e92017-06-08 14:11:21 +080012302 len += scnprintf(buf + len, *size - len,
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012303 "\n device_mode: %d", adapter->device_mode);
12304 switch (adapter->device_mode) {
12305 case QDF_STA_MODE:
12306 case QDF_P2P_CLIENT_MODE:
12307 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
12308 len += scnprintf(buf + len, *size - len,
Jeff Johnsone7951512019-02-27 10:02:51 -080012309 "\n conn_state: %d",
12310 hdd_sta_ctx->conn_info.conn_state);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012311 break;
12312
12313 default:
12314 break;
12315 }
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012316 }
12317
12318 *size -= len;
12319 *buf_ptr += len;
12320}
12321
12322/**
12323 * hdd_register_debug_callback() - registration function for hdd layer
12324 * to print hdd state information
12325 *
12326 * Return: None
12327 */
12328static void hdd_register_debug_callback(void)
12329{
12330 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
12331}
Wen Gong3f003382018-05-14 14:26:37 +080012332#else /* WLAN_FEATURE_MEMDUMP_ENABLE */
Wen Gongaa6d55d2018-04-26 16:33:21 +080012333static void hdd_register_debug_callback(void)
12334{
12335}
Wen Gong3f003382018-05-14 14:26:37 +080012336#endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012337
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053012338/*
12339 * wlan_init_bug_report_lock() - Initialize bug report lock
12340 *
12341 * This function is used to create bug report lock
12342 *
12343 * Return: None
12344 */
12345static void wlan_init_bug_report_lock(void)
12346{
Jeff Johnson2b6982c2018-05-29 14:56:11 -070012347 struct cds_context *p_cds_context;
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053012348
12349 p_cds_context = cds_get_global_context();
12350 if (!p_cds_context) {
12351 hdd_err("cds context is NULL");
12352 return;
12353 }
12354
12355 qdf_spinlock_create(&p_cds_context->bug_report_lock);
12356}
12357
Nirav Shahd21a2e32018-04-20 16:34:43 +053012358#ifdef CONFIG_DP_TRACE
Mohit Khannaf8f96822017-05-17 17:11:59 -070012359void hdd_dp_trace_init(struct hdd_config *config)
12360{
Mohit Khannaf8f96822017-05-17 17:11:59 -070012361 bool live_mode = DP_TRACE_CONFIG_DEFAULT_LIVE_MODE;
12362 uint8_t thresh = DP_TRACE_CONFIG_DEFAULT_THRESH;
12363 uint16_t thresh_time_limit = DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT;
12364 uint8_t verbosity = DP_TRACE_CONFIG_DEFAULT_VERBOSTY;
12365 uint8_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP;
12366 uint8_t config_params[DP_TRACE_CONFIG_NUM_PARAMS];
12367 uint8_t num_entries = 0;
Lin Baiaa7f8d72017-10-18 17:23:45 +080012368 uint32_t bw_compute_interval;
Mohit Khannaf8f96822017-05-17 17:11:59 -070012369
Nirav Shahd21a2e32018-04-20 16:34:43 +053012370 if (!config->enable_dp_trace) {
12371 hdd_err("dp trace is disabled from ini");
12372 return;
12373 }
12374
Mohit Khannaf8f96822017-05-17 17:11:59 -070012375 hdd_string_to_u8_array(config->dp_trace_config, config_params,
12376 &num_entries, sizeof(config_params));
12377
12378 /* calculating, num bw timer intervals in a second (1000ms) */
Lin Baiaa7f8d72017-10-18 17:23:45 +080012379 bw_compute_interval = GET_BW_COMPUTE_INTV(config);
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080012380 if (bw_compute_interval <= 1000 && bw_compute_interval > 0)
Lin Baiaa7f8d72017-10-18 17:23:45 +080012381 thresh_time_limit = 1000 / bw_compute_interval;
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080012382 else if (bw_compute_interval > 1000) {
12383 hdd_err("busBandwidthComputeInterval > 1000, using 1000");
12384 thresh_time_limit = 1;
12385 } else
Mohit Khannaf8f96822017-05-17 17:11:59 -070012386 hdd_err("busBandwidthComputeInterval is 0, using defaults");
12387
12388 switch (num_entries) {
12389 case 4:
12390 proto_bitmap = config_params[3];
Alok Kumarb5a33a22018-05-07 18:09:14 +053012391 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070012392 case 3:
12393 verbosity = config_params[2];
Alok Kumarb5a33a22018-05-07 18:09:14 +053012394 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070012395 case 2:
12396 thresh = config_params[1];
Alok Kumarb5a33a22018-05-07 18:09:14 +053012397 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070012398 case 1:
12399 live_mode = config_params[0];
Alok Kumarb5a33a22018-05-07 18:09:14 +053012400 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070012401 default:
Dustin Browna7bb6ae2018-08-16 16:51:50 -070012402 hdd_debug("live_mode %u thresh %u time_limit %u verbosity %u bitmap 0x%x",
12403 live_mode, thresh, thresh_time_limit,
12404 verbosity, proto_bitmap);
Mohit Khannaf8f96822017-05-17 17:11:59 -070012405 };
12406
12407 qdf_dp_trace_init(live_mode, thresh, thresh_time_limit,
12408 verbosity, proto_bitmap);
12409
12410}
Nirav Shahd21a2e32018-04-20 16:34:43 +053012411#endif
12412
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012413#ifdef DISABLE_CHANNEL_LIST
Dustin Brown623e7e32018-09-05 14:27:50 -070012414static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012415{
12416 return qdf_mutex_create(&hdd_ctx->cache_channel_lock);
12417}
12418#else
Dustin Brown623e7e32018-09-05 14:27:50 -070012419static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012420{
Dustin Brown623e7e32018-09-05 14:27:50 -070012421 return QDF_STATUS_SUCCESS;
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012422}
12423#endif
12424
Dustin Brown693b5352019-01-17 10:00:31 -080012425static QDF_STATUS hdd_open_adapter_no_trans(struct hdd_context *hdd_ctx,
12426 enum QDF_OPMODE op_mode,
12427 const char *iface_name,
12428 uint8_t *mac_addr_bytes)
12429{
Dustin Brown2c5e0482019-02-05 16:14:43 -080012430 struct osif_vdev_sync *vdev_sync;
Dustin Brown693b5352019-01-17 10:00:31 -080012431 struct hdd_adapter *adapter;
12432 QDF_STATUS status;
12433 int errno;
12434
12435 QDF_BUG(rtnl_is_locked());
Dustin Brown693b5352019-01-17 10:00:31 -080012436
Dustin Brown2c5e0482019-02-05 16:14:43 -080012437 errno = osif_vdev_sync_create(hdd_ctx->parent_dev, &vdev_sync);
Dustin Brown693b5352019-01-17 10:00:31 -080012438 if (errno)
12439 return qdf_status_from_os_return(errno);
12440
12441 adapter = hdd_open_adapter(hdd_ctx, op_mode, iface_name,
12442 mac_addr_bytes, NET_NAME_UNKNOWN, true);
12443 if (!adapter) {
12444 status = QDF_STATUS_E_INVAL;
12445 goto destroy_sync;
12446 }
12447
Dustin Brown2c5e0482019-02-05 16:14:43 -080012448 osif_vdev_sync_register(adapter->dev, vdev_sync);
Dustin Brown693b5352019-01-17 10:00:31 -080012449
12450 return QDF_STATUS_SUCCESS;
12451
12452destroy_sync:
Dustin Brown2c5e0482019-02-05 16:14:43 -080012453 osif_vdev_sync_destroy(vdev_sync);
Dustin Brown693b5352019-01-17 10:00:31 -080012454
12455 return status;
12456}
12457
12458#ifdef WLAN_OPEN_P2P_INTERFACE
12459/**
12460 * hdd_open_p2p_interface - Open P2P interface
12461 * @hdd_ctx: HDD context
12462 *
12463 * Return: QDF_STATUS
12464 */
12465static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
12466{
12467 QDF_STATUS status;
12468 bool p2p_dev_addr_admin;
12469 bool is_p2p_locally_administered = false;
12470
12471 cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
12472
12473 if (p2p_dev_addr_admin) {
12474 if (hdd_ctx->num_provisioned_addr &&
12475 !(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) {
12476 hdd_ctx->p2p_device_address =
12477 hdd_ctx->provisioned_mac_addr[0];
12478
12479 /*
12480 * Generate the P2P Device Address. This consists of
12481 * the device's primary MAC address with the locally
12482 * administered bit set.
12483 */
12484
12485 hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
12486 is_p2p_locally_administered = true;
12487 } else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) {
12488 hdd_ctx->p2p_device_address =
12489 hdd_ctx->derived_mac_addr[0];
12490 /*
12491 * Generate the P2P Device Address. This consists of
12492 * the device's primary MAC address with the locally
12493 * administered bit set.
12494 */
12495 hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
12496 is_p2p_locally_administered = true;
12497 }
12498 }
12499 if (!is_p2p_locally_administered) {
12500 uint8_t *p2p_dev_addr;
12501
12502 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx,
12503 QDF_P2P_DEVICE_MODE);
12504 if (!p2p_dev_addr) {
12505 hdd_err("Failed to get MAC address for new p2p device");
12506 return QDF_STATUS_E_INVAL;
12507 }
12508
12509 qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
12510 p2p_dev_addr, QDF_MAC_ADDR_SIZE);
12511 }
12512
12513 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_P2P_DEVICE_MODE,
12514 "p2p%d",
12515 hdd_ctx->p2p_device_address.bytes);
12516 if (QDF_IS_STATUS_ERROR(status)) {
12517 hdd_err("Failed to open p2p interface");
12518 return QDF_STATUS_E_INVAL;
12519 }
12520
12521 return QDF_STATUS_SUCCESS;
12522}
12523#else
12524static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
12525{
12526 return QDF_STATUS_SUCCESS;
12527}
12528#endif
12529
12530static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
12531{
12532 QDF_STATUS status;
12533 uint8_t *mac_addr;
12534
12535 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE);
12536 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE,
12537 "wlanocb%d", mac_addr);
12538 if (QDF_IS_STATUS_ERROR(status))
12539 hdd_err("Failed to open 802.11p interface");
12540
12541 return status;
12542}
12543
12544static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
12545{
12546 QDF_STATUS status;
12547 const char *iface_name;
12548 uint8_t *mac_addr;
12549
12550 if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, ""))
12551 return QDF_STATUS_SUCCESS;
12552
12553 iface_name = hdd_ctx->config->enable_concurrent_sta;
12554 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
12555 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
12556 iface_name, mac_addr);
12557 if (QDF_IS_STATUS_ERROR(status))
12558 hdd_err("Failed to open concurrent station interface");
12559
12560 return status;
12561}
12562
Dustin Brown61cc3932018-10-18 16:12:13 -070012563static QDF_STATUS
12564hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
Dustin Browna2deeb72018-10-18 14:19:27 -070012565{
Dustin Browna2deeb72018-10-18 14:19:27 -070012566 enum dot11p_mode dot11p_mode;
Dustin Brown61cc3932018-10-18 16:12:13 -070012567 QDF_STATUS status;
Dustin Brown693b5352019-01-17 10:00:31 -080012568 uint8_t *mac_addr;
Dustin Browna2deeb72018-10-18 14:19:27 -070012569
12570 ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode);
12571
12572 /* Create only 802.11p interface? */
12573 if (dot11p_mode == CFG_11P_STANDALONE)
Dustin Brown61cc3932018-10-18 16:12:13 -070012574 return hdd_open_ocb_interface(hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070012575
Dustin Brown693b5352019-01-17 10:00:31 -080012576 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
12577 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
12578 "wlan%d", mac_addr);
12579 if (QDF_IS_STATUS_ERROR(status))
12580 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070012581
Dustin Brown61cc3932018-10-18 16:12:13 -070012582 /* opening concurrent STA is best effort, continue on error */
12583 hdd_open_concurrent_interface(hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070012584
Dustin Brown61cc3932018-10-18 16:12:13 -070012585 status = hdd_open_p2p_interface(hdd_ctx);
12586 if (status)
Dustin Browna2deeb72018-10-18 14:19:27 -070012587 goto err_close_adapters;
12588
12589 /* Open 802.11p Interface */
12590 if (dot11p_mode == CFG_11P_CONCURRENT) {
Dustin Brown61cc3932018-10-18 16:12:13 -070012591 status = hdd_open_ocb_interface(hdd_ctx);
12592 if (QDF_IS_STATUS_ERROR(status))
Dustin Browna2deeb72018-10-18 14:19:27 -070012593 goto err_close_adapters;
12594 }
12595
Dustin Brown61cc3932018-10-18 16:12:13 -070012596 return QDF_STATUS_SUCCESS;
Dustin Browna2deeb72018-10-18 14:19:27 -070012597
12598err_close_adapters:
12599 hdd_close_all_adapters(hdd_ctx, true);
12600
Dustin Brown61cc3932018-10-18 16:12:13 -070012601 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070012602}
12603
Dustin Brown61cc3932018-10-18 16:12:13 -070012604static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx)
Dustin Browna2deeb72018-10-18 14:19:27 -070012605{
Dustin Brown693b5352019-01-17 10:00:31 -080012606 uint8_t *mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE);
Dustin Brown61cc3932018-10-18 16:12:13 -070012607
Dustin Brown693b5352019-01-17 10:00:31 -080012608 return hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE,
12609 "wlan%d", mac_addr);
Dustin Brown61cc3932018-10-18 16:12:13 -070012610}
12611
12612static QDF_STATUS
12613hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx)
12614{
Dustin Brown693b5352019-01-17 10:00:31 -080012615 uint8_t *mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE);
Dustin Brown61cc3932018-10-18 16:12:13 -070012616
Dustin Brown693b5352019-01-17 10:00:31 -080012617 return hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE,
12618 "wlan%d", mac_addr);
Dustin Brown61cc3932018-10-18 16:12:13 -070012619}
12620
12621static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx)
12622{
Nirav Shah6aeecf92019-02-13 14:05:03 +053012623 epping_enable_adapter();
Dustin Brown61cc3932018-10-18 16:12:13 -070012624 return QDF_STATUS_SUCCESS;
Dustin Brown61cc3932018-10-18 16:12:13 -070012625}
12626
12627typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx);
12628
12629static const hdd_open_mode_handler
12630hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = {
12631 [QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode,
12632 [QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode,
12633 [QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode,
12634 [QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode,
12635};
12636
Dustin Brown92bd8382018-10-31 15:49:46 -070012637static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
12638 enum QDF_GLOBAL_MODE driver_mode)
Dustin Brown61cc3932018-10-18 16:12:13 -070012639{
12640 QDF_STATUS status;
12641
12642 if (driver_mode < 0 ||
12643 driver_mode >= QDF_GLOBAL_MAX_MODE ||
12644 !hdd_open_mode_handlers[driver_mode]) {
12645 hdd_err("Driver mode %d not supported", driver_mode);
12646 return -ENOTSUPP;
12647 }
Dustin Browna2deeb72018-10-18 14:19:27 -070012648
12649 hdd_hold_rtnl_lock();
Dustin Brown61cc3932018-10-18 16:12:13 -070012650 status = hdd_open_mode_handlers[driver_mode](hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070012651 hdd_release_rtnl_lock();
12652
Dustin Brown92bd8382018-10-31 15:49:46 -070012653 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070012654}
12655
Dustin Brown623e7e32018-09-05 14:27:50 -070012656int hdd_wlan_startup(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080012657{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012658 QDF_STATUS status;
Dustin Brown623e7e32018-09-05 14:27:50 -070012659 int errno;
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +053012660 bool is_imps_enabled;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080012661
Dustin Brown491d54b2018-03-14 12:39:11 -070012662 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080012663
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053012664 hdd_action_oui_config(hdd_ctx);
12665
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +053012666 qdf_nbuf_init_replenish_timer();
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012667
Dustin Brown623e7e32018-09-05 14:27:50 -070012668 status = wlan_hdd_cache_chann_mutex_create(hdd_ctx);
12669 if (QDF_IS_STATUS_ERROR(status))
12670 return qdf_status_to_os_return(status);
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012671
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +053012672#ifdef FEATURE_WLAN_CH_AVOID
12673 mutex_init(&hdd_ctx->avoid_freq_lock);
12674#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053012675
Naveen Rawate02f8f52018-04-05 11:58:04 -070012676 osif_request_manager_init();
Dustin Brown021cecd2017-12-11 13:56:43 -080012677 hdd_driver_memdump_init();
Dustin Brown86d196b2018-08-02 11:51:49 -070012678 hdd_bus_bandwidth_init(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -080012679
Dustin Brown623e7e32018-09-05 14:27:50 -070012680 errno = hdd_wlan_start_modules(hdd_ctx, false);
12681 if (errno) {
12682 hdd_err("Failed to start modules; errno:%d", errno);
12683 goto memdump_deinit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012684 }
12685
Nirav Shah6aeecf92019-02-13 14:05:03 +053012686 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
12687 return 0;
12688
Yingying Tang80e15f32016-09-27 18:23:01 +080012689 wlan_hdd_update_wiphy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012690
Dustin Brown623e7e32018-09-05 14:27:50 -070012691 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
12692 if (!hdd_ctx->mac_handle) {
Jeff Johnson16528362018-06-14 12:34:16 -070012693 hdd_err("Mac Handle is null");
Dustin Brown623e7e32018-09-05 14:27:50 -070012694 goto stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012695 }
12696
Dustin Brown623e7e32018-09-05 14:27:50 -070012697 errno = hdd_wiphy_init(hdd_ctx);
12698 if (errno) {
12699 hdd_err("Failed to initialize wiphy; errno:%d", errno);
12700 goto stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012701 }
12702
Nirav Shahd21a2e32018-04-20 16:34:43 +053012703 hdd_dp_trace_init(hdd_ctx->config);
Nirav Shahcc1f1ae2016-04-26 11:41:29 +053012704
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053012705 errno = hdd_initialize_mac_address(hdd_ctx);
12706 if (errno) {
12707 hdd_err("MAC initializtion failed: %d", errno);
12708 goto unregister_wiphy;
12709 }
Prashanth Bhatta75fa9a12016-01-11 18:30:08 -080012710
Dustin Brown623e7e32018-09-05 14:27:50 -070012711 errno = register_netdevice_notifier(&hdd_netdev_notifier);
12712 if (errno) {
12713 hdd_err("register_netdevice_notifier failed; errno:%d", errno);
12714 goto unregister_wiphy;
Paul Zhangfb02f452017-12-22 11:58:43 +080012715 }
Arun Khandavalli08479ba2017-08-07 19:56:23 +053012716
Sandeep Puligilla34618782019-01-04 17:42:42 -080012717 wlan_hdd_update_11n_mode(hdd_ctx);
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080012718
Arunk Khandavalli40943af2017-05-15 19:25:34 +053012719 hdd_lpass_notify_wlan_version(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012720
Dustin Brown623e7e32018-09-05 14:27:50 -070012721 errno = hdd_register_notifiers(hdd_ctx);
12722 if (errno)
Arun Kumar Khandavalli4b6e2182019-04-29 18:32:09 +053012723 goto unregister_netdev;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -070012724
Paul Zhangfb02f452017-12-22 11:58:43 +080012725 status = wlansap_global_init();
Dustin Brown92bd8382018-10-31 15:49:46 -070012726 if (QDF_IS_STATUS_ERROR(status))
12727 goto unregister_notifiers;
Paul Zhangfb02f452017-12-22 11:58:43 +080012728
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +053012729 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
12730 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
Arun Kumar Khandavallideda5a82019-03-11 15:32:19 +053012731 hdd_debugfs_mws_coex_info_init(hdd_ctx);
Paul Zhang37185672019-05-14 11:20:14 +080012732 wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012733
Dustin Brown92bd8382018-10-31 15:49:46 -070012734 hdd_exit();
12735
12736 return 0;
12737
12738unregister_notifiers:
12739 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012740
Dustin Brown623e7e32018-09-05 14:27:50 -070012741unregister_netdev:
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053012742 unregister_netdevice_notifier(&hdd_netdev_notifier);
12743
Dustin Brown623e7e32018-09-05 14:27:50 -070012744unregister_wiphy:
Rachit Kankane30807332018-06-27 18:39:36 +053012745 qdf_dp_trace_deinit();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080012746 wiphy_unregister(hdd_ctx->wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012747
Dustin Brown623e7e32018-09-05 14:27:50 -070012748stop_modules:
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070012749 hdd_wlan_stop_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +053012750
Dustin Brown623e7e32018-09-05 14:27:50 -070012751memdump_deinit:
Dustin Brown86d196b2018-08-02 11:51:49 -070012752 hdd_bus_bandwidth_deinit(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -080012753 hdd_driver_memdump_deinit();
Naveen Rawate02f8f52018-04-05 11:58:04 -070012754 osif_request_manager_deinit();
Dustin Brown623e7e32018-09-05 14:27:50 -070012755 qdf_nbuf_deinit_replenish_timer();
Ryan Hsucfef0ae2016-04-28 10:20:46 -070012756
Nachiket Kukade8003d252017-03-30 15:55:58 +053012757 if (cds_is_fw_down())
12758 hdd_err("Not setting the complete event as fw is down");
12759 else
Dustin Brown623e7e32018-09-05 14:27:50 -070012760 hdd_start_complete(errno);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012761
Dustin Browne74003f2018-03-14 12:51:58 -070012762 hdd_exit();
Dustin Brown92bd8382018-10-31 15:49:46 -070012763
Dustin Brown623e7e32018-09-05 14:27:50 -070012764 return errno;
Dustin Brown92bd8382018-10-31 15:49:46 -070012765}
12766
12767QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx)
12768{
12769 enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam();
12770 QDF_STATUS status;
12771
12772 status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode);
12773 if (QDF_IS_STATUS_ERROR(status)) {
12774 hdd_err("Failed to create vdevs; status:%d", status);
12775 return status;
12776 }
12777
12778 if (hdd_ctx->rps)
12779 hdd_set_rps_cpu_mask(hdd_ctx);
12780
Guisen Yang2780b922019-06-03 16:21:39 +080012781 if (driver_mode != QDF_GLOBAL_FTM_MODE &&
12782 driver_mode != QDF_GLOBAL_EPPING_MODE)
Dustin Brown92bd8382018-10-31 15:49:46 -070012783 hdd_psoc_idle_timer_start(hdd_ctx);
12784
12785 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012786}
12787
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012788/**
Arun Khandavallifae92942016-08-01 13:31:08 +053012789 * hdd_wlan_update_target_info() - update target type info
12790 * @hdd_ctx: HDD context
12791 * @context: hif context
12792 *
12793 * Update target info received from firmware in hdd context
12794 * Return:None
12795 */
12796
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012797void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
Arun Khandavallifae92942016-08-01 13:31:08 +053012798{
12799 struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
12800
12801 if (!tgt_info) {
12802 hdd_err("Target info is Null");
12803 return;
12804 }
12805
12806 hdd_ctx->target_type = tgt_info->target_type;
12807}
12808
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053012809void hdd_get_nud_stats_cb(void *data, struct rsp_stats *rsp, void *context)
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012810{
12811 struct hdd_context *hdd_ctx = (struct hdd_context *)data;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012812 int status;
12813 struct hdd_adapter *adapter = NULL;
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012814 struct osif_request *request = NULL;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012815
Dustin Brown491d54b2018-03-14 12:39:11 -070012816 hdd_enter();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012817
12818 if (!rsp) {
12819 hdd_err("data is null");
12820 return;
12821 }
12822
12823 status = wlan_hdd_validate_context(hdd_ctx);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053012824 if (status != 0)
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012825 return;
12826
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012827 request = osif_request_get(context);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053012828 if (!request) {
12829 hdd_err("obselete request");
12830 return;
12831 }
12832
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012833 adapter = hdd_get_adapter_by_vdev(hdd_ctx, rsp->vdev_id);
Jeff Johnsond36fa332019-03-18 13:42:25 -070012834 if ((!adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012835 hdd_err("Invalid adapter or adapter has invalid magic");
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012836 osif_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012837 return;
12838 }
12839
Alok Kumarce2c29a2018-10-12 15:44:02 +053012840 hdd_debug("rsp->arp_req_enqueue :%x", rsp->arp_req_enqueue);
12841 hdd_debug("rsp->arp_req_tx_success :%x", rsp->arp_req_tx_success);
12842 hdd_debug("rsp->arp_req_tx_failure :%x", rsp->arp_req_tx_failure);
12843 hdd_debug("rsp->arp_rsp_recvd :%x", rsp->arp_rsp_recvd);
12844 hdd_debug("rsp->out_of_order_arp_rsp_drop_cnt :%x",
12845 rsp->out_of_order_arp_rsp_drop_cnt);
12846 hdd_debug("rsp->dad_detected :%x", rsp->dad_detected);
12847 hdd_debug("rsp->connect_status :%x", rsp->connect_status);
12848 hdd_debug("rsp->ba_session_establishment_status :%x",
12849 rsp->ba_session_establishment_status);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012850
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012851 adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012852 adapter->dad |= rsp->dad_detected;
12853 adapter->con_status = rsp->connect_status;
12854
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053012855 /* Flag true indicates connectivity check stats present. */
12856 if (rsp->connect_stats_present) {
Alok Kumarce2c29a2018-10-12 15:44:02 +053012857 hdd_debug("rsp->tcp_ack_recvd :%x", rsp->tcp_ack_recvd);
12858 hdd_debug("rsp->icmpv4_rsp_recvd :%x", rsp->icmpv4_rsp_recvd);
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053012859 adapter->hdd_stats.hdd_tcp_stats.rx_fw_cnt = rsp->tcp_ack_recvd;
12860 adapter->hdd_stats.hdd_icmpv4_stats.rx_fw_cnt =
12861 rsp->icmpv4_rsp_recvd;
12862 }
12863
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012864 osif_request_complete(request);
12865 osif_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012866
Dustin Browne74003f2018-03-14 12:51:58 -070012867 hdd_exit();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012868}
12869
Visweswara Tanuku633976b2019-01-07 16:13:12 +053012870#ifdef WLAN_FEATURE_MOTION_DETECTION
12871/**
12872 * hdd_md_host_evt_cb - Callback for Motion Detection Event
12873 * @ctx: HDD context
12874 * @event: motion detect event
12875 *
12876 * Callback for Motion Detection Event. Re-enables Motion
12877 * Detection again upon event
12878 *
12879 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
12880 * QDF_STATUS_E_FAILURE on failure
12881 */
12882QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event)
12883{
12884 struct hdd_adapter *adapter = NULL;
12885 struct hdd_context *hdd_ctx;
Visweswara Tanuku633976b2019-01-07 16:13:12 +053012886 struct sme_motion_det_en motion_det;
12887
12888 if (!ctx || !event)
12889 return QDF_STATUS_E_INVAL;
12890
12891 hdd_ctx = (struct hdd_context *)ctx;
Visweswara Tanuku41d21c02019-10-25 14:51:59 +053012892 if (wlan_hdd_validate_context(hdd_ctx))
Visweswara Tanuku633976b2019-01-07 16:13:12 +053012893 return QDF_STATUS_E_INVAL;
12894
12895 adapter = hdd_get_adapter_by_vdev(hdd_ctx, event->vdev_id);
12896 if (!adapter || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
12897 hdd_err("Invalid adapter or adapter has invalid magic");
12898 return QDF_STATUS_E_INVAL;
12899 }
12900
Visweswara Tanuku6aca9212019-10-31 20:38:29 +053012901 /* When motion is detected, reset the motion_det_in_progress flag */
12902 if (event->status)
12903 adapter->motion_det_in_progress = false;
12904
Visweswara Tanuku633976b2019-01-07 16:13:12 +053012905 hdd_debug("Motion Detection CB vdev_id=%u, status=%u",
12906 event->vdev_id, event->status);
12907
12908 if (adapter->motion_detection_mode) {
12909 motion_det.vdev_id = event->vdev_id;
12910 motion_det.enable = 1;
12911 hdd_debug("Motion Detect CB -> Enable Motion Detection again");
12912 sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det);
12913 }
12914
12915 return QDF_STATUS_SUCCESS;
12916}
Visweswara Tanuku41d21c02019-10-25 14:51:59 +053012917
12918/**
12919 * hdd_md_bl_evt_cb - Callback for Motion Detection Baseline Event
12920 * @ctx: HDD context
12921 * @event: motion detect baseline event
12922 *
12923 * Callback for Motion Detection Baseline completion
12924 *
12925 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
12926 * QDF_STATUS_E_FAILURE on failure
12927 */
12928QDF_STATUS hdd_md_bl_evt_cb(void *ctx, struct sir_md_bl_evt *event)
12929{
12930 struct hdd_adapter *adapter = NULL;
12931 struct hdd_context *hdd_ctx;
12932
12933 if (!ctx || !event)
12934 return QDF_STATUS_E_INVAL;
12935
12936 hdd_ctx = (struct hdd_context *)ctx;
12937 if (wlan_hdd_validate_context(hdd_ctx))
12938 return QDF_STATUS_E_INVAL;
12939
12940 adapter = hdd_get_adapter_by_vdev(hdd_ctx, event->vdev_id);
12941 if (!adapter || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
12942 hdd_err("Invalid adapter or adapter has invalid magic");
12943 return QDF_STATUS_E_INVAL;
12944 }
12945
12946 hdd_debug("Motion Detection Baseline CB vdev id=%u, baseline val = %d",
12947 event->vdev_id, event->bl_baseline_value);
12948
12949 adapter->motion_det_baseline_value = event->bl_baseline_value;
12950
12951 return QDF_STATUS_SUCCESS;
12952}
Visweswara Tanuku633976b2019-01-07 16:13:12 +053012953#endif /* WLAN_FEATURE_MOTION_DETECTION */
12954
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012955/**
Arun Khandavallifae92942016-08-01 13:31:08 +053012956 * hdd_register_cb - Register HDD callbacks.
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012957 * @hdd_ctx: HDD context
12958 *
12959 * Register the HDD callbacks to CDS/SME.
12960 *
12961 * Return: 0 for success or Error code for failure
12962 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012963int hdd_register_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012964{
12965 QDF_STATUS status;
12966 int ret = 0;
Jeff Johnson16528362018-06-14 12:34:16 -070012967 mac_handle_t mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012968
Dustin Brown491d54b2018-03-14 12:39:11 -070012969 hdd_enter();
Sourav Mohapatra674925f2018-04-16 11:16:58 +053012970 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
12971 hdd_err("in ftm mode, no need to register callbacks");
12972 return ret;
12973 }
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012974
Jeff Johnson16528362018-06-14 12:34:16 -070012975 mac_handle = hdd_ctx->mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012976
Jeff Johnson16528362018-06-14 12:34:16 -070012977 sme_register_oem_data_rsp_callback(mac_handle,
12978 hdd_send_oem_data_rsp_msg);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012979
Jeff Johnson16528362018-06-14 12:34:16 -070012980 sme_register_mgmt_frame_ind_callback(mac_handle,
Deepthi Gowrid5a58fe2016-09-03 16:01:28 +053012981 hdd_indicate_mgmt_frame);
Jeff Johnson16528362018-06-14 12:34:16 -070012982 sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx);
Jeff Johnson16528362018-06-14 12:34:16 -070012983 sme_stats_ext_register_callback(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012984 wlan_hdd_cfg80211_stats_ext_callback);
12985
Jeff Johnson16528362018-06-14 12:34:16 -070012986 sme_ext_scan_register_callback(mac_handle,
12987 wlan_hdd_cfg80211_extscan_callback);
12988 sme_stats_ext2_register_callback(mac_handle,
lifeng66831662017-05-19 16:01:35 +080012989 wlan_hdd_cfg80211_stats_ext2_callback);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012990
Jeff Johnson16528362018-06-14 12:34:16 -070012991 sme_set_rssi_threshold_breached_cb(mac_handle,
12992 hdd_rssi_threshold_breached);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012993
Jeff Johnson16528362018-06-14 12:34:16 -070012994 sme_set_link_layer_stats_ind_cb(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012995 wlan_hdd_cfg80211_link_layer_stats_callback);
12996
Jeff Johnson16528362018-06-14 12:34:16 -070012997 sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb);
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +053012998
Jeff Johnson16528362018-06-14 12:34:16 -070012999 sme_set_link_layer_ext_cb(mac_handle,
Zhang Qianca38fb12016-12-23 11:10:48 +080013000 wlan_hdd_cfg80211_link_layer_stats_ext_callback);
Abhinav Kumar338e57d2019-02-04 17:30:10 +053013001 sme_update_hidden_ssid_status_cb(mac_handle,
13002 hdd_hidden_ssid_enable_roaming);
Zhang Qianca38fb12016-12-23 11:10:48 +080013003
Jeff Johnson16528362018-06-14 12:34:16 -070013004 status = sme_set_lost_link_info_cb(mac_handle,
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +053013005 hdd_lost_link_info_cb);
Ashish Kumar Dhanotiya017e5022019-07-23 20:58:11 +053013006
13007 wlan_hdd_register_cp_stats_cb(hdd_ctx);
13008
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +053013009 /* print error and not block the startup process */
13010 if (!QDF_IS_STATUS_SUCCESS(status))
13011 hdd_err("set lost link info callback failed");
13012
Poddar, Siddarth34872782017-08-10 14:08:51 +053013013 ret = hdd_register_data_stall_detect_cb();
13014 if (ret) {
13015 hdd_err("Register data stall detect detect callback failed.");
13016 return ret;
13017 }
13018
Arun Khandavalli4b55da72016-07-19 19:55:01 +053013019 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
13020
Jeff Johnson16528362018-06-14 12:34:16 -070013021 sme_register_set_connection_info_cb(mac_handle,
13022 hdd_set_connection_in_progress,
13023 hdd_is_connection_in_progress);
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +053013024
Jeff Johnson16528362018-06-14 12:34:16 -070013025 status = sme_set_bt_activity_info_cb(mac_handle,
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053013026 hdd_bt_activity_cb);
13027 if (!QDF_IS_STATUS_SUCCESS(status))
13028 hdd_err("set bt activity info callback failed");
13029
Jeff Johnson16528362018-06-14 12:34:16 -070013030 status = sme_register_tx_queue_cb(mac_handle,
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -080013031 hdd_tx_queue_cb);
13032 if (!QDF_IS_STATUS_SUCCESS(status))
13033 hdd_err("Register tx queue callback failed");
13034
Visweswara Tanuku633976b2019-01-07 16:13:12 +053013035#ifdef WLAN_FEATURE_MOTION_DETECTION
13036 sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx);
Visweswara Tanuku41d21c02019-10-25 14:51:59 +053013037 sme_set_md_bl_evt_cb(mac_handle, hdd_md_bl_evt_cb, (void *)hdd_ctx);
Visweswara Tanuku633976b2019-01-07 16:13:12 +053013038#endif /* WLAN_FEATURE_MOTION_DETECTION */
13039
Arun Kumar Khandavalli42b44872019-10-21 19:02:04 +053013040 mac_register_sesssion_open_close_cb(hdd_ctx->mac_handle,
13041 hdd_sme_close_session_callback,
13042 hdd_common_roam_callback);
13043
Dustin Browne74003f2018-03-14 12:51:58 -070013044 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053013045
13046 return ret;
13047}
13048
13049/**
13050 * hdd_deregister_cb() - De-Register HDD callbacks.
13051 * @hdd_ctx: HDD context
13052 *
13053 * De-Register the HDD callbacks to CDS/SME.
13054 *
13055 * Return: void
13056 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013057void hdd_deregister_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053013058{
13059 QDF_STATUS status;
Poddar, Siddarth34872782017-08-10 14:08:51 +053013060 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -070013061 mac_handle_t mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053013062
Dustin Brown491d54b2018-03-14 12:39:11 -070013063 hdd_enter();
Sourav Mohapatra674925f2018-04-16 11:16:58 +053013064 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
13065 hdd_err("in ftm mode, no need to deregister callbacks");
13066 return;
13067 }
Arun Khandavalli4b55da72016-07-19 19:55:01 +053013068
Jeff Johnson16528362018-06-14 12:34:16 -070013069 mac_handle = hdd_ctx->mac_handle;
13070 sme_deregister_tx_queue_cb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053013071
Jeff Johnson16528362018-06-14 12:34:16 -070013072 sme_reset_link_layer_stats_ind_cb(mac_handle);
13073 sme_reset_rssi_threshold_breached_cb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053013074
Min Liud35ae312019-05-08 15:43:13 +080013075 sme_stats_ext_deregister_callback(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053013076
Jeff Johnson16528362018-06-14 12:34:16 -070013077 status = sme_reset_tsfcb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053013078 if (!QDF_IS_STATUS_SUCCESS(status))
13079 hdd_err("Failed to de-register tsfcb the callback:%d",
13080 status);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053013081
Poddar, Siddarth34872782017-08-10 14:08:51 +053013082 ret = hdd_deregister_data_stall_detect_cb();
13083 if (ret)
13084 hdd_err("Failed to de-register data stall detect event callback");
13085
Jeff Johnson16528362018-06-14 12:34:16 -070013086 sme_deregister_oem_data_rsp_callback(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053013087
Dustin Browne74003f2018-03-14 12:51:58 -070013088 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053013089}
13090
13091/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013092 * hdd_softap_sta_deauth() - handle deauth req from HDD
Jeff Johnson50e37e92019-03-08 11:32:25 -080013093 * @adapter: Pointer to the HDD adapter
13094 * @param: Params to the operation
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013095 *
13096 * This to take counter measure to handle deauth req from HDD
13097 *
13098 * Return: None
13099 */
Jeff Johnson9d295242017-08-29 14:39:48 -070013100QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
Jeff Johnson50e37e92019-03-08 11:32:25 -080013101 struct csr_del_sta_params *param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013102{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053013103 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013104
Dustin Brown491d54b2018-03-14 12:39:11 -070013105 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013106
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013107 /* Ignore request to deauth bcmc station */
Jeff Johnson50e37e92019-03-08 11:32:25 -080013108 if (param->peerMacAddr.bytes[0] & 0x1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053013109 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013110
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053013111 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013112 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Jeff Johnson50e37e92019-03-08 11:32:25 -080013113 param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013114
Dustin Browne74003f2018-03-14 12:51:58 -070013115 hdd_exit();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053013116 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013117}
13118
13119/**
13120 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
Jeff Johnson50e37e92019-03-08 11:32:25 -080013121 * @adapter: Pointer to the HDD
13122 * @param: pointer to station deletion parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013123 *
13124 * This to take counter measure to handle deauth req from HDD
13125 *
13126 * Return: None
13127 */
Jeff Johnson9d295242017-08-29 14:39:48 -070013128void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
Jeff Johnson50e37e92019-03-08 11:32:25 -080013129 struct csr_del_sta_params *param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013130{
Dustin Brown491d54b2018-03-14 12:39:11 -070013131 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013132
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013133 /* Ignore request to disassoc bcmc station */
Jeff Johnson50e37e92019-03-08 11:32:25 -080013134 if (param->peerMacAddr.bytes[0] & 0x1)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013135 return;
13136
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013137 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Jeff Johnson50e37e92019-03-08 11:32:25 -080013138 param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013139}
13140
Abhinav Kumar523ca372019-08-30 16:28:19 +053013141void wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter,
13142 uint32_t mlme_operation_requestor)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013143{
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053013144 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
13145 struct hdd_adapter *adapter = NULL;
13146 struct csr_roam_profile *roam_profile;
13147 struct hdd_station_ctx *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013148
Dustin Brown1dbefe62018-09-11 16:32:03 -070013149 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053013150 hdd_debug("No active sta session");
13151 return;
13152 }
13153
13154 hdd_for_each_adapter(hdd_ctx, adapter) {
13155 roam_profile = hdd_roam_profile(adapter);
13156 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
13157
Jeff Johnson5a6fc962019-02-04 14:20:25 -080013158 if (cur_adapter->vdev_id != adapter->vdev_id &&
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053013159 adapter->device_mode == QDF_STA_MODE &&
13160 hdd_conn_is_connected(sta_ctx)) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -080013161 hdd_debug("%d Disable roaming", adapter->vdev_id);
Jeff Johnson16528362018-06-14 12:34:16 -070013162 sme_stop_roaming(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080013163 adapter->vdev_id,
Abhinav Kumar523ca372019-08-30 16:28:19 +053013164 REASON_DRIVER_DISABLED,
13165 mlme_operation_requestor);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013166 }
13167 }
13168}
13169
Abhinav Kumar523ca372019-08-30 16:28:19 +053013170void wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter,
13171 uint32_t mlme_operation_requestor)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013172{
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053013173 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
13174 struct hdd_adapter *adapter = NULL;
13175 struct csr_roam_profile *roam_profile;
13176 struct hdd_station_ctx *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013177
Dustin Brown1dbefe62018-09-11 16:32:03 -070013178 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053013179 hdd_debug("No active sta session");
13180 return;
13181 }
13182
13183 hdd_for_each_adapter(hdd_ctx, adapter) {
13184 roam_profile = hdd_roam_profile(adapter);
13185 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
13186
Jeff Johnson5a6fc962019-02-04 14:20:25 -080013187 if (cur_adapter->vdev_id != adapter->vdev_id &&
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053013188 adapter->device_mode == QDF_STA_MODE &&
13189 hdd_conn_is_connected(sta_ctx)) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -080013190 hdd_debug("%d Enable roaming", adapter->vdev_id);
Jeff Johnson16528362018-06-14 12:34:16 -070013191 sme_start_roaming(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080013192 adapter->vdev_id,
Abhinav Kumar523ca372019-08-30 16:28:19 +053013193 REASON_DRIVER_ENABLED,
13194 mlme_operation_requestor);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013195 }
13196 }
13197}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013198
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053013199/**
13200 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
13201 * @skb: sk buffer pointer
13202 *
13203 * Sends the bcast message to SVC multicast group with generic nl socket
13204 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
13205 *
13206 * Return: None
13207 */
13208static void nl_srv_bcast_svc(struct sk_buff *skb)
13209{
13210#ifdef CNSS_GENL
13211 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
13212#else
13213 nl_srv_bcast(skb);
13214#endif
13215}
13216
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013217void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013218{
13219 struct sk_buff *skb;
13220 struct nlmsghdr *nlh;
13221 tAniMsgHdr *ani_hdr;
13222 void *nl_data = NULL;
13223 int flags = GFP_KERNEL;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013224 struct radio_index_tlv *radio_info;
13225 int tlv_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013226
13227 if (in_interrupt() || irqs_disabled() || in_atomic())
13228 flags = GFP_ATOMIC;
13229
13230 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
13231
Jeff Johnsond36fa332019-03-18 13:42:25 -070013232 if (!skb)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013233 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013234
13235 nlh = (struct nlmsghdr *)skb->data;
13236 nlh->nlmsg_pid = 0; /* from kernel */
13237 nlh->nlmsg_flags = 0;
13238 nlh->nlmsg_seq = 0;
13239 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
13240
13241 ani_hdr = NLMSG_DATA(nlh);
13242 ani_hdr->type = type;
13243
13244 switch (type) {
13245 case WLAN_SVC_FW_CRASHED_IND:
Komal Seelam78ff65a2016-08-18 15:25:24 +053013246 case WLAN_SVC_FW_SHUTDOWN_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013247 case WLAN_SVC_LTE_COEX_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013248 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070013249 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013250 ani_hdr->length = 0;
13251 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013252 break;
13253 case WLAN_SVC_WLAN_STATUS_IND:
13254 case WLAN_SVC_WLAN_VERSION_IND:
13255 case WLAN_SVC_DFS_CAC_START_IND:
13256 case WLAN_SVC_DFS_CAC_END_IND:
13257 case WLAN_SVC_DFS_RADAR_DETECT_IND:
13258 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
13259 case WLAN_SVC_WLAN_TP_IND:
Mohit Khannae71e2262015-11-10 09:37:24 -080013260 case WLAN_SVC_WLAN_TP_TX_IND:
Nirav Shahbd36b062016-07-18 11:12:59 +053013261 case WLAN_SVC_RPS_ENABLE_IND:
Orhan K AKYILDIZe7445a22017-01-19 21:21:47 -080013262 case WLAN_SVC_CORE_MINFREQ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013263 ani_hdr->length = len;
13264 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
13265 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
13266 memcpy(nl_data, data, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013267 break;
13268
13269 default:
Jeff Johnson34c88b72016-08-15 14:27:11 -070013270 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013271 type);
13272 kfree_skb(skb);
13273 return;
13274 }
13275
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013276 /*
Jeff Johnson0d52c7a2017-01-12 08:46:55 -080013277 * Add radio index at the end of the svc event in TLV format
13278 * to maintain the backward compatibility with userspace
13279 * applications.
13280 */
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013281
13282 tlv_len = 0;
13283
13284 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
13285 < WLAN_NL_MAX_PAYLOAD) {
13286 radio_info = (struct radio_index_tlv *)((char *) ani_hdr +
13287 sizeof(*ani_hdr) + len);
13288 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
13289 radio_info->length = (unsigned short) sizeof(radio_info->radio);
13290 radio_info->radio = radio;
13291 tlv_len = sizeof(*radio_info);
Dustin Browna2868622018-03-20 11:38:14 -070013292 hdd_debug("Added radio index tlv - radio index %d",
13293 radio_info->radio);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013294 }
13295
13296 nlh->nlmsg_len += tlv_len;
13297 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
13298
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053013299 nl_srv_bcast_svc(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013300}
13301
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013302#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
13303void wlan_hdd_auto_shutdown_cb(void)
13304{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013305 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013306
13307 if (!hdd_ctx)
13308 return;
13309
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013310 hdd_debug("Wlan Idle. Sending Shutdown event..");
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013311 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
13312 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013313}
13314
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013315void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013316{
Jeff Johnson9d295242017-08-29 14:39:48 -070013317 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013318 bool ap_connected = false, sta_connected = false;
Jeff Johnson16528362018-06-14 12:34:16 -070013319 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013320
Jeff Johnson16528362018-06-14 12:34:16 -070013321 mac_handle = hdd_ctx->mac_handle;
13322 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013323 return;
13324
Dundi Raviteja8e338282018-09-25 17:16:04 +053013325 if (hdd_ctx->config->wlan_auto_shutdown == 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013326 return;
13327
13328 if (enable == false) {
Jeff Johnson16528362018-06-14 12:34:16 -070013329 if (sme_set_auto_shutdown_timer(mac_handle, 0) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053013330 QDF_STATUS_SUCCESS) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070013331 hdd_err("Failed to stop wlan auto shutdown timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013332 }
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013333 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070013334 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013335 return;
13336 }
13337
13338 /* To enable shutdown timer check conncurrency */
Dustin Brown1dbefe62018-09-11 16:32:03 -070013339 if (policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc)) {
Dustin Brown920397d2017-12-13 16:27:50 -080013340 hdd_for_each_adapter(hdd_ctx, adapter) {
13341 if (adapter->device_mode == QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013342 if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
Jeff Johnsone7951512019-02-27 10:02:51 -080013343 conn_info.conn_state ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013344 eConnectionState_Associated) {
13345 sta_connected = true;
13346 break;
13347 }
13348 }
Dustin Brown920397d2017-12-13 16:27:50 -080013349
13350 if (adapter->device_mode == QDF_SAP_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013351 if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
Jeff Johnson136c51b2017-10-27 20:02:41 -070013352 ap_active == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013353 ap_connected = true;
13354 break;
13355 }
13356 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013357 }
13358 }
13359
13360 if (ap_connected == true || sta_connected == true) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013361 hdd_debug("CC Session active. Shutdown timer not enabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013362 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013363 }
Jeff Johnson68755312017-02-10 11:46:55 -080013364
Jeff Johnson16528362018-06-14 12:34:16 -070013365 if (sme_set_auto_shutdown_timer(mac_handle,
Dundi Raviteja8e338282018-09-25 17:16:04 +053013366 hdd_ctx->config->wlan_auto_shutdown)
Jeff Johnson68755312017-02-10 11:46:55 -080013367 != QDF_STATUS_SUCCESS)
13368 hdd_err("Failed to start wlan auto shutdown timer");
13369 else
Dustin Brown5e89ef82018-03-14 11:50:23 -070013370 hdd_info("Auto Shutdown timer for %d seconds enabled",
Dundi Raviteja8e338282018-09-25 17:16:04 +053013371 hdd_ctx->config->wlan_auto_shutdown);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013372}
13373#endif
13374
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070013375struct hdd_adapter *
13376hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
13377 bool check_start_bss)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013378{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013379 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070013380 struct hdd_adapter *adapter, *con_sap_adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013381
13382 con_sap_adapter = NULL;
13383
Dustin Brown920397d2017-12-13 16:27:50 -080013384 hdd_for_each_adapter(hdd_ctx, adapter) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080013385 if (adapter && ((adapter->device_mode == QDF_SAP_MODE) ||
13386 (adapter->device_mode == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013387 adapter != this_sap_adapter) {
13388 if (check_start_bss) {
13389 if (test_bit(SOFTAP_BSS_STARTED,
13390 &adapter->event_flags)) {
13391 con_sap_adapter = adapter;
13392 break;
13393 }
13394 } else {
13395 con_sap_adapter = adapter;
13396 break;
13397 }
13398 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013399 }
13400
13401 return con_sap_adapter;
13402}
13403
Tiger Yu8b119e92019-04-09 13:55:07 +080013404#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
Jeff Johnson9d295242017-08-29 14:39:48 -070013405static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013406{
Dustin Brown5ec6b552017-03-31 12:11:40 -070013407 return adapter->device_mode == QDF_STA_MODE ||
13408 adapter->device_mode == QDF_P2P_CLIENT_MODE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013409}
13410
Jeff Johnson9d295242017-08-29 14:39:48 -070013411static inline bool hdd_adapter_is_ap(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013412{
Dustin Brown5ec6b552017-03-31 12:11:40 -070013413 return adapter->device_mode == QDF_SAP_MODE ||
13414 adapter->device_mode == QDF_P2P_GO_MODE;
13415}
13416
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013417static bool hdd_any_adapter_is_assoc(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013418{
Dustin Brown920397d2017-12-13 16:27:50 -080013419 struct hdd_adapter *adapter;
Dustin Brown5ec6b552017-03-31 12:11:40 -070013420
Dustin Brown920397d2017-12-13 16:27:50 -080013421 hdd_for_each_adapter(hdd_ctx, adapter) {
13422 if (hdd_adapter_is_sta(adapter) &&
Dustin Brown5ec6b552017-03-31 12:11:40 -070013423 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
Jeff Johnsone7951512019-02-27 10:02:51 -080013424 conn_info.conn_state == eConnectionState_Associated) {
Dustin Brown5ec6b552017-03-31 12:11:40 -070013425 return true;
13426 }
13427
Dustin Brown920397d2017-12-13 16:27:50 -080013428 if (hdd_adapter_is_ap(adapter) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -070013429 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active) {
Dustin Brown5ec6b552017-03-31 12:11:40 -070013430 return true;
13431 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070013432 }
13433
13434 return false;
13435}
13436
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013437static void __hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013438{
Dustin Browna20bad52019-03-05 12:03:30 -080013439 qdf_periodic_work_start(&hdd_ctx->bus_bw_work,
13440 hdd_ctx->config->bus_bw_compute_interval);
Dustin Brown5ec6b552017-03-31 12:11:40 -070013441}
13442
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013443void hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013444{
Dustin Brown491d54b2018-03-14 12:39:11 -070013445 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013446
Dustin Brown5ec6b552017-03-31 12:11:40 -070013447 __hdd_bus_bw_compute_timer_start(hdd_ctx);
13448
Dustin Browne74003f2018-03-14 12:51:58 -070013449 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013450}
13451
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013452void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013453{
Dustin Brown491d54b2018-03-14 12:39:11 -070013454 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013455
Dustin Brown5ec6b552017-03-31 12:11:40 -070013456 if (hdd_any_adapter_is_assoc(hdd_ctx))
13457 __hdd_bus_bw_compute_timer_start(hdd_ctx);
13458
Dustin Browne74003f2018-03-14 12:51:58 -070013459 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013460}
13461
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013462static void __hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013463{
Dustin Browna20bad52019-03-05 12:03:30 -080013464 if (!qdf_periodic_work_stop_sync(&hdd_ctx->bus_bw_work))
13465 return;
13466
Dustin Brown07901ec2018-09-07 11:02:41 -070013467 ucfg_ipa_set_perf_level(hdd_ctx->pdev, 0, 0);
Dustin Brown5ec6b552017-03-31 12:11:40 -070013468 hdd_reset_tcp_delack(hdd_ctx);
Tiger Yue40e7832019-04-25 10:46:53 +080013469 cdp_pdev_reset_driver_del_ack(cds_get_context(QDF_MODULE_ID_SOC),
Rakesh Pillai6a36b0a2019-09-06 16:30:05 +053013470 OL_TXRX_PDEV_ID);
Dustin Brown5ec6b552017-03-31 12:11:40 -070013471}
13472
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013473void hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013474{
Dustin Brown491d54b2018-03-14 12:39:11 -070013475 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013476
Dustin Brown5ec6b552017-03-31 12:11:40 -070013477 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
13478
Dustin Browne74003f2018-03-14 12:51:58 -070013479 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013480}
13481
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013482void hdd_bus_bw_compute_timer_try_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013483{
Dustin Brown491d54b2018-03-14 12:39:11 -070013484 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013485
Dustin Brown5ec6b552017-03-31 12:11:40 -070013486 if (!hdd_any_adapter_is_assoc(hdd_ctx))
13487 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
13488
Dustin Browne74003f2018-03-14 12:51:58 -070013489 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013490}
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +053013491
13492void hdd_bus_bw_compute_prev_txrx_stats(struct hdd_adapter *adapter)
13493{
13494 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13495
13496 qdf_spin_lock_bh(&hdd_ctx->bus_bw_lock);
13497 adapter->prev_tx_packets = adapter->stats.tx_packets;
13498 adapter->prev_rx_packets = adapter->stats.rx_packets;
13499 cdp_get_intra_bss_fwd_pkts_count(cds_get_context(QDF_MODULE_ID_SOC),
13500 adapter->vdev_id,
13501 &adapter->prev_fwd_tx_packets,
13502 &adapter->prev_fwd_rx_packets);
13503 qdf_spin_unlock_bh(&hdd_ctx->bus_bw_lock);
13504}
13505
13506void hdd_bus_bw_compute_reset_prev_txrx_stats(struct hdd_adapter *adapter)
13507{
13508 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13509
13510 qdf_spin_lock_bh(&hdd_ctx->bus_bw_lock);
13511 adapter->prev_tx_packets = 0;
13512 adapter->prev_rx_packets = 0;
13513 adapter->prev_fwd_tx_packets = 0;
13514 adapter->prev_fwd_rx_packets = 0;
13515 qdf_spin_unlock_bh(&hdd_ctx->bus_bw_lock);
13516}
13517
Tiger Yu8b119e92019-04-09 13:55:07 +080013518#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013519
13520/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013521 * wlan_hdd_stop_sap() - This function stops bss of SAP.
13522 * @ap_adapter: SAP adapter
13523 *
13524 * This function will process the stopping of sap adapter.
13525 *
13526 * Return: None
13527 */
Jeff Johnson9d295242017-08-29 14:39:48 -070013528void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013529{
Jeff Johnson87251032017-08-29 13:31:11 -070013530 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070013531 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053013532 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013533 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013534
Jeff Johnsond36fa332019-03-18 13:42:25 -070013535 if (!ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070013536 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013537 return;
13538 }
13539
13540 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
13541 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Abhishek Singh23edd1c2016-05-05 11:56:06 +053013542 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013543 return;
Abhishek Singh23edd1c2016-05-05 11:56:06 +053013544
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013545 mutex_lock(&hdd_ctx->sap_lock);
13546 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080013547 wlan_hdd_del_station(ap_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013548 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013549 hdd_debug("Now doing SAP STOPBSS");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053013550 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053013551 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070013552 sap_context)) {
Nachiket Kukade0396b732017-11-14 16:35:16 +053013553 qdf_status = qdf_wait_for_event_completion(&hostapd_state->
Naveen Rawatb56880c2016-12-13 17:56:03 -080013554 qdf_stop_bss_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053013555 SME_CMD_STOP_BSS_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +053013556 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013557 mutex_unlock(&hdd_ctx->sap_lock);
Jeff Johnson28f8a772016-08-15 15:30:36 -070013558 hdd_err("SAP Stop Failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013559 return;
13560 }
13561 }
13562 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -070013563 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013564 ap_adapter->device_mode,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080013565 ap_adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070013566 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053013567 false);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013568 hdd_debug("SAP Stop Success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013569 } else {
Jeff Johnson28f8a772016-08-15 15:30:36 -070013570 hdd_err("Can't stop ap because its not started");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013571 }
13572 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013573}
13574
13575/**
13576 * wlan_hdd_start_sap() - this function starts bss of SAP.
13577 * @ap_adapter: SAP adapter
13578 *
13579 * This function will process the starting of sap adapter.
13580 *
13581 * Return: None
13582 */
Jeff Johnson9d295242017-08-29 14:39:48 -070013583void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013584{
Jeff Johnson87251032017-08-29 13:31:11 -070013585 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070013586 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053013587 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013588 struct hdd_context *hdd_ctx;
Jeff Johnson8f8ceb92019-03-24 08:16:55 -070013589 struct sap_config *sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013590
Jeff Johnsond36fa332019-03-18 13:42:25 -070013591 if (!ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070013592 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013593 return;
13594 }
13595
Krunal Soni9b04c9b2016-03-10 13:08:05 -080013596 if (QDF_SAP_MODE != ap_adapter->device_mode) {
Peng Xuf5d60c82015-10-02 17:17:03 -070013597 hdd_err("SoftAp role has not been enabled");
13598 return;
13599 }
13600
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013601 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
13602 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
13603 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -070013604 sap_config = &ap_adapter->session.ap.sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013605
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013606 mutex_lock(&hdd_ctx->sap_lock);
13607 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
13608 goto end;
13609
13610 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070013611 hdd_err("SAP Not able to set AP IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013612 goto end;
13613 }
Liangwei Dong8ffc0cc2019-09-26 18:36:10 +080013614 wlan_reg_set_channel_params_for_freq(
13615 hdd_ctx->pdev,
13616 hdd_ap_ctx->sap_config.chan_freq,
13617 0, &hdd_ap_ctx->sap_config.ch_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013618
Wei Song2f76f642016-11-18 16:32:53 +080013619 qdf_event_reset(&hostapd_state->qdf_event);
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070013620 if (wlansap_start_bss(hdd_ap_ctx->sap_context, hdd_hostapd_sap_event_cb,
Jeff Johnson91df29d2017-10-27 19:29:50 -070013621 &hdd_ap_ctx->sap_config,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013622 ap_adapter->dev)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053013623 != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013624 goto end;
13625
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013626 hdd_debug("Waiting for SAP to start");
Nachiket Kukade0396b732017-11-14 16:35:16 +053013627 qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053013628 SME_CMD_START_BSS_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +053013629 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070013630 hdd_err("SAP Start failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013631 goto end;
13632 }
Jeff Johnson28f8a772016-08-15 15:30:36 -070013633 hdd_info("SAP Start Success");
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053013634 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013635 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053013636 if (hostapd_state->bss_state == BSS_START) {
Dustin Brown1dbefe62018-09-11 16:32:03 -070013637 policy_mgr_incr_active_session(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013638 ap_adapter->device_mode,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080013639 ap_adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070013640 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053013641 true);
13642 }
Sourav Mohapatra9bc67112017-11-08 09:36:11 +053013643 mutex_unlock(&hdd_ctx->sap_lock);
13644
13645 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013646end:
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053013647 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013648 mutex_unlock(&hdd_ctx->sap_lock);
Manikandan Mohan3dad1a42017-06-14 10:50:18 -070013649 /* SAP context and beacon cleanup will happen during driver unload
13650 * in hdd_stop_adapter
13651 */
13652 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
13653
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013654}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013655
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013656#ifdef QCA_CONFIG_SMP
13657/**
13658 * wlan_hdd_get_cpu() - get cpu_index
13659 *
13660 * Return: cpu_index
13661 */
13662int wlan_hdd_get_cpu(void)
13663{
13664 int cpu_index = get_cpu();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070013665
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013666 put_cpu();
13667 return cpu_index;
13668}
13669#endif
13670
13671/**
13672 * hdd_get_fwpath() - get framework path
13673 *
13674 * This function is used to get the string written by
13675 * userspace to start the wlan driver
13676 *
13677 * Return: string
13678 */
13679const char *hdd_get_fwpath(void)
13680{
13681 return fwpath.string;
13682}
13683
Dustin Brown94ce20f2018-09-04 13:11:38 -070013684static inline int hdd_state_query_cb(void)
13685{
13686 return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD));
13687}
13688
Dustin Brown265e82b2019-03-18 11:07:32 -070013689static int __hdd_op_protect_cb(void **out_sync, const char *func)
13690{
13691 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13692
13693 if (!hdd_ctx)
13694 return -EAGAIN;
13695
13696 return __osif_psoc_sync_op_start(hdd_ctx->parent_dev,
13697 (struct osif_psoc_sync **)out_sync,
13698 func);
13699}
13700
13701static void __hdd_op_unprotect_cb(void *sync, const char *func)
13702{
13703 __osif_psoc_sync_op_stop(sync, func);
13704}
13705
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013706/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013707 * hdd_init() - Initialize Driver
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013708 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013709 * This function initilizes CDS global context with the help of cds_init. This
13710 * has to be the first function called after probe to get a valid global
13711 * context.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013712 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013713 * Return: 0 for success, errno on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013714 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013715int hdd_init(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013716{
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070013717 QDF_STATUS status;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013718
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070013719 status = cds_init();
wadesongae4ffd12017-10-24 16:45:54 +080013720 if (QDF_IS_STATUS_ERROR(status)) {
13721 hdd_err("Failed to allocate CDS context");
Dustin Brownc1d81af2019-03-01 13:43:43 -080013722 return -ENOMEM;
wadesongae4ffd12017-10-24 16:45:54 +080013723 }
Dustin Brownc1d81af2019-03-01 13:43:43 -080013724
Dustin Brown265e82b2019-03-18 11:07:32 -070013725 qdf_op_callbacks_register(__hdd_op_protect_cb, __hdd_op_unprotect_cb);
Hanumanth Reddy Pothula788a37e2017-08-17 18:40:11 +053013726
13727 wlan_init_bug_report_lock();
13728
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013729#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13730 wlan_logging_sock_init_svc();
13731#endif
13732
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013733 hdd_trace_init();
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053013734 hdd_register_debug_callback();
Qiwei Caiad9b01c2018-07-09 17:21:31 +080013735 wlan_roam_debug_init();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013736
Dustin Brownfe50cef2018-12-10 10:42:37 -080013737 return 0;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013738}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013739
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013740/**
13741 * hdd_deinit() - Deinitialize Driver
13742 *
13743 * This function frees CDS global context with the help of cds_deinit. This
13744 * has to be the last function call in remove callback to free the global
13745 * context.
13746 */
13747void hdd_deinit(void)
13748{
Qiwei Caiad9b01c2018-07-09 17:21:31 +080013749 wlan_roam_debug_deinit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013750
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013751#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13752 wlan_logging_sock_deinit_svc();
13753#endif
Qiwei Caiad9b01c2018-07-09 17:21:31 +080013754
13755 wlan_destroy_bug_report_lock();
Dustin Brown265e82b2019-03-18 11:07:32 -070013756 qdf_op_callbacks_register(NULL, NULL);
Qiwei Caiad9b01c2018-07-09 17:21:31 +080013757 cds_deinit();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013758}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013759
Yue Ma6e7b1a02017-04-03 14:17:46 -070013760#ifdef QCA_WIFI_NAPIER_EMULATION
13761#define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
13762#else
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013763#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
Yue Ma6e7b1a02017-04-03 14:17:46 -070013764#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013765
Sachin Ahujadddd2632017-03-07 19:07:24 +053013766static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
13767 struct file *file)
13768{
13769 return 0;
13770}
13771
gaurank kathpaliafc166a12019-06-19 15:07:27 +053013772static void hdd_inform_wifi_off(void)
13773{
13774 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13775
13776 if (!hdd_ctx) {
13777 hdd_err("Invalid hdd/pdev context");
13778 return;
13779 }
13780 ucfg_blm_wifi_off(hdd_ctx->pdev);
13781}
13782
Sachin Ahujadddd2632017-03-07 19:07:24 +053013783static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
13784 const char __user *user_buf,
13785 size_t count,
13786 loff_t *f_pos)
13787{
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053013788 char buf[3];
Sachin Ahujadddd2632017-03-07 19:07:24 +053013789 static const char wlan_off_str[] = "OFF";
13790 static const char wlan_on_str[] = "ON";
13791 int ret;
13792 unsigned long rc;
13793
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053013794 if (copy_from_user(buf, user_buf, 3)) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053013795 pr_err("Failed to read buffer\n");
13796 return -EINVAL;
13797 }
13798
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053013799 if (strncmp(buf, wlan_off_str, strlen(wlan_off_str)) == 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053013800 pr_debug("Wifi turning off from UI\n");
gaurank kathpaliafc166a12019-06-19 15:07:27 +053013801 hdd_inform_wifi_off();
Sachin Ahujadddd2632017-03-07 19:07:24 +053013802 goto exit;
13803 }
13804
Srinivas Girigowdad2412882018-09-07 15:42:04 -070013805 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) == 0)
Sachin Ahuja16904db2017-12-13 19:56:57 +053013806 pr_info("Wifi Turning On from UI\n");
Sachin Ahuja16904db2017-12-13 19:56:57 +053013807
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053013808 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) != 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053013809 pr_err("Invalid value received from framework");
13810 goto exit;
13811 }
13812
13813 if (!cds_is_driver_loaded()) {
Sachin Ahujaee62b542017-04-21 14:14:16 +053013814 init_completion(&wlan_start_comp);
Sachin Ahujadddd2632017-03-07 19:07:24 +053013815 rc = wait_for_completion_timeout(&wlan_start_comp,
13816 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
13817 if (!rc) {
Srinivas Girigowda09625b02018-09-10 15:28:09 -070013818 hdd_alert("Timed-out!!");
Sachin Ahujadddd2632017-03-07 19:07:24 +053013819 ret = -EINVAL;
Sachin Ahujadddd2632017-03-07 19:07:24 +053013820 return ret;
13821 }
13822
13823 hdd_start_complete(0);
13824 }
13825
13826exit:
13827 return count;
13828}
13829
13830
13831const struct file_operations wlan_hdd_state_fops = {
13832 .owner = THIS_MODULE,
13833 .open = wlan_hdd_state_ctrl_param_open,
13834 .write = wlan_hdd_state_ctrl_param_write,
13835};
13836
13837static int wlan_hdd_state_ctrl_param_create(void)
13838{
13839 unsigned int wlan_hdd_state_major = 0;
13840 int ret;
13841 struct device *dev;
13842
13843 device = MKDEV(wlan_hdd_state_major, 0);
13844
13845 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
13846 if (ret) {
13847 pr_err("Failed to register qcwlanstate");
13848 goto dev_alloc_err;
13849 }
13850 wlan_hdd_state_major = MAJOR(device);
13851
13852 class = class_create(THIS_MODULE, WLAN_MODULE_NAME);
13853 if (IS_ERR(class)) {
13854 pr_err("wlan_hdd_state class_create error");
13855 goto class_err;
13856 }
13857
13858 dev = device_create(class, NULL, device, NULL, WLAN_MODULE_NAME);
13859 if (IS_ERR(dev)) {
13860 pr_err("wlan_hdd_statedevice_create error");
13861 goto err_class_destroy;
13862 }
13863
13864 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
13865 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
13866 if (ret) {
13867 pr_err("Failed to add cdev error");
13868 goto cdev_add_err;
13869 }
13870
13871 pr_info("wlan_hdd_state %s major(%d) initialized",
13872 WLAN_MODULE_NAME, wlan_hdd_state_major);
13873
13874 return 0;
13875
13876cdev_add_err:
13877 device_destroy(class, device);
13878err_class_destroy:
13879 class_destroy(class);
13880class_err:
13881 unregister_chrdev_region(device, dev_num);
13882dev_alloc_err:
13883 return -ENODEV;
13884}
13885
13886static void wlan_hdd_state_ctrl_param_destroy(void)
13887{
13888 cdev_del(&wlan_hdd_state_cdev);
13889 device_destroy(class, device);
13890 class_destroy(class);
13891 unregister_chrdev_region(device, dev_num);
13892
13893 pr_info("Device node unregistered");
13894}
13895
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013896/**
Dustin Brownd585cb32018-09-12 17:12:23 -070013897 * hdd_component_init() - Initialize all components
Mukul Sharmad75a6672017-06-22 15:40:53 +053013898 *
Dustin Brownd585cb32018-09-12 17:12:23 -070013899 * Return: QDF_STATUS
Mukul Sharmad75a6672017-06-22 15:40:53 +053013900 */
Dustin Brownd585cb32018-09-12 17:12:23 -070013901static QDF_STATUS hdd_component_init(void)
Mukul Sharmad75a6672017-06-22 15:40:53 +053013902{
Dustin Brownd585cb32018-09-12 17:12:23 -070013903 QDF_STATUS status;
13904
13905 /* initialize converged components */
Abhishek Singhd5cf22d2019-01-08 19:51:09 +053013906 status = ucfg_mlme_global_init();
Arif Hussain49698112018-07-31 00:32:50 -070013907 if (QDF_IS_STATUS_ERROR(status))
Wu Gaob4944be2019-08-15 15:23:07 +080013908 return status;
Arif Hussain49698112018-07-31 00:32:50 -070013909
Abhishek Singhd5cf22d2019-01-08 19:51:09 +053013910 status = dispatcher_init();
13911 if (QDF_IS_STATUS_ERROR(status))
13912 goto mlme_global_deinit;
13913
Wu Gaob4944be2019-08-15 15:23:07 +080013914 status = target_if_init(wma_get_psoc_from_scn_handle);
13915 if (QDF_IS_STATUS_ERROR(status))
13916 goto dispatcher_deinit;
13917
Dustin Brownd585cb32018-09-12 17:12:23 -070013918 /* initialize non-converged components */
13919 status = ucfg_mlme_init();
13920 if (QDF_IS_STATUS_ERROR(status))
Wu Gaob4944be2019-08-15 15:23:07 +080013921 goto target_if_deinit;
Dustin Brownd585cb32018-09-12 17:12:23 -070013922
13923 status = ucfg_fwol_init();
13924 if (QDF_IS_STATUS_ERROR(status))
13925 goto mlme_deinit;
13926
13927 status = disa_init();
13928 if (QDF_IS_STATUS_ERROR(status))
13929 goto fwol_deinit;
13930
13931 status = pmo_init();
13932 if (QDF_IS_STATUS_ERROR(status))
13933 goto disa_deinit;
13934
13935 status = ucfg_ocb_init();
13936 if (QDF_IS_STATUS_ERROR(status))
13937 goto pmo_deinit;
13938
13939 status = ipa_init();
13940 if (QDF_IS_STATUS_ERROR(status))
13941 goto ocb_deinit;
13942
13943 status = ucfg_action_oui_init();
13944 if (QDF_IS_STATUS_ERROR(status))
13945 goto ipa_deinit;
13946
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013947 status = nan_init();
13948 if (QDF_IS_STATUS_ERROR(status))
13949 goto action_oui_deinit;
13950
Wu Gao637d58a2018-12-08 10:37:34 +080013951 status = ucfg_p2p_init();
13952 if (QDF_IS_STATUS_ERROR(status))
13953 goto nan_deinit;
13954
Paul Zhang37185672019-05-14 11:20:14 +080013955 status = ucfg_interop_issues_ap_init();
Wu Gaod6b5e402018-12-03 22:09:24 +080013956 if (QDF_IS_STATUS_ERROR(status))
13957 goto p2p_deinit;
13958
Paul Zhang37185672019-05-14 11:20:14 +080013959 status = policy_mgr_init();
13960 if (QDF_IS_STATUS_ERROR(status))
13961 goto interop_issues_ap_deinit;
13962
Wu Gao5f793402018-12-08 11:04:00 +080013963 status = ucfg_tdls_init();
13964 if (QDF_IS_STATUS_ERROR(status))
13965 goto policy_deinit;
13966
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +053013967 status = ucfg_blm_init();
13968 if (QDF_IS_STATUS_ERROR(status))
13969 goto tdls_deinit;
13970
Dustin Brownd585cb32018-09-12 17:12:23 -070013971 return QDF_STATUS_SUCCESS;
13972
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +053013973tdls_deinit:
13974 ucfg_tdls_deinit();
13975
Wu Gao5f793402018-12-08 11:04:00 +080013976policy_deinit:
13977 policy_mgr_deinit();
Paul Zhang37185672019-05-14 11:20:14 +080013978interop_issues_ap_deinit:
13979 ucfg_interop_issues_ap_deinit();
Wu Gaod6b5e402018-12-03 22:09:24 +080013980p2p_deinit:
13981 ucfg_p2p_deinit();
Wu Gao637d58a2018-12-08 10:37:34 +080013982nan_deinit:
13983 nan_deinit();
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013984action_oui_deinit:
13985 ucfg_action_oui_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013986ipa_deinit:
13987 ipa_deinit();
13988ocb_deinit:
13989 ucfg_ocb_deinit();
13990pmo_deinit:
13991 pmo_deinit();
13992disa_deinit:
13993 disa_deinit();
13994fwol_deinit:
13995 ucfg_fwol_deinit();
13996mlme_deinit:
13997 ucfg_mlme_deinit();
Wu Gaob4944be2019-08-15 15:23:07 +080013998target_if_deinit:
13999 target_if_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070014000dispatcher_deinit:
14001 dispatcher_deinit();
Abhishek Singhd5cf22d2019-01-08 19:51:09 +053014002mlme_global_deinit:
14003 ucfg_mlme_global_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070014004
14005 return status;
Mukul Sharmad75a6672017-06-22 15:40:53 +053014006}
14007
14008/**
Dustin Brownd585cb32018-09-12 17:12:23 -070014009 * hdd_component_deinit() - Deinitialize all components
Mukul Sharmad75a6672017-06-22 15:40:53 +053014010 *
14011 * Return: None
14012 */
Dustin Brownd585cb32018-09-12 17:12:23 -070014013static void hdd_component_deinit(void)
Mukul Sharmad75a6672017-06-22 15:40:53 +053014014{
Dustin Brownd585cb32018-09-12 17:12:23 -070014015 /* deinitialize non-converged components */
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +053014016 ucfg_blm_deinit();
Wu Gao5f793402018-12-08 11:04:00 +080014017 ucfg_tdls_deinit();
Wu Gaod6b5e402018-12-03 22:09:24 +080014018 policy_mgr_deinit();
Paul Zhang37185672019-05-14 11:20:14 +080014019 ucfg_interop_issues_ap_deinit();
Wu Gao637d58a2018-12-08 10:37:34 +080014020 ucfg_p2p_deinit();
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053014021 nan_deinit();
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053014022 ucfg_action_oui_deinit();
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +053014023 ipa_deinit();
Zhang Qian47e22ce2018-01-04 15:38:38 +080014024 ucfg_ocb_deinit();
Mukul Sharmad75a6672017-06-22 15:40:53 +053014025 pmo_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053014026 disa_deinit();
Sourav Mohapatra113685f2018-08-29 14:21:55 +053014027 ucfg_fwol_deinit();
Vignesh Viswanathana0921c42018-09-04 19:03:35 +053014028 ucfg_mlme_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070014029
14030 /* deinitialize converged components */
Wu Gaob4944be2019-08-15 15:23:07 +080014031 target_if_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070014032 dispatcher_deinit();
Abhishek Singhd5cf22d2019-01-08 19:51:09 +053014033 ucfg_mlme_global_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053014034}
14035
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053014036QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc)
14037{
Sourav Mohapatra113685f2018-08-29 14:21:55 +053014038 QDF_STATUS status;
14039
14040 status = ucfg_mlme_psoc_open(psoc);
14041 if (QDF_IS_STATUS_ERROR(status))
14042 return status;
14043
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +053014044 status = ucfg_blm_psoc_open(psoc);
14045 if (QDF_IS_STATUS_ERROR(status))
14046 goto err_blm;
14047
Sourav Mohapatra113685f2018-08-29 14:21:55 +053014048 status = ucfg_fwol_psoc_open(psoc);
14049 if (QDF_IS_STATUS_ERROR(status))
Wu Gao66454f12018-09-26 19:55:41 +080014050 goto err_fwol;
14051
14052 status = ucfg_pmo_psoc_open(psoc);
14053 if (QDF_IS_STATUS_ERROR(status))
14054 goto err_pmo;
Sourav Mohapatra113685f2018-08-29 14:21:55 +053014055
Krunal Sonie9c12f52018-10-04 11:45:42 -070014056 status = ucfg_policy_mgr_psoc_open(psoc);
14057 if (QDF_IS_STATUS_ERROR(status))
14058 goto err_plcy_mgr;
14059
Wu Gao637d58a2018-12-08 10:37:34 +080014060 status = ucfg_p2p_psoc_open(psoc);
14061 if (QDF_IS_STATUS_ERROR(status))
14062 goto err_p2p;
Wu Gao5f793402018-12-08 11:04:00 +080014063
14064 status = ucfg_tdls_psoc_open(psoc);
14065 if (QDF_IS_STATUS_ERROR(status))
14066 goto err_tdls;
14067
Manikandan Mohan4e66c9a2019-07-12 14:55:17 -070014068 status = ucfg_nan_psoc_open(psoc);
14069 if (QDF_IS_STATUS_ERROR(status))
14070 goto err_nan;
14071
Sourav Mohapatra113685f2018-08-29 14:21:55 +053014072 return status;
14073
Manikandan Mohan4e66c9a2019-07-12 14:55:17 -070014074err_nan:
14075 ucfg_nan_psoc_close(psoc);
Wu Gao5f793402018-12-08 11:04:00 +080014076err_tdls:
14077 ucfg_tdls_psoc_close(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080014078err_p2p:
14079 ucfg_p2p_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070014080err_plcy_mgr:
14081 ucfg_pmo_psoc_close(psoc);
Wu Gao66454f12018-09-26 19:55:41 +080014082err_pmo:
14083 ucfg_fwol_psoc_close(psoc);
14084err_fwol:
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +053014085 ucfg_blm_psoc_close(psoc);
14086err_blm:
Sourav Mohapatra113685f2018-08-29 14:21:55 +053014087 ucfg_mlme_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070014088
Sourav Mohapatra113685f2018-08-29 14:21:55 +053014089 return status;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053014090}
14091
14092void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc)
14093{
Wu Gao5f793402018-12-08 11:04:00 +080014094 ucfg_tdls_psoc_close(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080014095 ucfg_p2p_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070014096 ucfg_policy_mgr_psoc_close(psoc);
Wu Gao66454f12018-09-26 19:55:41 +080014097 ucfg_pmo_psoc_close(psoc);
Sourav Mohapatra113685f2018-08-29 14:21:55 +053014098 ucfg_fwol_psoc_close(psoc);
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +053014099 ucfg_blm_psoc_close(psoc);
Vignesh Viswanathana0921c42018-09-04 19:03:35 +053014100 ucfg_mlme_psoc_close(psoc);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053014101}
14102
Nachiket Kukade98f562a2017-12-15 12:18:07 +053014103void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc)
14104{
Zhang Qian47e22ce2018-01-04 15:38:38 +080014105 ocb_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053014106 disa_psoc_enable(psoc);
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053014107 nan_psoc_enable(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080014108 p2p_psoc_enable(psoc);
Paul Zhang37185672019-05-14 11:20:14 +080014109 ucfg_interop_issues_ap_psoc_enable(psoc);
Wu Gaod6b5e402018-12-03 22:09:24 +080014110 policy_mgr_psoc_enable(psoc);
Wu Gaoa67c3802018-12-27 12:07:52 +080014111 ucfg_tdls_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053014112}
14113
14114void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc)
14115{
Wu Gaoa67c3802018-12-27 12:07:52 +080014116 ucfg_tdls_psoc_disable(psoc);
Wu Gaod6b5e402018-12-03 22:09:24 +080014117 policy_mgr_psoc_disable(psoc);
Paul Zhang37185672019-05-14 11:20:14 +080014118 ucfg_interop_issues_ap_psoc_disable(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080014119 p2p_psoc_disable(psoc);
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053014120 nan_psoc_disable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053014121 disa_psoc_disable(psoc);
Zhang Qian47e22ce2018-01-04 15:38:38 +080014122 ocb_psoc_disable(psoc);
Mukul Sharmad75a6672017-06-22 15:40:53 +053014123}
14124
Sandeep Puligillab7beb472018-08-13 22:54:20 -070014125QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev)
14126{
14127 return ucfg_mlme_pdev_open(pdev);
14128}
14129
14130void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev)
14131{
14132 ucfg_mlme_pdev_close(pdev);
14133}
14134
Dustin Browna2a39dc2018-09-17 15:29:59 -070014135static QDF_STATUS hdd_qdf_print_init(void)
14136{
14137 QDF_STATUS status;
14138 int qdf_print_idx;
14139
14140 status = qdf_print_setup();
14141 if (QDF_IS_STATUS_ERROR(status)) {
14142 pr_err("Failed qdf_print_setup; status:%u\n", status);
14143 return status;
14144 }
14145
14146 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
14147 if (qdf_print_idx < 0) {
14148 pr_err("Failed to register for qdf_print_ctrl\n");
14149 return QDF_STATUS_E_FAILURE;
14150 }
14151
14152 qdf_set_pidx(qdf_print_idx);
14153
14154 return QDF_STATUS_SUCCESS;
14155}
14156
14157static void hdd_qdf_print_deinit(void)
14158{
14159 int qdf_pidx = qdf_get_pidx();
14160
14161 qdf_set_pidx(-1);
14162 qdf_print_ctrl_cleanup(qdf_pidx);
14163
14164 /* currently, no qdf print 'un-setup'*/
14165}
14166
14167static QDF_STATUS hdd_qdf_init(void)
14168{
14169 QDF_STATUS status;
14170
14171 status = hdd_qdf_print_init();
14172 if (QDF_IS_STATUS_ERROR(status))
14173 goto exit;
14174
14175 status = qdf_debugfs_init();
14176 if (QDF_IS_STATUS_ERROR(status)) {
14177 hdd_err("Failed to init debugfs; status:%u", status);
14178 goto print_deinit;
14179 }
14180
14181 qdf_lock_stats_init();
14182 qdf_mem_init();
Dustin Brownc2796312019-03-13 16:43:36 -070014183 qdf_delayed_work_feature_init();
Dustin Brown4a93bb52019-03-13 11:46:34 -070014184 qdf_periodic_work_feature_init();
Dustin Browna2a39dc2018-09-17 15:29:59 -070014185 qdf_mc_timer_manager_init();
14186 qdf_event_list_init();
14187
Dustin Brownd315c452018-11-27 11:28:48 -080014188 status = qdf_talloc_feature_init();
14189 if (QDF_IS_STATUS_ERROR(status)) {
14190 hdd_err("Failed to init talloc; status:%u", status);
14191 goto event_deinit;
14192 }
14193
Dustin Browna2a39dc2018-09-17 15:29:59 -070014194 status = qdf_cpuhp_init();
14195 if (QDF_IS_STATUS_ERROR(status)) {
14196 hdd_err("Failed to init cpuhp; status:%u", status);
Dustin Brownd315c452018-11-27 11:28:48 -080014197 goto talloc_deinit;
Dustin Browna2a39dc2018-09-17 15:29:59 -070014198 }
14199
14200 status = qdf_trace_spin_lock_init();
14201 if (QDF_IS_STATUS_ERROR(status)) {
14202 hdd_err("Failed to init spinlock; status:%u", status);
14203 goto cpuhp_deinit;
14204 }
14205
14206 qdf_trace_init();
14207 qdf_register_debugcb_init();
14208
14209 return QDF_STATUS_SUCCESS;
14210
14211cpuhp_deinit:
14212 qdf_cpuhp_deinit();
Dustin Brownd315c452018-11-27 11:28:48 -080014213talloc_deinit:
14214 qdf_talloc_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070014215event_deinit:
14216 qdf_event_list_destroy();
14217 qdf_mc_timer_manager_exit();
Dustin Brown4a93bb52019-03-13 11:46:34 -070014218 qdf_periodic_work_feature_deinit();
Dustin Brownc2796312019-03-13 16:43:36 -070014219 qdf_delayed_work_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070014220 qdf_mem_exit();
14221 qdf_lock_stats_deinit();
14222 qdf_debugfs_exit();
14223print_deinit:
14224 hdd_qdf_print_deinit();
14225
14226exit:
14227 return status;
14228}
14229
14230static void hdd_qdf_deinit(void)
14231{
14232 /* currently, no debugcb deinit */
14233
14234 qdf_trace_deinit();
14235
14236 /* currently, no trace spinlock deinit */
14237
14238 qdf_cpuhp_deinit();
Dustin Brownd315c452018-11-27 11:28:48 -080014239 qdf_talloc_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070014240 qdf_event_list_destroy();
14241 qdf_mc_timer_manager_exit();
Dustin Brown4a93bb52019-03-13 11:46:34 -070014242 qdf_periodic_work_feature_deinit();
Dustin Brownc2796312019-03-13 16:43:36 -070014243 qdf_delayed_work_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070014244 qdf_mem_exit();
14245 qdf_lock_stats_deinit();
14246 qdf_debugfs_exit();
14247 hdd_qdf_print_deinit();
14248}
Dustin Brownf0f70562018-09-14 10:29:38 -070014249
Dustin Brown26afe8f2019-03-01 12:37:24 -080014250#ifdef FEATURE_MONITOR_MODE_SUPPORT
14251static bool is_monitor_mode_supported(void)
14252{
14253 return true;
14254}
14255#else
14256static bool is_monitor_mode_supported(void)
14257{
14258 pr_err("Monitor mode not supported!");
14259 return false;
14260}
14261#endif
14262
14263#ifdef WLAN_FEATURE_EPPING
14264static bool is_epping_mode_supported(void)
14265{
14266 return true;
14267}
14268#else
14269static bool is_epping_mode_supported(void)
14270{
14271 pr_err("Epping mode not supported!");
14272 return false;
14273}
14274#endif
14275
14276#ifdef QCA_WIFI_FTM
14277static bool is_ftm_mode_supported(void)
14278{
14279 return true;
14280}
14281#else
14282static bool is_ftm_mode_supported(void)
14283{
14284 pr_err("FTM mode not supported!");
14285 return false;
14286}
14287#endif
14288
14289/**
14290 * is_con_mode_valid() check con mode is valid or not
14291 * @mode: global con mode
14292 *
14293 * Return: TRUE on success FALSE on failure
14294 */
14295static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
14296{
14297 switch (mode) {
14298 case QDF_GLOBAL_MONITOR_MODE:
14299 return is_monitor_mode_supported();
14300 case QDF_GLOBAL_EPPING_MODE:
14301 return is_epping_mode_supported();
14302 case QDF_GLOBAL_FTM_MODE:
14303 return is_ftm_mode_supported();
14304 case QDF_GLOBAL_MISSION_MODE:
14305 return true;
14306 default:
14307 return false;
14308 }
14309}
14310
14311static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
14312 enum QDF_GLOBAL_MODE curr_mode)
14313{
14314 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
14315 return;
14316
14317 switch (curr_mode) {
14318 case QDF_GLOBAL_MONITOR_MODE:
14319 hdd_info("Release wakelock for monitor mode!");
14320 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
14321 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
14322 /* fallthrough */
14323 case QDF_GLOBAL_MISSION_MODE:
14324 case QDF_GLOBAL_FTM_MODE:
14325 hdd_abort_mac_scan_all_adapters(hdd_ctx);
14326 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
14327 hdd_stop_all_adapters(hdd_ctx);
14328 hdd_deinit_all_adapters(hdd_ctx, false);
14329
14330 break;
14331 default:
14332 break;
14333 }
14334}
14335
14336static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
14337 enum QDF_GLOBAL_MODE curr_mode)
14338{
14339 int driver_status;
14340
14341 driver_status = hdd_ctx->driver_status;
14342
14343 switch (curr_mode) {
14344 case QDF_GLOBAL_MISSION_MODE:
14345 case QDF_GLOBAL_MONITOR_MODE:
14346 case QDF_GLOBAL_FTM_MODE:
14347 hdd_close_all_adapters(hdd_ctx, false);
14348 break;
14349 case QDF_GLOBAL_EPPING_MODE:
14350 epping_disable();
14351 epping_close();
14352 break;
14353 default:
14354 return;
14355 }
14356}
14357
14358static int
14359hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode)
14360{
14361 QDF_STATUS status;
14362 uint32_t mode;
14363
14364 *out_mode = QDF_GLOBAL_MAX_MODE;
14365
14366 status = qdf_uint32_parse(mode_str, &mode);
14367 if (QDF_IS_STATUS_ERROR(status))
14368 return qdf_status_to_os_return(status);
14369
14370 if (mode >= QDF_GLOBAL_MAX_MODE)
14371 return -ERANGE;
14372
14373 *out_mode = (enum QDF_GLOBAL_MODE)mode;
14374
14375 return 0;
14376}
14377
Rajeev Kumar588a2542019-04-08 10:57:19 -070014378static int hdd_mode_change_psoc_idle_shutdown(struct device *dev)
14379{
14380 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14381
Rajeev Kumar47b77292019-06-19 14:01:59 -070014382 if (!hdd_ctx)
14383 return -EINVAL;
14384
Rajeev Kumar588a2542019-04-08 10:57:19 -070014385 return hdd_wlan_stop_modules(hdd_ctx, true);
14386}
14387
14388static int hdd_mode_change_psoc_idle_restart(struct device *dev)
14389{
14390 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Alan Chene523cd92019-07-15 16:45:09 -070014391 int ret;
Rajeev Kumar588a2542019-04-08 10:57:19 -070014392
Rajeev Kumar47b77292019-06-19 14:01:59 -070014393 if (!hdd_ctx)
14394 return -EINVAL;
Alan Chen0f29e972019-09-04 12:04:22 -070014395 ret = hdd_soc_idle_restart_lock(dev);
14396 if (ret)
14397 return ret;
Alan Chene523cd92019-07-15 16:45:09 -070014398 ret = hdd_wlan_start_modules(hdd_ctx, false);
14399 hdd_soc_idle_restart_unlock();
Rajeev Kumar47b77292019-06-19 14:01:59 -070014400
Alan Chene523cd92019-07-15 16:45:09 -070014401 return ret;
Rajeev Kumar588a2542019-04-08 10:57:19 -070014402}
14403
Dustin Brown26afe8f2019-03-01 12:37:24 -080014404/**
14405 * __hdd_driver_mode_change() - Handles a driver mode change
14406 * @hdd_ctx: Pointer to the global HDD context
14407 * @next_mode: the driver mode to transition to
14408 *
14409 * This function is invoked when user updates con_mode using sys entry,
14410 * to initialize and bring-up driver in that specific mode.
14411 *
14412 * Return: Errno
14413 */
14414static int __hdd_driver_mode_change(struct hdd_context *hdd_ctx,
14415 enum QDF_GLOBAL_MODE next_mode)
14416{
14417 enum QDF_GLOBAL_MODE curr_mode;
14418 int errno;
14419
14420 hdd_info("Driver mode changing to %d", next_mode);
14421
14422 errno = wlan_hdd_validate_context(hdd_ctx);
14423 if (errno)
14424 return errno;
14425
14426 if (!is_con_mode_valid(next_mode)) {
14427 hdd_err_rl("Requested driver mode is invalid");
14428 return -EINVAL;
14429 }
14430
Dustin Brown26afe8f2019-03-01 12:37:24 -080014431 curr_mode = hdd_get_conparam();
14432 if (curr_mode == next_mode) {
14433 hdd_err_rl("Driver is already in the requested mode");
Dustin Browne0a77272019-03-19 16:28:06 -070014434 return 0;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014435 }
14436
Varuneshwar Petlozudbe255c2019-07-18 17:22:22 +053014437 hdd_psoc_idle_timer_stop(hdd_ctx);
14438
Dustin Brown26afe8f2019-03-01 12:37:24 -080014439 /* ensure adapters are stopped */
14440 hdd_stop_present_mode(hdd_ctx, curr_mode);
14441
Varuneshwar Petlozudbe255c2019-07-18 17:22:22 +053014442 if (DRIVER_MODULES_CLOSED != hdd_ctx->driver_status) {
14443 is_mode_change_psoc_idle_shutdown = true;
14444 errno = pld_idle_shutdown(hdd_ctx->parent_dev,
14445 hdd_mode_change_psoc_idle_shutdown);
14446 if (errno) {
14447 is_mode_change_psoc_idle_shutdown = false;
14448 hdd_err("Stop wlan modules failed");
14449 return errno;
14450 }
Dustin Brown26afe8f2019-03-01 12:37:24 -080014451 }
14452
14453 /* Cleanup present mode before switching to new mode */
14454 hdd_cleanup_present_mode(hdd_ctx, curr_mode);
14455
14456 hdd_set_conparam(next_mode);
14457
Rajeev Kumar588a2542019-04-08 10:57:19 -070014458 errno = pld_idle_restart(hdd_ctx->parent_dev,
14459 hdd_mode_change_psoc_idle_restart);
Dustin Brown26afe8f2019-03-01 12:37:24 -080014460 if (errno) {
14461 hdd_err("Start wlan modules failed: %d", errno);
Dustin Browne0a77272019-03-19 16:28:06 -070014462 return errno;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014463 }
14464
14465 errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode);
14466 if (errno) {
14467 hdd_err("Failed to open adapters");
Dustin Browne0a77272019-03-19 16:28:06 -070014468 return errno;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014469 }
14470
14471 if (next_mode == QDF_GLOBAL_MONITOR_MODE) {
14472 struct hdd_adapter *adapter =
14473 hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
14474
14475 QDF_BUG(adapter);
14476 if (!adapter) {
14477 hdd_err("Failed to get monitor adapter");
Dustin Browne0a77272019-03-19 16:28:06 -070014478 return -EINVAL;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014479 }
14480
14481 errno = hdd_start_adapter(adapter);
14482 if (errno) {
14483 hdd_err("Failed to start monitor adapter");
Dustin Browne0a77272019-03-19 16:28:06 -070014484 return errno;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014485 }
14486
14487 hdd_info("Acquire wakelock for monitor mode");
14488 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
14489 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
14490 }
14491
14492 /* con_mode is a global module parameter */
14493 con_mode = next_mode;
14494 hdd_info("Driver mode successfully changed to %d", next_mode);
14495
Dustin Browne0a77272019-03-19 16:28:06 -070014496 return 0;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014497}
14498
14499static int hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode)
14500{
Dustin Brownc1d81af2019-03-01 13:43:43 -080014501 struct osif_driver_sync *driver_sync;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014502 struct hdd_context *hdd_ctx;
14503 QDF_STATUS status;
14504 int errno;
14505
14506 hdd_enter();
14507
Dustin Brownc1d81af2019-03-01 13:43:43 -080014508 status = osif_driver_sync_trans_start_wait(&driver_sync);
Dustin Brown26afe8f2019-03-01 12:37:24 -080014509 if (QDF_IS_STATUS_ERROR(status)) {
14510 hdd_err("Failed to start 'mode change'; status:%u", status);
14511 errno = qdf_status_to_os_return(status);
14512 goto exit;
14513 }
14514
Dustin Brownc1d81af2019-03-01 13:43:43 -080014515 osif_driver_sync_wait_for_ops(driver_sync);
Dustin Brown26afe8f2019-03-01 12:37:24 -080014516
14517 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14518 errno = wlan_hdd_validate_context(hdd_ctx);
14519 if (errno)
14520 goto trans_stop;
14521
Dustin Brown26afe8f2019-03-01 12:37:24 -080014522 errno = __hdd_driver_mode_change(hdd_ctx, mode);
Dustin Brown26afe8f2019-03-01 12:37:24 -080014523
14524trans_stop:
Dustin Brownc1d81af2019-03-01 13:43:43 -080014525 osif_driver_sync_trans_stop(driver_sync);
Dustin Brown26afe8f2019-03-01 12:37:24 -080014526
14527exit:
14528 hdd_exit();
14529
14530 return errno;
14531}
14532
14533static int hdd_set_con_mode(enum QDF_GLOBAL_MODE mode)
14534{
14535 con_mode = mode;
14536
14537 return 0;
14538}
14539
14540static int (*hdd_set_con_mode_cb)(enum QDF_GLOBAL_MODE mode) = hdd_set_con_mode;
14541
14542static void hdd_driver_mode_change_register(void)
14543{
14544 hdd_set_con_mode_cb = hdd_driver_mode_change;
14545}
14546
14547static void hdd_driver_mode_change_unregister(void)
14548{
14549 hdd_set_con_mode_cb = hdd_set_con_mode;
14550}
14551
14552static int con_mode_handler(const char *kmessage, const struct kernel_param *kp)
14553{
14554 enum QDF_GLOBAL_MODE mode;
14555 int errno;
14556
14557 errno = hdd_parse_driver_mode(kmessage, &mode);
14558 if (errno) {
14559 hdd_err_rl("Failed to parse driver mode '%s'", kmessage);
14560 return errno;
14561 }
14562
14563 return hdd_set_con_mode_cb(mode);
14564}
Dustin Brown95ff00b2019-02-28 13:41:13 -080014565
Dustin Brownf0f70562018-09-14 10:29:38 -070014566/**
14567 * hdd_driver_load() - Perform the driver-level load operation
14568 *
14569 * Note: this is used in both static and DLKM driver builds
14570 *
14571 * Return: Errno
14572 */
14573static int hdd_driver_load(void)
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014574{
Dustin Brownc1d81af2019-03-01 13:43:43 -080014575 struct osif_driver_sync *driver_sync;
Dustin Brownd585cb32018-09-12 17:12:23 -070014576 QDF_STATUS status;
Dustin Brownf0f70562018-09-14 10:29:38 -070014577 int errno;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014578
Dustin Brownc1d81af2019-03-01 13:43:43 -080014579 pr_err("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
Rajeev Kumare555e2d2018-09-17 11:52:37 -070014580 g_wlan_driver_version);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014581
Dustin Browna2a39dc2018-09-17 15:29:59 -070014582 status = hdd_qdf_init();
14583 if (QDF_IS_STATUS_ERROR(status)) {
14584 errno = qdf_status_to_os_return(status);
14585 goto exit;
14586 }
14587
Dustin Brownc1d81af2019-03-01 13:43:43 -080014588 osif_sync_init();
Dustin Brown21a1d462018-07-31 15:13:06 -070014589
Dustin Brownc1d81af2019-03-01 13:43:43 -080014590 status = osif_driver_sync_create_and_trans(&driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070014591 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Brownc1d81af2019-03-01 13:43:43 -080014592 hdd_err("Failed to init driver sync; status:%u", status);
Dustin Brown21a1d462018-07-31 15:13:06 -070014593 errno = qdf_status_to_os_return(status);
Dustin Brownc1d81af2019-03-01 13:43:43 -080014594 goto sync_deinit;
Dustin Brown21a1d462018-07-31 15:13:06 -070014595 }
14596
Dustin Brownf0f70562018-09-14 10:29:38 -070014597 errno = hdd_init();
14598 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014599 hdd_err("Failed to init HDD; errno:%d", errno);
Dustin Brown21a1d462018-07-31 15:13:06 -070014600 goto trans_stop;
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053014601 }
14602
Dustin Brownd585cb32018-09-12 17:12:23 -070014603 status = hdd_component_init();
14604 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014605 hdd_err("Failed to init components; status:%u", status);
Dustin Brownf0f70562018-09-14 10:29:38 -070014606 errno = qdf_status_to_os_return(status);
Dustin Brownd585cb32018-09-12 17:12:23 -070014607 goto hdd_deinit;
14608 }
Mukul Sharmad75a6672017-06-22 15:40:53 +053014609
Dustin Brownf0f70562018-09-14 10:29:38 -070014610 status = qdf_wake_lock_create(&wlan_wake_lock, "wlan");
14611 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014612 hdd_err("Failed to create wake lock; status:%u", status);
Dustin Brownf0f70562018-09-14 10:29:38 -070014613 errno = qdf_status_to_os_return(status);
14614 goto comp_deinit;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014615 }
14616
Dustin Brownf0f70562018-09-14 10:29:38 -070014617 hdd_set_conparam(con_mode);
14618
Dustin Brownf0f70562018-09-14 10:29:38 -070014619 errno = wlan_hdd_state_ctrl_param_create();
14620 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014621 hdd_err("Failed to create ctrl param; errno:%d", errno);
Dustin Brown4b9dbe62018-09-14 15:41:11 -070014622 goto wakelock_destroy;
14623 }
14624
Dustin Brown25843ad2018-09-17 14:54:33 -070014625 errno = pld_init();
14626 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014627 hdd_err("Failed to init PLD; errno:%d", errno);
Dustin Brown25843ad2018-09-17 14:54:33 -070014628 goto param_destroy;
14629 }
14630
Dustin Brown95ff00b2019-02-28 13:41:13 -080014631 hdd_driver_mode_change_register();
Dustin Brownc1d81af2019-03-01 13:43:43 -080014632
14633 osif_driver_sync_register(driver_sync);
14634 osif_driver_sync_trans_stop(driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070014635
14636 /* psoc probe can happen in registration; do after 'load' transition */
Dustin Brown4b9dbe62018-09-14 15:41:11 -070014637 errno = wlan_hdd_register_driver();
14638 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014639 hdd_err("Failed to register driver; errno:%d", errno);
Dustin Brown25843ad2018-09-17 14:54:33 -070014640 goto pld_deinit;
Sachin Ahuja16904db2017-12-13 19:56:57 +053014641 }
14642
Dustin Browna2a39dc2018-09-17 15:29:59 -070014643 hdd_debug("%s: driver loaded", WLAN_MODULE_NAME);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014644
14645 return 0;
Dustin Brownd585cb32018-09-12 17:12:23 -070014646
Dustin Brown25843ad2018-09-17 14:54:33 -070014647pld_deinit:
Dustin Brownc1d81af2019-03-01 13:43:43 -080014648 status = osif_driver_sync_trans_start(&driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070014649 QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
14650
Dustin Brownc1d81af2019-03-01 13:43:43 -080014651 osif_driver_sync_unregister();
14652 osif_driver_sync_wait_for_ops(driver_sync);
14653
Dustin Brown95ff00b2019-02-28 13:41:13 -080014654 hdd_driver_mode_change_unregister();
Dustin Brown25843ad2018-09-17 14:54:33 -070014655 pld_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070014656
Alan Chen30181292019-08-20 10:06:43 -070014657 hdd_start_complete(errno);
Dustin Brown4b9dbe62018-09-14 15:41:11 -070014658param_destroy:
14659 wlan_hdd_state_ctrl_param_destroy();
Dustin Brownf0f70562018-09-14 10:29:38 -070014660wakelock_destroy:
Anurag Chouhana37b5b72016-02-21 14:53:42 +053014661 qdf_wake_lock_destroy(&wlan_wake_lock);
Dustin Brownf0f70562018-09-14 10:29:38 -070014662comp_deinit:
Dustin Brownd585cb32018-09-12 17:12:23 -070014663 hdd_component_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070014664hdd_deinit:
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053014665 hdd_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070014666trans_stop:
Dustin Brownc1d81af2019-03-01 13:43:43 -080014667 osif_driver_sync_trans_stop(driver_sync);
14668 osif_driver_sync_destroy(driver_sync);
14669sync_deinit:
14670 osif_sync_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070014671 hdd_qdf_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070014672
Dustin Brown25843ad2018-09-17 14:54:33 -070014673exit:
Dustin Brownf0f70562018-09-14 10:29:38 -070014674 return errno;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014675}
14676
14677/**
Dustin Brownf0f70562018-09-14 10:29:38 -070014678 * hdd_driver_unload() - Performs the driver-level unload operation
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014679 *
Dustin Brownf0f70562018-09-14 10:29:38 -070014680 * Note: this is used in both static and DLKM driver builds
14681 *
14682 * Return: None
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014683 */
Dustin Brownf0f70562018-09-14 10:29:38 -070014684static void hdd_driver_unload(void)
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014685{
Dustin Brownc1d81af2019-03-01 13:43:43 -080014686 struct osif_driver_sync *driver_sync;
Will Huang36049722018-04-13 11:48:51 +080014687 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Dustin Brown21a1d462018-07-31 15:13:06 -070014688 QDF_STATUS status;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +053014689
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014690 pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
14691 QWLAN_VERSIONSTR);
14692
Tiger Yu80fbbe12019-10-17 16:08:54 +080014693 cds_set_driver_loaded(false);
14694 cds_set_unload_in_progress(true);
14695
Dustin Brown8c0b5e32019-01-18 13:56:02 -080014696 if (hdd_ctx)
14697 hdd_psoc_idle_timer_stop(hdd_ctx);
14698
14699 /* trigger SoC remove */
14700 wlan_hdd_unregister_driver();
14701
Dustin Brownc1d81af2019-03-01 13:43:43 -080014702 status = osif_driver_sync_trans_start_wait(&driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070014703 QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
14704 if (QDF_IS_STATUS_ERROR(status)) {
14705 hdd_err("Unable to unload wlan; status:%u", status);
Arunk Khandavalli830c9692018-03-22 12:17:40 +053014706 return;
Dustin Brown21a1d462018-07-31 15:13:06 -070014707 }
14708
Dustin Brownc1d81af2019-03-01 13:43:43 -080014709 osif_driver_sync_unregister();
14710 osif_driver_sync_wait_for_ops(driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070014711
Dustin Brown95ff00b2019-02-28 13:41:13 -080014712 hdd_driver_mode_change_unregister();
Dustin Brown25843ad2018-09-17 14:54:33 -070014713 pld_deinit();
Dustin Brown4b9dbe62018-09-14 15:41:11 -070014714 wlan_hdd_state_ctrl_param_destroy();
Dustin Brownf0f70562018-09-14 10:29:38 -070014715 hdd_set_conparam(0);
Anurag Chouhana37b5b72016-02-21 14:53:42 +053014716 qdf_wake_lock_destroy(&wlan_wake_lock);
Dustin Brownd585cb32018-09-12 17:12:23 -070014717 hdd_component_deinit();
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053014718 hdd_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070014719
Dustin Brownc1d81af2019-03-01 13:43:43 -080014720 osif_driver_sync_trans_stop(driver_sync);
14721 osif_driver_sync_destroy(driver_sync);
Dustin Brown623e7e32018-09-05 14:27:50 -070014722
Dustin Brownc1d81af2019-03-01 13:43:43 -080014723 osif_sync_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070014724
Dustin Browna2a39dc2018-09-17 15:29:59 -070014725 hdd_qdf_deinit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014726}
14727
Arun Khandavallifae92942016-08-01 13:31:08 +053014728#ifndef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014729/**
Arun Khandavallifae92942016-08-01 13:31:08 +053014730 * wlan_boot_cb() - Wlan boot callback
14731 * @kobj: object whose directory we're creating the link in.
14732 * @attr: attribute the user is interacting with
14733 * @buff: the buffer containing the user data
14734 * @count: number of bytes in the buffer
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014735 *
Arun Khandavallifae92942016-08-01 13:31:08 +053014736 * This callback is invoked when the fs is ready to start the
14737 * wlan driver initialization.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014738 *
Arun Khandavallifae92942016-08-01 13:31:08 +053014739 * Return: 'count' on success or a negative error code in case of failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014740 */
Arun Khandavallifae92942016-08-01 13:31:08 +053014741static ssize_t wlan_boot_cb(struct kobject *kobj,
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014742 struct kobj_attribute *attr,
14743 const char *buf,
14744 size_t count)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014745{
Arun Khandavallifae92942016-08-01 13:31:08 +053014746
Arun Khandavallifae92942016-08-01 13:31:08 +053014747 if (wlan_loader->loaded_state) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014748 hdd_err("wlan driver already initialized");
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014749 return -EALREADY;
Arun Khandavallifae92942016-08-01 13:31:08 +053014750 }
14751
Dustin Brownf0f70562018-09-14 10:29:38 -070014752 if (hdd_driver_load())
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014753 return -EIO;
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014754
14755 wlan_loader->loaded_state = MODULE_INITIALIZED;
Arun Khandavallifae92942016-08-01 13:31:08 +053014756
14757 return count;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014758}
Arun Khandavallifae92942016-08-01 13:31:08 +053014759
14760/**
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014761 * hdd_sysfs_cleanup() - cleanup sysfs
14762 *
14763 * Return: None
14764 *
14765 */
14766static void hdd_sysfs_cleanup(void)
14767{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014768 /* remove from group */
14769 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
14770 sysfs_remove_group(wlan_loader->boot_wlan_obj,
14771 wlan_loader->attr_group);
14772
14773 /* unlink the object from parent */
14774 kobject_del(wlan_loader->boot_wlan_obj);
14775
14776 /* free the object */
14777 kobject_put(wlan_loader->boot_wlan_obj);
14778
14779 kfree(wlan_loader->attr_group);
14780 kfree(wlan_loader);
14781
14782 wlan_loader = NULL;
14783}
14784
14785/**
Arun Khandavallifae92942016-08-01 13:31:08 +053014786 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
14787 * ready
14788 *
14789 * This is creates the syfs entry boot_wlan. Which shall be invoked
14790 * when the filesystem is ready.
14791 *
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014792 * QDF API cannot be used here since this function is called even before
14793 * initializing WLAN driver.
14794 *
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070014795 * Return: 0 for success, errno on failure
Arun Khandavallifae92942016-08-01 13:31:08 +053014796 */
14797static int wlan_init_sysfs(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014798{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014799 int ret = -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053014800
14801 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070014802 if (!wlan_loader)
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014803 return -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053014804
14805 wlan_loader->boot_wlan_obj = NULL;
14806 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
14807 GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070014808 if (!wlan_loader->attr_group)
Arun Khandavallifae92942016-08-01 13:31:08 +053014809 goto error_return;
Arun Khandavallifae92942016-08-01 13:31:08 +053014810
14811 wlan_loader->loaded_state = 0;
14812 wlan_loader->attr_group->attrs = attrs;
14813
Qun Zhang4a83a462018-09-11 16:28:51 +080014814 wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME,
Arun Khandavallifae92942016-08-01 13:31:08 +053014815 kernel_kobj);
14816 if (!wlan_loader->boot_wlan_obj) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014817 hdd_err("sysfs create and add failed");
Arun Khandavallifae92942016-08-01 13:31:08 +053014818 goto error_return;
14819 }
14820
14821 ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
14822 wlan_loader->attr_group);
14823 if (ret) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014824 hdd_err("sysfs create group failed; errno:%d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053014825 goto error_return;
14826 }
14827
14828 return 0;
14829
14830error_return:
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014831 hdd_sysfs_cleanup();
Arun Khandavallifae92942016-08-01 13:31:08 +053014832
14833 return ret;
14834}
14835
14836/**
14837 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
14838 *
14839 * Return: 0 on success or errno on failure
14840 */
14841static int wlan_deinit_sysfs(void)
14842{
Arun Khandavallifae92942016-08-01 13:31:08 +053014843 if (!wlan_loader) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014844 hdd_err("wlan_loader is null");
Arun Khandavallifae92942016-08-01 13:31:08 +053014845 return -EINVAL;
14846 }
14847
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014848 hdd_sysfs_cleanup();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014849 return 0;
14850}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014851
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014852#endif /* MODULE */
Arun Khandavallifae92942016-08-01 13:31:08 +053014853
14854#ifdef MODULE
14855/**
Dustin Brownf0f70562018-09-14 10:29:38 -070014856 * hdd_module_init() - Module init helper
Arun Khandavallifae92942016-08-01 13:31:08 +053014857 *
14858 * Module init helper function used by both module and static driver.
14859 *
14860 * Return: 0 for success, errno on failure
14861 */
14862static int hdd_module_init(void)
14863{
Dustin Brownf0f70562018-09-14 10:29:38 -070014864 if (hdd_driver_load())
Dustin Brownab482ac2017-06-09 17:00:44 -070014865 return -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053014866
Dustin Brownab482ac2017-06-09 17:00:44 -070014867 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053014868}
14869#else
14870static int __init hdd_module_init(void)
14871{
14872 int ret = -EINVAL;
14873
14874 ret = wlan_init_sysfs();
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070014875 if (ret)
Dustin Browna2a39dc2018-09-17 15:29:59 -070014876 hdd_err("Failed to create sysfs entry");
Arun Khandavallifae92942016-08-01 13:31:08 +053014877
14878 return ret;
14879}
14880#endif
14881
14882
14883#ifdef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014884/**
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014885 * hdd_module_exit() - Exit function
14886 *
14887 * This is the driver exit point (invoked when module is unloaded using rmmod)
14888 *
14889 * Return: None
14890 */
14891static void __exit hdd_module_exit(void)
14892{
Dustin Brownf0f70562018-09-14 10:29:38 -070014893 hdd_driver_unload();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014894}
Arun Khandavallifae92942016-08-01 13:31:08 +053014895#else
14896static void __exit hdd_module_exit(void)
14897{
Dustin Brownf0f70562018-09-14 10:29:38 -070014898 hdd_driver_unload();
Arun Khandavallifae92942016-08-01 13:31:08 +053014899 wlan_deinit_sysfs();
14900}
14901#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014902
Srinivas Girigowda841da292018-02-21 16:33:00 -080014903static int fwpath_changed_handler(const char *kmessage,
14904 const struct kernel_param *kp)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014905{
14906 return param_set_copystring(kmessage, kp);
14907}
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014908
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053014909static int con_mode_handler_ftm(const char *kmessage,
Srinivas Girigowda841da292018-02-21 16:33:00 -080014910 const struct kernel_param *kp)
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053014911{
14912 int ret;
14913
14914 ret = param_set_int(kmessage, kp);
14915
14916 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
14917 pr_err("Only FTM mode supported!");
14918 return -ENOTSUPP;
14919 }
14920
14921 hdd_set_conparam(con_mode_ftm);
14922 con_mode = con_mode_ftm;
14923
14924 return ret;
14925}
14926
Nirav Shah6aeecf92019-02-13 14:05:03 +053014927#ifdef WLAN_FEATURE_EPPING
14928static int con_mode_handler_epping(const char *kmessage,
14929 const struct kernel_param *kp)
14930{
14931 int ret;
14932
14933 ret = param_set_int(kmessage, kp);
14934
14935 if (con_mode_epping != QDF_GLOBAL_EPPING_MODE) {
14936 pr_err("Only EPPING mode supported!");
14937 return -ENOTSUPP;
14938 }
14939
14940 hdd_set_conparam(con_mode_epping);
14941 con_mode = con_mode_epping;
14942
14943 return ret;
14944}
14945#endif
14946
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014947/**
14948 * hdd_get_conparam() - driver exit point
14949 *
14950 * This is the driver exit point (invoked when module is unloaded using rmmod)
14951 *
Jeff Johnson876c1a62017-12-12 10:43:07 -080014952 * Return: enum QDF_GLOBAL_MODE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014953 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080014954enum QDF_GLOBAL_MODE hdd_get_conparam(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014955{
Jeff Johnson876c1a62017-12-12 10:43:07 -080014956 return (enum QDF_GLOBAL_MODE) curr_con_mode;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014957}
14958
Dustin Brownf0f70562018-09-14 10:29:38 -070014959void hdd_set_conparam(int32_t con_param)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014960{
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080014961 curr_con_mode = con_param;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014962}
14963
Komal Seelamc11bb222016-01-27 18:57:10 +053014964/**
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014965 * hdd_clean_up_pre_cac_interface() - Clean up the pre cac interface
14966 * @hdd_ctx: HDD context
14967 *
14968 * Cleans up the pre cac interface, if it exists
14969 *
14970 * Return: None
14971 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014972void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx)
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014973{
Jeff Johnson55d2ab42019-03-06 11:43:49 -080014974 uint8_t vdev_id;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014975 QDF_STATUS status;
Jeff Johnson85b5c112017-08-11 15:15:23 -070014976 struct hdd_adapter *precac_adapter;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014977
Jeff Johnson55d2ab42019-03-06 11:43:49 -080014978 status = wlan_sap_get_pre_cac_vdev_id(hdd_ctx->mac_handle, &vdev_id);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014979 if (QDF_IS_STATUS_ERROR(status)) {
14980 hdd_err("failed to get pre cac vdev id");
14981 return;
14982 }
14983
Jeff Johnson55d2ab42019-03-06 11:43:49 -080014984 precac_adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014985 if (!precac_adapter) {
Jeff Johnsondd2f1fc2018-05-06 11:22:52 -070014986 hdd_err("invalid pre cac adapter");
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014987 return;
14988 }
14989
14990 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
14991 wlan_hdd_sap_pre_cac_failure,
14992 (void *)precac_adapter);
14993 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
14994
14995}
14996
14997/**
Yu Ouyang486fac82019-07-02 14:12:15 +080014998 * hdd_svc_fw_crashed_ind() - API to send FW CRASHED IND to Userspace
14999 *
15000 * Return: void
15001 */
15002static void hdd_svc_fw_crashed_ind(void)
15003{
15004 struct hdd_context *hdd_ctx;
15005
15006 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15007
15008 hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
15009 WLAN_SVC_FW_CRASHED_IND,
15010 NULL, 0) : 0;
15011}
15012
15013/**
Komal Seelamec702b02016-02-24 18:42:16 +053015014 * hdd_update_ol_config - API to update ol configuration parameters
15015 * @hdd_ctx: HDD context
Komal Seelamc11bb222016-01-27 18:57:10 +053015016 *
Komal Seelamc11bb222016-01-27 18:57:10 +053015017 * Return: void
15018 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015019static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
Komal Seelamc11bb222016-01-27 18:57:10 +053015020{
Abhishek Singh98278ce2018-12-27 11:41:03 +053015021 struct ol_config_info cfg = {0};
Anurag Chouhandf2b2682016-02-29 14:15:27 +053015022 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053015023 bool self_recovery = false;
15024 QDF_STATUS status;
Komal Seelamc11bb222016-01-27 18:57:10 +053015025
Komal Seelamec702b02016-02-24 18:42:16 +053015026 if (!ol_ctx)
15027 return;
15028
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053015029 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
15030 if (QDF_IS_STATUS_ERROR(status))
15031 hdd_err("Failed to get self recovery ini config");
15032
15033 cfg.enable_self_recovery = self_recovery;
Komal Seelamec702b02016-02-24 18:42:16 +053015034 cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
15035 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
15036 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
Jeff Johnsonb8bf9072016-09-23 17:39:27 -070015037 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
Komal Seelamec702b02016-02-24 18:42:16 +053015038
15039 ol_init_ini_config(ol_ctx, &cfg);
Yu Ouyang486fac82019-07-02 14:12:15 +080015040 ol_set_fw_crashed_cb(ol_ctx, hdd_svc_fw_crashed_ind);
Komal Seelamec702b02016-02-24 18:42:16 +053015041}
15042
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070015043#ifdef FEATURE_RUNTIME_PM
15044/**
15045 * hdd_populate_runtime_cfg() - populate runtime configuration
15046 * @hdd_ctx: hdd context
15047 * @cfg: pointer to the configuration memory being populated
15048 *
15049 * Return: void
15050 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015051static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070015052 struct hif_config_info *cfg)
15053{
15054 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
Wu Gao66454f12018-09-26 19:55:41 +080015055 cfg->runtime_pm_delay =
15056 ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc);
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070015057}
15058#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015059static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070015060 struct hif_config_info *cfg)
15061{
15062}
15063#endif
15064
Komal Seelamec702b02016-02-24 18:42:16 +053015065/**
15066 * hdd_update_hif_config - API to update HIF configuration parameters
15067 * @hdd_ctx: HDD Context
15068 *
15069 * Return: void
15070 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015071static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053015072{
Anurag Chouhandf2b2682016-02-29 14:15:27 +053015073 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
Abhishek Singh98278ce2018-12-27 11:41:03 +053015074 struct hif_config_info cfg = {0};
Vignesh Viswanathana851d752018-10-03 19:44:38 +053015075 bool prevent_link_down = false;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053015076 bool self_recovery = false;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053015077 QDF_STATUS status;
Komal Seelamec702b02016-02-24 18:42:16 +053015078
15079 if (!scn)
15080 return;
15081
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053015082 status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc,
15083 &prevent_link_down);
Vignesh Viswanathana851d752018-10-03 19:44:38 +053015084 if (QDF_IS_STATUS_ERROR(status))
15085 hdd_err("Failed to get prevent_link_down config");
15086
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053015087 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
15088 if (QDF_IS_STATUS_ERROR(status))
15089 hdd_err("Failed to get self recovery ini config");
15090
15091 cfg.enable_self_recovery = self_recovery;
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070015092 hdd_populate_runtime_cfg(hdd_ctx, &cfg);
Mohit Khannaa8c9f562019-03-25 22:17:02 -070015093 cfg.rx_softirq_max_yield_duration_ns =
15094 cfg_get(hdd_ctx->psoc,
15095 CFG_DP_RX_SOFTIRQ_MAX_YIELD_TIME_NS);
15096
Komal Seelamec702b02016-02-24 18:42:16 +053015097 hif_init_ini_config(scn, &cfg);
Dustin Brownee3e0592017-09-07 13:50:11 -070015098
Vignesh Viswanathana851d752018-10-03 19:44:38 +053015099 if (prevent_link_down)
Dustin Brownee3e0592017-09-07 13:50:11 -070015100 hif_vote_link_up(scn);
Komal Seelamec702b02016-02-24 18:42:16 +053015101}
15102
Mohit Khannaa8c9f562019-03-25 22:17:02 -070015103#ifdef WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT
15104/**
15105 * hdd_update_dp_config_rx_softirq_limits() - Update DP rx softirq limit config
15106 * datapath
15107 * @hdd_ctx: HDD Context
15108 * @params: pointer to cdp_config_params to be updated
15109 *
15110 * Void
15111 */
15112static
15113void hdd_update_dp_config_rx_softirq_limits(struct hdd_context *hdd_ctx,
15114 struct cdp_config_params *params)
15115{
15116 params->tx_comp_loop_pkt_limit = cfg_get(hdd_ctx->psoc,
15117 CFG_DP_TX_COMP_LOOP_PKT_LIMIT);
15118 params->rx_reap_loop_pkt_limit = cfg_get(hdd_ctx->psoc,
15119 CFG_DP_RX_REAP_LOOP_PKT_LIMIT);
15120 params->rx_hp_oos_update_limit = cfg_get(hdd_ctx->psoc,
15121 CFG_DP_RX_HP_OOS_UPDATE_LIMIT);
15122}
15123#else
15124static
15125void hdd_update_dp_config_rx_softirq_limits(struct hdd_context *hdd_ctx,
15126 struct cdp_config_params *params)
15127{
15128}
15129#endif /* WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT */
15130
hangtianb9c91362019-06-07 10:39:38 +080015131#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
15132static void
15133hdd_update_dp_config_queue_threshold(struct hdd_context *hdd_ctx,
15134 struct cdp_config_params *params)
15135{
15136 params->tx_flow_stop_queue_threshold =
15137 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
15138 params->tx_flow_start_queue_offset =
15139 cfg_get(hdd_ctx->psoc,
15140 CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
15141}
15142#else
15143static inline void
15144hdd_update_dp_config_queue_threshold(struct hdd_context *hdd_ctx,
15145 struct cdp_config_params *params)
15146{
15147}
15148#endif
15149
Komal Seelamec702b02016-02-24 18:42:16 +053015150/**
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015151 * hdd_update_dp_config() - Propagate config parameters to Lithium
15152 * datapath
15153 * @hdd_ctx: HDD Context
15154 *
15155 * Return: 0 for success/errno for failure
15156 */
15157static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
15158{
Abhishek Singh98278ce2018-12-27 11:41:03 +053015159 struct cdp_config_params params = {0};
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015160 QDF_STATUS status;
jitiphil377bcc12018-10-05 19:46:08 +053015161 void *soc;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015162
jitiphil377bcc12018-10-05 19:46:08 +053015163 soc = cds_get_context(QDF_MODULE_ID_SOC);
15164 params.tso_enable = cfg_get(hdd_ctx->psoc, CFG_DP_TSO);
15165 params.lro_enable = cfg_get(hdd_ctx->psoc, CFG_DP_LRO);
hangtianb9c91362019-06-07 10:39:38 +080015166 hdd_update_dp_config_queue_threshold(hdd_ctx, &params);
jitiphil377bcc12018-10-05 19:46:08 +053015167 params.flow_steering_enable =
15168 cfg_get(hdd_ctx->psoc, CFG_DP_FLOW_STEERING_ENABLED);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015169 params.napi_enable = hdd_ctx->napi_enable;
15170 params.tcp_udp_checksumoffload =
jitiphil377bcc12018-10-05 19:46:08 +053015171 cfg_get(hdd_ctx->psoc,
15172 CFG_DP_TCP_UDP_CKSUM_OFFLOAD);
Sravan Kumar Kairam0af1ee52018-12-12 20:37:51 +053015173 params.ipa_enable = ucfg_ipa_is_enabled();
Mohit Khanna81418772018-10-30 14:14:46 -070015174 params.gro_enable = cfg_get(hdd_ctx->psoc, CFG_DP_GRO);
Mohit Khannaa8c9f562019-03-25 22:17:02 -070015175 params.tx_comp_loop_pkt_limit = cfg_get(hdd_ctx->psoc,
15176 CFG_DP_TX_COMP_LOOP_PKT_LIMIT);
15177 params.rx_reap_loop_pkt_limit = cfg_get(hdd_ctx->psoc,
15178 CFG_DP_RX_REAP_LOOP_PKT_LIMIT);
15179 params.rx_hp_oos_update_limit = cfg_get(hdd_ctx->psoc,
15180 CFG_DP_RX_HP_OOS_UPDATE_LIMIT);
15181 hdd_update_dp_config_rx_softirq_limits(hdd_ctx, &params);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015182
jitiphil377bcc12018-10-05 19:46:08 +053015183 status = cdp_update_config_parameters(soc, &params);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015184 if (status) {
Dustin Browna2868622018-03-20 11:38:14 -070015185 hdd_err("Failed to attach config parameters");
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015186 return status;
15187 }
15188
15189 return 0;
15190}
15191
15192/**
Komal Seelamec702b02016-02-24 18:42:16 +053015193 * hdd_update_config() - Initialize driver per module ini parameters
15194 * @hdd_ctx: HDD Context
15195 *
15196 * API is used to initialize all driver per module configuration parameters
Arun Khandavallic811dcc2016-06-26 07:37:21 +053015197 * Return: 0 for success, errno for failure
Komal Seelamec702b02016-02-24 18:42:16 +053015198 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015199int hdd_update_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053015200{
Arun Khandavallic811dcc2016-06-26 07:37:21 +053015201 int ret;
15202
Wu Gao66454f12018-09-26 19:55:41 +080015203 if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc))
15204 hdd_ctx->ns_offload_enable = true;
15205
Komal Seelamec702b02016-02-24 18:42:16 +053015206 hdd_update_ol_config(hdd_ctx);
15207 hdd_update_hif_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053015208 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
15209 ret = hdd_update_cds_config_ftm(hdd_ctx);
15210 else
15211 ret = hdd_update_cds_config(hdd_ctx);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080015212 ret = hdd_update_user_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053015213
Rajeev Kumar Sirasanagandla1b3a5352019-08-05 21:33:03 +053015214 hdd_update_regdb_offload_config(hdd_ctx);
15215
Arun Khandavallic811dcc2016-06-26 07:37:21 +053015216 return ret;
Komal Seelamc11bb222016-01-27 18:57:10 +053015217}
15218
Mukul Sharma9d797a02017-01-05 20:26:03 +053015219/**
15220 * hdd_update_pmo_config - API to update pmo configuration parameters
15221 * @hdd_ctx: HDD context
15222 *
15223 * Return: void
15224 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015225static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053015226{
Abhishek Singh98278ce2018-12-27 11:41:03 +053015227 struct pmo_psoc_cfg psoc_cfg = {0};
Mukul Sharma9d797a02017-01-05 20:26:03 +053015228 QDF_STATUS status;
Wu Gao66454f12018-09-26 19:55:41 +080015229 enum pmo_wow_enable_type wow_enable;
15230
15231 ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg);
Mukul Sharma9d797a02017-01-05 20:26:03 +053015232
15233 /*
15234 * Value of hdd_ctx->wowEnable can be,
15235 * 0 - Disable both magic pattern match and pattern byte match.
15236 * 1 - Enable magic pattern match on all interfaces.
15237 * 2 - Enable pattern byte match on all interfaces.
15238 * 3 - Enable both magic patter and pattern byte match on
15239 * all interfaces.
15240 */
Wu Gao66454f12018-09-26 19:55:41 +080015241 wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc);
15242 psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false;
Mukul Sharma9d797a02017-01-05 20:26:03 +053015243 psoc_cfg.ptrn_match_enable_all_vdev =
Wu Gao66454f12018-09-26 19:55:41 +080015244 (wow_enable & 0x02) ? true : false;
Mukul Sharma9d797a02017-01-05 20:26:03 +053015245 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
Will Huang3cd2b7c2017-11-17 13:16:56 +080015246 psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
Bala Venkatesh46e29032018-11-14 18:24:55 +053015247 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
15248 &psoc_cfg.sta_max_li_mod_dtim);
15249
Mukul Sharma9d797a02017-01-05 20:26:03 +053015250
Mukul Sharma9223f232017-03-08 18:42:27 +053015251 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053015252
Dustin Brown1dbefe62018-09-11 16:32:03 -070015253 status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg);
Dustin Brownb9987af2018-03-01 17:15:11 -080015254 if (QDF_IS_STATUS_ERROR(status))
15255 hdd_err("failed pmo psoc configuration; status:%d", status);
15256
15257 return qdf_status_to_os_return(status);
Mukul Sharma9d797a02017-01-05 20:26:03 +053015258}
15259
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015260void hdd_update_ie_whitelist_attr(struct probe_req_whitelist_attr *ie_whitelist,
Dundi Raviteja85a240a2018-09-10 15:03:07 +053015261 struct hdd_context *hdd_ctx)
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015262{
Dundi Raviteja85a240a2018-09-10 15:03:07 +053015263 struct wlan_fwol_ie_whitelist whitelist = {0};
15264 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Dundi Raviteja85a240a2018-09-10 15:03:07 +053015265 QDF_STATUS status;
15266 bool is_ie_whitelist_enable = false;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015267 uint8_t i = 0;
15268
Dundi Raviteja85a240a2018-09-10 15:03:07 +053015269 status = ucfg_fwol_get_ie_whitelist(psoc, &is_ie_whitelist_enable);
15270 if (QDF_IS_STATUS_ERROR(status)) {
15271 hdd_err("Unable to get IE whitelist param");
15272 return;
15273 }
15274
15275 ie_whitelist->white_list = is_ie_whitelist_enable;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015276 if (!ie_whitelist->white_list)
15277 return;
15278
Dundi Raviteja85a240a2018-09-10 15:03:07 +053015279 status = ucfg_fwol_get_all_whitelist_params(psoc, &whitelist);
15280 if (QDF_IS_STATUS_ERROR(status)) {
15281 hdd_err("Unable to get all whitelist params");
15282 return;
15283 }
15284
15285 ie_whitelist->ie_bitmap[0] = whitelist.ie_bitmap_0;
15286 ie_whitelist->ie_bitmap[1] = whitelist.ie_bitmap_1;
15287 ie_whitelist->ie_bitmap[2] = whitelist.ie_bitmap_2;
15288 ie_whitelist->ie_bitmap[3] = whitelist.ie_bitmap_3;
15289 ie_whitelist->ie_bitmap[4] = whitelist.ie_bitmap_4;
15290 ie_whitelist->ie_bitmap[5] = whitelist.ie_bitmap_5;
15291 ie_whitelist->ie_bitmap[6] = whitelist.ie_bitmap_6;
15292 ie_whitelist->ie_bitmap[7] = whitelist.ie_bitmap_7;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015293
Dundi Raviteja9ab4e7b2018-09-28 14:18:28 +053015294 ie_whitelist->num_vendor_oui = whitelist.no_of_probe_req_ouis;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015295 for (i = 0; i < ie_whitelist->num_vendor_oui; i++)
Dundi Raviteja9ab4e7b2018-09-28 14:18:28 +053015296 ie_whitelist->voui[i] = whitelist.probe_req_voui[i];
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015297}
15298
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015299uint32_t hdd_limit_max_per_index_score(uint32_t per_index_score)
15300{
15301 uint8_t i, score;
15302
15303 for (i = 0; i < MAX_INDEX_PER_INI; i++) {
15304 score = WLAN_GET_SCORE_PERCENTAGE(per_index_score, i);
15305 if (score > MAX_INDEX_SCORE)
15306 WLAN_SET_SCORE_PERCENTAGE(per_index_score,
15307 MAX_INDEX_SCORE, i);
15308 }
15309
15310 return per_index_score;
15311}
15312
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053015313QDF_STATUS hdd_update_score_config(
15314 struct scoring_config *score_config, struct hdd_context *hdd_ctx)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015315{
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053015316 struct hdd_config *cfg = hdd_ctx->config;
gaurank kathpaliaae52c982018-10-04 01:35:18 +053015317 QDF_STATUS status;
gaurank kathpalia651abcd2018-11-12 22:41:23 +053015318 struct wlan_mlme_nss_chains vdev_ini_cfg;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053015319 bool bval = false;
Wu Gaoed616a12019-01-16 15:19:21 +080015320 uint32_t channel_bonding_mode;
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015321
Abhishek Singh98278ce2018-12-27 11:41:03 +053015322 qdf_mem_zero(&vdev_ini_cfg, sizeof(struct wlan_mlme_nss_chains));
gaurank kathpalia651abcd2018-11-12 22:41:23 +053015323 /* Populate the nss chain params from ini for this vdev type */
15324 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
15325 QDF_STA_MODE,
15326 hdd_ctx->num_rf_chains);
15327
15328 score_config->vdev_nss_24g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ];
gaurank kathpalia19c23542019-06-01 16:57:28 +053015329 score_config->vdev_nss_5g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ];
gaurank kathpalia651abcd2018-11-12 22:41:23 +053015330
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053015331 sme_update_score_config(hdd_ctx->mac_handle, score_config);
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015332
Wu Gaoed616a12019-01-16 15:19:21 +080015333 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
15334 &channel_bonding_mode);
15335 score_config->cb_mode_24G = channel_bonding_mode;
15336 ucfg_mlme_get_channel_bonding_5ghz(hdd_ctx->psoc,
15337 &channel_bonding_mode);
15338 score_config->cb_mode_5G = channel_bonding_mode;
gaurank kathpaliaae52c982018-10-04 01:35:18 +053015339
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015340 if (cfg->dot11Mode == eHDD_DOT11_MODE_AUTO ||
15341 cfg->dot11Mode == eHDD_DOT11_MODE_11ax ||
15342 cfg->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)
15343 score_config->he_cap = 1;
15344
15345 if (score_config->he_cap ||
15346 cfg->dot11Mode == eHDD_DOT11_MODE_11ac ||
15347 cfg->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)
15348 score_config->vht_cap = 1;
15349
15350 if (score_config->vht_cap || cfg->dot11Mode == eHDD_DOT11_MODE_11n ||
15351 cfg->dot11Mode == eHDD_DOT11_MODE_11n_ONLY)
15352 score_config->ht_cap = 1;
15353
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053015354 status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &bval);
15355 if (!QDF_IS_STATUS_SUCCESS(status))
15356 hdd_err("Failed to get vht_for_24ghz");
15357 if (score_config->vht_cap && bval)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015358 score_config->vht_24G_cap = 1;
15359
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053015360 status = ucfg_mlme_get_vht_enable_tx_bf(hdd_ctx->psoc,
15361 &bval);
15362 if (!QDF_IS_STATUS_SUCCESS(status))
15363 hdd_err("unable to get vht_enable_tx_bf");
15364
15365 if (bval)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015366 score_config->beamformee_cap = 1;
15367
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053015368 return QDF_STATUS_SUCCESS;
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015369}
15370
Abhishek Singh257a9482017-03-06 16:52:39 +053015371/**
bings81fe50a2017-11-27 14:33:26 +080015372 * hdd_update_dfs_config() - API to update dfs configuration parameters.
15373 * @hdd_ctx: HDD context
15374 *
15375 * Return: 0 if success else err
15376 */
15377static int hdd_update_dfs_config(struct hdd_context *hdd_ctx)
15378{
Dustin Brown1dbefe62018-09-11 16:32:03 -070015379 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Abhishek Singh98278ce2018-12-27 11:41:03 +053015380 struct dfs_user_config dfs_cfg = {0};
bings81fe50a2017-11-27 14:33:26 +080015381 QDF_STATUS status;
15382
Arif Hussain224d3812018-11-16 17:58:38 -080015383 ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc,
15384 &dfs_cfg.dfs_is_phyerr_filter_offload);
bings81fe50a2017-11-27 14:33:26 +080015385 status = ucfg_dfs_update_config(psoc, &dfs_cfg);
15386 if (QDF_IS_STATUS_ERROR(status)) {
15387 hdd_err("failed dfs psoc configuration");
15388 return -EINVAL;
15389 }
15390
15391 return 0;
15392}
15393
15394/**
Abhishek Singh257a9482017-03-06 16:52:39 +053015395 * hdd_update_scan_config - API to update scan configuration parameters
15396 * @hdd_ctx: HDD context
15397 *
15398 * Return: 0 if success else err
15399 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015400static int hdd_update_scan_config(struct hdd_context *hdd_ctx)
Abhishek Singh257a9482017-03-06 16:52:39 +053015401{
Dustin Brown1dbefe62018-09-11 16:32:03 -070015402 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Sandeep Puligillad7887022019-02-26 00:48:52 -080015403 struct scan_user_cfg scan_cfg;
Abhishek Singh257a9482017-03-06 16:52:39 +053015404 QDF_STATUS status;
Krunal Sonid2c33e12018-12-06 15:02:37 -080015405 uint32_t mcast_mcc_rest_time = 0;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053015406
Sandeep Puligillad7887022019-02-26 00:48:52 -080015407 qdf_mem_zero(&scan_cfg, sizeof(scan_cfg));
Krunal Sonid2c33e12018-12-06 15:02:37 -080015408 status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc,
15409 &mcast_mcc_rest_time);
15410 if (!QDF_IS_STATUS_SUCCESS(status)) {
15411 hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def");
15412 return -EIO;
15413 }
15414 scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time;
Dundi Raviteja85a240a2018-09-10 15:03:07 +053015415 hdd_update_ie_whitelist_attr(&scan_cfg.ie_whitelist, hdd_ctx);
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053015416
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053015417 status = hdd_update_score_config(&scan_cfg.score_config, hdd_ctx);
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053015418 if (QDF_IS_STATUS_ERROR(status)) {
15419 hdd_err("Failed to update scoring config");
15420 return -EINVAL;
15421 }
Abhishek Singhb20db962017-03-03 21:28:46 +053015422
Abhishek Singh257a9482017-03-06 16:52:39 +053015423 status = ucfg_scan_update_user_config(psoc, &scan_cfg);
15424 if (status != QDF_STATUS_SUCCESS) {
15425 hdd_err("failed pmo psoc configuration");
15426 return -EINVAL;
15427 }
15428
15429 return 0;
15430}
Abhishek Singh257a9482017-03-06 16:52:39 +053015431
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015432int hdd_update_components_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053015433{
15434 int ret;
15435
15436 ret = hdd_update_pmo_config(hdd_ctx);
Abhishek Singh257a9482017-03-06 16:52:39 +053015437 if (ret)
15438 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015439
Abhishek Singh257a9482017-03-06 16:52:39 +053015440 ret = hdd_update_scan_config(hdd_ctx);
Frank Liud4b2fa02017-03-29 11:46:48 +080015441 if (ret)
15442 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015443
Frank Liud4b2fa02017-03-29 11:46:48 +080015444 ret = hdd_update_tdls_config(hdd_ctx);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015445 if (ret)
15446 return ret;
15447
15448 ret = hdd_update_dp_config(hdd_ctx);
bings81fe50a2017-11-27 14:33:26 +080015449 if (ret)
15450 return ret;
15451
15452 ret = hdd_update_dfs_config(hdd_ctx);
Ashish Kumar Dhanotiyaee0332a2019-11-15 21:20:02 +053015453 if (ret)
15454 return ret;
15455
15456 ret = hdd_update_regulatory_config(hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053015457
15458 return ret;
15459}
15460
Agrawal Ashish65634612016-08-18 13:24:32 +053015461/**
15462 * wlan_hdd_get_dfs_mode() - get ACS DFS mode
15463 * @mode : cfg80211 DFS mode
15464 *
15465 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
15466 */
15467enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
15468{
15469 switch (mode) {
15470 case DFS_MODE_ENABLE:
15471 return ACS_DFS_MODE_ENABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053015472 case DFS_MODE_DISABLE:
15473 return ACS_DFS_MODE_DISABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053015474 case DFS_MODE_DEPRIORITIZE:
15475 return ACS_DFS_MODE_DEPRIORITIZE;
Agrawal Ashish65634612016-08-18 13:24:32 +053015476 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080015477 hdd_debug("ACS dfs mode is NONE");
15478 return ACS_DFS_MODE_NONE;
Agrawal Ashish65634612016-08-18 13:24:32 +053015479 }
15480}
15481
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053015482/**
15483 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
15484 * @hddctx: pointer to hdd context
15485 * @set_value: enable/disable
15486 *
15487 * When Host sends vendor command enable, FW will send *ONE* CA ind to
15488 * Host(even though it is duplicate). When Host send vendor command
15489 * disable,FW doesn't perform any action. Whenever any change in
15490 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
15491 *
15492 * return - 0 on success, appropriate error values on failure.
15493 */
Jeff Johnson16528362018-06-14 12:34:16 -070015494int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value)
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053015495{
15496 QDF_STATUS status;
15497
Jeff Johnson16528362018-06-14 12:34:16 -070015498 if (0 != wlan_hdd_validate_context(hdd_ctx))
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053015499 return -EAGAIN;
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053015500
Jeff Johnson16528362018-06-14 12:34:16 -070015501 status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle,
15502 set_value);
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053015503 if (!QDF_IS_STATUS_SUCCESS(status)) {
15504 hdd_err("Failed to send chan avoid command to SME");
15505 return -EINVAL;
15506 }
15507 return 0;
15508}
Agrawal Ashish65634612016-08-18 13:24:32 +053015509
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015510/**
15511 * hdd_set_roaming_in_progress() - to set the roaming in progress flag
15512 * @value: value to set
15513 *
15514 * This function will set the passed value to roaming in progress flag.
15515 *
15516 * Return: None
15517 */
15518void hdd_set_roaming_in_progress(bool value)
15519{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015520 struct hdd_context *hdd_ctx;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015521
15522 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15523 if (!hdd_ctx) {
15524 hdd_err("HDD context is NULL");
15525 return;
15526 }
15527
15528 hdd_ctx->roaming_in_progress = value;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080015529 hdd_debug("Roaming in Progress set to %d", value);
Abhinav Kumar2b431b62019-03-18 20:23:58 +053015530 if (!hdd_ctx->roaming_in_progress) {
15531 /* Reset scan reject params on successful roam complete */
15532 hdd_debug("Reset scan reject params");
15533 hdd_init_scan_reject_params(hdd_ctx);
15534 }
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015535}
15536
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053015537bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx)
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015538{
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015539 if (!hdd_ctx) {
15540 hdd_err("HDD context is NULL");
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053015541 return false;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015542 }
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080015543
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053015544 hdd_debug("roaming_in_progress = %d", hdd_ctx->roaming_in_progress);
15545
15546 return hdd_ctx->roaming_in_progress;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015547}
15548
Alan Chenc255b802019-11-18 16:59:32 -080015549/**
15550 * struct hdd_is_connection_in_progress_priv - adapter connection info
15551 * @out_vdev_id: id of vdev where connection is occurring
15552 * @out_reason: scan reject reason
15553 */
15554struct hdd_is_connection_in_progress_priv {
15555 uint8_t out_vdev_id;
15556 enum scan_reject_states out_reason;
15557 bool connection_in_progress;
15558};
15559
15560/**
15561 * hdd_is_connection_in_progress_iterator() - Check adapter connection based
15562 * on device mode
15563 * @adapter: current adapter of interest
15564 * @context: user context supplied
15565 *
15566 * Check if connection is in progress for the current adapter according to the
15567 * device mode
15568 *
15569 * Return:
15570 * * QDF_STATUS_SUCCESS if iteration should continue
15571 * * QDF_STATUS_E_ABORTED if iteration should be aborted
15572 */
15573static QDF_STATUS hdd_is_connection_in_progress_iterator(
15574 struct hdd_adapter *adapter,
15575 void *ctx)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015576{
Alan Chenc255b802019-11-18 16:59:32 -080015577 struct hdd_station_ctx *hdd_sta_ctx;
Sourav Mohapatra43e6dea2019-08-18 11:39:23 +053015578 uint8_t index = 0;
Alan Chenc255b802019-11-18 16:59:32 -080015579 uint8_t *sta_mac;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015580 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -070015581 mac_handle_t mac_handle;
Alan Chenc255b802019-11-18 16:59:32 -080015582 struct hdd_station_info *sta_info;
15583 struct hdd_is_connection_in_progress_priv *context = ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015584
15585 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15586 if (!hdd_ctx) {
15587 hdd_err("HDD context is NULL");
Alan Chenc255b802019-11-18 16:59:32 -080015588 return QDF_STATUS_E_ABORTED;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015589 }
15590
Jeff Johnson16528362018-06-14 12:34:16 -070015591 mac_handle = hdd_ctx->mac_handle;
15592
Alan Chenc255b802019-11-18 16:59:32 -080015593 hdd_debug("Adapter with device mode %s(%d) exists",
15594 qdf_opmode_str(adapter->device_mode),
15595 adapter->device_mode);
15596 if (((QDF_STA_MODE == adapter->device_mode)
15597 || (QDF_P2P_CLIENT_MODE == adapter->device_mode)
15598 || (QDF_P2P_DEVICE_MODE == adapter->device_mode))
15599 && (eConnectionState_Connecting ==
15600 (WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
15601 conn_info.conn_state)) {
15602 hdd_debug("%pK(%d) Connection is in progress",
15603 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
15604 adapter->vdev_id);
15605
15606 context->out_vdev_id = adapter->vdev_id;
15607 context->out_reason = CONNECTION_IN_PROGRESS;
15608 context->connection_in_progress = true;
15609
15610 return QDF_STATUS_E_ABORTED;
15611 }
15612 /*
15613 * sme_neighbor_middle_of_roaming is for LFR2
15614 * hdd_is_roaming_in_progress is for LFR3
15615 */
15616 if (((QDF_STA_MODE == adapter->device_mode) &&
15617 sme_neighbor_middle_of_roaming(
15618 mac_handle,
15619 adapter->vdev_id)) ||
15620 hdd_is_roaming_in_progress(hdd_ctx)) {
15621 hdd_debug("%pK(%d) Reassociation in progress",
15622 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
15623 adapter->vdev_id);
15624
15625 context->out_vdev_id = adapter->vdev_id;
15626 context->out_reason = REASSOC_IN_PROGRESS;
15627 context->connection_in_progress = true;
15628 return QDF_STATUS_E_ABORTED;
15629 }
15630
15631 if ((QDF_STA_MODE == adapter->device_mode) ||
15632 (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
15633 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
15634 hdd_sta_ctx =
15635 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
15636 if ((eConnectionState_Associated ==
15637 hdd_sta_ctx->conn_info.conn_state)
15638 && sme_is_sta_key_exchange_in_progress(
15639 mac_handle, adapter->vdev_id)) {
15640 sta_mac = (uint8_t *)&(adapter->mac_addr.bytes[0]);
15641 hdd_debug("client " QDF_MAC_ADDR_STR
15642 " is in middle of WPS/EAPOL exchange.",
15643 QDF_MAC_ADDR_ARRAY(sta_mac));
15644
15645 context->out_vdev_id = adapter->vdev_id;
15646 context->out_reason = EAPOL_IN_PROGRESS;
15647 context->connection_in_progress = true;
15648
15649 return QDF_STATUS_E_ABORTED;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015650 }
Alan Chenc255b802019-11-18 16:59:32 -080015651 } else if ((QDF_SAP_MODE == adapter->device_mode) ||
15652 (QDF_P2P_GO_MODE == adapter->device_mode)) {
15653 hdd_for_each_station(adapter->sta_info_list, sta_info,
15654 index) {
15655 if (sta_info->peer_state !=
15656 OL_TXRX_PEER_STATE_CONN)
15657 continue;
15658
15659 sta_mac = sta_info->sta_mac.bytes;
15660 hdd_debug("client " QDF_MAC_ADDR_STR
15661 " of SAP/GO is in middle of WPS/EAPOL exchange",
15662 QDF_MAC_ADDR_ARRAY(sta_mac));
15663
15664 context->out_vdev_id = adapter->vdev_id;
15665 context->out_reason = SAP_EAPOL_IN_PROGRESS;
15666 context->connection_in_progress = true;
15667
15668 return QDF_STATUS_E_ABORTED;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015669 }
Alan Chenc255b802019-11-18 16:59:32 -080015670 if (hdd_ctx->connection_in_progress) {
15671 hdd_debug("AP/GO: connection is in progress");
15672 context->out_reason = SAP_CONNECTION_IN_PROGRESS;
15673 context->out_vdev_id = adapter->vdev_id;
15674 context->connection_in_progress = true;
Sourav Mohapatra43e6dea2019-08-18 11:39:23 +053015675
Alan Chenc255b802019-11-18 16:59:32 -080015676 return QDF_STATUS_E_ABORTED;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015677 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015678 }
Dustin Brown920397d2017-12-13 16:27:50 -080015679
Alan Chenc255b802019-11-18 16:59:32 -080015680 return QDF_STATUS_SUCCESS;
15681}
15682
15683bool hdd_is_connection_in_progress(uint8_t *out_vdev_id,
15684 enum scan_reject_states *out_reason)
15685{
15686 struct hdd_is_connection_in_progress_priv hdd_conn;
15687 hdd_adapter_iterate_cb cb;
15688
15689 hdd_conn.out_vdev_id = 0;
15690 hdd_conn.out_reason = SCAN_REJECT_DEFAULT;
15691 hdd_conn.connection_in_progress = false;
15692
15693 cb = hdd_is_connection_in_progress_iterator;
15694
15695 hdd_adapter_iterate(cb, &hdd_conn);
15696
15697 if (hdd_conn.connection_in_progress && out_vdev_id && out_reason) {
15698 *out_vdev_id = hdd_conn.out_vdev_id;
15699 *out_reason = hdd_conn.out_reason;
15700 }
15701
15702 return hdd_conn.connection_in_progress;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015703}
15704
15705/**
15706 * hdd_restart_sap() - to restart SAP in driver internally
Jeff Johnson9d295242017-08-29 14:39:48 -070015707 * @ap_adapter: Pointer to SAP struct hdd_adapter structure
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015708 *
15709 * Return: None
15710 */
Jeff Johnson9d295242017-08-29 14:39:48 -070015711void hdd_restart_sap(struct hdd_adapter *ap_adapter)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015712{
Jeff Johnson87251032017-08-29 13:31:11 -070015713 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070015714 struct hdd_hostapd_state *hostapd_state;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015715 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015716 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Jeff Johnson8f8ceb92019-03-24 08:16:55 -070015717 struct sap_config *sap_config;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015718 void *sap_ctx;
15719
15720 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
Jeff Johnson91df29d2017-10-27 19:29:50 -070015721 sap_config = &hdd_ap_ctx->sap_config;
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070015722 sap_ctx = hdd_ap_ctx->sap_context;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015723
15724 mutex_lock(&hdd_ctx->sap_lock);
15725 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
15726 wlan_hdd_del_station(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015727 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
15728 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
15729 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
15730 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053015731 qdf_wait_for_event_completion(&hostapd_state->
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015732 qdf_stop_bss_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053015733 SME_CMD_STOP_BSS_TIMEOUT);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015734
15735 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015736 hdd_err("SAP Stop Failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015737 goto end;
15738 }
15739 }
15740 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -070015741 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015742 ap_adapter->device_mode, ap_adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070015743 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053015744 false);
Jeff Johnson6867ec32017-09-29 20:30:20 -070015745 hdd_err("SAP Stop Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015746
15747 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015748 hdd_err("SAP Not able to set AP IEs");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015749 wlansap_reset_sap_config_add_ie(sap_config,
15750 eUPDATE_IE_ALL);
15751 goto end;
15752 }
15753
15754 qdf_event_reset(&hostapd_state->qdf_event);
15755 if (wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
15756 sap_config,
15757 ap_adapter->dev) != QDF_STATUS_SUCCESS) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015758 hdd_err("SAP Start Bss fail");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015759 wlansap_reset_sap_config_add_ie(sap_config,
15760 eUPDATE_IE_ALL);
15761 goto end;
15762 }
15763
Jeff Johnson6867ec32017-09-29 20:30:20 -070015764 hdd_info("Waiting for SAP to start");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015765 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053015766 qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053015767 SME_CMD_START_BSS_TIMEOUT);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015768 wlansap_reset_sap_config_add_ie(sap_config,
15769 eUPDATE_IE_ALL);
15770 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015771 hdd_err("SAP Start failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015772 goto end;
15773 }
Jeff Johnson6867ec32017-09-29 20:30:20 -070015774 hdd_err("SAP Start Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015775 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053015776 if (hostapd_state->bss_state == BSS_START) {
Dustin Brown1dbefe62018-09-11 16:32:03 -070015777 policy_mgr_incr_active_session(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080015778 ap_adapter->device_mode,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015779 ap_adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070015780 hdd_green_ap_start_state_mc(hdd_ctx,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053015781 ap_adapter->device_mode,
15782 true);
15783 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015784 }
15785end:
15786 mutex_unlock(&hdd_ctx->sap_lock);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015787}
15788
15789/**
15790 * hdd_check_and_restart_sap_with_non_dfs_acs() - Restart SAP
15791 * with non dfs acs
15792 *
15793 * Restarts SAP in non-DFS ACS mode when STA-AP mode DFS is not supported
15794 *
15795 * Return: None
15796 */
15797void hdd_check_and_restart_sap_with_non_dfs_acs(void)
15798{
Jeff Johnson9d295242017-08-29 14:39:48 -070015799 struct hdd_adapter *ap_adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015800 struct hdd_context *hdd_ctx;
Jeff Johnson2b6982c2018-05-29 14:56:11 -070015801 struct cds_context *cds_ctx;
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053015802 uint8_t restart_chan;
gaurank kathpaliaaa252b52019-10-30 15:29:04 +053015803 uint32_t restart_freq;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015804
15805 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15806 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015807 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015808 return;
15809 }
15810
15811 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
15812 if (!cds_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015813 hdd_err("Invalid CDS Context");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015814 return;
15815 }
15816
Dustin Brown1dbefe62018-09-11 16:32:03 -070015817 if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc)
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080015818 != (QDF_STA_MASK | QDF_SAP_MASK)) {
Dustin Brown7e761c72018-07-31 13:50:17 -070015819 hdd_debug("Concurrency mode is not SAP");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015820 return;
15821 }
15822
15823 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
Dustin Brown07901ec2018-09-07 11:02:41 -070015824 if (ap_adapter &&
15825 test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags) &&
Will Huang4b097f52019-08-29 10:51:56 -070015826 wlan_reg_is_dfs_for_freq(
15827 hdd_ctx->pdev,
15828 ap_adapter->session.ap.operating_chan_freq)) {
Liangwei Dong444cd262019-05-08 23:22:56 -040015829 if (policy_mgr_get_dfs_master_dynamic_enabled(
15830 hdd_ctx->psoc, ap_adapter->vdev_id))
15831 return;
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053015832 hdd_warn("STA-AP Mode DFS not supported, Switch SAP channel to Non DFS");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015833
gaurank kathpaliaaa252b52019-10-30 15:29:04 +053015834 restart_freq =
bings6c4672b2019-03-19 16:00:19 +080015835 wlansap_get_safe_channel_from_pcl_and_acs_range(
15836 WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter));
gaurank kathpaliaaa252b52019-10-30 15:29:04 +053015837
15838 restart_chan = wlan_reg_freq_to_chan(hdd_ctx->pdev,
15839 restart_freq);
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053015840 if (!restart_chan ||
Dustin Brown07901ec2018-09-07 11:02:41 -070015841 wlan_reg_is_dfs_ch(hdd_ctx->pdev, restart_chan))
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053015842 restart_chan = SAP_DEFAULT_5GHZ_CHANNEL;
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +053015843 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, ap_adapter->vdev_id,
15844 CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS);
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053015845 hdd_switch_sap_channel(ap_adapter, restart_chan, true);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015846 }
15847}
15848
15849/**
15850 * hdd_set_connection_in_progress() - to set the connection in
15851 * progress flag
15852 * @value: value to set
15853 *
15854 * This function will set the passed value to connection in progress flag.
15855 * If value is previously being set to true then no need to set it again.
15856 *
15857 * Return: true if value is being set correctly and false otherwise.
15858 */
15859bool hdd_set_connection_in_progress(bool value)
15860{
15861 bool status = true;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015862 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015863
15864 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15865 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015866 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015867 return false;
15868 }
15869
15870 qdf_spin_lock(&hdd_ctx->connection_status_lock);
15871 /*
15872 * if the value is set to true previously and if someone is
15873 * trying to make it true again then it could be some race
15874 * condition being triggered. Avoid this situation by returning
15875 * false
15876 */
15877 if (hdd_ctx->connection_in_progress && value)
15878 status = false;
15879 else
15880 hdd_ctx->connection_in_progress = value;
15881 qdf_spin_unlock(&hdd_ctx->connection_status_lock);
15882 return status;
15883}
15884
Jeff Johnson9d295242017-08-29 14:39:48 -070015885int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070015886{
15887 if (!adapter) {
15888 hdd_err("Invalid adapter");
15889 return -EINVAL;
15890 }
15891 hdd_info("Send MCC P2P QUOTA to WMA: %d", set_value);
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015892 sme_cli_set_command(adapter->vdev_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070015893 WMA_VDEV_MCC_SET_TIME_QUOTA,
15894 set_value, VDEV_CMD);
15895 return 0;
15896
15897}
15898
Jeff Johnson9d295242017-08-29 14:39:48 -070015899int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070015900{
15901 if (!adapter) {
15902 hdd_err("Invalid adapter");
15903 return -EINVAL;
15904 }
15905
15906 hdd_info("Send MCC latency WMA: %d", set_value);
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015907 sme_cli_set_command(adapter->vdev_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070015908 WMA_VDEV_MCC_SET_TIME_LATENCY,
15909 set_value, VDEV_CMD);
15910 return 0;
15911}
15912
Jeff Johnson9d295242017-08-29 14:39:48 -070015913struct hdd_adapter *wlan_hdd_get_adapter_from_vdev(struct wlan_objmgr_psoc
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070015914 *psoc, uint8_t vdev_id)
15915{
Jeff Johnson9d295242017-08-29 14:39:48 -070015916 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015917 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070015918
15919 /*
15920 * Currently PSOC is not being used. But this logic will
15921 * change once we have the converged implementation of
15922 * HDD context per PSOC in place. This would break if
15923 * multiple vdev objects reuse the vdev id.
15924 */
15925 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
15926 if (!adapter)
15927 hdd_err("Get adapter by vdev id failed");
15928
15929 return adapter;
15930}
15931
Jeff Johnson9d295242017-08-29 14:39:48 -070015932int hdd_get_rssi_snr_by_bssid(struct hdd_adapter *adapter, const uint8_t *bssid,
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053015933 int8_t *rssi, int8_t *snr)
15934{
15935 QDF_STATUS status;
Jeff Johnson16528362018-06-14 12:34:16 -070015936 mac_handle_t mac_handle;
Jeff Johnson025618c2018-03-18 14:41:00 -070015937 struct csr_roam_profile *roam_profile;
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053015938
Jeff Johnson025618c2018-03-18 14:41:00 -070015939 roam_profile = hdd_roam_profile(adapter);
Jeff Johnson16528362018-06-14 12:34:16 -070015940 mac_handle = hdd_adapter_get_mac_handle(adapter);
15941 status = sme_get_rssi_snr_by_bssid(mac_handle,
Jeff Johnson025618c2018-03-18 14:41:00 -070015942 roam_profile, bssid, rssi, snr);
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053015943 if (QDF_STATUS_SUCCESS != status) {
15944 hdd_warn("sme_get_rssi_snr_by_bssid failed");
15945 return -EINVAL;
15946 }
15947
15948 return 0;
15949}
15950
Ganesh Kondabattini35739572017-06-21 16:26:39 +053015951/**
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015952 * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
15953 * @adapter - HDD adapter
15954 *
15955 * Return: 0 on success and non zero value on failure
15956 */
15957int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
15958{
15959 struct hdd_context *hdd_ctx;
15960 int ret;
15961 QDF_STATUS status;
Krunal Sonie71838d2018-09-27 10:45:05 -070015962 uint8_t sys_pref = 0;
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015963
15964 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
15965 ret = wlan_hdd_validate_context(hdd_ctx);
15966 if (ret < 0)
15967 return ret;
15968
Krunal Sonie71838d2018-09-27 10:45:05 -070015969 ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc,
15970 &sys_pref);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015971 /* set the system preferece to default */
Krunal Sonie71838d2018-09-27 10:45:05 -070015972 policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015973
15974 /* clear the bitmap */
15975 adapter->active_ac = 0;
15976
15977 hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015978 adapter->vdev_id, adapter->active_ac);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015979
Jeff Johnson16528362018-06-14 12:34:16 -070015980 status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015981 adapter->vdev_id,
Jeff Johnson16528362018-06-14 12:34:16 -070015982 false, 0, 0, false);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015983 if (!QDF_IS_STATUS_SUCCESS(status)) {
15984 hdd_err("failed to reset limit off chan params");
15985 ret = -EINVAL;
15986 }
Ganesh Kondabattini35739572017-06-21 16:26:39 +053015987
15988 return ret;
15989}
15990
Yun Parkff6a16a2017-09-26 16:38:18 -070015991void hdd_set_rx_mode_rps(bool enable)
15992{
15993 struct cds_config_info *cds_cfg = cds_get_ini_config();
Ryan Hsu0e878fa2018-05-04 15:22:09 -070015994 struct hdd_context *hdd_ctx;
15995 struct hdd_adapter *adapter;
Yun Parkff6a16a2017-09-26 16:38:18 -070015996
Ryan Hsu0e878fa2018-05-04 15:22:09 -070015997 if (!cds_cfg)
15998 return;
15999
16000 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
16001 if (!hdd_ctx)
16002 return;
16003
16004 adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
16005 if (!adapter)
16006 return;
16007
16008 if (!hdd_ctx->rps && cds_cfg->uc_offload_enabled) {
Yun Parkff6a16a2017-09-26 16:38:18 -070016009 if (enable && !cds_cfg->rps_enabled)
16010 hdd_send_rps_ind(adapter);
16011 else if (!enable && cds_cfg->rps_enabled)
16012 hdd_send_rps_disable_ind(adapter);
16013 }
16014}
16015
Abhinav Kumar338e57d2019-02-04 17:30:10 +053016016void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id)
16017{
16018 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
16019 struct hdd_adapter *adapter;
16020
16021 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
16022
16023 if (!adapter) {
16024 hdd_err("Adapter is null");
16025 return;
16026 }
16027 /* enable roaming on all adapters once hdd get hidden ssid rsp */
Abhinav Kumar523ca372019-08-30 16:28:19 +053016028 wlan_hdd_enable_roaming(adapter, RSO_START_BSS);
Abhinav Kumar338e57d2019-02-04 17:30:10 +053016029}
16030
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016031/* Register the module init/exit functions */
16032module_init(hdd_module_init);
16033module_exit(hdd_module_exit);
16034
16035MODULE_LICENSE("Dual BSD/GPL");
16036MODULE_AUTHOR("Qualcomm Atheros, Inc.");
16037MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
16038
Srinivas Girigowda841da292018-02-21 16:33:00 -080016039static const struct kernel_param_ops con_mode_ops = {
16040 .set = con_mode_handler,
16041 .get = param_get_int,
16042};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016043
Srinivas Girigowda841da292018-02-21 16:33:00 -080016044static const struct kernel_param_ops con_mode_ftm_ops = {
16045 .set = con_mode_handler_ftm,
16046 .get = param_get_int,
16047};
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053016048
Nirav Shah6aeecf92019-02-13 14:05:03 +053016049#ifdef WLAN_FEATURE_EPPING
16050static const struct kernel_param_ops con_mode_epping_ops = {
16051 .set = con_mode_handler_epping,
16052 .get = param_get_int,
16053};
16054#endif
16055
Srinivas Girigowda841da292018-02-21 16:33:00 -080016056static const struct kernel_param_ops fwpath_ops = {
16057 .set = fwpath_changed_handler,
16058 .get = param_get_string,
16059};
16060
16061module_param_cb(con_mode, &con_mode_ops, &con_mode,
16062 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
16063
16064module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm,
16065 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
16066
Nirav Shah6aeecf92019-02-13 14:05:03 +053016067#ifdef WLAN_FEATURE_EPPING
16068module_param_cb(con_mode_epping, &con_mode_epping_ops,
16069 &con_mode_epping, 0644);
16070#endif
16071
Srinivas Girigowda841da292018-02-21 16:33:00 -080016072module_param_cb(fwpath, &fwpath_ops, &fwpath,
16073 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080016074
16075module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
16076
16077module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
16078
16079module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);
Dustin Brown4bbd5462019-03-22 11:18:13 -070016080
16081static int timer_multiplier_get_handler(char *buffer,
16082 const struct kernel_param *kp)
16083{
16084 return scnprintf(buffer, PAGE_SIZE, "%u", qdf_timer_get_multiplier());
16085}
16086
16087static int timer_multiplier_set_handler(const char *kmessage,
16088 const struct kernel_param *kp)
16089{
16090 QDF_STATUS status;
16091 uint32_t scalar;
16092
16093 status = qdf_uint32_parse(kmessage, &scalar);
16094 if (QDF_IS_STATUS_ERROR(status))
16095 return qdf_status_to_os_return(status);
16096
16097 if (!cfg_in_range(CFG_TIMER_MULTIPLIER, scalar))
16098 return -ERANGE;
16099
16100 qdf_timer_set_multiplier(scalar);
16101
16102 return 0;
16103}
16104
16105static const struct kernel_param_ops timer_multiplier_ops = {
16106 .get = timer_multiplier_get_handler,
16107 .set = timer_multiplier_set_handler,
16108};
16109
16110module_param_cb(timer_multiplier, &timer_multiplier_ops, NULL, 0644);
16111