blob: 8ecc624b1b2ea08b3621ccb39ec8e60d976e34b1 [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"
Manikandan Mohan4e66c9a2019-07-12 14:55:17 -0700175#include "nan_ucfg_api.h"
Liangwei Dong3abfe8f2018-09-20 02:25:44 -0400176
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800177#ifdef MODULE
178#define WLAN_MODULE_NAME module_name(THIS_MODULE)
179#else
180#define WLAN_MODULE_NAME "wlan"
181#endif
182
183#ifdef TIMER_MANAGER
184#define TIMER_MANAGER_STR " +TIMER_MANAGER"
185#else
186#define TIMER_MANAGER_STR ""
187#endif
188
189#ifdef MEMORY_DEBUG
190#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
191#else
192#define MEMORY_DEBUG_STR ""
193#endif
194
Dustin Brownc1034df2018-02-07 14:51:32 -0800195#ifdef PANIC_ON_BUG
196#define PANIC_ON_BUG_STR " +PANIC_ON_BUG"
197#else
198#define PANIC_ON_BUG_STR ""
199#endif
200
Sachin Ahujadddd2632017-03-07 19:07:24 +0530201int wlan_start_ret_val;
202static DECLARE_COMPLETION(wlan_start_comp);
203static unsigned int dev_num = 1;
204static struct cdev wlan_hdd_state_cdev;
205static struct class *class;
206static dev_t device;
Arun Khandavallifae92942016-08-01 13:31:08 +0530207#ifndef MODULE
208static struct gwlan_loader *wlan_loader;
209static ssize_t wlan_boot_cb(struct kobject *kobj,
210 struct kobj_attribute *attr,
211 const char *buf, size_t count);
212struct gwlan_loader {
213 bool loaded_state;
214 struct kobject *boot_wlan_obj;
215 struct attribute_group *attr_group;
216};
217
218static struct kobj_attribute wlan_boot_attribute =
219 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
220
221static struct attribute *attrs[] = {
222 &wlan_boot_attribute.attr,
223 NULL,
224};
225
226#define MODULE_INITIALIZED 1
Qun Zhang4a83a462018-09-11 16:28:51 +0800227
228#ifdef MULTI_IF_NAME
229#define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME
230#else
231#define WLAN_LOADER_NAME "boot_wlan"
232#endif
Arun Khandavallifae92942016-08-01 13:31:08 +0530233#endif
234
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800235/* the Android framework expects this param even though we don't use it */
236#define BUF_LEN 20
237static char fwpath_buffer[BUF_LEN];
238static struct kparam_string fwpath = {
239 .string = fwpath_buffer,
240 .maxlen = BUF_LEN,
241};
242
243static char *country_code;
244static int enable_11d = -1;
245static int enable_dfs_chan_scan = -1;
Rajeev Kumar588a2542019-04-08 10:57:19 -0700246static bool is_mode_change_psoc_idle_shutdown;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800247
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800248#define WLAN_NLINK_CESIUM 30
249
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530250static qdf_wake_lock_t wlan_wake_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800251
252#define WOW_MAX_FILTER_LISTS 1
253#define WOW_MAX_FILTERS_PER_LIST 4
254#define WOW_MIN_PATTERN_SIZE 6
255#define WOW_MAX_PATTERN_SIZE 64
256
Bala Venkatesh110b03e2018-07-10 16:02:08 +0530257/* max peer can be tdls peers + self peer + bss peer */
258#define HDD_MAX_VDEV_PEER_COUNT (HDD_MAX_NUM_TDLS_STA + 2)
Sourav Mohapatra808e3d42018-07-04 09:34:23 +0530259#define IS_IDLE_STOP (!cds_is_driver_unloading() && \
260 !cds_is_driver_recovering() && !cds_is_driver_loading())
Bala Venkatesh110b03e2018-07-10 16:02:08 +0530261
Ashish Kumar Dhanotiyaeadb28b2019-06-28 14:34:19 +0530262#define HDD_FW_VER_MAJOR_SPID(tgt_fw_ver) ((tgt_fw_ver & 0xf0000000) >> 28)
263#define HDD_FW_VER_MINOR_SPID(tgt_fw_ver) ((tgt_fw_ver & 0xf000000) >> 24)
264#define HDD_FW_VER_SIID(tgt_fw_ver) ((tgt_fw_ver & 0xf00000) >> 20)
265#define HDD_FW_VER_CRM_ID(tgt_fw_ver) (tgt_fw_ver & 0x7fff)
266#define HDD_FW_VER_SUB_ID(tgt_fw_ver_ext) \
267((tgt_fw_ver_ext & 0xf0000000) >> 28)
268#define HDD_FW_VER_REL_ID(tgt_fw_ver_ext) \
269((tgt_fw_ver_ext & 0xf800000) >> 23)
270
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800271#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
272static const struct wiphy_wowlan_support wowlan_support_reg_init = {
273 .flags = WIPHY_WOWLAN_ANY |
274 WIPHY_WOWLAN_MAGIC_PKT |
275 WIPHY_WOWLAN_DISCONNECT |
276 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
277 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
278 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
279 WIPHY_WOWLAN_4WAY_HANDSHAKE |
280 WIPHY_WOWLAN_RFKILL_RELEASE,
281 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
282 .pattern_min_len = WOW_MIN_PATTERN_SIZE,
283 .pattern_max_len = WOW_MAX_PATTERN_SIZE,
284};
285#endif
286
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700287static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
288 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL},
289 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL},
290 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL},
291 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL},
292 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL},
293 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL},
294 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL},
295 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL},
296 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL},
297 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL},
298 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL},
299 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
300 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
301 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL},
302 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL},
303 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL},
304 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL},
305 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL},
306 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL},
307 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL},
308 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL},
309 [QDF_MODULE_ID_DP] = {QDF_TRACE_LEVEL_ALL},
310 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL},
311 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL},
312 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL},
313 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL},
314 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL},
315 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL},
316 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL},
317 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL},
318 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL},
319 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL},
320 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL},
321 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL},
Arif Hussainfde76e72017-09-05 16:58:23 -0700322 [QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumarca8ef9d2017-10-06 10:43:21 -0700323 [QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL},
Deepak Dhamdheref918d422017-07-06 12:56:29 -0700324 [QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL},
Himanshu Agarwalb229a142017-12-21 10:16:45 +0530325 [QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL},
Zhang Qian47e22ce2018-01-04 15:38:38 +0800326 [QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL},
Sravan Kumar Kairam1309e7e2018-03-13 09:29:52 +0530327 [QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +0530328 [QDF_MODULE_ID_ACTION_OUI] = {QDF_TRACE_LEVEL_ALL},
Dustin Brown84f46ea2018-02-15 11:57:36 -0800329 [QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL},
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +0530330 [QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL},
Ashish Kumar Dhanotiya8d039c82018-07-11 20:41:14 +0530331 [QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL},
Kiran Kumar Lokere4ce40482018-08-30 16:31:00 -0700332 [QDF_MODULE_ID_CRYPTO] = {QDF_TRACE_LEVEL_ALL},
Sourav Mohapatra113685f2018-08-29 14:21:55 +0530333 [QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL},
Abhishek Singh0b0105f2018-09-25 10:44:16 +0530334 [QDF_MODULE_ID_SM_ENGINE] = {QDF_TRACE_LEVEL_ALL},
335 [QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL},
Nachiket Kukade089b9832018-12-12 16:38:17 +0530336 [QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL},
Ashish Kumar Dhanotiya6ed44342019-02-07 21:11:00 +0530337 [QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL},
Paul Zhang37185672019-05-14 11:20:14 +0800338 [QDF_MODULE_ID_INTEROP_ISSUES_AP] = {QDF_TRACE_LEVEL_ALL},
gaurank kathpalia7ef72182019-05-29 19:41:25 +0530339 [QDF_MODULE_ID_BLACKLIST_MGR] = {QDF_TRACE_LEVEL_ALL},
Wu Gaoe73c3882019-05-29 16:22:10 +0800340 [QDF_MODULE_ID_DIRECT_BUF_RX] = {QDF_TRACE_LEVEL_ALL},
341 [QDF_MODULE_ID_SPECTRAL] = {QDF_TRACE_LEVEL_ALL},
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700342};
343
Ashish Kumar Dhanotiyacf11bae2017-04-04 03:29:47 +0530344struct notifier_block hdd_netdev_notifier;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800345
346struct sock *cesium_nl_srv_sock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800347#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700348static void wlan_hdd_auto_shutdown_cb(void);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800349#endif
350
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +0530351/**
352 * hdd_mic_flush_work() - disable and flush pending mic work
353 * @adapter: Pointer to hdd adapter
354 *
355 * Return: None
356 */
357static void
358hdd_mic_flush_work(struct hdd_adapter *adapter)
359{
360 hdd_debug("Flush the MIC error work");
361
362 qdf_spin_lock_bh(&adapter->mic_work.lock);
Rakshith Suresh Patkar30bb8c12019-08-23 15:57:40 +0530363 if (adapter->mic_work.status != MIC_SCHEDULED) {
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +0530364 qdf_spin_unlock_bh(&adapter->mic_work.lock);
365 return;
366 }
367 adapter->mic_work.status = MIC_DISABLED;
368 qdf_spin_unlock_bh(&adapter->mic_work.lock);
369
370 qdf_flush_work(&adapter->mic_work.work);
371}
372
373/**
374 * hdd_mic_enable_work() - enable mic error work
375 * @adapter: Pointer to hdd adapter
376 *
377 * Return: None
378 */
379static void
380hdd_mic_enable_work(struct hdd_adapter *adapter)
381{
382 hdd_debug("Enable the MIC error work");
383
384 qdf_spin_lock_bh(&adapter->mic_work.lock);
385 if (adapter->mic_work.status == MIC_DISABLED)
386 adapter->mic_work.status = MIC_INITIALIZED;
387 qdf_spin_unlock_bh(&adapter->mic_work.lock);
388}
389
390/**
391 * hdd_mic_deinit_work() - deinitialize mic error work
392 * @hdd_adapter: Pointer to hdd adapter
393 *
394 * Return: None
395 */
396static void
397hdd_mic_deinit_work(struct hdd_adapter *adapter)
398{
399 hdd_debug("DeInitialize the MIC error work");
400
401 if (adapter->mic_work.status != MIC_UNINITIALIZED) {
402 qdf_destroy_work(NULL, &adapter->mic_work.work);
403
404 qdf_spin_lock_bh(&adapter->mic_work.lock);
405 adapter->mic_work.status = MIC_UNINITIALIZED;
406 if (adapter->mic_work.info) {
407 qdf_mem_free(adapter->mic_work.info);
408 adapter->mic_work.info = NULL;
409 }
410 qdf_spin_unlock_bh(&adapter->mic_work.lock);
411 qdf_spinlock_destroy(&adapter->mic_work.lock);
412 }
413}
414
415/**
416 * hdd_process_sta_mic_error() - Indicate STA mic error to supplicant
417 * @adapter: Pointer to hdd adapter
418 *
419 * Return: None
420 */
421static void
422hdd_process_sta_mic_error(struct hdd_adapter *adapter)
423{
424 struct hdd_station_ctx *sta_ctx;
425 struct hdd_mic_error_info *info;
426
427 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
428
429 if (eConnectionState_Associated !=
430 sta_ctx->conn_info.conn_state)
431 return;
432
433 info = adapter->mic_work.info;
434 /* inform mic failure to nl80211 */
435 cfg80211_michael_mic_failure(adapter->dev,
436 (uint8_t *)&info->ta_mac_addr,
437 info->multicast ?
438 NL80211_KEYTYPE_GROUP :
439 NL80211_KEYTYPE_PAIRWISE,
440 info->key_id,
441 info->tsc,
442 GFP_KERNEL);
443}
444
445/**
446 * hdd_process_sap_mic_error() - Indicate SAP mic error to supplicant
447 * @adapter: Pointer to hdd adapter
448 *
449 * Return: None
450 */
451static void
452hdd_process_sap_mic_error(struct hdd_adapter *adapter)
453{
454 struct hdd_mic_error_info *info;
455
456 info = adapter->mic_work.info;
457 /* inform mic failure to nl80211 */
458 cfg80211_michael_mic_failure(adapter->dev,
459 (uint8_t *)&info->ta_mac_addr,
460 info->multicast ?
461 NL80211_KEYTYPE_GROUP :
462 NL80211_KEYTYPE_PAIRWISE,
463 info->key_id,
464 info->tsc,
465 GFP_KERNEL);
466}
467
468/**
469 * __hdd_process_mic_error() - Indicate mic error to supplicant
470 * @adapter: Pointer to hdd adapter
471 *
472 * Return: None
473 */
474static void
475__hdd_process_mic_error(struct hdd_adapter *adapter)
476{
477 if (adapter->device_mode == QDF_STA_MODE ||
478 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
479 hdd_process_sta_mic_error(adapter);
480 } else if (adapter->device_mode == QDF_SAP_MODE ||
481 adapter->device_mode == QDF_P2P_GO_MODE) {
482 hdd_process_sap_mic_error(adapter);
483 } else {
484 hdd_err("Invalid interface type:%d", adapter->device_mode);
485 }
486}
487
488/**
489 * hdd_process_mic_error() - process mic error work
490 * @data: void pointer to hdd adapter
491 *
492 * Return: None
493 */
494static void
495hdd_process_mic_error(void *data)
496{
497 struct hdd_adapter *adapter = data;
498 struct osif_vdev_sync *vdev_sync;
499
500 if (hdd_validate_adapter(adapter))
501 goto exit;
502
503 if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync))
504 goto exit;
505
506 __hdd_process_mic_error(adapter);
507
508 osif_vdev_sync_op_stop(vdev_sync);
509exit:
510 qdf_spin_lock_bh(&adapter->mic_work.lock);
511 if (adapter->mic_work.info) {
512 qdf_mem_free(adapter->mic_work.info);
513 adapter->mic_work.info = NULL;
514 }
515 if (adapter->mic_work.status == MIC_SCHEDULED)
516 adapter->mic_work.status = MIC_INITIALIZED;
517 qdf_spin_unlock_bh(&adapter->mic_work.lock);
518}
519
520/**
521 * hdd_mic_init_work() - init mic error work
522 * @hdd_adapter: Pointer to hdd adapter
523 *
524 * Return: None
525 */
526static void
527hdd_mic_init_work(struct hdd_adapter *adapter)
528{
529 qdf_spinlock_create(&adapter->mic_work.lock);
530 qdf_create_work(0, &adapter->mic_work.work,
531 hdd_process_mic_error, adapter);
532 adapter->mic_work.status = MIC_INITIALIZED;
533 adapter->mic_work.info = NULL;
534}
535
Sachin Ahujadddd2632017-03-07 19:07:24 +0530536void hdd_start_complete(int ret)
537{
538 wlan_start_ret_val = ret;
539
540 complete(&wlan_start_comp);
541}
542
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800543/**
Nirav Shahbd36b062016-07-18 11:12:59 +0530544 * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700545 * @hdd_ctx: pointer to struct hdd_context
Nirav Shahbd36b062016-07-18 11:12:59 +0530546 *
547 * Return: none
548 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700549static void hdd_set_rps_cpu_mask(struct hdd_context *hdd_ctx)
Nirav Shahbd36b062016-07-18 11:12:59 +0530550{
Jeff Johnson9d295242017-08-29 14:39:48 -0700551 struct hdd_adapter *adapter;
Nirav Shahbd36b062016-07-18 11:12:59 +0530552
Dustin Brown920397d2017-12-13 16:27:50 -0800553 hdd_for_each_adapter(hdd_ctx, adapter)
554 hdd_send_rps_ind(adapter);
Nirav Shahbd36b062016-07-18 11:12:59 +0530555}
556
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530557#ifdef QCA_HL_NETDEV_FLOW_CONTROL
558void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter,
559 enum netif_action_type action)
560{
561 if (!adapter->tx_flow_timer_initialized)
562 return;
563
564 if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) {
565 qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
Ajit Pal Singhe6da1de2018-12-27 16:20:45 +0530566 adapter->hdd_stats.tx_rx_stats.is_txflow_paused = false;
567 adapter->hdd_stats.tx_rx_stats.txflow_unpause_cnt++;
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530568 } else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) {
569 QDF_STATUS status =
570 qdf_mc_timer_start(&adapter->tx_flow_control_timer,
571 WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
572
573 if (!QDF_IS_STATUS_SUCCESS(status))
574 hdd_err("Failed to start tx_flow_control_timer");
575 else
576 adapter->
577 hdd_stats.tx_rx_stats.txflow_timer_cnt++;
578
579 adapter->hdd_stats.tx_rx_stats.txflow_pause_cnt++;
580 adapter->hdd_stats.tx_rx_stats.is_txflow_paused = true;
581 }
582}
583#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
584
Tiger Yu8b119e92019-04-09 13:55:07 +0800585#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
Alok Kumar2fad6442018-11-08 19:19:28 +0530586void wlan_hdd_update_tcp_rx_param(struct hdd_context *hdd_ctx, void *data)
587{
588 if (!hdd_ctx) {
589 hdd_err("HDD context is null");
590 return;
591 }
592
593 if (!data) {
594 hdd_err("Data is null");
595 return;
596 }
597 if (hdd_ctx->config->enable_tcp_param_update)
598 wlan_hdd_send_tcp_param_update_event(hdd_ctx, data, 1);
599 else
600 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
601 WLAN_SVC_WLAN_TP_IND,
602 data,
603 sizeof(struct wlan_rx_tp_data));
604}
605
606void wlan_hdd_update_tcp_tx_param(struct hdd_context *hdd_ctx, void *data)
607{
608 enum wlan_tp_level next_tx_level;
609 struct wlan_tx_tp_data *tx_tp_data;
610
611 if (!hdd_ctx) {
612 hdd_err("HDD context is null");
613 return;
614 }
615
616 if (!data) {
617 hdd_err("Data is null");
618 return;
619 }
620
621 tx_tp_data = (struct wlan_tx_tp_data *)data;
622 next_tx_level = tx_tp_data->level;
623
624 if (hdd_ctx->config->enable_tcp_param_update)
625 wlan_hdd_send_tcp_param_update_event(hdd_ctx, data, 0);
626 else
627 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
628 WLAN_SVC_WLAN_TP_TX_IND,
629 &next_tx_level,
630 sizeof(next_tx_level));
631}
632
633/**
634 * wlan_hdd_send_tcp_param_update_event() - Send vendor event to update
635 * TCP parameter through Wi-Fi HAL
636 * @hdd_ctx: Pointer to HDD context
637 * @data: Parameters to update
638 * @dir: Direction(tx/rx) to update
639 *
640 * Return: None
641 */
642void wlan_hdd_send_tcp_param_update_event(struct hdd_context *hdd_ctx,
643 void *data,
644 uint8_t dir)
645{
646 struct sk_buff *vendor_event;
647 uint32_t event_len;
648 bool tcp_limit_output = false;
649 bool tcp_del_ack_ind_enabled = false;
650 bool tcp_adv_win_scl_enabled = false;
651 enum wlan_tp_level next_tp_level = WLAN_SVC_TP_NONE;
652
653 event_len = sizeof(uint8_t) + sizeof(uint8_t) + NLMSG_HDRLEN;
654
655 if (dir == 0) /*TX Flow */ {
656 struct wlan_tx_tp_data *tx_tp_data =
657 (struct wlan_tx_tp_data *)data;
658
659 next_tp_level = tx_tp_data->level;
660
661 if (tx_tp_data->tcp_limit_output) {
662 /* TCP_LIMIT_OUTPUT_BYTES */
663 event_len += sizeof(uint32_t);
664 tcp_limit_output = true;
665 }
666 } else if (dir == 1) /* RX Flow */ {
667 struct wlan_rx_tp_data *rx_tp_data =
668 (struct wlan_rx_tp_data *)data;
669
670 next_tp_level = rx_tp_data->level;
671
672 if (rx_tp_data->rx_tp_flags & TCP_DEL_ACK_IND_MASK) {
673 event_len += sizeof(uint32_t); /* TCP_DELACK_SEG */
674 tcp_del_ack_ind_enabled = true;
675 }
676 if (rx_tp_data->rx_tp_flags & TCP_ADV_WIN_SCL_MASK) {
677 event_len += sizeof(uint32_t); /* TCP_ADV_WIN_SCALE */
678 tcp_adv_win_scl_enabled = true;
679 }
680 } else {
681 hdd_err("Invalid Direction [%d]", dir);
682 return;
683 }
684
685 vendor_event =
686 cfg80211_vendor_event_alloc(
687 hdd_ctx->wiphy,
688 NULL, event_len,
689 QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT_INDEX,
690 GFP_KERNEL);
691
692 if (!vendor_event) {
693 hdd_err("cfg80211_vendor_event_alloc failed");
694 return;
695 }
696
697 if (nla_put_u8(
698 vendor_event,
699 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION,
700 dir))
701 goto tcp_param_change_nla_failed;
702
703 if (nla_put_u8(
704 vendor_event,
705 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL,
706 (next_tp_level == WLAN_SVC_TP_LOW ?
707 QCA_WLAN_THROUGHPUT_LEVEL_LOW :
708 QCA_WLAN_THROUGHPUT_LEVEL_HIGH)))
709 goto tcp_param_change_nla_failed;
710
711 if (tcp_limit_output &&
712 nla_put_u32(
713 vendor_event,
714 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES,
715 (next_tp_level == WLAN_SVC_TP_LOW ?
716 TCP_LIMIT_OUTPUT_BYTES_LOW :
717 TCP_LIMIT_OUTPUT_BYTES_HI)))
718 goto tcp_param_change_nla_failed;
719
720 if (tcp_del_ack_ind_enabled &&
721 (nla_put_u32(
722 vendor_event,
723 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG,
724 (next_tp_level == WLAN_SVC_TP_LOW ?
725 TCP_DEL_ACK_LOW : TCP_DEL_ACK_HI))))
726 goto tcp_param_change_nla_failed;
727
728 if (tcp_adv_win_scl_enabled &&
729 (nla_put_u32(
730 vendor_event,
731 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE,
732 (next_tp_level == WLAN_SVC_TP_LOW ?
733 WIN_SCALE_LOW : WIN_SCALE_HI))))
734 goto tcp_param_change_nla_failed;
735
736 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
737 return;
738
739tcp_param_change_nla_failed:
740 hdd_err("nla_put api failed");
741 kfree_skb(vendor_event);
742}
Tiger Yu8b119e92019-04-09 13:55:07 +0800743#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
Alok Kumar2fad6442018-11-08 19:19:28 +0530744
Nirav Shahbd36b062016-07-18 11:12:59 +0530745/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800746 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
747 * @vdev_id: vdev_id
748 * @action: action type
749 * @reason: reason type
750 *
751 * Return: none
752 */
753void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
754 enum netif_action_type action, enum netif_reason_type reason)
755{
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700756 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson9d295242017-08-29 14:39:48 -0700757 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800758
759 if (!hdd_ctx) {
760 hdd_err("hdd ctx is NULL");
761 return;
762 }
763 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530764 wlan_hdd_mod_fc_timer(adapter, action);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800765 wlan_hdd_netif_queue_control(adapter, action, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800766}
767
768/*
Dustin Brownab482ac2017-06-09 17:00:44 -0700769 * Store WLAN driver version and timestamp info in global variables such that
770 * crash debugger can extract them from driver debug symbol and crashdump for
771 * post processing
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800772 */
Dustin Brown96cd9632017-11-13 12:45:04 -0800773#ifdef BUILD_TAG
Rajeev Kumare555e2d2018-09-17 11:52:37 -0700774uint8_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 -0800775#else
Rajeev Kumare555e2d2018-09-17 11:52:37 -0700776uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR;
Naveen Rawat93836252017-06-20 16:30:59 -0700777#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800778
779/**
Liangwei Dong17bf2662018-01-05 02:02:05 -0500780 * hdd_get_valid_chan() - return current chan list from regulatory.
781 * @hdd_ctx: HDD context
782 * @chan_list: buf hold returned chan list
783 * @chan_num: input buf size and output returned chan num
784 *
785 * This function helps get current available chan list from regulatory
786 * module. It excludes the "disabled" and "invalid" channels.
787 *
788 * Return: 0 for success.
789 */
790static int hdd_get_valid_chan(struct hdd_context *hdd_ctx,
791 uint8_t *chan_list,
792 uint32_t *chan_num)
793{
794 int i = 0, j = 0;
795 struct regulatory_channel *cur_chan_list;
796 struct wlan_objmgr_pdev *pdev;
797
Dustin Brown07901ec2018-09-07 11:02:41 -0700798 if (!hdd_ctx || !hdd_ctx->pdev || !chan_list || !chan_num)
Liangwei Dong17bf2662018-01-05 02:02:05 -0500799 return -EINVAL;
800
Dustin Brown07901ec2018-09-07 11:02:41 -0700801 pdev = hdd_ctx->pdev;
Liangwei Dong17bf2662018-01-05 02:02:05 -0500802 cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
803 sizeof(struct regulatory_channel));
804 if (!cur_chan_list)
805 return -ENOMEM;
806
807 if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) !=
808 QDF_STATUS_SUCCESS) {
809 qdf_mem_free(cur_chan_list);
810 return -EINVAL;
811 }
812
813 for (i = 0; i < NUM_CHANNELS; i++) {
814 uint32_t ch = cur_chan_list[i].chan_num;
815 enum channel_state state = wlan_reg_get_channel_state(pdev,
816 ch);
817
818 if (state != CHANNEL_STATE_DISABLE &&
819 state != CHANNEL_STATE_INVALID &&
820 j < *chan_num) {
821 chan_list[j] = (uint8_t)ch;
822 j++;
823 }
824 }
825 *chan_num = j;
826 qdf_mem_free(cur_chan_list);
827 return 0;
828}
829
830/**
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530831 * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo
832 * @adapter: HDD adapter
833 * @chan_number: Channel number
834 * @chan_bw: Bandwidth
835 *
836 * Checks if the given bandwidth is valid for the given channel number.
837 *
838 * Return: 0 for success, non-zero for failure
839 */
Jeff Johnson9d295242017-08-29 14:39:48 -0700840int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530841 uint32_t chan_number,
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800842 enum phy_ch_width chan_bw)
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530843{
Liangwei Dong17bf2662018-01-05 02:02:05 -0500844 uint8_t chan[NUM_CHANNELS];
845 uint32_t len = NUM_CHANNELS, i;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530846 bool found = false;
Jeff Johnson16528362018-06-14 12:34:16 -0700847 mac_handle_t mac_handle;
Liangwei Dong17bf2662018-01-05 02:02:05 -0500848 int ret;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530849
Jeff Johnson16528362018-06-14 12:34:16 -0700850 mac_handle = hdd_adapter_get_mac_handle(adapter);
851 if (!mac_handle) {
852 hdd_err("Invalid MAC handle");
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530853 return -EINVAL;
854 }
855
Liangwei Dong17bf2662018-01-05 02:02:05 -0500856 ret = hdd_get_valid_chan(adapter->hdd_ctx, chan,
857 &len);
858 if (ret) {
859 hdd_err("error %d in getting valid channel list", ret);
860 return ret;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530861 }
862
863 for (i = 0; i < len; i++) {
864 if (chan[i] == chan_number) {
865 found = true;
866 break;
867 }
868 }
869
870 if (found == false) {
871 hdd_err("Channel not in driver's valid channel list");
872 return -EOPNOTSUPP;
873 }
874
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700875 if ((!WLAN_REG_IS_24GHZ_CH(chan_number)) &&
876 (!WLAN_REG_IS_5GHZ_CH(chan_number))) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530877 hdd_err("CH %d is not in 2.4GHz or 5GHz", chan_number);
878 return -EINVAL;
879 }
880
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700881 if (WLAN_REG_IS_24GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530882 if (chan_bw == CH_WIDTH_80MHZ) {
883 hdd_err("BW80 not possible in 2.4GHz band");
884 return -EINVAL;
885 }
886 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 14) &&
887 (chan_bw != CH_WIDTH_MAX)) {
888 hdd_err("Only BW20 possible on channel 14");
889 return -EINVAL;
890 }
891 }
892
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530893 return 0;
894}
895
Will Huang79af29f2019-04-11 15:46:26 +0800896uint8_t hdd_get_adapter_home_channel(struct hdd_adapter *adapter)
897{
898 uint8_t home_channel = 0;
Jingxiang Gece7c5472019-07-23 16:19:23 +0800899 struct hdd_context *hdd_ctx;
900
901 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
902 if (!hdd_ctx) {
903 hdd_err("hdd context is NULL");
904 return 0;
905 }
Will Huang79af29f2019-04-11 15:46:26 +0800906
907 if ((adapter->device_mode == QDF_SAP_MODE ||
908 adapter->device_mode == QDF_P2P_GO_MODE) &&
909 test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
910 home_channel = adapter->session.ap.operating_channel;
911 } else if ((adapter->device_mode == QDF_STA_MODE ||
912 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
913 adapter->session.station.conn_info.conn_state ==
914 eConnectionState_Associated) {
915 home_channel =
Jingxiang Gece7c5472019-07-23 16:19:23 +0800916 wlan_reg_freq_to_chan(
917 hdd_ctx->pdev,
Jingxiang Geae80dc62019-08-13 17:32:22 +0800918 adapter->session.station.conn_info.chan_freq);
Will Huang79af29f2019-04-11 15:46:26 +0800919 }
920
921 return home_channel;
922}
923
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800924#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
Dustin Brown98f7c822019-03-06 12:25:49 -0800925static inline struct net_device *hdd_net_dev_from_notifier(void *context)
926{
927 struct netdev_notifier_info *info = context;
928
929 return info->dev;
930}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800931#else
Dustin Brown98f7c822019-03-06 12:25:49 -0800932static inline struct net_device *hdd_net_dev_from_notifier(void *context)
933{
934 return context;
935}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800936#endif
Dustin Brown98f7c822019-03-06 12:25:49 -0800937
938static int __hdd_netdev_notifier_call(struct net_device *net_dev,
939 unsigned long state)
940{
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530941 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700942 struct hdd_context *hdd_ctx;
Min Liu8c5d99e2018-09-10 17:18:44 +0800943 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800944
Dustin Brown98f7c822019-03-06 12:25:49 -0800945 hdd_enter_dev(net_dev);
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800946
Dustin Brown98f7c822019-03-06 12:25:49 -0800947 if (!net_dev->ieee80211_ptr) {
Dustin Brownaeb55642018-07-30 17:20:32 -0700948 hdd_debug("ieee80211_ptr is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800949 return NOTIFY_DONE;
950 }
951
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530952 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
953 if (!hdd_ctx) {
954 hdd_err("HDD Context is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800955 return NOTIFY_DONE;
956 }
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800957
958 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -0700959 hdd_debug("%s: Driver module is closed", __func__);
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800960 return NOTIFY_DONE;
961 }
962
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530963 /* Make sure that this callback corresponds to our device. */
Dustin Brown98f7c822019-03-06 12:25:49 -0800964 adapter = hdd_get_adapter_by_iface_name(hdd_ctx, net_dev->name);
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530965 if (!adapter) {
Dustin Brown98f7c822019-03-06 12:25:49 -0800966 hdd_debug("failed to look up adapter for '%s'", net_dev->name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800967 return NOTIFY_DONE;
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530968 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800969
Dustin Brown98f7c822019-03-06 12:25:49 -0800970 if (adapter != WLAN_HDD_GET_PRIV_PTR(net_dev)) {
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530971 hdd_err("HDD adapter mismatch!");
972 return NOTIFY_DONE;
973 }
974
Dustin Brownaeb55642018-07-30 17:20:32 -0700975 if (cds_is_driver_recovering()) {
976 hdd_debug("Driver is recovering");
977 return NOTIFY_DONE;
978 }
979
980 if (cds_is_driver_in_bad_state()) {
981 hdd_debug("Driver is in failed recovery state");
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530982 return NOTIFY_DONE;
983 }
984
Dustin Brown98f7c822019-03-06 12:25:49 -0800985 hdd_debug("%s New Net Device State = %lu", net_dev->name, state);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800986
987 switch (state) {
988 case NETDEV_REGISTER:
989 break;
990
991 case NETDEV_UNREGISTER:
992 break;
993
994 case NETDEV_UP:
Jeff Johnson16528362018-06-14 12:34:16 -0700995 sme_ch_avoid_update_req(hdd_ctx->mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800996 break;
997
998 case NETDEV_DOWN:
999 break;
1000
1001 case NETDEV_CHANGE:
Jeff Johnsonc72c5732017-10-28 12:49:37 -07001002 if (adapter->is_link_up_service_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001003 complete(&adapter->linkup_event_var);
1004 break;
1005
1006 case NETDEV_GOING_DOWN:
Min Liu8c5d99e2018-09-10 17:18:44 +08001007 vdev = hdd_objmgr_get_vdev(adapter);
1008 if (!vdev)
1009 break;
1010 if (ucfg_scan_get_vdev_status(vdev) !=
Sandeep Puligilla5f86d992017-10-29 14:58:53 -07001011 SCAN_NOT_IN_PROGRESS) {
Dustin Brown07901ec2018-09-07 11:02:41 -07001012 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08001013 adapter->vdev_id, INVALID_SCAN_ID,
Dustin Brown07901ec2018-09-07 11:02:41 -07001014 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001015 }
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05301016 hdd_objmgr_put_vdev(vdev);
Min Liu9be5d4a2018-05-17 11:51:53 +08001017 cds_flush_work(&adapter->scan_block_work);
1018 /* Need to clean up blocked scan request */
Dustin Brown96b98dd2019-03-06 12:39:37 -08001019 wlan_hdd_cfg80211_scan_block(adapter);
Min Liu9be5d4a2018-05-17 11:51:53 +08001020 hdd_debug("Scan is not Pending from user");
Arunk Khandavallif0c0d762017-12-07 10:18:50 +05301021 /*
1022 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
1023 * of return status of hdd_stop call, kernel resets the IFF_UP
1024 * flag after which driver does not send the cfg80211_scan_done.
1025 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN
1026 */
Dustin Brown98f7c822019-03-06 12:25:49 -08001027 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, net_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001028 break;
1029
1030 default:
1031 break;
1032 }
1033
1034 return NOTIFY_DONE;
1035}
1036
1037/**
1038 * hdd_netdev_notifier_call() - netdev notifier callback function
1039 * @nb: pointer to notifier block
1040 * @state: state
Dustin Brown98f7c822019-03-06 12:25:49 -08001041 * @context: notifier callback context pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001042 *
1043 * Return: 0 on success, error number otherwise.
1044 */
1045static int hdd_netdev_notifier_call(struct notifier_block *nb,
1046 unsigned long state,
Dustin Brown98f7c822019-03-06 12:25:49 -08001047 void *context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001048{
Dustin Brown98f7c822019-03-06 12:25:49 -08001049 struct net_device *net_dev = hdd_net_dev_from_notifier(context);
1050 struct osif_vdev_sync *vdev_sync;
1051 int errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001052
Dustin Brown98f7c822019-03-06 12:25:49 -08001053 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
1054 if (errno)
1055 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001056
Dustin Brown98f7c822019-03-06 12:25:49 -08001057 errno = __hdd_netdev_notifier_call(net_dev, state);
1058
1059 osif_vdev_sync_op_stop(vdev_sync);
1060
1061 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001062}
1063
1064struct notifier_block hdd_netdev_notifier = {
1065 .notifier_call = hdd_netdev_notifier_call,
1066};
1067
1068/* variable to hold the insmod parameters */
1069static int con_mode;
Prashanth Bhatta05aaf012015-12-10 17:34:24 -08001070
Arunk Khandavalliba3d5582017-07-11 19:48:32 +05301071static int con_mode_ftm;
Nirav Shah6aeecf92019-02-13 14:05:03 +05301072int con_mode_epping;
Arunk Khandavalliba3d5582017-07-11 19:48:32 +05301073
Prashanth Bhatta05aaf012015-12-10 17:34:24 -08001074/* Variable to hold connection mode including module parameter con_mode */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001075static int curr_con_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001076
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301077/**
1078 * hdd_map_nl_chan_width() - Map NL channel width to internal representation
1079 * @ch_width: NL channel width
1080 *
1081 * Converts the NL channel width to the driver's internal representation
1082 *
1083 * Return: Converted channel width. In case of non matching NL channel width,
1084 * CH_WIDTH_MAX will be returned.
1085 */
Kiran Kumar Lokere13644672016-02-29 15:40:10 -08001086enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301087{
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001088 uint8_t fw_ch_bw;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001089
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001090 fw_ch_bw = wma_get_vht_ch_width();
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301091 switch (ch_width) {
1092 case NL80211_CHAN_WIDTH_20_NOHT:
1093 case NL80211_CHAN_WIDTH_20:
1094 return CH_WIDTH_20MHZ;
1095 case NL80211_CHAN_WIDTH_40:
1096 return CH_WIDTH_40MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301097 case NL80211_CHAN_WIDTH_80:
1098 return CH_WIDTH_80MHZ;
1099 case NL80211_CHAN_WIDTH_80P80:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001100 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
1101 return CH_WIDTH_80P80MHZ;
1102 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1103 return CH_WIDTH_160MHZ;
1104 else
1105 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301106 case NL80211_CHAN_WIDTH_160:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001107 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
1108 return CH_WIDTH_160MHZ;
1109 else
1110 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301111 case NL80211_CHAN_WIDTH_5:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -08001112 return CH_WIDTH_5MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301113 case NL80211_CHAN_WIDTH_10:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -08001114 return CH_WIDTH_10MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301115 default:
1116 hdd_err("Invalid channel width %d, setting to default",
1117 ch_width);
Kiran Kumar Lokere13644672016-02-29 15:40:10 -08001118 return CH_WIDTH_INVALID;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +05301119 }
1120}
1121
Dustin Brown56377e12018-10-10 17:04:04 -07001122QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type,
1123 enum QDF_OPMODE *out_qdf_type)
1124{
1125 switch (nl_type) {
1126 case NL80211_IFTYPE_ADHOC:
1127 *out_qdf_type = QDF_IBSS_MODE;
1128 break;
1129 case NL80211_IFTYPE_AP:
1130 *out_qdf_type = QDF_SAP_MODE;
1131 break;
1132 case NL80211_IFTYPE_MONITOR:
1133 *out_qdf_type = QDF_MONITOR_MODE;
1134 break;
1135 case NL80211_IFTYPE_OCB:
1136 *out_qdf_type = QDF_OCB_MODE;
1137 break;
1138 case NL80211_IFTYPE_P2P_CLIENT:
1139 *out_qdf_type = QDF_P2P_CLIENT_MODE;
1140 break;
1141 case NL80211_IFTYPE_P2P_DEVICE:
1142 *out_qdf_type = QDF_P2P_DEVICE_MODE;
1143 break;
1144 case NL80211_IFTYPE_P2P_GO:
1145 *out_qdf_type = QDF_P2P_GO_MODE;
1146 break;
1147 case NL80211_IFTYPE_STATION:
1148 *out_qdf_type = QDF_STA_MODE;
1149 break;
1150 case NL80211_IFTYPE_WDS:
1151 *out_qdf_type = QDF_WDS_MODE;
1152 break;
1153 default:
1154 hdd_err("Invalid nl80211 interface type %d", nl_type);
1155 return QDF_STATUS_E_INVAL;
1156 }
1157
1158 return QDF_STATUS_SUCCESS;
1159}
1160
Jeff Johnson16528362018-06-14 12:34:16 -07001161uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel,
1162 uint8_t bw_offset)
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +05301163{
1164 uint8_t opclass = 0;
1165
Jeff Johnson16528362018-06-14 12:34:16 -07001166 sme_get_opclass(mac_handle, channel, bw_offset, &opclass);
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +05301167 return opclass;
1168}
1169
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001170/**
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301171 * hdd_qdf_trace_enable() - configure initial QDF Trace enable
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301172 * @module_id: Module whose trace level is being configured
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001173 * @bitmask: Bitmask of log levels to be enabled
1174 *
1175 * Called immediately after the cfg.ini is read in order to configure
1176 * the desired trace levels.
1177 *
1178 * Return: None
1179 */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301180int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001181{
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301182 QDF_TRACE_LEVEL level;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301183 int qdf_print_idx = -1;
1184 int status = -1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001185 /*
1186 * if the bitmask is the default value, then a bitmask was not
1187 * specified in cfg.ini, so leave the logging level alone (it
1188 * will remain at the "compiled in" default value)
1189 */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001190 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301191 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001192
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301193 qdf_print_idx = qdf_get_pidx();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001194
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301195 /* a mask was specified. start by disabling all logging */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301196 status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301197 QDF_TRACE_LEVEL_NONE, 0);
1198
1199 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301200 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001201 /* now cycle through the bitmask until all "set" bits are serviced */
Ashish Kumar Dhanotiya83f286b2017-09-15 19:52:58 +05301202 level = QDF_TRACE_LEVEL_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001203 while (0 != bitmask) {
1204 if (bitmask & 1) {
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301205 status = qdf_print_set_category_verbose(qdf_print_idx,
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301206 module_id, level, 1);
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301207 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301208 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001209 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001210
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001211 level++;
1212 bitmask >>= 1;
1213 }
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301214 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001215}
1216
Dustin Brownda351e32018-07-23 15:48:22 -07001217int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func)
Chris Guo1751acf2017-07-03 14:09:01 +08001218{
Dustin Brownda351e32018-07-23 15:48:22 -07001219 if (!hdd_ctx) {
1220 hdd_err("HDD context is null (via %s)", func);
1221 return -ENODEV;
1222 }
1223
1224 if (!hdd_ctx->config) {
1225 hdd_err("HDD config is null (via %s)", func);
Chris Guo1751acf2017-07-03 14:09:01 +08001226 return -ENODEV;
1227 }
1228
1229 if (cds_is_driver_recovering()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001230 hdd_debug("Recovery in progress (via %s); state:0x%x",
1231 func, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001232 return -EAGAIN;
1233 }
1234
Yue Ma9f275d92017-09-14 16:58:41 -07001235 if (cds_is_load_or_unload_in_progress()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001236 hdd_debug("Load/unload in progress (via %s); state:0x%x",
1237 func, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001238 return -EAGAIN;
Yue Ma9f275d92017-09-14 16:58:41 -07001239 }
Arun Khandavallia172c3e2016-08-26 17:33:13 +05301240
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301241 if (cds_is_driver_in_bad_state()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001242 hdd_debug("Driver in bad state (via %s); state:0x%x",
1243 func, cds_get_driver_state());
Sourav Mohapatra21b3c982018-04-03 17:33:03 +05301244 return -EAGAIN;
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301245 }
1246
Arunk Khandavalli2859fa12018-02-14 10:46:26 +05301247 if (cds_is_fw_down()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001248 hdd_debug("FW is down (via %s); state:0x%x",
1249 func, cds_get_driver_state());
Sourav Mohapatra21b3c982018-04-03 17:33:03 +05301250 return -EAGAIN;
Arunk Khandavalli2859fa12018-02-14 10:46:26 +05301251 }
1252
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001253 return 0;
1254}
1255
Dustin Browna8700cc2018-08-07 12:04:47 -07001256int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func)
Dustin Brownf13b8c32017-05-19 17:23:08 -07001257{
1258 if (!adapter) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001259 hdd_err("adapter is null (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001260 return -EINVAL;
1261 }
1262
1263 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001264 hdd_err("bad adapter magic (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001265 return -EINVAL;
1266 }
1267
1268 if (!adapter->dev) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001269 hdd_err("adapter net_device is null (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001270 return -EINVAL;
1271 }
1272
1273 if (!(adapter->dev->flags & IFF_UP)) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001274 hdd_debug_rl("adapter '%s' is not up (via %s)",
1275 adapter->dev->name, func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001276 return -EAGAIN;
1277 }
1278
Jeff Johnson7eb6e842019-02-23 14:33:34 -08001279 return __wlan_hdd_validate_vdev_id(adapter->vdev_id, func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001280}
1281
Jeff Johnson7eb6e842019-02-23 14:33:34 -08001282int __wlan_hdd_validate_vdev_id(uint8_t vdev_id, const char *func)
Dustin Brown63500612018-08-07 11:36:09 -07001283{
Srinivas Girigowdad8697d42019-03-08 15:34:39 -08001284 if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) {
Dustin Brown63500612018-08-07 11:36:09 -07001285 hdd_debug_rl("adapter is not up (via %s)", func);
1286 return -EINVAL;
1287 }
1288
Jeff Johnson7eb6e842019-02-23 14:33:34 -08001289 if (vdev_id >= WLAN_MAX_VDEVS) {
1290 hdd_err("bad vdev Id:%u (via %s)", vdev_id, func);
Dustin Brown63500612018-08-07 11:36:09 -07001291 return -EINVAL;
1292 }
1293
1294 return 0;
1295}
1296
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05301297QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr,
1298 const char *func)
1299{
1300 if (!mac_addr) {
1301 hdd_err("Received NULL mac address (via %s)", func);
1302 return QDF_STATUS_E_INVAL;
1303 }
1304
1305 if (qdf_is_macaddr_zero(mac_addr)) {
1306 hdd_err("MAC is all zero (via %s)", func);
1307 return QDF_STATUS_E_INVAL;
1308 }
1309
1310 if (qdf_is_macaddr_broadcast(mac_addr)) {
1311 hdd_err("MAC is Broadcast (via %s)", func);
1312 return QDF_STATUS_E_INVAL;
1313 }
1314
1315 if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) {
1316 hdd_err("MAC is Multicast (via %s)", func);
1317 return QDF_STATUS_E_INVAL;
1318 }
1319
1320 return QDF_STATUS_SUCCESS;
1321}
1322
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001323/**
Arun Khandavallica892f62017-05-26 14:25:50 +05301324 * wlan_hdd_validate_modules_state() - Check modules status
1325 * @hdd_ctx: HDD context pointer
1326 *
1327 * Check's the driver module's state and returns true if the
1328 * modules are enabled returns false if modules are closed.
1329 *
1330 * Return: True if modules are enabled or false.
1331 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001332bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx)
Arun Khandavallica892f62017-05-26 14:25:50 +05301333{
Arun Khandavallica892f62017-05-26 14:25:50 +05301334 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07001335 hdd_info("Modules not enabled, Present status: %d",
1336 hdd_ctx->driver_status);
Arun Khandavallica892f62017-05-26 14:25:50 +05301337 return false;
1338 }
Dustin Brownf688ea12019-03-19 17:02:32 -07001339
Arun Khandavallica892f62017-05-26 14:25:50 +05301340 return true;
1341}
1342
Abhishek Ambure68677462019-09-13 12:44:26 +05301343#ifdef QCA_IBSS_SUPPORT
Jeff Johnson9d295242017-08-29 14:39:48 -07001344QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001345{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001346 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001347
Jeff Johnsond36fa332019-03-18 13:42:25 -07001348 if (!hdd_ctx) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001349 hdd_err("HDD context is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301350 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001351 }
1352
Manikandan Mohan2bd09772018-11-28 18:27:32 -08001353 return ucfg_mlme_ibss_power_save_setup(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08001354 adapter->vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001355}
Abhishek Ambure68677462019-09-13 12:44:26 +05301356#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001357
Yue Macd359b72017-10-03 15:21:00 -07001358#ifdef FEATURE_RUNTIME_PM
1359/**
1360 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
1361 * @hdd_ctx: HDD context
1362 *
1363 * Return: None
1364 */
1365static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
1366{
1367 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1368
Yue Macd359b72017-10-03 15:21:00 -07001369 qdf_runtime_lock_init(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001370 qdf_runtime_lock_init(&ctx->connect);
Yue Macd359b72017-10-03 15:21:00 -07001371
Dustin Brown07901ec2018-09-07 11:02:41 -07001372 wlan_scan_runtime_pm_init(hdd_ctx->pdev);
Yue Macd359b72017-10-03 15:21:00 -07001373}
1374
1375/**
1376 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
1377 * @hdd_ctx: HDD Context
1378 *
1379 * Return: None
1380 */
1381static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
1382{
1383 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1384
Yue Macd359b72017-10-03 15:21:00 -07001385 qdf_runtime_lock_deinit(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001386 qdf_runtime_lock_deinit(&ctx->connect);
Yue Macd359b72017-10-03 15:21:00 -07001387
Dustin Brown07901ec2018-09-07 11:02:41 -07001388 wlan_scan_runtime_pm_deinit(hdd_ctx->pdev);
Yue Macd359b72017-10-03 15:21:00 -07001389}
1390
Yue Macd359b72017-10-03 15:21:00 -07001391#else /* FEATURE_RUNTIME_PM */
1392static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {}
1393static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {}
Yue Macd359b72017-10-03 15:21:00 -07001394#endif /* FEATURE_RUNTIME_PM */
1395
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001396#define INTF_MACADDR_MASK 0x7
1397
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301398void hdd_update_macaddr(struct hdd_context *hdd_ctx,
1399 struct qdf_mac_addr hw_macaddr, bool generate_mac_auto)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001400{
1401 int8_t i;
1402 uint8_t macaddr_b3, tmp_br3;
1403
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301404 /*
1405 * If "generate_mac_auto" is true, it indicates that all the
1406 * addresses are derived addresses, else the first addresses
1407 * is not derived address (It is provided by fw).
1408 */
1409 if (!generate_mac_auto) {
1410 qdf_mem_copy(hdd_ctx->provisioned_mac_addr[0].bytes,
1411 hw_macaddr.bytes, QDF_MAC_ADDR_SIZE);
1412 hdd_ctx->num_provisioned_addr++;
1413 hdd_info("hdd_ctx->provisioned_mac_addr[0]: "
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07001414 QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07001415 QDF_MAC_ADDR_ARRAY(hdd_ctx->
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301416 provisioned_mac_addr[0].bytes));
1417 } else {
1418 qdf_mem_copy(hdd_ctx->derived_mac_addr[0].bytes,
1419 hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301420 QDF_MAC_ADDR_SIZE);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301421 hdd_ctx->num_derived_addr++;
1422 hdd_info("hdd_ctx->derived_mac_addr[0]: "
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07001423 QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07001424 QDF_MAC_ADDR_ARRAY(hdd_ctx->derived_mac_addr[0].bytes));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301425 }
1426 for (i = hdd_ctx->num_derived_addr; i < (QDF_MAX_CONCURRENCY_PERSONA -
1427 hdd_ctx->num_provisioned_addr);
1428 i++) {
1429 qdf_mem_copy(hdd_ctx->derived_mac_addr[i].bytes,
1430 hw_macaddr.bytes,
1431 QDF_MAC_ADDR_SIZE);
1432 macaddr_b3 = hdd_ctx->derived_mac_addr[i].bytes[3];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001433 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
1434 INTF_MACADDR_MASK;
1435 macaddr_b3 += tmp_br3;
1436
1437 /* XOR-ing bit-24 of the mac address. This will give enough
1438 * mac address range before collision
1439 */
1440 macaddr_b3 ^= (1 << 7);
1441
1442 /* Set locally administered bit */
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301443 hdd_ctx->derived_mac_addr[i].bytes[0] |= 0x02;
1444 hdd_ctx->derived_mac_addr[i].bytes[3] = macaddr_b3;
1445 hdd_info("hdd_ctx->derived_mac_addr[%d]: "
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07001446 QDF_MAC_ADDR_STR, i,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07001447 QDF_MAC_ADDR_ARRAY(hdd_ctx->derived_mac_addr[i].bytes));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301448 hdd_ctx->num_derived_addr++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001449 }
1450}
1451
Jeff Johnson2de58792019-02-08 07:49:17 -08001452#ifdef FEATURE_WLAN_TDLS
Kabilan Kannan44a58372017-12-06 18:16:11 -08001453static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1454{
Dustin Brown1dbefe62018-09-11 16:32:03 -07001455 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001456 struct tdls_start_params tdls_cfg;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001457 QDF_STATUS status;
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301458 struct wlan_mlme_nss_chains vdev_ini_cfg;
1459
1460 /* Populate the nss chain params from ini for this vdev type */
1461 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
1462 QDF_TDLS_MODE,
1463 hdd_ctx->num_rf_chains);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001464
Dustin Brown1dbefe62018-09-11 16:32:03 -07001465 cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301466 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]);
Dustin Brown1dbefe62018-09-11 16:32:03 -07001467 cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301468 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]);
jiad7b8a5e02018-11-26 16:37:57 +08001469 hdd_init_tdls_config(&tdls_cfg);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001470 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
1471 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
1472 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
1473 tdls_cfg.tdls_evt_cb_data = psoc;
Jeff Johnson1d40f5b2018-03-02 08:35:53 -08001474 tdls_cfg.tdls_peer_context = hdd_ctx;
1475 tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer;
1476 tdls_cfg.tdls_dereg_peer = hdd_tdls_deregister_peer;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001477 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
1478 tdls_cfg.tdls_wmm_cb_data = psoc;
1479 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
1480 tdls_cfg.tdls_rx_cb_data = psoc;
1481 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
Arun Kumar Khandavalli43fdd252019-04-24 18:34:18 +05301482 tdls_cfg.tdls_osif_init_cb = wlan_cfg80211_tdls_osif_priv_init;
1483 tdls_cfg.tdls_osif_deinit_cb = wlan_cfg80211_tdls_osif_priv_deinit;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001484
1485 status = ucfg_tdls_update_config(psoc, &tdls_cfg);
1486 if (status != QDF_STATUS_SUCCESS) {
1487 hdd_err("failed pmo psoc configuration");
1488 return -EINVAL;
1489 }
1490
1491 hdd_ctx->tdls_umac_comp_active = true;
1492 /* enable napier specific tdls data path */
1493 hdd_ctx->tdls_nap_active = true;
1494
1495 return 0;
1496}
Jeff Johnson74c6bb22019-02-15 10:15:07 -08001497#else
1498static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1499{
1500 return 0;
1501}
1502#endif
Kabilan Kannan44a58372017-12-06 18:16:11 -08001503
Wu Gaoca416ff2018-09-17 11:05:07 +08001504#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1505static void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1506 struct wma_tgt_services *cfg)
1507{
1508 bool roam_offload_enable;
1509
Dustin Brown1dbefe62018-09-11 16:32:03 -07001510 ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable);
1511 ucfg_mlme_set_roaming_offload(hdd_ctx->psoc,
Wu Gaoca416ff2018-09-17 11:05:07 +08001512 roam_offload_enable &
1513 cfg->en_roam_offload);
1514}
1515#else
1516static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1517 struct wma_tgt_services *cfg)
1518{
1519}
1520#endif
1521
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001522static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001523 struct wma_tgt_services *cfg)
1524{
1525 struct hdd_config *config = hdd_ctx->config;
Wu Gao66454f12018-09-26 19:55:41 +08001526 bool arp_offload_enable;
Wu Gao1ab05582018-11-08 16:22:49 +08001527 bool mawc_enabled;
Wu Gaobdb7f272018-07-05 19:33:26 +08001528#ifdef FEATURE_WLAN_TDLS
1529 bool tdls_support;
1530 bool tdls_off_channel;
1531 bool tdls_buffer_sta;
1532 uint32_t tdls_uapsd_mask;
1533#endif
Will Huangb9cb1242019-04-02 14:52:17 +08001534 bool get_peer_info_enable;
jiad7b8a5e02018-11-26 16:37:57 +08001535
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001536 /* Set up UAPSD */
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05301537 ucfg_mlme_set_sap_uapsd_flag(hdd_ctx->psoc, cfg->uapsd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001538
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08001539 /* 11AX mode support */
1540 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
1541 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
1542 config->dot11Mode = eHDD_DOT11_MODE_11ac;
1543
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001544 /* 11AC mode support */
1545 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
1546 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
1547 config->dot11Mode = eHDD_DOT11_MODE_AUTO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001548
1549 /* ARP offload: override user setting if invalid */
Wu Gao66454f12018-09-26 19:55:41 +08001550 arp_offload_enable =
1551 ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc);
1552 ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc,
1553 arp_offload_enable & cfg->arp_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001554#ifdef FEATURE_WLAN_SCAN_PNO
1555 /* PNO offload */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001556 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557 if (cfg->pno_offload)
Pragaspathi Thilagaraj24789d32018-12-10 22:28:03 +05301558 ucfg_scan_set_pno_offload(hdd_ctx->psoc, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001560#ifdef FEATURE_WLAN_TDLS
Dustin Brown1dbefe62018-09-11 16:32:03 -07001561 cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support);
1562 cfg_tdls_set_support_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001563 tdls_support & cfg->en_tdls);
1564
Dustin Brown1dbefe62018-09-11 16:32:03 -07001565 cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel);
1566 cfg_tdls_set_off_channel_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001567 tdls_off_channel &&
1568 cfg->en_tdls_offchan);
1569
Dustin Brown1dbefe62018-09-11 16:32:03 -07001570 cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta);
1571 cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001572 tdls_buffer_sta &&
1573 cfg->en_tdls_uapsd_buf_sta);
1574
Dustin Brown1dbefe62018-09-11 16:32:03 -07001575 cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask);
Wu Gaobdb7f272018-07-05 19:33:26 +08001576 if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta)
Dustin Brown1dbefe62018-09-11 16:32:03 -07001577 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001578 else
Dustin Brown1dbefe62018-09-11 16:32:03 -07001579 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001580#endif
Wu Gaoca416ff2018-09-17 11:05:07 +08001581 hdd_update_roam_offload(hdd_ctx, cfg);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05301582
Will Huangb9cb1242019-04-02 14:52:17 +08001583 if (ucfg_mlme_get_sap_get_peer_info(
1584 hdd_ctx->psoc, &get_peer_info_enable) == QDF_STATUS_SUCCESS) {
1585 get_peer_info_enable &= cfg->get_peer_info_enabled;
1586 ucfg_mlme_set_sap_get_peer_info(hdd_ctx->psoc,
1587 get_peer_info_enable);
1588 }
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05301589
Wu Gao1ab05582018-11-08 16:22:49 +08001590 ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled);
1591 ucfg_mlme_set_mawc_enabled(hdd_ctx->psoc,
1592 mawc_enabled & cfg->is_fw_mawc_capable);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001593 hdd_update_tdls_config(hdd_ctx);
Jeff Johnson16528362018-06-14 12:34:16 -07001594 sme_update_tgt_services(hdd_ctx->mac_handle, cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001595}
1596
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001597/**
1598 * hdd_update_vdev_nss() - sets the vdev nss
1599 * @hdd_ctx: HDD context
1600 *
1601 * Sets the Nss per vdev type based on INI
1602 *
1603 * Return: None
1604 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001605static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx)
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001606{
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001607 uint8_t max_supp_nss = 1;
Jeff Johnson16528362018-06-14 12:34:16 -07001608 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301609 QDF_STATUS status;
1610 bool bval;
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001611
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301612 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
1613 if (!QDF_IS_STATUS_SUCCESS(status))
1614 hdd_err("unable to get vht_enable2x2");
1615
1616 if (bval && !cds_is_sub_20_mhz_enabled())
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001617 max_supp_nss = 2;
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301618
1619 hdd_debug("max nss %d", max_supp_nss);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001620
Jeff Johnson16528362018-06-14 12:34:16 -07001621 mac_handle = hdd_ctx->mac_handle;
1622 sme_update_vdev_type_nss(mac_handle, max_supp_nss,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301623 NSS_CHAINS_BAND_2GHZ);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001624
Jeff Johnson16528362018-06-14 12:34:16 -07001625 sme_update_vdev_type_nss(mac_handle, max_supp_nss,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301626 NSS_CHAINS_BAND_5GHZ);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001627}
1628
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301629/**
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301630 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
1631 * @hdd_ctx: HDD context
1632 *
1633 * Updates wiphy vhtcap fields
1634 *
1635 * Return: None
1636 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001637static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx)
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301638{
1639 struct ieee80211_supported_band *band_5g =
1640 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301641 QDF_STATUS status;
1642 uint8_t value = 0, value1 = 0;
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301643
1644 if (!band_5g) {
1645 hdd_debug("5GHz band disabled, skipping capability population");
1646 return;
1647 }
1648
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301649 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
1650 &value);
1651 if (!QDF_IS_STATUS_SUCCESS(status))
1652 hdd_err("unable to get tx_bfee_ant_supp");
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301653
Abhinav Kumare057b412018-10-09 17:28:16 +05301654 band_5g->vht_cap.cap |=
1655 (value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301656
1657 value1 = NUM_OF_SOUNDING_DIMENSIONS;
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301658 band_5g->vht_cap.cap |=
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301659 (value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301660
Dustin Brown7e761c72018-07-31 13:50:17 -07001661 hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301662 band_5g->vht_cap.cap, value, value1);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301663}
1664
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001665static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001666 struct wma_tgt_ht_cap *cfg)
1667{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301668 QDF_STATUS status;
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301669 qdf_size_t value_len;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301670 uint32_t value;
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301671 uint8_t mpdu_density;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301672 struct mlme_ht_capabilities_info ht_cap_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001673 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301674 bool b_enable1x1;
Jeff Johnson16528362018-06-14 12:34:16 -07001675
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676 /* get the MPDU density */
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301677 status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density);
1678 if (QDF_IS_STATUS_ERROR(status)) {
1679 hdd_err("could not get HT MPDU Density");
1680 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001681 }
1682
1683 /*
1684 * MPDU density:
1685 * override user's setting if value is larger
1686 * than the one supported by target
1687 */
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301688 if (mpdu_density > cfg->mpdu_density) {
1689 status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc,
1690 cfg->mpdu_density);
1691 if (QDF_IS_STATUS_ERROR(status))
1692 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001693 }
1694
1695 /* get the HT capability info */
Dustin Brown1dbefe62018-09-11 16:32:03 -07001696 status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301697 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001698 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001699 return;
1700 }
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301701
1702 /* check and update RX STBC */
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301703 if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc)
1704 ht_cap_info.rx_stbc = cfg->ht_rx_stbc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001705
1706 /* Set the LDPC capability */
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301707 ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001708
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301709 if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20)
1710 ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001711
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301712 if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40)
1713 ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001714
1715 hdd_ctx->num_rf_chains = cfg->num_rf_chains;
1716 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
1717
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301718 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1);
1719 if (!QDF_IS_STATUS_SUCCESS(status))
1720 hdd_err("unable to get vht_enable2x2");
1721
1722 b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2);
1723
1724 status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1);
1725 if (!QDF_IS_STATUS_SUCCESS(status))
1726 hdd_err("unable to set vht_enable2x2");
1727
Abhinav Kumare057b412018-10-09 17:28:16 +05301728 if (!b_enable1x1) {
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301729 ht_cap_info.tx_stbc = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730
1731 /* 1x1 */
1732 /* Update Rx Highest Long GI data Rate */
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301733 status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(
1734 hdd_ctx->psoc,
1735 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1);
1736 if (!QDF_IS_STATUS_SUCCESS(status))
1737 hdd_err("Failed to set rx_supp_data_rate");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001738 /* Update Tx Highest Long GI data Rate */
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301739 status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(
1740 hdd_ctx->psoc,
1741 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1);
1742 if (!QDF_IS_STATUS_SUCCESS(status))
1743 hdd_err("Failed to set tx_supp_data_rate");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001744 }
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301745 if (!(cfg->ht_tx_stbc && b_enable1x1))
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301746 ht_cap_info.tx_stbc = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001747
Dustin Brown1dbefe62018-09-11 16:32:03 -07001748 status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301749 if (status != QDF_STATUS_SUCCESS)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001750 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001751#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301752 value_len = SIZE_OF_SUPPORTED_MCS_SET;
1753 if (ucfg_mlme_get_supported_mcs_set(
1754 hdd_ctx->psoc, mcs_set,
1755 &value_len) == QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001756 hdd_debug("Read MCS rate set");
gaurank kathpalia18b49362018-04-15 23:12:03 +05301757 if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET)
1758 cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301759
1760 if (b_enable1x1) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001761 for (value = 0; value < cfg->num_rf_chains; value++)
1762 mcs_set[value] =
1763 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
1764
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301765 status = ucfg_mlme_set_supported_mcs_set(
1766 hdd_ctx->psoc,
1767 mcs_set,
1768 (qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET);
1769 if (QDF_IS_STATUS_ERROR(status))
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001770 hdd_err("could not set MCS SET to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001771 }
1772 }
1773#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
1774}
1775
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001776static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001777 struct wma_tgt_vht_cap *cfg)
1778{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301779 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001780 struct wiphy *wiphy = hdd_ctx->wiphy;
1781 struct ieee80211_supported_band *band_5g =
Srinivas Girigowda11c28e02017-06-27 20:06:21 -07001782 wiphy->bands[HDD_NL80211_BAND_5GHZ];
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001783 uint32_t ch_width;
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001784 struct wma_caps_per_phy caps_per_phy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001785
Dustin Brown5e06bd32016-10-04 12:49:10 -07001786 if (!band_5g) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001787 hdd_debug("5GHz band disabled, skipping capability population");
Dustin Brown5e06bd32016-10-04 12:49:10 -07001788 return;
1789 }
1790
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301791 status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg);
1792 if (QDF_IS_STATUS_ERROR(status))
1793 hdd_err("could not update vht capabilities");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001794
1795 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
1796 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1797 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
1798 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1799 else
1800 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1801
1802
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001803 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001804 band_5g->vht_cap.cap |=
1805 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001806 ch_width = VHT_CAP_160_AND_80P80_SUPP;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001807 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001808 band_5g->vht_cap.cap |=
1809 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001810 ch_width = VHT_CAP_160_SUPP;
1811 } else {
1812 ch_width = VHT_CAP_NO_160M_SUPP;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001813 }
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001814
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001815 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, ch_width);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301816 if (QDF_IS_STATUS_ERROR(status))
1817 hdd_err("could not set the channel width");
Kiran Kumar Lokerec220a512019-07-24 18:30:47 -07001818 else
1819 hdd_debug("supported channel width %d", ch_width);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001820
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001821 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001822 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001823 hdd_debug("VHT RxLDPC capability is set");
1824 } else {
1825 /*
1826 * Get the RX LDPC capability for the NON DBS
1827 * hardware mode for 5G band
1828 */
1829 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
1830 HW_MODE_DBS_NONE, CDS_BAND_5GHZ);
1831 if ((QDF_IS_STATUS_SUCCESS(status)) &&
1832 (caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) {
1833 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
1834 hdd_debug("VHT RX LDPC capability is set");
1835 }
1836 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001837
1838 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
1839 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1840 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
1841 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1842
1843 if (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)
1844 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
1845
1846 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
1847 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1848 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)
1849 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
1850 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
1851 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
1852
1853 band_5g->vht_cap.cap |=
1854 (cfg->vht_max_ampdu_len_exp <<
1855 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
1856
1857 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
1858 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1859 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
1860 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1861 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
1862 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1863 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
1864 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1865
1866 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
1867 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1868
1869}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001870
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001871/**
1872 * hdd_generate_macaddr_auto() - Auto-generate mac address
1873 * @hdd_ctx: Pointer to the HDD context
1874 *
1875 * Auto-generate mac address using device serial number.
1876 * Keep the first 3 bytes of OUI as before and replace
1877 * the last 3 bytes with the lower 3 bytes of serial number.
1878 *
1879 * Return: 0 for success
1880 * Non zero failure code for errors
1881 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001882static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx)
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001883{
1884 unsigned int serialno = 0;
1885 struct qdf_mac_addr mac_addr = {
1886 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
1887 };
1888
Yuanyuan Liuf97e8222016-09-21 10:31:38 -07001889 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001890 if (serialno == 0)
1891 return -EINVAL;
1892
1893 serialno &= 0x00ffffff;
1894
1895 mac_addr.bytes[3] = (serialno >> 16) & 0xff;
1896 mac_addr.bytes[4] = (serialno >> 8) & 0xff;
1897 mac_addr.bytes[5] = serialno & 0xff;
1898
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301899 hdd_update_macaddr(hdd_ctx, mac_addr, true);
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001900 return 0;
1901}
1902
Jeff Johnsonf9176382018-07-17 19:15:58 -07001903static void hdd_sar_target_config(struct hdd_context *hdd_ctx,
1904 struct wma_tgt_cfg *cfg)
1905{
1906 hdd_ctx->sar_version = cfg->sar_version;
1907}
1908
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001909static void hdd_update_vhtcap_2g(struct hdd_context *hdd_ctx)
1910{
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001911 uint32_t chip_mode = 0;
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001912 QDF_STATUS status;
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001913 bool b2g_vht_cfg = false;
1914 bool b2g_vht_target = false;
1915 struct wma_caps_per_phy caps_per_phy;
1916 struct wmi_unified *wmi_handle;
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001917
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001918 wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc);
1919 if (!wmi_handle) {
1920 hdd_err("wmi handle is NULL");
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001921 return;
1922 }
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001923
1924 status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &b2g_vht_cfg);
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001925 if (QDF_IS_STATUS_ERROR(status)) {
1926 hdd_err("Failed to get 2g vht mode");
1927 return;
1928 }
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001929 if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) {
1930 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
1931 HW_MODE_DBS_NONE,
1932 CDS_BAND_ALL);
1933 if (QDF_IS_STATUS_ERROR(status)) {
1934 hdd_err("Failed to get phy caps");
1935 return;
1936 }
1937 if (caps_per_phy.vht_2g)
1938 b2g_vht_target = true;
1939 } else {
1940 status = wlan_reg_get_chip_mode(hdd_ctx->pdev, &chip_mode);
1941 if (QDF_IS_STATUS_ERROR(status)) {
1942 hdd_err("Failed to get chip mode");
1943 return;
1944 }
1945 b2g_vht_target =
1946 (chip_mode & WMI_HOST_REGDMN_MODE_11AC_VHT20_2G) ?
1947 true : false;
1948 }
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001949
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001950 b2g_vht_cfg = b2g_vht_cfg && b2g_vht_target;
1951 hdd_debug("vht 2g target: %d, cfg: %d", b2g_vht_target, b2g_vht_cfg);
1952 status = ucfg_mlme_set_vht_for_24ghz(hdd_ctx->psoc, b2g_vht_cfg);
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001953 if (QDF_IS_STATUS_ERROR(status)) {
1954 hdd_err("Failed to update 2g vht mode");
1955 return;
1956 }
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001957}
1958
Ashish Kumar Dhanotiyaeadb28b2019-06-28 14:34:19 +05301959static void hdd_extract_fw_version_info(struct hdd_context *hdd_ctx)
1960{
1961 hdd_ctx->fw_version_info.major_spid =
1962 HDD_FW_VER_MAJOR_SPID(hdd_ctx->target_fw_version);
1963 hdd_ctx->fw_version_info.minor_spid =
1964 HDD_FW_VER_MINOR_SPID(hdd_ctx->target_fw_version);
1965 hdd_ctx->fw_version_info.siid =
1966 HDD_FW_VER_SIID(hdd_ctx->target_fw_version);
1967 hdd_ctx->fw_version_info.crmid =
1968 HDD_FW_VER_CRM_ID(hdd_ctx->target_fw_version);
1969 hdd_ctx->fw_version_info.sub_id =
1970 HDD_FW_VER_SUB_ID(hdd_ctx->target_fw_vers_ext);
1971 hdd_ctx->fw_version_info.rel_id =
1972 HDD_FW_VER_REL_ID(hdd_ctx->target_fw_vers_ext);
1973}
1974
gaurank kathpaliaccfca4a2019-08-13 11:51:27 +05301975#if defined(WLAN_FEATURE_11AX) && \
1976 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
1977static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx)
1978{
1979 tDot11fIEhe_cap he_cap_cfg;
1980 struct ieee80211_supported_band *band_2g =
1981 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_2GHZ];
1982 struct ieee80211_supported_band *band_5g =
1983 hdd_ctx->wiphy->bands[HDD_NL80211_BAND_5GHZ];
1984 QDF_STATUS status;
1985
1986 status = ucfg_mlme_cfg_get_he_caps(hdd_ctx->psoc, &he_cap_cfg);
1987
1988 if (QDF_IS_STATUS_ERROR(status))
1989 return;
1990
1991 if (band_2g) {
1992 hdd_ctx->iftype_data_2g->types_mask =
1993 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
1994 hdd_ctx->iftype_data_2g->he_cap.has_he = he_cap_cfg.present;
1995 band_2g->n_iftype_data = 1;
1996 band_2g->iftype_data = hdd_ctx->iftype_data_2g;
1997 }
1998 if (band_5g) {
1999 hdd_ctx->iftype_data_5g->types_mask =
2000 (BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP));
2001 hdd_ctx->iftype_data_5g->he_cap.has_he = he_cap_cfg.present;
2002 band_5g->n_iftype_data = 1;
2003 band_5g->iftype_data = hdd_ctx->iftype_data_5g;
2004 }
2005}
2006#else
2007static void hdd_update_wiphy_he_cap(struct hdd_context *hdd_ctx)
2008{
2009}
2010#endif
2011
Ashish Kumar Dhanotiyab0355702019-09-19 18:06:30 +05302012static void hdd_component_cfg_chan_to_freq(struct wlan_objmgr_pdev *pdev)
2013{
2014 ucfg_mlme_cfg_chan_to_freq(pdev);
2015}
2016
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302017int hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018{
Rajeev Kumarf49dfdb2017-01-13 15:40:35 -08002019 int ret;
Jeff Johnsonea70b942018-07-02 09:42:31 -07002020 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302021 uint8_t temp_band_cap, band_capability;
Naveen Rawat64e477e2016-05-20 10:34:56 -07002022 struct cds_config_info *cds_cfg = cds_get_ini_config();
Nitesh Shahe50711f2017-04-26 16:30:45 +05302023 uint8_t antenna_mode;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05302024 uint8_t sub_20_chan_width;
Arif Hussainee10f902017-12-27 16:30:17 -08002025 QDF_STATUS status;
Jeff Johnson16528362018-06-14 12:34:16 -07002026 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302027 bool bval = false;
2028 uint8_t value = 0;
Arif Hussainbd5194c2018-11-27 19:01:15 -08002029 uint32_t fine_time_meas_cap = 0;
gaurank kathpaliafa7ad0a2019-03-12 19:17:56 +05302030 enum nss_chains_band_info band;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302031
gaurank kathpalia843f7c32018-07-02 18:04:14 +05302032 if (!hdd_ctx) {
2033 hdd_err("HDD context is NULL");
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302034 return -EINVAL;
gaurank kathpalia843f7c32018-07-02 18:04:14 +05302035 }
Dustin Brownbd68fe12017-11-21 15:28:52 -08002036 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
2037 if (ret) {
Dustin Brown64204d22018-08-15 16:35:19 -07002038 QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret);
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302039 return -EINVAL;
Dustin Brown64204d22018-08-15 16:35:19 -07002040 }
2041
2042 hdd_debug("New pdev has been created with pdev_id = %u",
Dustin Brown07901ec2018-09-07 11:02:41 -07002043 hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id);
Dustin Brown64204d22018-08-15 16:35:19 -07002044
Dustin Brown07901ec2018-09-07 11:02:41 -07002045 status = dispatcher_pdev_open(hdd_ctx->pdev);
Dustin Brown64204d22018-08-15 16:35:19 -07002046 if (QDF_IS_STATUS_ERROR(status)) {
2047 QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d",
2048 status);
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302049 ret = qdf_status_to_os_return(status);
2050 goto exit;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05302051 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07002052
Sandeep Puligillab7beb472018-08-13 22:54:20 -07002053 status = hdd_component_pdev_open(hdd_ctx->pdev);
2054 if (QDF_IS_STATUS_ERROR(status)) {
2055 QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d",
2056 status);
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302057 ret = qdf_status_to_os_return(status);
2058 goto dispatcher_close;
Sandeep Puligillab7beb472018-08-13 22:54:20 -07002059 }
Ashish Kumar Dhanotiyab0355702019-09-19 18:06:30 +05302060 /*
2061 * For 6GHz support this api is added to convert mlme cfgs
2062 * channel numbers to frequency
2063 */
2064 hdd_component_cfg_chan_to_freq(hdd_ctx->pdev);
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302065
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05302066 cdp_pdev_set_ctrl_pdev(cds_get_context(QDF_MODULE_ID_SOC),
2067 cds_get_context(QDF_MODULE_ID_TXRX),
Dustin Brown07901ec2018-09-07 11:02:41 -07002068 (struct cdp_ctrl_objmgr_pdev *)hdd_ctx->pdev);
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05302069
Dustin Brown07901ec2018-09-07 11:02:41 -07002070 wlan_pdev_set_dp_handle(hdd_ctx->pdev,
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05302071 cds_get_context(QDF_MODULE_ID_TXRX));
2072
Will Huang07244172018-05-14 14:23:30 +08002073 hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count);
2074
Dustin Brown1dbefe62018-09-11 16:32:03 -07002075 ucfg_ipa_set_dp_handle(hdd_ctx->psoc,
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05302076 cds_get_context(QDF_MODULE_ID_SOC));
Dustin Brown1dbefe62018-09-11 16:32:03 -07002077 ucfg_ipa_set_txrx_handle(hdd_ctx->psoc,
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05302078 cds_get_context(QDF_MODULE_ID_TXRX));
Dustin Brown07901ec2018-09-07 11:02:41 -07002079 ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev,
Vevek Venkatesan78f7f092019-05-23 17:16:28 +05302080 hdd_softap_ipa_start_xmit);
Dustin Brown07901ec2018-09-07 11:02:41 -07002081 ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev,
Vevek Venkatesan3b6be822019-05-28 18:19:15 +05302082 hdd_ipa_send_nbuf_to_network);
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05302083
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05302084 status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
2085 &sub_20_chan_width);
2086 if (QDF_IS_STATUS_ERROR(status)) {
2087 hdd_err("Failed to get sub_20_chan_width config");
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302088 ret = qdf_status_to_os_return(status);
2089 goto pdev_close;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05302090 }
2091
Naveen Rawat64e477e2016-05-20 10:34:56 -07002092 if (cds_cfg) {
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05302093 if (sub_20_chan_width !=
2094 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
Naveen Rawat64e477e2016-05-20 10:34:56 -07002095 hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
2096 cds_cfg->sub_20_channel_width =
2097 WLAN_SUB_20_CH_WIDTH_NONE;
2098 } else {
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05302099 cds_cfg->sub_20_channel_width = sub_20_chan_width;
Naveen Rawat64e477e2016-05-20 10:34:56 -07002100 }
2101 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002102
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302103 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
2104 if (QDF_IS_STATUS_ERROR(status)) {
2105 hdd_err("Failed to get MLME band capability");
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302106 ret = qdf_status_to_os_return(status);
2107 goto pdev_close;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302108 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002109
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302110 /* first store the INI band capability */
2111 temp_band_cap = band_capability;
2112
2113 band_capability = cfg->band_cap;
Vignesh Viswanathan731186f2017-09-18 13:47:37 +05302114 hdd_ctx->is_fils_roaming_supported =
2115 cfg->services.is_fils_roaming_supported;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002116
Vignesh Viswanathan694e28e2018-01-18 20:53:57 +05302117 hdd_ctx->config->is_11k_offload_supported =
2118 cfg->services.is_11k_offload_supported;
2119
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08002120 /*
2121 * now overwrite the target band capability with INI
2122 * setting if INI setting is a subset
2123 */
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302124 if ((band_capability == BAND_ALL) &&
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002125 (temp_band_cap != BAND_ALL))
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302126 band_capability = temp_band_cap;
2127 else if ((band_capability != BAND_ALL) &&
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08002128 (temp_band_cap != BAND_ALL) &&
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302129 (band_capability != temp_band_cap)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07002130 hdd_warn("ini BandCapability not supported by the target");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002131 }
2132
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302133 status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability);
2134 if (QDF_IS_STATUS_ERROR(status)) {
2135 hdd_err("Failed to set MLME Band Capability");
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302136 ret = qdf_status_to_os_return(status);
2137 goto pdev_close;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05302138 }
2139
2140 hdd_ctx->curr_band = band_capability;
Amar Singhal58b45ef2017-08-01 13:43:54 -07002141
Qun Zhang043635a2019-02-27 15:19:29 +08002142 status = wlan_hdd_update_wiphy_supported_band(hdd_ctx);
2143 if (QDF_IS_STATUS_ERROR(status)) {
2144 hdd_err("Failed to update wiphy band info");
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302145 goto pdev_close;
Qun Zhang043635a2019-02-27 15:19:29 +08002146 }
2147
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05302148 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149 hdd_ctx->reg.reg_domain = cfg->reg_domain;
2150 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
2151 }
2152
2153 /* This can be extended to other configurations like ht, vht cap... */
2154
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05302155 if (!qdf_is_macaddr_zero(&cfg->hw_macaddr))
2156 qdf_mem_copy(&hdd_ctx->hw_macaddr, &cfg->hw_macaddr,
2157 QDF_MAC_ADDR_SIZE);
2158 else
2159 hdd_info("hw_mac is zero");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002160
2161 hdd_ctx->target_fw_version = cfg->target_fw_version;
Sandeep Puligilla3d6a8e22016-10-11 18:57:14 -07002162 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
Ashish Kumar Dhanotiyaeadb28b2019-06-28 14:34:19 +05302163 hdd_extract_fw_version_info(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002164
Ryan Hsuc6918552018-05-16 13:29:59 -07002165 hdd_ctx->hw_bd_id = cfg->hw_bd_id;
2166 qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info,
2167 sizeof(cfg->hw_bd_info));
2168
Dustin Brownad06be62019-02-04 14:52:56 -08002169 if (cfg->max_intf_count > WLAN_MAX_VDEVS) {
Dustin Brownbee82832018-07-23 10:10:51 -07002170 hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u",
Dustin Brownad06be62019-02-04 14:52:56 -08002171 cfg->max_intf_count, WLAN_MAX_VDEVS, WLAN_MAX_VDEVS);
2172 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS;
Dustin Brownbee82832018-07-23 10:10:51 -07002173 } else {
2174 hdd_ctx->max_intf_count = cfg->max_intf_count;
2175 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002176
Jeff Johnsonf9176382018-07-17 19:15:58 -07002177 hdd_sar_target_config(hdd_ctx, cfg);
Jeff Johnsonc875e242016-09-23 18:12:34 -07002178 hdd_lpass_target_config(hdd_ctx, cfg);
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08002179
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002180 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
Pragaspathi Thilagarajeb367282019-02-19 00:42:28 +05302181
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002182 hdd_update_tgt_services(hdd_ctx, &cfg->services);
2183
2184 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
2185
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002186 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
Krishna Kumaar Natarajaned1efd92016-09-24 18:05:47 -07002187 if (cfg->services.en_11ax) {
2188 hdd_info("11AX: 11ax is enabled - update HDD config");
2189 hdd_update_tgt_he_cap(hdd_ctx, cfg);
gaurank kathpaliaccfca4a2019-08-13 11:51:27 +05302190 hdd_update_wiphy_he_cap(hdd_ctx);
Krishna Kumaar Natarajaned1efd92016-09-24 18:05:47 -07002191 }
Varun Reddy Yeturue93d2462018-05-22 13:54:52 -07002192 hdd_update_tgt_twt_cap(hdd_ctx, cfg);
Tushnim Bhattacharyyaf44a9d82016-07-05 10:52:06 -07002193
gaurank kathpaliafa7ad0a2019-03-12 19:17:56 +05302194 for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) {
2195 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2196 QDF_STA_MODE, band);
2197 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2198 QDF_SAP_MODE, band);
2199 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2200 QDF_TDLS_MODE, band);
2201 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2202 QDF_P2P_DEVICE_MODE,
2203 band);
2204 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2205 QDF_OCB_MODE, band);
2206 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
2207 QDF_TDLS_MODE, band);
2208 }
2209
Tushnim Bhattacharyyaf44a9d82016-07-05 10:52:06 -07002210 hdd_update_vdev_nss(hdd_ctx);
2211
gaurank kathpalia5fcefa92018-10-24 15:03:15 +05302212 hdd_ctx->dynamic_nss_chains_support =
2213 cfg->dynamic_nss_chains_support;
Arif Hussainbd5194c2018-11-27 19:01:15 -08002214 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap);
2215 fine_time_meas_cap &= cfg->fine_time_measurement_cap;
2216 status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc,
2217 fine_time_meas_cap);
2218 if (QDF_IS_STATUS_ERROR(status)) {
2219 hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x",
2220 fine_time_meas_cap, cfg->fine_time_measurement_cap);
2221 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
2222 &fine_time_meas_cap);
2223 }
2224
Krunal Sonie3531942016-04-12 17:43:53 -07002225 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
Arif Hussainbd5194c2018-11-27 19:01:15 -08002226 hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap);
Archana Ramachandran393f3792015-11-13 17:13:21 -08002227
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302228 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
2229 if (!QDF_IS_STATUS_SUCCESS(status))
2230 hdd_err("unable to get vht_enable2x2");
2231
2232 antenna_mode = (bval == 0x01) ?
Nitesh Shahe50711f2017-04-26 16:30:45 +05302233 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
2234 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002235 hdd_debug("Init current antenna mode: %d",
Arif Hussainee10f902017-12-27 16:30:17 -08002236 hdd_ctx->current_antenna_mode);
Archana Ramachandran393f3792015-11-13 17:13:21 -08002237
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05302238 hdd_ctx->rcpi_enabled = cfg->rcpi_enabled;
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05302239
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302240 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
Abhinav Kumare057b412018-10-09 17:28:16 +05302241 &value);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302242 if (QDF_IS_STATUS_ERROR(status)) {
2243 status = false;
2244 hdd_err("set tx_bfee_ant_supp failed");
2245 }
2246
Pragaspathi Thilagaraj6fc0a9a2019-05-17 16:49:45 +05302247 if ((value > MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302248 !cfg->tx_bfee_8ss_enabled) {
Pragaspathi Thilagaraj6fc0a9a2019-05-17 16:49:45 +05302249 status = ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
2250 MLME_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302251 if (QDF_IS_STATUS_ERROR(status)) {
2252 status = false;
2253 hdd_err("set tx_bfee_ant_supp failed");
2254 }
2255 }
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302256
Jeff Johnson16528362018-06-14 12:34:16 -07002257 mac_handle = hdd_ctx->mac_handle;
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302258
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302259 hdd_debug("txBFCsnValue %d", value);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05302260
2261 /*
2262 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
2263 */
2264 hdd_update_wiphy_vhtcap(hdd_ctx);
Manjeet Singh70d3d932016-12-20 20:41:10 +05302265
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08002266 hdd_update_vhtcap_2g(hdd_ctx);
2267
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05302268 hdd_ctx->wmi_max_len = cfg->wmi_max_len;
2269
Ashish Kumar Dhanotiya908925d2019-03-01 17:35:30 +05302270 wlan_config_sched_scan_plans_to_wiphy(hdd_ctx->wiphy, hdd_ctx->psoc);
Yue Macd359b72017-10-03 15:21:00 -07002271 /*
2272 * This needs to be done after HDD pdev is created and stored since
2273 * it will access the HDD pdev object lock.
2274 */
2275 hdd_runtime_suspend_context_init(hdd_ctx);
2276
Deepak Dhamdhere13230d32016-05-26 00:46:53 -07002277 /* Configure NAN datapath features */
2278 hdd_nan_datapath_target_config(hdd_ctx, cfg);
Nachiket Kukade85aa3782018-11-02 20:12:34 +05302279 ucfg_nan_set_tgt_caps(hdd_ctx->psoc, &cfg->nan_caps);
Arif Hussain759a0232017-03-20 13:17:18 -07002280 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08002281 hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share;
Liangwei Dong0da14262018-07-03 03:30:23 -04002282 hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload;
Wu Gao5f764082019-01-04 15:54:38 +08002283 status = ucfg_mlme_set_obss_detection_offload_enabled(
2284 hdd_ctx->psoc, cfg->obss_detection_offloaded);
Arif Hussainee10f902017-12-27 16:30:17 -08002285 if (QDF_IS_STATUS_ERROR(status))
2286 hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG");
Arif Hussain05fb4872018-01-03 16:02:55 -08002287
Wu Gao5f764082019-01-04 15:54:38 +08002288 status = ucfg_mlme_set_obss_color_collision_offload_enabled(
2289 hdd_ctx->psoc, cfg->obss_color_collision_offloaded);
Arif Hussain05fb4872018-01-03 16:02:55 -08002290 if (QDF_IS_STATUS_ERROR(status))
2291 hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD");
Arif Hussain50689082019-03-26 12:07:58 -07002292
2293 ucfg_mlme_get_bcast_twt(hdd_ctx->psoc, &bval);
2294 if (bval)
2295 ucfg_mlme_set_bcast_twt(hdd_ctx->psoc, cfg->bcast_twt_support);
2296 else
2297 hdd_debug("bcast twt is disable in ini, fw cap %d",
2298 cfg->bcast_twt_support);
Arun Kumar Khandavallia4234582019-03-20 16:16:05 +05302299 return 0;
2300
2301dispatcher_close:
2302 dispatcher_pdev_close(hdd_ctx->pdev);
2303pdev_close:
2304 hdd_component_pdev_close(hdd_ctx->pdev);
2305exit:
2306 hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
2307
2308 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002309}
2310
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002311bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002312{
Jeff Johnson9d295242017-08-29 14:39:48 -07002313 struct hdd_adapter *adapter;
Jeff Johnson87251032017-08-29 13:31:11 -07002314 struct hdd_ap_ctx *ap_ctx;
Arif Hussain224d3812018-11-16 17:58:38 -08002315 bool dfs_disable_channel_switch = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002316
Jiachao Wuf610d912018-01-23 17:47:32 +08002317 if (!hdd_ctx) {
2318 hdd_info("Couldn't get hdd_ctx");
2319 return true;
2320 }
2321
Arif Hussain224d3812018-11-16 17:58:38 -08002322 ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc,
2323 &dfs_disable_channel_switch);
2324 if (dfs_disable_channel_switch) {
Jeff Johnson36e74c42017-09-18 08:15:42 -07002325 hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d",
Arif Hussain224d3812018-11-16 17:58:38 -08002326 hdd_ctx, dfs_disable_channel_switch);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302327 return true;
Arif Hussaincd151632017-02-11 16:57:19 -08002328 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002329
Dustin Brown920397d2017-12-13 16:27:50 -08002330 hdd_for_each_adapter(hdd_ctx, adapter) {
Arif Hussaincd151632017-02-11 16:57:19 -08002331 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
2332
2333 if ((QDF_SAP_MODE == adapter->device_mode ||
2334 QDF_P2P_GO_MODE == adapter->device_mode) &&
Dustin Brown07901ec2018-09-07 11:02:41 -07002335 (wlan_reg_is_passive_or_disable_ch(hdd_ctx->pdev,
Jeff Johnson01206862017-10-27 20:55:59 -07002336 ap_ctx->operating_channel))) {
Arif Hussaincd151632017-02-11 16:57:19 -08002337 WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx =
2338 true;
Jeff Johnson7eb6e842019-02-23 14:33:34 -08002339 hdd_info("tx blocked for vdev: %d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -08002340 adapter->vdev_id);
bings6fb9bf62018-07-05 14:01:53 +08002341 if (adapter->txrx_vdev)
2342 cdp_fc_vdev_flush(
2343 cds_get_context(QDF_MODULE_ID_SOC),
bings0e03a982018-05-09 08:40:59 +08002344 adapter->txrx_vdev);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302345 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002346 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302347
2348 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002349}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002350
Jeff Johnson030cd902018-11-11 10:19:40 -08002351bool hdd_is_valid_mac_address(const uint8_t *mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002352{
2353 int xdigit = 0;
2354 int separator = 0;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002355
Jeff Johnson030cd902018-11-11 10:19:40 -08002356 while (*mac_addr) {
2357 if (isxdigit(*mac_addr)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002358 xdigit++;
Jeff Johnson030cd902018-11-11 10:19:40 -08002359 } else if (':' == *mac_addr) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002360 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
2361 break;
2362
2363 ++separator;
2364 } else {
2365 /* Invalid MAC found */
Jeff Johnson030cd902018-11-11 10:19:40 -08002366 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002367 }
Jeff Johnson030cd902018-11-11 10:19:40 -08002368 ++mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002369 }
2370 return xdigit == 12 && (separator == 5 || separator == 0);
2371}
2372
2373/**
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302374 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
2375 * @dev: Handle to struct net_device to be updated.
2376 *
2377 * Return: None
2378 */
2379static void hdd_mon_mode_ether_setup(struct net_device *dev)
2380{
2381 dev->header_ops = NULL;
2382 dev->type = ARPHRD_IEEE80211_RADIOTAP;
2383 dev->hard_header_len = ETH_HLEN;
2384 dev->mtu = ETH_DATA_LEN;
2385 dev->addr_len = ETH_ALEN;
2386 dev->tx_queue_len = 1000; /* Ethernet wants good queues */
2387 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
2388 dev->priv_flags |= IFF_TX_SKB_SHARING;
2389
2390 memset(dev->broadcast, 0xFF, ETH_ALEN);
2391}
2392
Nirav Shah73713f72018-05-17 14:50:41 +05302393#ifdef FEATURE_MONITOR_MODE_SUPPORT
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302394/**
chenguo71303962018-10-24 19:44:34 +08002395 * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device.
2396 * @hdd_ctx: Pointer to HDD context.
2397 *
2398 * Return: None
2399 */
2400static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx)
2401{
2402 ucfg_pmo_set_power_save_mode(hdd_ctx->psoc, PS_NOT_SUPPORTED);
2403 ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH);
2404}
2405
2406/**
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002407 * __hdd__mon_open() - HDD Open function
2408 * @dev: Pointer to net_device structure
2409 *
2410 * This is called in response to ifconfig up
2411 *
2412 * Return: 0 for success; non-zero for failure
2413 */
2414static int __hdd_mon_open(struct net_device *dev)
2415{
2416 int ret;
Ravi Joshia307f632017-07-17 23:41:41 -07002417 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2418 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002419
Dustin Brownfdf17c12018-03-14 12:55:34 -07002420 hdd_enter_dev(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002421
2422 ret = wlan_hdd_validate_context(hdd_ctx);
2423 if (ret)
2424 return ret;
2425
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302426 hdd_mon_mode_ether_setup(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002427
2428 if (con_mode == QDF_GLOBAL_MONITOR_MODE) {
Rajeev Kumar473f9af2019-04-05 14:25:56 -07002429 ret = hdd_trigger_psoc_idle_restart(hdd_ctx);
Ravi Joshia307f632017-07-17 23:41:41 -07002430 if (ret) {
2431 hdd_err("Failed to start WLAN modules return");
2432 return ret;
2433 }
2434 hdd_err("hdd_wlan_start_modules() successful !");
2435
2436 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
2437 ret = hdd_start_adapter(adapter);
2438 if (ret) {
2439 hdd_err("Failed to start adapter :%d",
2440 adapter->device_mode);
2441 return ret;
2442 }
2443 hdd_err("hdd_start_adapters() successful !");
2444 }
chenguo71303962018-10-24 19:44:34 +08002445 hdd_mon_turn_off_ps_and_wow(hdd_ctx);
Ravi Joshia307f632017-07-17 23:41:41 -07002446 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
2447 }
2448
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002449 ret = hdd_set_mon_rx_cb(dev);
Ravi Joshi4f095952017-06-29 15:39:19 -07002450
2451 if (!ret)
2452 ret = hdd_enable_monitor_mode(dev);
2453
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002454 return ret;
2455}
2456
2457/**
2458 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
2459 * @dev: Pointer to net_device structure
2460 *
2461 * This is called in response to ifconfig up
2462 *
2463 * Return: 0 for success; non-zero for failure
2464 */
Dustin Brown0e1e1622019-01-17 11:00:22 -08002465static int hdd_mon_open(struct net_device *net_dev)
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002466{
Dustin Brown0e1e1622019-01-17 11:00:22 -08002467 int errno;
2468 struct osif_vdev_sync *vdev_sync;
2469
2470 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
2471 if (errno)
2472 return errno;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002473
Dustin Brown0e1e1622019-01-17 11:00:22 -08002474 errno = __hdd_mon_open(net_dev);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002475
Dustin Brown0e1e1622019-01-17 11:00:22 -08002476 osif_vdev_sync_trans_stop(vdev_sync);
2477
2478 return errno;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002479}
Nirav Shah73713f72018-05-17 14:50:41 +05302480#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002481
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002482static QDF_STATUS
2483wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
2484{
2485 struct policy_mgr_dual_mac_config cfg = {0};
2486 QDF_STATUS status;
Krunal Sonie64b17e2018-12-13 16:00:02 -08002487 uint32_t chnl_sel_logic_conc = 0;
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002488 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Krunal Sonidf29bc42018-11-15 13:26:29 -08002489 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002490
2491 if (!hdd_ctx) {
2492 hdd_err("HDD context is NULL");
2493 return QDF_STATUS_E_FAILURE;
2494 }
2495
Krunal Sonie64b17e2018-12-13 16:00:02 -08002496 /*
2497 * ROME platform doesn't support any DBS related commands in FW,
2498 * so if driver sends wmi command with dual_mac_config with all set to
2499 * 0 then FW wouldn't respond back and driver would timeout on waiting
2500 * for response. Check if FW supports DBS to eliminate ROME vs
2501 * NON-ROME platform.
2502 */
2503 if (!policy_mgr_find_if_fw_supports_dbs(hdd_ctx->psoc))
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002504 return QDF_STATUS_SUCCESS;
2505
2506 cfg.scan_config = 0;
2507 cfg.fw_mode_config = 0;
2508 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
Krunal Sonie64b17e2018-12-13 16:00:02 -08002509 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) {
2510 status =
2511 ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc,
2512 &chnl_sel_logic_conc);
2513 if (status != QDF_STATUS_SUCCESS) {
2514 hdd_err("can't get chnl sel policy, use def");
2515 return status;
2516 }
Krunal Sonidf29bc42018-11-15 13:26:29 -08002517 }
2518 status =
2519 ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
2520 &dual_mac_feature);
2521 if (status != QDF_STATUS_SUCCESS) {
2522 hdd_err("ucfg_policy_mgr_get_dual_mac_feature failed, use def");
2523 return status;
2524 }
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002525
Krunal Sonidf29bc42018-11-15 13:26:29 -08002526 if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) {
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002527 status = policy_mgr_get_updated_scan_and_fw_mode_config(
Dustin Brown1dbefe62018-09-11 16:32:03 -07002528 hdd_ctx->psoc, &cfg.scan_config,
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002529 &cfg.fw_mode_config,
Krunal Sonidf29bc42018-11-15 13:26:29 -08002530 dual_mac_feature,
Krunal Sonie64b17e2018-12-13 16:00:02 -08002531 chnl_sel_logic_conc);
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002532
2533 if (status != QDF_STATUS_SUCCESS) {
2534 hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",
2535 status);
2536 return status;
2537 }
2538 }
2539
2540 hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw",
2541 cfg.scan_config, cfg.fw_mode_config);
2542
2543 status = sme_soc_set_dual_mac_config(cfg);
2544 if (status != QDF_STATUS_SUCCESS) {
2545 hdd_err("sme_soc_set_dual_mac_config failed %d", status);
2546 return status;
2547 }
2548
2549 return QDF_STATUS_SUCCESS;
2550}
2551
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002552/**
Arun Khandavallifae92942016-08-01 13:31:08 +05302553 * hdd_start_adapter() - Wrapper function for device specific adapter
2554 * @adapter: pointer to HDD adapter
2555 *
2556 * This function is called to start the device specific adapter for
2557 * the mode passed in the adapter's device_mode.
2558 *
2559 * Return: 0 for success; non-zero for failure
2560 */
Jeff Johnson9d295242017-08-29 14:39:48 -07002561int hdd_start_adapter(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05302562{
2563
2564 int ret;
Jeff Johnsonc1e62782017-11-09 09:50:17 -08002565 enum QDF_OPMODE device_mode = adapter->device_mode;
Arun Khandavallifae92942016-08-01 13:31:08 +05302566
Dustin Brownfdf17c12018-03-14 12:55:34 -07002567 hdd_enter_dev(adapter->dev);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002568 hdd_debug("Start_adapter for mode : %d", adapter->device_mode);
Arun Khandavallifae92942016-08-01 13:31:08 +05302569
2570 switch (device_mode) {
2571 case QDF_P2P_CLIENT_MODE:
2572 case QDF_P2P_DEVICE_MODE:
2573 case QDF_OCB_MODE:
2574 case QDF_STA_MODE:
2575 case QDF_MONITOR_MODE:
2576 ret = hdd_start_station_adapter(adapter);
2577 if (ret)
2578 goto err_start_adapter;
Alok Kumar81e1d732018-09-04 11:10:36 +05302579
2580 hdd_nud_ignore_tracking(adapter, false);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05302581 hdd_mic_enable_work(adapter);
Arun Khandavallifae92942016-08-01 13:31:08 +05302582 break;
2583 case QDF_P2P_GO_MODE:
2584 case QDF_SAP_MODE:
2585 ret = hdd_start_ap_adapter(adapter);
2586 if (ret)
2587 goto err_start_adapter;
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05302588 hdd_mic_enable_work(adapter);
Arun Khandavallifae92942016-08-01 13:31:08 +05302589 break;
Arun Khandavallib2f6c262016-08-18 19:07:19 +05302590 case QDF_IBSS_MODE:
2591 /*
2592 * For IBSS interface is initialized as part of
2593 * hdd_init_station_mode()
2594 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08002595 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302596 case QDF_FTM_MODE:
Dustin Browndb2a8be2017-12-20 11:49:56 -08002597 /* vdevs are dynamically managed by firmware in FTM */
Arun Kumar Khandavallif573e062019-04-16 17:17:40 +05302598 hdd_register_wext(adapter->dev);
Dustin Browndb2a8be2017-12-20 11:49:56 -08002599 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302600 default:
2601 hdd_err("Invalid session type %d", device_mode);
2602 QDF_ASSERT(0);
2603 goto err_start_adapter;
2604 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08002605
Arun Khandavallifae92942016-08-01 13:31:08 +05302606 if (hdd_set_fw_params(adapter))
2607 hdd_err("Failed to set the FW params for the adapter!");
2608
Jeff Johnson912b1bb2019-03-06 10:12:36 -08002609 if (adapter->vdev_id != WLAN_UMAC_VDEV_ID_MAX) {
Dustin Browne7e71d32018-05-11 16:00:08 -07002610 ret = wlan_hdd_cfg80211_register_frames(adapter);
2611 if (ret < 0) {
2612 hdd_err("Failed to register frames - ret %d", ret);
2613 goto err_start_adapter;
2614 }
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302615 }
Dustin Browne7e71d32018-05-11 16:00:08 -07002616
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002617 wlan_hdd_update_dbs_scan_and_fw_mode_config();
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302618
Dustin Browndb2a8be2017-12-20 11:49:56 -08002619exit_with_success:
Dustin Browne74003f2018-03-14 12:51:58 -07002620 hdd_exit();
Dustin Browndb2a8be2017-12-20 11:49:56 -08002621
Arun Khandavallifae92942016-08-01 13:31:08 +05302622 return 0;
Dustin Browndb2a8be2017-12-20 11:49:56 -08002623
Arun Khandavallifae92942016-08-01 13:31:08 +05302624err_start_adapter:
2625 return -EINVAL;
2626}
2627
2628/**
Komal Seelamf2136bb2016-09-28 18:30:44 +05302629 * hdd_enable_power_management() - API to Enable Power Management
2630 *
2631 * API invokes Bus Interface Layer power management functionality
2632 *
2633 * Return: None
2634 */
2635static void hdd_enable_power_management(void)
2636{
2637 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2638
2639 if (!hif_ctx) {
2640 hdd_err("Bus Interface Context is Invalid");
2641 return;
2642 }
2643
2644 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
2645}
2646
2647/**
2648 * hdd_disable_power_management() - API to disable Power Management
2649 *
2650 * API disable Bus Interface Layer Power management functionality
2651 *
2652 * Return: None
2653 */
2654static void hdd_disable_power_management(void)
2655{
2656 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2657
2658 if (!hif_ctx) {
2659 hdd_err("Bus Interface Context is Invalid");
2660 return;
2661 }
2662
2663 hif_disable_power_management(hif_ctx);
2664}
2665
Ryan Hsuaadba072018-04-20 13:01:53 -07002666void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx)
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302667{
2668 void *hif_sc;
Dustin Brown6f17a022017-07-19 13:40:55 -07002669 size_t target_hw_name_len;
2670 const char *target_hw_name;
Ryan Hsuaadba072018-04-20 13:01:53 -07002671 uint8_t *buf;
2672 uint32_t buf_len;
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302673
2674 hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
2675 if (!hif_sc) {
2676 hdd_err("HIF context is NULL");
2677 return;
2678 }
2679
Ryan Hsuaadba072018-04-20 13:01:53 -07002680 hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302681 &hdd_ctx->target_hw_revision,
Dustin Brown6f17a022017-07-19 13:40:55 -07002682 &target_hw_name);
2683
2684 if (hdd_ctx->target_hw_name)
2685 qdf_mem_free(hdd_ctx->target_hw_name);
2686
2687 target_hw_name_len = strlen(target_hw_name) + 1;
2688 hdd_ctx->target_hw_name = qdf_mem_malloc(target_hw_name_len);
2689 if (hdd_ctx->target_hw_name)
2690 qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name,
2691 target_hw_name_len);
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302692
Ryan Hsuaadba072018-04-20 13:01:53 -07002693 buf = qdf_mem_malloc(WE_MAX_STR_LEN);
2694 if (buf) {
2695 buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf);
2696 hdd_info("%s", buf);
2697 qdf_mem_free(buf);
2698 }
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302699}
2700
2701/**
gbian62edd7e2017-03-07 13:12:13 +08002702 * hdd_update_cds_ac_specs_params() - update cds ac_specs params
2703 * @hdd_ctx: Pointer to hdd context
2704 *
2705 * Return: none
2706 */
2707static void
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002708hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx)
gbian62edd7e2017-03-07 13:12:13 +08002709{
jitiphil8e15ea62018-11-16 18:05:34 +05302710 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM] = {0};
2711 qdf_size_t out_size = 0;
gbian62edd7e2017-03-07 13:12:13 +08002712 int i;
Jeff Johnson2b6982c2018-05-29 14:56:11 -07002713 struct cds_context *cds_ctx;
gbian62edd7e2017-03-07 13:12:13 +08002714
Jeff Johnsond36fa332019-03-18 13:42:25 -07002715 if (!hdd_ctx)
gbian62edd7e2017-03-07 13:12:13 +08002716 return;
2717
Jeff Johnsond36fa332019-03-18 13:42:25 -07002718 if (!hdd_ctx->config) {
gbian62edd7e2017-03-07 13:12:13 +08002719 /* Do nothing if hdd_ctx is invalid */
2720 hdd_err("%s: Warning: hdd_ctx->cfg_ini is NULL", __func__);
2721 return;
2722 }
2723
2724 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2725
2726 if (!cds_ctx) {
2727 hdd_err("Invalid CDS Context");
2728 return;
2729 }
2730
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002731 for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
gbian62edd7e2017-03-07 13:12:13 +08002732 switch (i) {
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002733 case QCA_WLAN_AC_BE:
jitiphil8e15ea62018-11-16 18:05:34 +05302734 qdf_uint8_array_parse(
2735 cfg_get(hdd_ctx->psoc,
2736 CFG_DP_ENABLE_TX_SCHED_WRR_BE),
2737 tx_sched_wrr_param,
2738 sizeof(tx_sched_wrr_param),
2739 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002740 break;
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002741 case QCA_WLAN_AC_BK:
jitiphil8e15ea62018-11-16 18:05:34 +05302742 qdf_uint8_array_parse(
2743 cfg_get(hdd_ctx->psoc,
2744 CFG_DP_ENABLE_TX_SCHED_WRR_BK),
2745 tx_sched_wrr_param,
2746 sizeof(tx_sched_wrr_param),
2747 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002748 break;
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002749 case QCA_WLAN_AC_VI:
jitiphil8e15ea62018-11-16 18:05:34 +05302750 qdf_uint8_array_parse(
2751 cfg_get(hdd_ctx->psoc,
2752 CFG_DP_ENABLE_TX_SCHED_WRR_VI),
2753 tx_sched_wrr_param,
2754 sizeof(tx_sched_wrr_param),
2755 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002756 break;
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002757 case QCA_WLAN_AC_VO:
jitiphil8e15ea62018-11-16 18:05:34 +05302758 qdf_uint8_array_parse(
2759 cfg_get(hdd_ctx->psoc,
2760 CFG_DP_ENABLE_TX_SCHED_WRR_VO),
2761 tx_sched_wrr_param,
2762 sizeof(tx_sched_wrr_param),
2763 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002764 break;
2765 default:
gbian62edd7e2017-03-07 13:12:13 +08002766 break;
2767 }
2768
jitiphil8e15ea62018-11-16 18:05:34 +05302769 if (out_size == TX_SCHED_WRR_PARAMS_NUM) {
gbian62edd7e2017-03-07 13:12:13 +08002770 cds_ctx->ac_specs[i].wrr_skip_weight =
2771 tx_sched_wrr_param[0];
2772 cds_ctx->ac_specs[i].credit_threshold =
2773 tx_sched_wrr_param[1];
2774 cds_ctx->ac_specs[i].send_limit =
2775 tx_sched_wrr_param[2];
2776 cds_ctx->ac_specs[i].credit_reserve =
2777 tx_sched_wrr_param[3];
2778 cds_ctx->ac_specs[i].discard_weight =
2779 tx_sched_wrr_param[4];
2780 }
2781
jitiphil8e15ea62018-11-16 18:05:34 +05302782 out_size = 0;
gbian62edd7e2017-03-07 13:12:13 +08002783 }
2784}
2785
Ryan Hsuaadba072018-04-20 13:01:53 -07002786uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx,
2787 const size_t version_len, uint8_t *version)
2788{
2789 uint32_t size;
Sourav Mohapatra939e0742019-07-26 09:07:18 +05302790 uint8_t reg_major = 0, reg_minor = 0, bdf_major = 0, bdf_minor = 0;
2791 struct target_psoc_info *tgt_hdl;
Ryan Hsuaadba072018-04-20 13:01:53 -07002792
2793 if (!hdd_ctx) {
2794 hdd_err("Invalid context, HDD context is null");
2795 return 0;
2796 }
2797
Ashish Kumar Dhanotiya7353f882018-05-15 12:50:19 +05302798 if (!version || version_len == 0) {
Ryan Hsuaadba072018-04-20 13:01:53 -07002799 hdd_err("Invalid buffer pointr or buffer len\n");
2800 return 0;
2801 }
Sourav Mohapatra939e0742019-07-26 09:07:18 +05302802 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
2803 if (tgt_hdl)
2804 target_psoc_get_version_info(tgt_hdl, &reg_major, &reg_minor,
2805 &bdf_major, &bdf_minor);
Ryan Hsuaadba072018-04-20 13:01:53 -07002806
Ryan Hsuaadba072018-04-20 13:01:53 -07002807 size = scnprintf(version, version_len,
Sourav Mohapatra939e0742019-07-26 09:07:18 +05302808 "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 -07002809 QWLAN_VERSIONSTR,
Ashish Kumar Dhanotiyaeadb28b2019-06-28 14:34:19 +05302810 hdd_ctx->fw_version_info.major_spid,
2811 hdd_ctx->fw_version_info.minor_spid,
2812 hdd_ctx->fw_version_info.siid,
2813 hdd_ctx->fw_version_info.rel_id,
2814 hdd_ctx->fw_version_info.crmid,
2815 hdd_ctx->fw_version_info.sub_id,
Ryan Hsuc6918552018-05-16 13:29:59 -07002816 hdd_ctx->target_hw_name,
2817 hdd_ctx->hw_bd_info.bdf_version,
2818 hdd_ctx->hw_bd_info.ref_design_id,
2819 hdd_ctx->hw_bd_info.customer_id,
2820 hdd_ctx->hw_bd_info.project_id,
Sourav Mohapatra939e0742019-07-26 09:07:18 +05302821 hdd_ctx->hw_bd_info.board_data_rev,
2822 reg_major, reg_minor, bdf_major, bdf_minor);
Ryan Hsuaadba072018-04-20 13:01:53 -07002823
2824 return size;
2825}
2826
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302827int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value,
2828 struct sap_config *sap_config)
2829{
2830 uint8_t preamble = 0, nss = 0, rix = 0;
2831 int ret;
2832 mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
2833
2834 if (!sap_config) {
2835 if (!sme_is_feature_supported_by_fw(DOT11AX)) {
2836 hdd_err("Target does not support 11ax");
2837 return -EIO;
2838 }
2839 } else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax &&
2840 sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) {
Kiran Kumar Lokere229212a2019-08-20 19:03:30 -07002841 hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch_freq = %d",
2842 sap_config->SapHw_mode, sap_config->chan_freq);
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302843 return -EIO;
2844 }
2845
2846 if (set_value != 0xff) {
2847 rix = RC_2_RATE_IDX_11AX(set_value);
2848 preamble = WMI_RATE_PREAMBLE_HE;
2849 nss = HT_RC_2_STREAMS_11AX(set_value);
2850
2851 set_value = hdd_assemble_rate_code(preamble, nss, rix);
2852 } else {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08002853 ret = sme_set_auto_rate_he_ltf(mac_handle, adapter->vdev_id,
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302854 QCA_WLAN_HE_LTF_AUTO);
2855 }
2856
2857 hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d",
2858 set_value, rix, preamble, nss);
2859
Jeff Johnson5a6fc962019-02-04 14:20:25 -08002860 ret = wma_cli_set_command(adapter->vdev_id,
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302861 WMI_VDEV_PARAM_FIXED_RATE,
2862 set_value, VDEV_CMD);
2863
2864 return ret;
2865}
2866
2867int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate)
2868{
2869 int set_value;
2870
2871 if (sme_is_feature_supported_by_fw(DOT11AX))
2872 set_value = WMI_ASSEMBLE_RATECODE_V1(rate, nss, preamble);
2873 else
2874 set_value = (preamble << 6) | (nss << 4) | rate;
2875
2876 return set_value;
2877}
2878
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002879#ifdef FEATURE_WLAN_WAPI
2880/**
2881 * hdd_wapi_security_sta_exist() - return wapi security sta exist or not
2882 *
2883 * This API returns the wapi security station exist or not
2884 *
2885 * Return: true - wapi security station exist
2886 */
2887static bool hdd_wapi_security_sta_exist(void)
2888{
2889 struct hdd_adapter *adapter = NULL;
2890 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2891
2892 hdd_for_each_adapter(hdd_ctx, adapter) {
2893 if ((adapter->device_mode == QDF_STA_MODE) &&
2894 adapter->wapi_info.wapi_mode &&
2895 (adapter->wapi_info.wapi_auth_mode != WAPI_AUTH_MODE_OPEN))
2896 return true;
2897 }
2898 return false;
2899}
2900#else
2901static bool hdd_wapi_security_sta_exist(void)
2902{
2903 return false;
2904}
2905#endif
2906
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002907#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002908static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
2909 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
2910{
Jeff Johnson9d295242017-08-29 14:39:48 -07002911 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002912 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002913
2914 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2915 if (!adapter) {
2916 hdd_err("Adapter is NULL");
2917 return PM_MAX_NUM_OF_MODE;
2918 }
2919
2920 return policy_mgr_convert_device_mode_to_qdf_type(
2921 adapter->device_mode);
2922}
2923
Abhishek Singh3bbf6cb2019-03-28 14:05:43 +05302924/**
2925 * hdd_is_chan_switch_in_progress() - Check if any adapter has channel switch in
2926 * progress
2927 *
2928 * Return: true, if any adapter has channel switch in
2929 * progress else false
2930 */
2931static bool hdd_is_chan_switch_in_progress(void)
2932{
2933 struct hdd_adapter *adapter = NULL;
2934 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2935
2936 hdd_for_each_adapter(hdd_ctx, adapter) {
2937 if ((adapter->device_mode == QDF_SAP_MODE ||
2938 adapter->device_mode == QDF_P2P_GO_MODE) &&
2939 qdf_atomic_read(&adapter->ch_switch_in_progress)) {
2940 hdd_debug("channel switch progress for vdev_id %d",
2941 adapter->vdev_id);
2942 return true;
2943 }
2944 }
2945
2946 return false;
2947}
2948
2949
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002950static void hdd_register_policy_manager_callback(
2951 struct wlan_objmgr_psoc *psoc)
2952{
2953 struct policy_mgr_hdd_cbacks hdd_cbacks;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07002954
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002955 qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks));
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002956 hdd_cbacks.sap_restart_chan_switch_cb =
Jeff Johnson23812942017-10-06 11:33:55 -07002957 hdd_sap_restart_chan_switch_cb;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002958 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
2959 wlan_hdd_get_channel_for_sap_restart;
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002960 hdd_cbacks.get_mode_for_non_connected_vdev =
2961 wlan_hdd_get_mode_for_non_connected_vdev;
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05302962 hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode;
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002963 hdd_cbacks.hdd_wapi_security_sta_exist =
2964 hdd_wapi_security_sta_exist;
Abhishek Singh3bbf6cb2019-03-28 14:05:43 +05302965 hdd_cbacks.hdd_is_chan_switch_in_progress =
2966 hdd_is_chan_switch_in_progress;
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +05302967 hdd_cbacks.wlan_hdd_set_sap_csa_reason =
2968 wlan_hdd_set_sap_csa_reason;
Abhishek Singh3bbf6cb2019-03-28 14:05:43 +05302969
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002970 if (QDF_STATUS_SUCCESS !=
2971 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
2972 hdd_err("HDD callback registration with policy manager failed");
2973 }
2974}
2975#else
2976static void hdd_register_policy_manager_callback(
2977 struct wlan_objmgr_psoc *psoc)
2978{
2979}
2980#endif
2981
Nachiket Kukade2fb1fdb2019-01-08 15:35:27 +05302982#ifdef WLAN_FEATURE_NAN
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002983static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002984{
2985 struct nan_callbacks cb_obj = {0};
2986
2987 cb_obj.ndi_open = hdd_ndi_open;
2988 cb_obj.ndi_close = hdd_ndi_close;
2989 cb_obj.ndi_start = hdd_ndi_start;
2990 cb_obj.ndi_delete = hdd_ndi_delete;
2991 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
2992 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
2993
Naveen Rawat37f62c82017-03-26 22:24:43 -07002994 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002995 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
Naveen Rawat37f62c82017-03-26 22:24:43 -07002996
Dustin Brown1dbefe62018-09-11 16:32:03 -07002997 os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002998}
jiadff1ac132018-11-26 16:27:48 +08002999#else
3000static inline void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
3001{
3002}
3003#endif
Naveen Rawatcb5c5402017-03-22 10:12:19 -07003004
Dustin Brown26b3d042017-12-21 11:13:27 -08003005#ifdef CONFIG_LEAK_DETECTION
Dustin Brown4c5b9902017-12-19 11:17:19 -08003006/**
3007 * hdd_check_for_leaks() - Perform runtime memory leak checks
Dustin Browna6246dd2018-05-24 14:35:58 -07003008 * @hdd_ctx: the global HDD context
Dustin Brown29533f22018-07-24 13:11:56 -07003009 * @is_ssr: true if SSR is in progress
Dustin Brown4c5b9902017-12-19 11:17:19 -08003010 *
3011 * This API triggers runtime memory leak detection. This feature enforces the
3012 * policy that any memory allocated at runtime must also be released at runtime.
3013 *
3014 * Allocating memory at runtime and releasing it at unload is effectively a
3015 * memory leak for configurations which never unload (e.g. LONU, statically
3016 * compiled driver). Such memory leaks are NOT false positives, and must be
3017 * fixed.
3018 *
3019 * Return: None
3020 */
Dustin Brown29533f22018-07-24 13:11:56 -07003021static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
Dustin Brown4bc0a622017-12-06 15:56:50 -08003022{
Dustin Brown4c5b9902017-12-19 11:17:19 -08003023 /* DO NOT REMOVE these checks; for false positives, read above first */
3024
Dustin Brown1dbefe62018-09-11 16:32:03 -07003025 wlan_objmgr_psoc_check_for_peer_leaks(hdd_ctx->psoc);
3026 wlan_objmgr_psoc_check_for_vdev_leaks(hdd_ctx->psoc);
3027 wlan_objmgr_psoc_check_for_pdev_leaks(hdd_ctx->psoc);
Dustin Brown29533f22018-07-24 13:11:56 -07003028
3029 /* many adapter resources are not freed by design during SSR */
3030 if (is_ssr)
3031 return;
3032
Dustin Brownc2796312019-03-13 16:43:36 -07003033 qdf_delayed_work_check_for_leaks();
Dustin Brown677e0862017-10-10 16:30:09 -07003034 qdf_mc_timer_check_for_leaks();
Dustin Brown8e711502017-12-07 16:49:11 -08003035 qdf_nbuf_map_check_for_leaks();
Dustin Brown4a93bb52019-03-13 11:46:34 -07003036 qdf_periodic_work_check_for_leaks();
Dustin Browne6b9d5a2017-12-14 15:18:49 -08003037 qdf_mem_check_for_leaks();
Dustin Brown4bc0a622017-12-06 15:56:50 -08003038}
3039
Dustin Brown26b3d042017-12-21 11:13:27 -08003040#define hdd_debug_domain_set(domain) qdf_debug_domain_set(domain)
3041#else
Dustin Brown29533f22018-07-24 13:11:56 -07003042static inline void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
3043{ }
Dustin Brown26b3d042017-12-21 11:13:27 -08003044
3045#define hdd_debug_domain_set(domain)
3046#endif /* CONFIG_LEAK_DETECTION */
3047
Lin Bai56386f52019-08-08 13:58:23 +08003048#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
3049/**
3050 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
3051 * @data: pointer to struct hdd_context
3052 *
3053 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
3054 * Then new ACS request will do a fresh scan without reusing the cached
3055 * scan information.
3056 *
3057 * Return: void
3058 */
3059static void hdd_skip_acs_scan_timer_handler(void *data)
3060{
3061 struct hdd_context *hdd_ctx = data;
3062 mac_handle_t mac_handle;
3063
3064 hdd_debug("ACS Scan result expired. Reset ACS scan skip");
3065 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
3066 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
Lin Bai96f66092019-08-20 11:23:14 +08003067 qdf_mem_free(hdd_ctx->last_acs_freq_list);
3068 hdd_ctx->last_acs_freq_list = NULL;
Lin Bai56386f52019-08-08 13:58:23 +08003069 hdd_ctx->num_of_channels = 0;
3070 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
3071
3072 mac_handle = hdd_ctx->mac_handle;
3073 if (!mac_handle)
3074 return;
3075}
3076
3077static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx)
3078{
3079 QDF_STATUS status;
3080
3081 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
3082 QDF_TIMER_TYPE_SW,
3083 hdd_skip_acs_scan_timer_handler,
3084 hdd_ctx);
3085 if (QDF_IS_STATUS_ERROR(status))
3086 hdd_err("Failed to init ACS Skip timer");
3087 qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
3088}
3089
3090static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx)
3091{
3092 if (QDF_TIMER_STATE_RUNNING ==
3093 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
3094 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
3095 }
3096
3097 if (!QDF_IS_STATUS_SUCCESS
3098 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
3099 hdd_err("Cannot deallocate ACS Skip timer");
3100 }
3101 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
Lin Bai96f66092019-08-20 11:23:14 +08003102 qdf_mem_free(hdd_ctx->last_acs_freq_list);
3103 hdd_ctx->last_acs_freq_list = NULL;
Lin Bai56386f52019-08-08 13:58:23 +08003104 hdd_ctx->num_of_channels = 0;
3105 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
3106}
3107#else
3108static void hdd_skip_acs_scan_timer_init(struct hdd_context *hdd_ctx) {}
3109static void hdd_skip_acs_scan_timer_deinit(struct hdd_context *hdd_ctx) {}
3110#endif
3111
gbian62edd7e2017-03-07 13:12:13 +08003112/**
Paul Zhange03cf4c2018-01-19 18:33:22 +08003113 * hdd_update_country_code - Update country code
3114 * @hdd_ctx: HDD context
3115 *
3116 * Update country code based on module parameter country_code
3117 *
3118 * Return: 0 on success and errno on failure
3119 */
3120static int hdd_update_country_code(struct hdd_context *hdd_ctx)
3121{
3122 if (!country_code)
3123 return 0;
3124
3125 return hdd_reg_set_country(hdd_ctx, country_code);
3126}
3127
Dustin Browne7e71d32018-05-11 16:00:08 -07003128int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
Arun Khandavallifae92942016-08-01 13:31:08 +05303129{
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07003130 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05303131 qdf_device_t qdf_dev;
3132 QDF_STATUS status;
Arun Khandavallifae92942016-08-01 13:31:08 +05303133 bool unint = false;
3134 void *hif_ctx;
3135
Arun Khandavallifae92942016-08-01 13:31:08 +05303136 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
3137 if (!qdf_dev) {
3138 hdd_err("QDF Device Context is Invalid return");
3139 return -EINVAL;
3140 }
3141
Dustin Brown4c663222018-10-23 14:19:36 -07003142 hdd_psoc_idle_timer_stop(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303143
Arun Khandavalli5a62a822017-11-14 19:43:00 +05303144 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07003145 hdd_debug("Driver modules already Enabled");
Dustin Browne74003f2018-03-14 12:51:58 -07003146 hdd_exit();
Arun Khandavalli5a62a822017-11-14 19:43:00 +05303147 return 0;
3148 }
3149
Arun Khandavallifae92942016-08-01 13:31:08 +05303150 switch (hdd_ctx->driver_status) {
3151 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown550f6d22017-12-14 15:44:01 -08003152 hdd_info("Wlan transitioning (UNINITIALIZED -> CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +05303153 unint = true;
3154 /* Fall through dont add break here */
3155 case DRIVER_MODULES_CLOSED:
Dustin Brown1a20b082018-08-03 17:27:15 -07003156 hdd_info("Wlan transitioning (CLOSED -> ENABLED)");
Dustin Brown550f6d22017-12-14 15:44:01 -08003157
Dustin Brown26b3d042017-12-21 11:13:27 -08003158 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
Dustin Brown4bc0a622017-12-06 15:56:50 -08003159
Arun Khandavallifae92942016-08-01 13:31:08 +05303160 if (!reinit && !unint) {
3161 ret = pld_power_on(qdf_dev->dev);
3162 if (ret) {
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07003163 hdd_err("Failed to power up device; errno:%d",
Dustin Browndca39692017-11-09 15:30:25 -08003164 ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05303165 goto release_lock;
3166 }
3167 }
Yuanyuan Liuf8fe4bc2017-06-07 16:55:58 -07003168
3169 pld_set_fw_log_mode(hdd_ctx->parent_dev,
3170 hdd_ctx->config->enable_fw_log);
Arun Khandavallifae92942016-08-01 13:31:08 +05303171 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
3172 qdf_dev->bus_type,
3173 (reinit == true) ? HIF_ENABLE_TYPE_REINIT :
3174 HIF_ENABLE_TYPE_PROBE);
3175 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08003176 hdd_err("Failed to open hif; errno: %d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05303177 goto power_down;
3178 }
3179
3180 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
Arun Khandavalli1318b992016-08-09 11:04:57 +05303181 if (!hif_ctx) {
3182 hdd_err("hif context is null!!");
Dustin Browndca39692017-11-09 15:30:25 -08003183 ret = -EINVAL;
Arun Khandavalli1318b992016-08-09 11:04:57 +05303184 goto power_down;
3185 }
3186
Arun Khandavallifae92942016-08-01 13:31:08 +05303187 status = ol_cds_init(qdf_dev, hif_ctx);
3188 if (status != QDF_STATUS_SUCCESS) {
Dustin Browndca39692017-11-09 15:30:25 -08003189 hdd_err("No Memory to Create BMI Context; status: %d",
3190 status);
3191 ret = qdf_status_to_os_return(status);
Arun Khandavallifae92942016-08-01 13:31:08 +05303192 goto hif_close;
3193 }
3194
Nirav Shah6aeecf92019-02-13 14:05:03 +05303195 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
3196 status = epping_open();
3197 if (status) {
3198 hdd_err("Failed to open in epping mode: %d",
3199 status);
3200 ret = -EINVAL;
3201 goto cds_free;
3202 }
3203
3204 status = epping_enable(qdf_dev->dev, false);
3205 if (status) {
3206 hdd_err("Failed to enable in epping mode : %d",
3207 status);
3208 epping_close();
3209 goto cds_free;
3210 }
3211
3212 hdd_info("epping mode enabled");
3213 break;
3214 }
3215
jitiphil4c256a32018-09-07 08:51:52 +05303216 ucfg_ipa_component_config_update(hdd_ctx->psoc);
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05303217
gbian62edd7e2017-03-07 13:12:13 +08003218 hdd_update_cds_ac_specs_params(hdd_ctx);
3219
Dustin Brown1dbefe62018-09-11 16:32:03 -07003220 status = hdd_component_psoc_open(hdd_ctx->psoc);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05303221 if (QDF_IS_STATUS_ERROR(status)) {
3222 hdd_err("Failed to Open legacy components; status: %d",
3223 status);
3224 ret = qdf_status_to_os_return(status);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05303225 goto cds_free;
3226 }
3227
3228 ret = hdd_update_config(hdd_ctx);
3229 if (ret) {
3230 hdd_err("Failed to update configuration; errno: %d",
3231 ret);
3232 goto cds_free;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05303233 }
3234
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +05303235 status = wbuff_module_init();
3236 if (QDF_IS_STATUS_ERROR(status))
3237 hdd_err("WBUFF init unsuccessful; status: %d", status);
3238
Dustin Brown1dbefe62018-09-11 16:32:03 -07003239 status = cds_open(hdd_ctx->psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07003240 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08003241 hdd_err("Failed to Open CDS; status: %d", status);
Dustin Brown28b17892017-10-10 13:29:38 -07003242 ret = qdf_status_to_os_return(status);
Krunal Sonie71838d2018-09-27 10:45:05 -07003243 goto psoc_close;
Arun Khandavallifae92942016-08-01 13:31:08 +05303244 }
3245
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +05303246 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
3247
Manjunathappa Prakashb6b4ff12018-06-04 12:32:33 -07003248 if (hdd_ctx->config->rx_thread_affinity_mask)
3249 cds_set_rx_thread_cpu_mask(
3250 hdd_ctx->config->rx_thread_affinity_mask);
3251
3252 /* initialize components configurations after psoc open */
Mukul Sharma9d797a02017-01-05 20:26:03 +05303253 ret = hdd_update_components_config(hdd_ctx);
3254 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08003255 hdd_err("Failed to update component configs; errno: %d",
Mukul Sharma9d797a02017-01-05 20:26:03 +05303256 ret);
3257 goto close;
3258 }
Sourav Mohapatra674925f2018-04-16 11:16:58 +05303259
Dustin Brown1dbefe62018-09-11 16:32:03 -07003260 status = cds_dp_open(hdd_ctx->psoc);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003261 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08003262 hdd_err("Failed to Open cds post open; status: %d",
3263 status);
3264 ret = qdf_status_to_os_return(status);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003265 goto close;
3266 }
Mukul Sharma9d797a02017-01-05 20:26:03 +05303267
Sourav Mohapatra674925f2018-04-16 11:16:58 +05303268 ret = hdd_register_cb(hdd_ctx);
3269 if (ret) {
3270 hdd_err("Failed to register HDD callbacks!");
3271 goto cds_txrx_free;
3272 }
3273
Naveen Rawatcb5c5402017-03-22 10:12:19 -07003274 /*
3275 * NAN compoenet requires certian operations like, open adapter,
3276 * close adapter, etc. to be initiated by HDD, for those
3277 * register HDD callbacks with UMAC's NAN componenet.
3278 */
3279 hdd_nan_register_callbacks(hdd_ctx);
3280
Jeff Johnson3a280122017-09-13 07:42:00 -07003281 status = cds_pre_enable();
Arun Khandavallifae92942016-08-01 13:31:08 +05303282 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08003283 hdd_err("Failed to pre-enable CDS; status: %d", status);
3284 ret = qdf_status_to_os_return(status);
Sourav Mohapatra674925f2018-04-16 11:16:58 +05303285 goto deregister_cb;
Arun Khandavallifae92942016-08-01 13:31:08 +05303286 }
3287
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07003288 hdd_register_policy_manager_callback(
Dustin Brown1dbefe62018-09-11 16:32:03 -07003289 hdd_ctx->psoc);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07003290
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05303291 hdd_sysfs_create_driver_root_obj();
Dustin Brown1dbefe62018-09-11 16:32:03 -07003292 hdd_sysfs_create_version_interface(hdd_ctx->psoc);
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05303293 hdd_sysfs_create_powerstats_interface();
Arunk Khandavalli67193d52017-02-21 12:03:48 +05303294 hdd_update_hw_sw_info(hdd_ctx);
Dustin Brown550f6d22017-12-14 15:44:01 -08003295
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05303296 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
Mahesh Kumar Kalikot Veetil59a9a782019-07-16 16:05:11 -07003297 hdd_enable_power_management();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05303298 hdd_err("in ftm mode, no need to configure cds modules");
Dustin Browndca39692017-11-09 15:30:25 -08003299 ret = -EINVAL;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05303300 break;
3301 }
Dustin Browndca39692017-11-09 15:30:25 -08003302
Dustin Browne7e71d32018-05-11 16:00:08 -07003303 ret = hdd_configure_cds(hdd_ctx);
Dustin Browndca39692017-11-09 15:30:25 -08003304 if (ret) {
3305 hdd_err("Failed to Enable cds modules; errno: %d", ret);
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05303306 goto destroy_driver_sysfs;
Arun Khandavallifae92942016-08-01 13:31:08 +05303307 }
Dustin Browndca39692017-11-09 15:30:25 -08003308
Komal Seelamf2136bb2016-09-28 18:30:44 +05303309 hdd_enable_power_management();
Dustin Brown550f6d22017-12-14 15:44:01 -08003310
Lin Bai56386f52019-08-08 13:58:23 +08003311 hdd_skip_acs_scan_timer_init(hdd_ctx);
3312
Arun Khandavallifae92942016-08-01 13:31:08 +05303313 break;
Dustin Brown550f6d22017-12-14 15:44:01 -08003314
Arun Khandavallifae92942016-08-01 13:31:08 +05303315 default:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07003316 QDF_DEBUG_PANIC("Unknown driver state:%d",
Arun Khandavallifae92942016-08-01 13:31:08 +05303317 hdd_ctx->driver_status);
Dustin Browndca39692017-11-09 15:30:25 -08003318 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05303319 goto release_lock;
3320 }
Dustin Brown550f6d22017-12-14 15:44:01 -08003321
Dustin Brown1a20b082018-08-03 17:27:15 -07003322 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
3323 hdd_info("Wlan transitioned (now ENABLED)");
3324
Dustin Browne74003f2018-03-14 12:51:58 -07003325 hdd_exit();
Dustin Brown550f6d22017-12-14 15:44:01 -08003326
Arun Khandavallifae92942016-08-01 13:31:08 +05303327 return 0;
3328
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05303329destroy_driver_sysfs:
3330 hdd_sysfs_destroy_powerstats_interface();
3331 hdd_sysfs_destroy_version_interface();
3332 hdd_sysfs_destroy_driver_root_obj();
Rajeev Kumarbe021242017-02-16 16:12:23 -08003333 cds_post_disable();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003334
Sourav Mohapatra674925f2018-04-16 11:16:58 +05303335deregister_cb:
3336 hdd_deregister_cb(hdd_ctx);
3337
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003338cds_txrx_free:
Jingxiang Ge95912f82018-04-19 12:01:26 +08003339
Jingxiang Geaaded482019-09-11 20:02:37 +08003340 hdd_runtime_suspend_context_deinit(hdd_ctx);
3341 if (hdd_ctx->pdev) {
Dustin Brown07901ec2018-09-07 11:02:41 -07003342 dispatcher_pdev_close(hdd_ctx->pdev);
Jingxiang Ge95912f82018-04-19 12:01:26 +08003343 hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
3344 }
3345
Dustin Brown1dbefe62018-09-11 16:32:03 -07003346 cds_dp_close(hdd_ctx->psoc);
Dustin Brown550f6d22017-12-14 15:44:01 -08003347
Arun Khandavallifae92942016-08-01 13:31:08 +05303348close:
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003349 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -08003350 hdd_info("Wlan transition aborted (now CLOSED)");
3351
Dustin Brown1dbefe62018-09-11 16:32:03 -07003352 cds_close(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +05303353
Krunal Sonie71838d2018-09-27 10:45:05 -07003354psoc_close:
Dustin Brown1dbefe62018-09-11 16:32:03 -07003355 hdd_component_psoc_close(hdd_ctx->psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07003356 cds_deinit_ini_config();
3357
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003358cds_free:
Arun Khandavallifae92942016-08-01 13:31:08 +05303359 ol_cds_free();
3360
3361hif_close:
Jeff Johnson60dc2b12017-09-28 14:56:02 -07003362 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
3363 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303364power_down:
3365 if (!reinit && !unint)
3366 pld_power_off(qdf_dev->dev);
3367release_lock:
Abhinav Kumar7ae9b7b2017-12-19 15:11:54 +05303368 if (hdd_ctx->target_hw_name) {
3369 qdf_mem_free(hdd_ctx->target_hw_name);
3370 hdd_ctx->target_hw_name = NULL;
3371 }
Dustin Brown29533f22018-07-24 13:11:56 -07003372
3373 hdd_check_for_leaks(hdd_ctx, reinit);
Dustin Brown26b3d042017-12-21 11:13:27 -08003374 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -08003375
Dustin Browne74003f2018-03-14 12:51:58 -07003376 hdd_exit();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003377
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07003378 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05303379}
3380
Naveen Rawat910726a2017-03-06 11:42:51 -08003381#ifdef WIFI_POS_CONVERGED
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003382static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003383{
3384 int ret = os_if_wifi_pos_register_nl();
3385
3386 if (ret)
3387 hdd_err("os_if_wifi_pos_register_nl failed");
3388
3389 return ret;
3390}
3391
3392static int hdd_deactivate_wifi_pos(void)
3393{
3394 int ret = os_if_wifi_pos_deregister_nl();
3395
3396 if (ret)
3397 hdd_err("os_if_wifi_pos_deregister_nl failed");
3398
3399 return ret;
3400}
3401
3402/**
3403 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
3404 * @hdd_ctx: hdd context
3405 *
3406 * Return: status of operation
3407 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003408static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003409{
Dustin Brown1dbefe62018-09-11 16:32:03 -07003410 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Wu Gao1ab05582018-11-08 16:22:49 +08003411 uint16_t neighbor_scan_max_chan_time;
3412 uint16_t neighbor_scan_min_chan_time;
Naveen Rawat910726a2017-03-06 11:42:51 -08003413
3414 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
3415 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
3416 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
3417 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
3418 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
3419 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
Wu Gao1ab05582018-11-08 16:22:49 +08003420 ucfg_mlme_get_neighbor_scan_max_chan_time(psoc,
3421 &neighbor_scan_max_chan_time);
3422 ucfg_mlme_get_neighbor_scan_min_chan_time(psoc,
3423 &neighbor_scan_min_chan_time);
3424 wifi_pos_set_dwell_time_min(psoc, neighbor_scan_min_chan_time);
3425 wifi_pos_set_dwell_time_max(psoc, neighbor_scan_max_chan_time);
Naveen Rawat910726a2017-03-06 11:42:51 -08003426}
3427#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003428static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003429{
3430 return oem_activate_service(hdd_ctx);
3431}
3432
3433static int hdd_deactivate_wifi_pos(void)
3434{
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05303435 return oem_deactivate_service();
Naveen Rawat910726a2017-03-06 11:42:51 -08003436}
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{
3440}
3441#endif
3442
Arun Khandavallifae92942016-08-01 13:31:08 +05303443/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003444 * __hdd_open() - HDD Open function
3445 * @dev: Pointer to net_device structure
3446 *
3447 * This is called in response to ifconfig up
3448 *
3449 * Return: 0 for success; non-zero for failure
3450 */
3451static int __hdd_open(struct net_device *dev)
3452{
Jeff Johnson9d295242017-08-29 14:39:48 -07003453 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003454 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003455 int ret;
3456
Dustin Brownfdf17c12018-03-14 12:55:34 -07003457 hdd_enter_dev(dev);
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +05303458
3459 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
3460 TRACE_CODE_HDD_OPEN_REQUEST,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08003461 adapter->vdev_id, adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003462
Ashish Kumar Dhanotiya15a7db52017-08-03 10:27:34 +05303463 /* Nothing to be done if device is unloading */
3464 if (cds_is_driver_unloading()) {
3465 hdd_err("Driver is unloading can not open the hdd");
3466 return -EBUSY;
3467 }
3468
Dustin Brown01847752017-10-25 13:56:27 -07003469 if (cds_is_driver_recovering()) {
3470 hdd_err("WLAN is currently recovering; Please try again.");
3471 return -EBUSY;
3472 }
3473
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303474 /*
3475 * This scenario can be hit in cases where in the wlan driver after
3476 * registering the netdevices and there is a failure in driver
3477 * initialization. So return error gracefully because the netdevices
3478 * will be de-registered as part of the load failure.
3479 */
3480
3481 if (!cds_is_driver_loaded()) {
3482 hdd_err("Failed to start the wlan driver!!");
Dustin Brown3da3a832019-03-19 15:51:54 -07003483 return -EIO;
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303484 }
Abhishek Singh23edd1c2016-05-05 11:56:06 +05303485
Rajeev Kumar473f9af2019-04-05 14:25:56 -07003486 ret = hdd_trigger_psoc_idle_restart(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303487 if (ret) {
3488 hdd_err("Failed to start WLAN modules return");
Dustin Brown3da3a832019-03-19 15:51:54 -07003489 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05303490 }
3491
Arun Khandavallifae92942016-08-01 13:31:08 +05303492 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
3493 ret = hdd_start_adapter(adapter);
3494 if (ret) {
3495 hdd_err("Failed to start adapter :%d",
3496 adapter->device_mode);
Dustin Brown3da3a832019-03-19 15:51:54 -07003497 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05303498 }
3499 }
3500
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003501 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3502 if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003503 hdd_debug("Enabling Tx Queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003504 /* Enable TX queues only when we are connected */
3505 wlan_hdd_netif_queue_control(adapter,
Arun Khandavallifae92942016-08-01 13:31:08 +05303506 WLAN_START_ALL_NETIF_QUEUE,
3507 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003508 }
3509
Naveen Rawat286def52016-09-23 15:38:02 -07003510 /* Enable carrier and transmit queues for NDI */
3511 if (WLAN_HDD_IS_NDI(adapter)) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003512 hdd_debug("Enabling Tx Queues");
Naveen Rawat286def52016-09-23 15:38:02 -07003513 wlan_hdd_netif_queue_control(adapter,
3514 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
3515 WLAN_CONTROL_PATH);
3516 }
3517
Naveen Rawat910726a2017-03-06 11:42:51 -08003518 hdd_populate_wifi_pos_cfg(hdd_ctx);
Arunk Khandavalli40943af2017-05-15 19:25:34 +05303519 hdd_lpass_notify_start(hdd_ctx, adapter);
Naveen Rawat910726a2017-03-06 11:42:51 -08003520
Dustin Brown3da3a832019-03-19 15:51:54 -07003521 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003522}
3523
3524/**
3525 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
Dustin Brown98f7c822019-03-06 12:25:49 -08003526 * @net_dev: Pointer to net_device structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003527 *
3528 * This is called in response to ifconfig up
3529 *
3530 * Return: 0 for success; non-zero for failure
3531 */
Dustin Brown0e1e1622019-01-17 11:00:22 -08003532static int hdd_open(struct net_device *net_dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003533{
Dustin Brown0e1e1622019-01-17 11:00:22 -08003534 int errno;
3535 struct osif_vdev_sync *vdev_sync;
3536
3537 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
3538 if (errno)
3539 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003540
Dustin Brown0e1e1622019-01-17 11:00:22 -08003541 errno = __hdd_open(net_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003542
Dustin Brown0e1e1622019-01-17 11:00:22 -08003543 osif_vdev_sync_trans_stop(vdev_sync);
3544
3545 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003546}
3547
3548/**
3549 * __hdd_stop() - HDD stop function
3550 * @dev: Pointer to net_device structure
3551 *
3552 * This is called in response to ifconfig down
3553 *
3554 * Return: 0 for success; non-zero for failure
3555 */
3556static int __hdd_stop(struct net_device *dev)
3557{
Jeff Johnson9d295242017-08-29 14:39:48 -07003558 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003559 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003560 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -07003561 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003562
Dustin Brownfdf17c12018-03-14 12:55:34 -07003563 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003564
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +05303565 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
3566 TRACE_CODE_HDD_STOP_REQUEST,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08003567 adapter->vdev_id, adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003568
3569 ret = wlan_hdd_validate_context(hdd_ctx);
Arunk Khandavalli987c8d52018-06-21 17:40:31 +05303570 if (ret) {
3571 set_bit(DOWN_DURING_SSR, &adapter->event_flags);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003572 return ret;
Arunk Khandavalli987c8d52018-06-21 17:40:31 +05303573 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003574
3575 /* Nothing to be done if the interface is not opened */
3576 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003577 hdd_err("NETDEV Interface is not OPENED");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003578 return -ENODEV;
3579 }
3580
3581 /* Make sure the interface is marked as closed */
3582 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303583
Jeff Johnson16528362018-06-14 12:34:16 -07003584 mac_handle = hdd_ctx->mac_handle;
3585
Mukul Sharmad16c2022017-07-25 18:56:12 +05303586 hdd_debug("Disabling Auto Power save timer");
3587 sme_ps_disable_auto_ps_timer(
Jeff Johnson16528362018-06-14 12:34:16 -07003588 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08003589 adapter->vdev_id);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303590
3591 /*
3592 * Disable TX on the interface, after this hard_start_xmit() will not
3593 * be called on that interface
3594 */
Dustin Browna7bb6ae2018-08-16 16:51:50 -07003595 hdd_debug("Disabling queues, adapter device mode: %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07003596 qdf_opmode_str(adapter->device_mode), adapter->device_mode);
Kabilan Kannan8dac3502017-10-30 12:40:27 -07003597
Himanshu Agarwal865201d2017-04-12 15:45:31 +05303598 wlan_hdd_netif_queue_control(adapter,
3599 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
3600 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003601
Arunk Khandavalli40943af2017-05-15 19:25:34 +05303602 if (adapter->device_mode == QDF_STA_MODE)
3603 hdd_lpass_notify_stop(hdd_ctx);
3604
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003605 /*
Naveen Rawat286def52016-09-23 15:38:02 -07003606 * NAN data interface is different in some sense. The traffic on NDI is
3607 * bursty in nature and depends on the need to transfer. The service
3608 * layer may down the interface after the usage and up again when
3609 * required. In some sense, the NDI is expected to be available
3610 * (like SAP) iface until NDI delete request is issued by the service
3611 * layer. Skip BSS termination and adapter deletion for NAN Data
3612 * interface (NDI).
3613 */
3614 if (WLAN_HDD_IS_NDI(adapter))
3615 return 0;
3616
3617 /*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003618 * The interface is marked as down for outside world (aka kernel)
3619 * But the driver is pretty much alive inside. The driver needs to
3620 * tear down the existing connection on the netdev (session)
3621 * cleanup the data pipes and wait until the control plane is stabilized
3622 * for this interface. The call also needs to wait until the above
3623 * mentioned actions are completed before returning to the caller.
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003624 * Notice that hdd_stop_adapter is requested not to close the session
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003625 * That is intentional to be able to scan if it is a STA/P2P interface
3626 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08003627 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003628
3629 /* DeInit the adapter. This ensures datapath cleanup as well */
3630 hdd_deinit_adapter(hdd_ctx, adapter, true);
3631
Dustin Brown4c663222018-10-23 14:19:36 -07003632 if (!hdd_is_any_interface_open(hdd_ctx))
3633 hdd_psoc_idle_timer_start(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303634
Dustin Browne74003f2018-03-14 12:51:58 -07003635 hdd_exit();
Dustin Brown4c663222018-10-23 14:19:36 -07003636
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003637 return 0;
3638}
3639
3640/**
3641 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
3642 * @dev: pointer to net_device structure
3643 *
3644 * This is called in response to ifconfig down
3645 *
3646 * Return: 0 for success and error number for failure
3647 */
Dustin Brown0e1e1622019-01-17 11:00:22 -08003648static int hdd_stop(struct net_device *net_dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003649{
Dustin Brown0e1e1622019-01-17 11:00:22 -08003650 int errno;
3651 struct osif_vdev_sync *vdev_sync;
3652
3653 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
3654 if (errno)
3655 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003656
Dustin Brown0e1e1622019-01-17 11:00:22 -08003657 errno = __hdd_stop(net_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003658
Dustin Brown0e1e1622019-01-17 11:00:22 -08003659 osif_vdev_sync_trans_stop(vdev_sync);
3660
3661 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003662}
3663
3664/**
Dustin Brown96b98dd2019-03-06 12:39:37 -08003665 * hdd_uninit() - HDD uninit function
3666 * @dev: Pointer to net_device structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003667 *
3668 * This is called during the netdev unregister to uninitialize all data
3669 * associated with the device
3670 *
Dustin Brown96b98dd2019-03-06 12:39:37 -08003671 * This function must be protected by a transition
3672 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003673 * Return: None
3674 */
Dustin Brown96b98dd2019-03-06 12:39:37 -08003675static void hdd_uninit(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003676{
Jeff Johnson9d295242017-08-29 14:39:48 -07003677 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson399c6272017-08-30 10:51:00 -07003678 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003679
Dustin Brownfdf17c12018-03-14 12:55:34 -07003680 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003681
Dustin Brown96b98dd2019-03-06 12:39:37 -08003682 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
3683 hdd_err("Invalid magic");
3684 goto exit;
3685 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003686
Dustin Brown96b98dd2019-03-06 12:39:37 -08003687 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3688 if (!hdd_ctx) {
3689 hdd_err("NULL hdd_ctx");
3690 goto exit;
3691 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003692
Dustin Brown96b98dd2019-03-06 12:39:37 -08003693 if (dev != adapter->dev)
3694 hdd_err("Invalid device reference");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003695
Dustin Brown96b98dd2019-03-06 12:39:37 -08003696 hdd_deinit_adapter(hdd_ctx, adapter, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003697
Dustin Brown96b98dd2019-03-06 12:39:37 -08003698 /* after uninit our adapter structure will no longer be valid */
3699 adapter->dev = NULL;
3700 adapter->magic = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003701
Dustin Brown96b98dd2019-03-06 12:39:37 -08003702exit:
Dustin Browne74003f2018-03-14 12:51:58 -07003703 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003704}
3705
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003706static int hdd_open_cesium_nl_sock(void)
3707{
3708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3709 struct netlink_kernel_cfg cfg = {
3710 .groups = WLAN_NLINK_MCAST_GRP_ID,
3711 .input = NULL
3712 };
3713#endif
3714 int ret = 0;
3715
3716#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3717 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3718#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
3719 THIS_MODULE,
3720#endif
3721 &cfg);
3722#else
3723 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3724 WLAN_NLINK_MCAST_GRP_ID,
3725 NULL, NULL, THIS_MODULE);
3726#endif
3727
Jeff Johnsond36fa332019-03-18 13:42:25 -07003728 if (!cesium_nl_srv_sock) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003729 hdd_err("NLINK: cesium netlink_kernel_create failed");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003730 ret = -ECONNREFUSED;
3731 }
3732
3733 return ret;
3734}
3735
3736static void hdd_close_cesium_nl_sock(void)
3737{
Jeff Johnsond36fa332019-03-18 13:42:25 -07003738 if (cesium_nl_srv_sock) {
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003739 netlink_kernel_release(cesium_nl_srv_sock);
3740 cesium_nl_srv_sock = NULL;
3741 }
3742}
3743
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303744void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx,
3745 struct qdf_mac_addr *curr_mac_addr,
3746 struct qdf_mac_addr *new_mac_addr)
3747{
3748 uint8_t i;
3749
3750 hdd_enter();
3751
3752 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303753 if (!qdf_mem_cmp(
3754 curr_mac_addr->bytes,
3755 &hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes[0],
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303756 sizeof(struct qdf_mac_addr))) {
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303757 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].dynamic_mac,
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303758 new_mac_addr->bytes,
3759 sizeof(struct qdf_mac_addr));
3760 break;
3761 }
3762 }
3763
3764 hdd_exit();
3765}
3766
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003767/**
3768 * __hdd_set_mac_address() - set the user specified mac address
3769 * @dev: Pointer to the net device.
3770 * @addr: Pointer to the sockaddr.
3771 *
3772 * This function sets the user specified mac address using
Jeff Johnson06095fb2018-05-06 16:16:42 -07003773 * the command ifconfig wlanX hw ether <mac address>.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003774 *
3775 * Return: 0 for success, non zero for failure
3776 */
3777static int __hdd_set_mac_address(struct net_device *dev, void *addr)
3778{
Jeff Johnson9d295242017-08-29 14:39:48 -07003779 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +05303780 struct hdd_adapter *adapter_temp;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003781 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003782 struct sockaddr *psta_mac_addr = addr;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303783 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003784 int ret;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303785 struct qdf_mac_addr mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003786
Dustin Brownfdf17c12018-03-14 12:55:34 -07003787 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003788
Hanumanth Reddy Pothula5c7a7812018-03-09 12:55:32 +05303789 if (netif_running(dev)) {
3790 hdd_err("On iface up, set mac address change isn't supported");
3791 return -EBUSY;
3792 }
3793
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003794 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3795 ret = wlan_hdd_validate_context(hdd_ctx);
3796 if (0 != ret)
3797 return ret;
3798
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303799 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +05303800 adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
3801 if (adapter_temp) {
3802 if (!qdf_str_cmp(adapter_temp->dev->name, dev->name))
3803 return 0;
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003804 hdd_err("%s adapter exist with same address " QDF_MAC_ADDR_STR,
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +05303805 adapter_temp->dev->name,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003806 QDF_MAC_ADDR_ARRAY(mac_addr.bytes));
Ashish Kumar Dhanotiyaf974f332018-04-19 16:03:15 +05303807 return -EINVAL;
3808 }
3809
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05303810 qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr);
3811 if (QDF_IS_STATUS_ERROR(qdf_ret_status))
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303812 return -EINVAL;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303813
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003814 hdd_info("Changing MAC to " QDF_MAC_ADDR_STR " of the interface %s ",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003815 QDF_MAC_ADDR_ARRAY(mac_addr.bytes), dev->name);
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303816
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303817 hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr);
Jeff Johnson1e851a12017-10-28 14:36:12 -07003818 memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003819 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
3820
Dustin Browne74003f2018-03-14 12:51:58 -07003821 hdd_exit();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303822 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003823}
3824
3825/**
3826 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
Dustin Brown98f7c822019-03-06 12:25:49 -08003827 * function from SSR
3828 * @net_dev: pointer to net_device structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003829 * @addr: Pointer to the sockaddr
3830 *
3831 * This function sets the user specified mac address using
Jeff Johnson06095fb2018-05-06 16:16:42 -07003832 * the command ifconfig wlanX hw ether <mac address>.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003833 *
3834 * Return: 0 for success.
3835 */
Dustin Brown98f7c822019-03-06 12:25:49 -08003836static int hdd_set_mac_address(struct net_device *net_dev, void *addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003837{
Dustin Brown98f7c822019-03-06 12:25:49 -08003838 struct osif_vdev_sync *vdev_sync;
3839 int errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003840
Dustin Brown98f7c822019-03-06 12:25:49 -08003841 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
3842 if (errno)
3843 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003844
Dustin Brown98f7c822019-03-06 12:25:49 -08003845 errno = __hdd_set_mac_address(net_dev, addr);
3846
3847 osif_vdev_sync_op_stop(vdev_sync);
3848
3849 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003850}
3851
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303852static uint8_t *wlan_hdd_get_derived_intf_addr(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003853{
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303854 int i, j;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003855
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303856 i = qdf_ffz(hdd_ctx->derived_intf_addr_mask);
3857 if (i < 0 || i >= hdd_ctx->num_derived_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003858 return NULL;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303859 qdf_atomic_set_bit(i, &hdd_ctx->derived_intf_addr_mask);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003860 hdd_info("Assigning MAC from derived list" QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003861 QDF_MAC_ADDR_ARRAY(hdd_ctx->derived_mac_addr[i].bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003862
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303863 /* Copy the mac in dynamic mac list at first free position */
3864 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) {
3865 if (qdf_is_macaddr_zero(&hdd_ctx->
3866 dynamic_mac_list[j].dynamic_mac))
3867 break;
3868 }
3869 if (j == QDF_MAX_CONCURRENCY_PERSONA) {
3870 hdd_err("Max interfaces are up");
3871 return NULL;
3872 }
Dustin Brown61cc3932018-10-18 16:12:13 -07003873
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303874 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes,
3875 &hdd_ctx->derived_mac_addr[i].bytes,
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303876 sizeof(struct qdf_mac_addr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303877 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = false;
3878 hdd_ctx->dynamic_mac_list[j].bit_position = i;
3879
3880 return hdd_ctx->derived_mac_addr[i].bytes;
3881}
3882
3883static uint8_t *wlan_hdd_get_provisioned_intf_addr(struct hdd_context *hdd_ctx)
3884{
3885 int i, j;
3886
3887 i = qdf_ffz(hdd_ctx->provisioned_intf_addr_mask);
3888 if (i < 0 || i >= hdd_ctx->num_provisioned_addr)
3889 return NULL;
3890 qdf_atomic_set_bit(i, &hdd_ctx->provisioned_intf_addr_mask);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003891 hdd_info("Assigning MAC from provisioned list" QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003892 QDF_MAC_ADDR_ARRAY(hdd_ctx->provisioned_mac_addr[i].bytes));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303893
3894 /* Copy the mac in dynamic mac list at first free position */
3895 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) {
3896 if (qdf_is_macaddr_zero(&hdd_ctx->
3897 dynamic_mac_list[j].dynamic_mac))
3898 break;
3899 }
3900 if (j == QDF_MAX_CONCURRENCY_PERSONA) {
3901 hdd_err("Max interfaces are up");
3902 return NULL;
3903 }
3904
3905 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes,
3906 &hdd_ctx->provisioned_mac_addr[i].bytes,
3907 sizeof(struct qdf_mac_addr));
3908 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = true;
3909 hdd_ctx->dynamic_mac_list[j].bit_position = i;
3910 return hdd_ctx->provisioned_mac_addr[i].bytes;
3911}
3912
3913uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx,
3914 enum QDF_OPMODE interface_type)
3915{
3916 uint8_t *mac_addr = NULL;
3917
3918 if (qdf_atomic_test_bit(interface_type,
3919 (unsigned long *)
3920 (&hdd_ctx->config->provisioned_intf_pool)))
3921 mac_addr = wlan_hdd_get_provisioned_intf_addr(hdd_ctx);
3922
3923 if ((!mac_addr) &&
3924 (qdf_atomic_test_bit(interface_type,
3925 (unsigned long *)
3926 (&hdd_ctx->config->derived_intf_pool))))
3927 mac_addr = wlan_hdd_get_derived_intf_addr(hdd_ctx);
3928
3929 if (!mac_addr)
3930 hdd_err("MAC is not available in both the lists");
3931 return mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003932}
3933
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07003934void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
3935 uint8_t *releaseAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003936{
3937 int i;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303938 int mac_pos_in_mask;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003939
Anurag Chouhan6d760662016-02-20 16:05:43 +05303940 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003941 if (!memcmp(releaseAddr,
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303942 hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes,
3943 QDF_MAC_ADDR_SIZE)) {
3944 mac_pos_in_mask =
3945 hdd_ctx->dynamic_mac_list[i].bit_position;
3946 if (hdd_ctx->dynamic_mac_list[i].is_provisioned_mac) {
3947 qdf_atomic_clear_bit(
3948 mac_pos_in_mask,
3949 &hdd_ctx->
3950 provisioned_intf_addr_mask);
3951 hdd_info("Releasing MAC from provisioned list");
3952 hdd_info(
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003953 QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003954 QDF_MAC_ADDR_ARRAY(releaseAddr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303955 } else {
3956 qdf_atomic_clear_bit(
3957 mac_pos_in_mask, &hdd_ctx->
3958 derived_intf_addr_mask);
3959 hdd_info("Releasing MAC from derived list");
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003960 hdd_info(QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003961 QDF_MAC_ADDR_ARRAY(releaseAddr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303962 }
3963 qdf_zero_macaddr(&hdd_ctx->
3964 dynamic_mac_list[i].dynamic_mac);
3965 hdd_ctx->dynamic_mac_list[i].is_provisioned_mac =
3966 false;
3967 hdd_ctx->dynamic_mac_list[i].bit_position = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003968 break;
3969 }
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303970
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003971 }
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303972 if (i == QDF_MAX_CONCURRENCY_PERSONA)
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07003973 hdd_err("Releasing non existing MAC" QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07003974 QDF_MAC_ADDR_ARRAY(releaseAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003975}
3976
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003977/**
3978 * __hdd_set_multicast_list() - set the multicast address list
3979 * @dev: Pointer to the WLAN device.
3980 * @skb: Pointer to OS packet (sk_buff).
3981 *
3982 * This funciton sets the multicast address list.
3983 *
3984 * Return: None
3985 */
3986static void __hdd_set_multicast_list(struct net_device *dev)
3987{
Jeff Johnson9d295242017-08-29 14:39:48 -07003988 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Dustin Brown0f874482018-06-13 14:39:22 -07003989 int i = 0, errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003990 struct netdev_hw_addr *ha;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003991 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303992 struct pmo_mc_addr_list_params *mc_list_request = NULL;
Dustin Brown1dbefe62018-09-11 16:32:03 -07003993 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303994 int mc_count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003995
Alan Chene825c3b2019-10-02 13:58:51 -07003996 if (hdd_ctx->hdd_wlan_suspended) {
3997 hdd_err_rl("Device is system suspended");
3998 return;
3999 }
4000
Dustin Brownfdf17c12018-03-14 12:55:34 -07004001 hdd_enter_dev(dev);
Anurag Chouhan6d760662016-02-20 16:05:43 +05304002 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304003 goto out;
Mukul Sharma51c44942015-10-30 19:30:19 +05304004
Dustin Brown0f874482018-06-13 14:39:22 -07004005 errno = wlan_hdd_validate_context(hdd_ctx);
4006 if (errno)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304007 goto out;
4008
Dustin Brown0f874482018-06-13 14:39:22 -07004009 errno = hdd_validate_adapter(adapter);
4010 if (errno)
Dustin Brownc788acb2017-08-01 17:43:51 -07004011 goto out;
4012
Arunk Khandavalli6a227882017-12-12 19:31:08 +05304013 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
4014 hdd_err("%s: Driver module is closed", __func__);
Dustin Brown0f874482018-06-13 14:39:22 -07004015 goto out;
Arunk Khandavalli6a227882017-12-12 19:31:08 +05304016 }
4017
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304018 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
Min Liu74a1a502018-10-10 19:59:07 +08004019 if (!mc_list_request)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304020 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004021
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05304022 /* Delete already configured multicast address list */
4023 if (adapter->mc_addr_list.mc_cnt > 0) {
Dustin Brown0f874482018-06-13 14:39:22 -07004024 hdd_debug("clear previously configured MC address list");
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05304025 hdd_disable_and_flush_mc_addr_list(adapter,
4026 pmo_mc_list_change_notify);
4027 }
4028
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004029 if (dev->flags & IFF_ALLMULTI) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004030 hdd_debug("allow all multicast frames");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304031 hdd_disable_and_flush_mc_addr_list(adapter,
4032 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004033 } else {
4034 mc_count = netdev_mc_count(dev);
Wu Gaod7dd6e42018-10-16 17:22:56 +08004035 if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004036 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
Wu Gaod7dd6e42018-10-16 17:22:56 +08004037 ucfg_pmo_max_mc_addr_supported(psoc));
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304038 hdd_disable_and_flush_mc_addr_list(adapter,
4039 pmo_mc_list_change_notify);
stonezdf2bdfd2018-11-20 14:45:06 +08004040 adapter->mc_addr_list.mc_cnt = 0;
Dustin Brown0f874482018-06-13 14:39:22 -07004041 goto free_req;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004042 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004043 netdev_for_each_mc_addr(ha, dev) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07004044 hdd_debug("ha_addr[%d] "QDF_MAC_ADDR_STR,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07004045 i, QDF_MAC_ADDR_ARRAY(ha->addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004046 if (i == mc_count)
4047 break;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304048 memset(&(mc_list_request->mc_addr[i].bytes),
4049 0, ETH_ALEN);
4050 memcpy(&(mc_list_request->mc_addr[i].bytes),
4051 ha->addr, ETH_ALEN);
Dustin Brown0f874482018-06-13 14:39:22 -07004052 hdd_debug("mlist[%d] = %pM", i,
4053 mc_list_request->mc_addr[i].bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004054 i++;
4055 }
4056 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304057
stonezdf2bdfd2018-11-20 14:45:06 +08004058 adapter->mc_addr_list.mc_cnt = mc_count;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304059 mc_list_request->psoc = psoc;
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004060 mc_list_request->vdev_id = adapter->vdev_id;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304061 mc_list_request->count = mc_count;
Dustin Brown0f874482018-06-13 14:39:22 -07004062
4063 errno = hdd_cache_mc_addr_list(mc_list_request);
4064 if (errno) {
4065 hdd_err("Failed to cache MC address list for vdev %u; errno:%d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004066 adapter->vdev_id, errno);
Dustin Brown0f874482018-06-13 14:39:22 -07004067 goto free_req;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004068 }
Dustin Brown0f874482018-06-13 14:39:22 -07004069
4070 hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify);
4071
4072free_req:
4073 qdf_mem_free(mc_list_request);
4074
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05304075out:
Dustin Browne74003f2018-03-14 12:51:58 -07004076 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004077}
4078
4079/**
4080 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
Dustin Brown98f7c822019-03-06 12:25:49 -08004081 * @net_dev: pointer to net_device
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004082 *
4083 * Return: none
4084 */
Dustin Brown98f7c822019-03-06 12:25:49 -08004085static void hdd_set_multicast_list(struct net_device *net_dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004086{
Dustin Brown98f7c822019-03-06 12:25:49 -08004087 struct osif_vdev_sync *vdev_sync;
4088
4089 if (osif_vdev_sync_op_start(net_dev, &vdev_sync))
4090 return;
4091
4092 __hdd_set_multicast_list(net_dev);
4093
4094 osif_vdev_sync_op_stop(vdev_sync);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004095}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004096
Subrat Dash5f36fbe2019-02-12 16:28:14 +05304097#ifdef WLAN_FEATURE_TSF_PTP
4098static const struct ethtool_ops wlan_ethtool_ops = {
4099 .get_ts_info = wlan_get_ts_info,
4100};
4101#endif
4102
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004103static const struct net_device_ops wlan_drv_ops = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004104 .ndo_open = hdd_open,
4105 .ndo_stop = hdd_stop,
4106 .ndo_uninit = hdd_uninit,
4107 .ndo_start_xmit = hdd_hard_start_xmit,
4108 .ndo_tx_timeout = hdd_tx_timeout,
4109 .ndo_get_stats = hdd_get_stats,
4110 .ndo_do_ioctl = hdd_ioctl,
4111 .ndo_set_mac_address = hdd_set_mac_address,
4112 .ndo_select_queue = hdd_select_queue,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004113 .ndo_set_rx_mode = hdd_set_multicast_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004114};
4115
Nirav Shah73713f72018-05-17 14:50:41 +05304116#ifdef FEATURE_MONITOR_MODE_SUPPORT
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004117/* Monitor mode net_device_ops, doesnot Tx and most of operations. */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004118static const struct net_device_ops wlan_mon_drv_ops = {
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004119 .ndo_open = hdd_mon_open,
4120 .ndo_stop = hdd_stop,
4121 .ndo_get_stats = hdd_get_stats,
4122};
4123
Subrat Dash5f36fbe2019-02-12 16:28:14 +05304124#ifdef WLAN_FEATURE_TSF_PTP
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004125/**
4126 * hdd_set_station_ops() - update net_device ops for monitor mode
Jeff Johnson5505db82017-11-02 21:19:23 -07004127 * @dev: Handle to struct net_device to be updated.
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004128 * Return: None
4129 */
Jeff Johnson5505db82017-11-02 21:19:23 -07004130void hdd_set_station_ops(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004131{
Subrat Dash5f36fbe2019-02-12 16:28:14 +05304132 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) {
4133 dev->netdev_ops = &wlan_mon_drv_ops;
4134 } else {
4135 dev->netdev_ops = &wlan_drv_ops;
4136 dev->ethtool_ops = &wlan_ethtool_ops;
4137 }
4138}
4139#else
4140void hdd_set_station_ops(struct net_device *dev)
4141{
4142 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
Jeff Johnson5505db82017-11-02 21:19:23 -07004143 dev->netdev_ops = &wlan_mon_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004144 else
Jeff Johnson5505db82017-11-02 21:19:23 -07004145 dev->netdev_ops = &wlan_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004146}
Subrat Dash5f36fbe2019-02-12 16:28:14 +05304147
4148#endif
4149#else
4150#ifdef WLAN_FEATURE_TSF_PTP
4151void hdd_set_station_ops(struct net_device *dev)
4152{
4153 dev->netdev_ops = &wlan_drv_ops;
4154 dev->ethtool_ops = &wlan_ethtool_ops;
4155}
Nirav Shah73713f72018-05-17 14:50:41 +05304156#else
4157void hdd_set_station_ops(struct net_device *dev)
4158{
4159 dev->netdev_ops = &wlan_drv_ops;
4160}
4161#endif
Subrat Dash5f36fbe2019-02-12 16:28:14 +05304162#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07004163
4164/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08004165 * hdd_alloc_station_adapter() - allocate the station hdd adapter
4166 * @hdd_ctx: global hdd context
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004167 * @mac_addr: mac address to assign to the interface
Ryan Hsu07495ea2016-01-21 15:25:39 -08004168 * @name: User-visible name of the interface
4169 *
4170 * hdd adapter pointer would point to the netdev->priv space, this function
Jeff Johnson62018292018-05-06 16:18:35 -07004171 * would retrieve the pointer, and setup the hdd adapter configuration.
Ryan Hsu07495ea2016-01-21 15:25:39 -08004172 *
4173 * Return: the pointer to hdd adapter, otherwise NULL
4174 */
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004175static struct hdd_adapter *
4176hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr,
4177 unsigned char name_assign_type, const char *name)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004178{
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004179 struct net_device *dev;
4180 struct hdd_adapter *adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07004181 struct hdd_station_ctx *sta_ctx;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304182 QDF_STATUS qdf_status;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004183
4184 /* cfg80211 initialization and registration */
4185 dev = alloc_netdev_mq(sizeof(*adapter), name,
Ryan Hsu07495ea2016-01-21 15:25:39 -08004186#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004187 name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004188#endif
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004189 (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE ?
4190 hdd_mon_mode_ether_setup : ether_setup),
4191 NUM_TX_QUEUES);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004192
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004193 if (!dev) {
4194 hdd_err("Failed to allocate new net_device '%s'", name);
4195 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004196 }
4197
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004198 adapter = netdev_priv(dev);
4199
4200 qdf_mem_zero(adapter, sizeof(*adapter));
4201 sta_ctx = &adapter->session.station;
Jeff Johnson0a082d92019-03-04 12:25:49 -08004202 qdf_mem_set(sta_ctx->conn_info.sta_id,
4203 sizeof(sta_ctx->conn_info.sta_id),
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004204 HDD_WLAN_INVALID_STA_ID);
4205 adapter->dev = dev;
4206 adapter->hdd_ctx = hdd_ctx;
4207 adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Jeff Johnson912b1bb2019-03-06 10:12:36 -08004208 adapter->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004209
4210 qdf_status = qdf_event_create(&adapter->qdf_session_open_event);
4211 if (QDF_IS_STATUS_ERROR(qdf_status))
4212 goto free_net_dev;
4213
4214 qdf_status = qdf_event_create(&adapter->qdf_session_close_event);
4215 if (QDF_IS_STATUS_ERROR(qdf_status))
4216 goto free_net_dev;
4217
4218 adapter->offloads_configured = false;
4219 adapter->is_link_up_service_needed = false;
4220 adapter->disconnection_in_progress = false;
4221 adapter->send_mode_change = true;
4222
4223 /* Init the net_device structure */
4224 strlcpy(dev->name, name, IFNAMSIZ);
4225
4226 qdf_mem_copy(dev->dev_addr, mac_addr, sizeof(tSirMacAddr));
4227 qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr));
4228 dev->watchdog_timeo = HDD_TX_TIMEOUT;
4229
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004230 hdd_set_station_ops(adapter->dev);
4231
4232 hdd_dev_setup_destructor(dev);
4233 dev->ieee80211_ptr = &adapter->wdev;
4234 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
4235 adapter->wdev.wiphy = hdd_ctx->wiphy;
4236 adapter->wdev.netdev = dev;
4237
4238 /* set dev's parent to underlying device */
4239 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
4240 hdd_wmm_init(adapter);
4241 spin_lock_init(&adapter->pause_map_lock);
4242 adapter->start_time = qdf_system_ticks();
4243 adapter->last_time = adapter->start_time;
4244
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004245 return adapter;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07004246
4247free_net_dev:
4248 free_netdev(adapter->dev);
4249
4250 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004251}
4252
Jeff Johnson9d295242017-08-29 14:39:48 -07004253static QDF_STATUS hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004254{
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004255 struct net_device *dev = adapter->dev;
4256 int ret;
4257
Dustin Brown491d54b2018-03-14 12:39:11 -07004258 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004259
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08004260 if (rtnl_held) {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004261 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
4262
4263 ret = dev_alloc_name(dev, dev->name);
4264 if (ret < 0) {
4265 hdd_err(
4266 "unable to get dev name: %s, err = 0x%x",
4267 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304268 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004269 }
4270 }
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004271
4272 ret = register_netdevice(dev);
4273 if (ret) {
4274 hdd_err("register_netdevice(%s) failed, err = 0x%x",
4275 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304276 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004277 }
4278 } else {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004279 ret = register_netdev(dev);
4280 if (ret) {
4281 hdd_err("register_netdev(%s) failed, err = 0x%x",
4282 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304283 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004284 }
4285 }
4286 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
4287
Dustin Browne74003f2018-03-14 12:51:58 -07004288 hdd_exit();
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07004289
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304290 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004291}
4292
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004293QDF_STATUS hdd_sme_open_session_callback(uint8_t vdev_id,
Pragaspathi Thilagaraj3551caa2018-09-26 15:52:56 +05304294 QDF_STATUS qdf_status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004295{
Krunal Sonib51eec72017-11-20 21:53:01 -08004296 struct hdd_adapter *adapter;
4297 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004298
Krunal Sonib51eec72017-11-20 21:53:01 -08004299 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4300 if (!hdd_ctx) {
4301 hdd_err("Invalid HDD_CTX");
4302 return QDF_STATUS_E_FAILURE;
4303 }
4304
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004305 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnsond36fa332019-03-18 13:42:25 -07004306 if (!adapter) {
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004307 hdd_err("NULL adapter for %d", vdev_id);
Krunal Sonib51eec72017-11-20 21:53:01 -08004308 return QDF_STATUS_E_INVAL;
4309 }
Pragaspathi Thilagaraj3551caa2018-09-26 15:52:56 +05304310
4311 if (qdf_status == QDF_STATUS_SUCCESS)
4312 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
4313
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304314 qdf_event_set(&adapter->qdf_session_open_event);
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004315 hdd_debug("session %d opened", adapter->vdev_id);
Krunal Sonib51eec72017-11-20 21:53:01 -08004316
4317 return QDF_STATUS_SUCCESS;
4318}
4319
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004320QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id)
Krunal Sonib51eec72017-11-20 21:53:01 -08004321{
4322 struct hdd_adapter *adapter;
4323 struct hdd_context *hdd_ctx;
4324
4325 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4326 if (!hdd_ctx) {
4327 hdd_err("Invalid HDD_CTX");
4328 return QDF_STATUS_E_FAILURE;
4329 }
4330
Jeff Johnson55d2ab42019-03-06 11:43:49 -08004331 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnsond36fa332019-03-18 13:42:25 -07004332 if (!adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004333 hdd_err("NULL adapter");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304334 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004335 }
4336
4337 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004338 hdd_err("Invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304339 return QDF_STATUS_NOT_INITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004340 }
4341
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004342 /*
4343 * For NAN Data interface, the close session results in the final
4344 * indication to the userspace
4345 */
Rakesh Sunki3480f962016-08-29 17:29:53 -07004346 if (adapter->device_mode == QDF_NDI_MODE)
4347 hdd_ndp_session_end_handler(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07004348
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004349 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
4350
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004351 /*
4352 * We can be blocked while waiting for scheduled work to be
4353 * flushed, and the adapter structure can potentially be freed, in
4354 * which case the magic will have been reset. So make sure the
4355 * magic is still good, and hence the adapter structure is still
4356 * valid, before signaling completion
4357 */
4358 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304359 qdf_event_set(&adapter->qdf_session_close_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004360
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304361 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004362}
4363
Jeff Johnson9d295242017-08-29 14:39:48 -07004364int hdd_vdev_ready(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004365{
Min Liu8c5d99e2018-09-10 17:18:44 +08004366 struct wlan_objmgr_vdev *vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004367 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004368
Min Liu8c5d99e2018-09-10 17:18:44 +08004369 vdev = hdd_objmgr_get_vdev(adapter);
4370 if (!vdev)
4371 return -EINVAL;
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004372
Min Liu8c5d99e2018-09-10 17:18:44 +08004373 status = pmo_vdev_ready(vdev);
4374 if (QDF_IS_STATUS_ERROR(status)) {
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304375 hdd_objmgr_put_vdev(vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004376 return qdf_status_to_os_return(status);
Min Liu8c5d99e2018-09-10 17:18:44 +08004377 }
4378
4379 status = ucfg_reg_11d_vdev_created_update(vdev);
4380 if (QDF_IS_STATUS_ERROR(status)) {
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304381 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08004382 return qdf_status_to_os_return(status);
4383 }
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004384
4385 if (wma_capability_enhanced_mcast_filter())
Min Liu8c5d99e2018-09-10 17:18:44 +08004386 status = ucfg_pmo_enhanced_mc_filter_enable(vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004387 else
Min Liu8c5d99e2018-09-10 17:18:44 +08004388 status = ucfg_pmo_enhanced_mc_filter_disable(vdev);
4389
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304390 hdd_objmgr_put_vdev(vdev);
Dustin Brownd28772b2017-03-17 14:16:07 -07004391
4392 return qdf_status_to_os_return(status);
4393}
4394
Jeff Johnson9d295242017-08-29 14:39:48 -07004395int hdd_vdev_destroy(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07004396{
4397 QDF_STATUS status;
Dustin Brown2da29eb2018-07-13 14:23:12 -07004398 int errno;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004399 struct hdd_context *hdd_ctx;
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004400 uint8_t vdev_id;
Min Liu8c5d99e2018-09-10 17:18:44 +08004401 struct wlan_objmgr_vdev *vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004402
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004403 vdev_id = adapter->vdev_id;
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004404 hdd_info("destroying vdev %d", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004405
4406 /* vdev created sanity check */
4407 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
Dustin Brown2da29eb2018-07-13 14:23:12 -07004408 hdd_err("vdev %u does not exist", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004409 return -EINVAL;
4410 }
Dustin Brown2da29eb2018-07-13 14:23:12 -07004411
Abhishek Singh628bb6f2019-03-26 14:52:40 +05304412 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4413
4414 /*
4415 * if this is the last active connection check & stop the
4416 * opportunistic timer first
4417 */
4418 if ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 1 &&
4419 policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
4420 policy_mgr_convert_device_mode_to_qdf_type(
4421 adapter->device_mode), NULL) == 1) ||
4422 !policy_mgr_get_connection_count(hdd_ctx->psoc))
4423 policy_mgr_check_and_stop_opportunistic_timer(hdd_ctx->psoc,
4424 adapter->vdev_id);
4425
Min Liu8c5d99e2018-09-10 17:18:44 +08004426 vdev = hdd_objmgr_get_vdev(adapter);
4427 if (!vdev)
4428 return -EINVAL;
Ashish Kumar Dhanotiya68ee2e42018-11-19 21:15:14 +05304429
4430 ucfg_pmo_del_wow_pattern(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08004431 status = ucfg_reg_11d_vdev_delete_update(vdev);
Abhishek Singh935e4772018-11-21 14:14:10 +05304432 ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304433 hdd_objmgr_put_vdev(vdev);
Yue Maf9782842017-05-08 12:49:49 -07004434
Dustin Brownd28772b2017-03-17 14:16:07 -07004435 /* close sme session (destroy vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304436 qdf_event_reset(&adapter->qdf_session_close_event);
Abhishek Amburecbef1442019-06-10 17:15:00 +05304437 status = sme_vdev_delete(hdd_ctx->mac_handle, adapter->vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004438 if (QDF_IS_STATUS_ERROR(status)) {
Abhishek Amburecbef1442019-06-10 17:15:00 +05304439 hdd_err("failed to delete vdev; status:%d", status);
Jiachao Wu2c42c222018-01-15 18:13:19 +08004440 goto release_vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004441 }
4442
4443 /* block on a completion variable until sme session is closed */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304444 status = qdf_wait_for_event_completion(
4445 &adapter->qdf_session_close_event,
Abhishek Singh13bf0ce2018-10-24 14:26:14 +05304446 SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
Dustin Brown2da29eb2018-07-13 14:23:12 -07004447
4448 if (QDF_IS_STATUS_ERROR(status)) {
4449 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
4450
Dustin Brownd28772b2017-03-17 14:16:07 -07004451 if (adapter->device_mode == QDF_NDI_MODE)
4452 hdd_ndp_session_end_handler(adapter);
Dustin Brown2da29eb2018-07-13 14:23:12 -07004453
4454 if (status == QDF_STATUS_E_TIMEOUT)
Abhishek Amburecbef1442019-06-10 17:15:00 +05304455 hdd_err("timed out waiting for sme vdev delete");
Dustin Brown2da29eb2018-07-13 14:23:12 -07004456 else if (adapter->qdf_session_close_event.force_set)
Abhishek Amburecbef1442019-06-10 17:15:00 +05304457 hdd_info("SSR occurred during sme vdev delete");
Dustin Brown2da29eb2018-07-13 14:23:12 -07004458 else
Abhishek Amburecbef1442019-06-10 17:15:00 +05304459 hdd_err("failed to wait for sme vdev delete; status:%u",
Dustin Brown2da29eb2018-07-13 14:23:12 -07004460 status);
Dustin Brownd28772b2017-03-17 14:16:07 -07004461 }
Jiachao Wu2c42c222018-01-15 18:13:19 +08004462
Yue Maf9782842017-05-08 12:49:49 -07004463release_vdev:
Jiachao Wu2c42c222018-01-15 18:13:19 +08004464
Sandeep Puligillaef415362017-08-30 16:37:13 -07004465 /* do vdev logical destroy via objmgr */
Dustin Brownb277dd62018-01-26 15:17:33 -08004466 errno = hdd_objmgr_release_and_destroy_vdev(adapter);
Sandeep Puligillaef415362017-08-30 16:37:13 -07004467 if (errno) {
Dustin Brownb277dd62018-01-26 15:17:33 -08004468 hdd_err("failed to destroy objmgr vdev; errno:%d", errno);
Sandeep Puligillaef415362017-08-30 16:37:13 -07004469 return errno;
4470 }
4471
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004472 hdd_info("vdev %d destroyed successfully", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004473
4474 return 0;
4475}
4476
Krunal Sonib51eec72017-11-20 21:53:01 -08004477static int hdd_set_sme_session_param(struct hdd_adapter *adapter,
4478 struct sme_session_params *session_param,
Jeff Johnson6a18c962018-07-01 09:09:37 -07004479 csr_roam_complete_cb callback,
Krunal Sonib51eec72017-11-20 21:53:01 -08004480 void *callback_ctx)
Dustin Brownd28772b2017-03-17 14:16:07 -07004481{
Abhishek Ambure74709762019-05-27 19:43:26 +05304482 session_param->vdev_id = adapter->vdev_id;
Krunal Sonib51eec72017-11-20 21:53:01 -08004483 session_param->self_mac_addr = (uint8_t *)&adapter->mac_addr;
Krunal Sonib51eec72017-11-20 21:53:01 -08004484 session_param->session_open_cb = hdd_sme_open_session_callback;
4485 session_param->session_close_cb = hdd_sme_close_session_callback;
4486 session_param->callback = callback;
4487 session_param->callback_ctx = callback_ctx;
Abhishek Ambure74709762019-05-27 19:43:26 +05304488 session_param->vdev = adapter->vdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08004489
4490 return 0;
4491}
4492
gaurank kathpalia6c4b50c2019-02-28 14:07:48 +05304493void
gaurank kathpalia78af1932018-10-27 20:33:10 +05304494hdd_store_nss_chains_cfg_in_vdev(struct hdd_adapter *adapter)
4495{
4496 struct wlan_mlme_nss_chains vdev_ini_cfg;
4497 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4498
gaurank kathpaliab414bce2018-11-09 18:44:46 +05304499 /* Populate the nss chain params from ini for this vdev type */
gaurank kathpalia78af1932018-10-27 20:33:10 +05304500 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
4501 adapter->device_mode,
4502 hdd_ctx->num_rf_chains);
gaurank kathpaliab414bce2018-11-09 18:44:46 +05304503
4504 /* Store the nss chain config into the vdev */
4505 sme_store_nss_chains_cfg_in_vdev(adapter->vdev, &vdev_ini_cfg);
gaurank kathpalia78af1932018-10-27 20:33:10 +05304506}
gaurank kathpalia6982d472018-10-31 21:54:15 +05304507
4508bool hdd_is_vdev_in_conn_state(struct hdd_adapter *adapter)
4509{
4510 switch (adapter->device_mode) {
4511 case QDF_STA_MODE:
4512 case QDF_P2P_CLIENT_MODE:
4513 case QDF_P2P_DEVICE_MODE:
4514 return hdd_conn_is_connected(
4515 WLAN_HDD_GET_STATION_CTX_PTR(adapter));
4516 case QDF_SAP_MODE:
4517 case QDF_P2P_GO_MODE:
4518 return (test_bit(SOFTAP_BSS_STARTED,
4519 &adapter->event_flags));
4520 default:
4521 hdd_err("Device mode %d invalid", adapter->device_mode);
4522 return 0;
4523 }
4524
4525 return 0;
4526}
4527
Krunal Sonib51eec72017-11-20 21:53:01 -08004528int hdd_vdev_create(struct hdd_adapter *adapter,
Jeff Johnson6a18c962018-07-01 09:09:37 -07004529 csr_roam_complete_cb callback, void *ctx)
Krunal Sonib51eec72017-11-20 21:53:01 -08004530{
4531 QDF_STATUS status;
4532 int errno;
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304533 bool bval;
Krunal Sonib51eec72017-11-20 21:53:01 -08004534 struct hdd_context *hdd_ctx;
4535 struct sme_session_params sme_session_params = {0};
Min Liu8c5d99e2018-09-10 17:18:44 +08004536 struct wlan_objmgr_vdev *vdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08004537
4538 hdd_info("creating new vdev");
Dustin Brownd28772b2017-03-17 14:16:07 -07004539
4540 /* do vdev create via objmgr */
4541 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Dustin Brown07901ec2018-09-07 11:02:41 -07004542 errno = hdd_objmgr_create_and_store_vdev(hdd_ctx->pdev, adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -07004543 if (errno) {
4544 hdd_err("failed to create objmgr vdev: %d", errno);
4545 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004546 }
Dustin Brownd28772b2017-03-17 14:16:07 -07004547
4548 /* Open a SME session (prepare vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304549 status = qdf_event_reset(&adapter->qdf_session_open_event);
4550 if (QDF_STATUS_SUCCESS != status) {
4551 hdd_err("failed to reinit session open event");
Ashish Kumar Dhanotiyacf3cf662019-08-12 17:58:06 +05304552 errno = qdf_status_to_os_return(status);
4553 goto objmgr_vdev_destroy_procedure;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304554 }
Krunal Sonib51eec72017-11-20 21:53:01 -08004555 errno = hdd_set_sme_session_param(adapter, &sme_session_params,
4556 callback, ctx);
4557 if (errno) {
4558 hdd_err("failed to populating SME params");
4559 goto objmgr_vdev_destroy_procedure;
4560 }
Abhishek Ambure74709762019-05-27 19:43:26 +05304561 status = sme_create_vdev(hdd_ctx->mac_handle,
4562 &sme_session_params);
Dustin Brownd28772b2017-03-17 14:16:07 -07004563 if (QDF_IS_STATUS_ERROR(status)) {
Abhishek Ambure74709762019-05-27 19:43:26 +05304564 hdd_err("failed to create vdev: %d", status);
Dustin Brownd28772b2017-03-17 14:16:07 -07004565 errno = qdf_status_to_os_return(status);
Krunal Soni4a020c72017-10-30 20:58:40 -07004566 goto objmgr_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004567 }
4568
Abhishek Ambure74709762019-05-27 19:43:26 +05304569 /* block on a completion variable until vdev is created in firmware */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304570 status = qdf_wait_for_event_completion(&adapter->qdf_session_open_event,
Abhishek Singh13bf0ce2018-10-24 14:26:14 +05304571 SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304572 if (QDF_STATUS_SUCCESS != status) {
Ashish Kumar Dhanotiyacf3cf662019-08-12 17:58:06 +05304573 if (adapter->qdf_session_open_event.force_set)
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304574 /*
4575 * SSR/PDR has caused shutdown, which has forcefully
Ashish Kumar Dhanotiyacf3cf662019-08-12 17:58:06 +05304576 * set the event.
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304577 */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304578 hdd_err("Session open event forcefully set");
Jeff Johnsonc66d3102018-02-28 11:58:26 -08004579
Ashish Kumar Dhanotiyacf3cf662019-08-12 17:58:06 +05304580 else if (QDF_STATUS_E_TIMEOUT == status)
Jeff Johnsonc66d3102018-02-28 11:58:26 -08004581 hdd_err("Session failed to open within timeout period");
4582 else
4583 hdd_err("Failed to wait for session open event(status-%d)",
4584 status);
4585 errno = -ETIMEDOUT;
4586 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
4587 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004588 }
4589
Pragaspathi Thilagaraj3551caa2018-09-26 15:52:56 +05304590 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
4591 hdd_err("Session failed to open due to vdev create failure");
4592 errno = -EINVAL;
4593 goto objmgr_vdev_destroy_procedure;
4594 }
4595
Dustin Brownd28772b2017-03-17 14:16:07 -07004596 /* firmware ready for component communication, raise vdev_ready event */
4597 errno = hdd_vdev_ready(adapter);
4598 if (errno) {
4599 hdd_err("failed to dispatch vdev ready event: %d", errno);
Krunal Soni4a020c72017-10-30 20:58:40 -07004600 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004601 }
4602
Naveen Rawat2b430892018-03-13 13:58:18 -07004603 if (adapter->device_mode == QDF_STA_MODE) {
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304604 bval = false;
4605 status = ucfg_mlme_get_rtt_mac_randomization(hdd_ctx->psoc,
4606 &bval);
4607 if (QDF_IS_STATUS_ERROR(status))
4608 hdd_err("unable to get RTT MAC randomization value");
4609
4610 hdd_debug("setting RTT mac randomization param: %d", bval);
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004611 errno = sme_cli_set_command(adapter->vdev_id,
Naveen Rawat2b430892018-03-13 13:58:18 -07004612 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC,
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304613 bval,
Naveen Rawat2b430892018-03-13 13:58:18 -07004614 VDEV_CMD);
4615 if (0 != errno)
4616 hdd_err("RTT mac randomization param set failed %d",
4617 errno);
4618 }
4619
Bala Venkatesh110b03e2018-07-10 16:02:08 +05304620 if (adapter->device_mode == QDF_STA_MODE ||
Min Liu8c5d99e2018-09-10 17:18:44 +08004621 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
4622 vdev = hdd_objmgr_get_vdev(adapter);
4623 if (!vdev)
4624 goto hdd_vdev_destroy_procedure;
4625 wlan_vdev_set_max_peer_count(vdev, HDD_MAX_VDEV_PEER_COUNT);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304626 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08004627 }
Bala Venkatesh110b03e2018-07-10 16:02:08 +05304628
gaurank kathpalia78af1932018-10-27 20:33:10 +05304629 hdd_store_nss_chains_cfg_in_vdev(adapter);
4630
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004631 hdd_info("vdev %d created successfully", adapter->vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004632
4633 return 0;
4634
4635 /*
4636 * Due to legacy constraints, we need to destroy in the same order as
4637 * create. So, split error handling into 2 cases to accommodate.
4638 */
4639
Krunal Soni4a020c72017-10-30 20:58:40 -07004640objmgr_vdev_destroy_procedure:
Dustin Brown7d043f62017-03-27 12:07:36 -07004641 QDF_BUG(!hdd_objmgr_release_and_destroy_vdev(adapter));
Dustin Brownd28772b2017-03-17 14:16:07 -07004642
4643 return errno;
4644
Krunal Soni4a020c72017-10-30 20:58:40 -07004645hdd_vdev_destroy_procedure:
Dustin Brownd28772b2017-03-17 14:16:07 -07004646 QDF_BUG(!hdd_vdev_destroy(adapter));
4647
4648 return errno;
4649}
4650
Jeff Johnson9d295242017-08-29 14:39:48 -07004651QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07004652{
Jeff Johnsonb9424862017-10-30 08:49:35 -07004653 struct hdd_station_ctx *sta_ctx = &adapter->session.station;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004654 struct hdd_context *hdd_ctx;
Dustin Brownd28772b2017-03-17 14:16:07 -07004655 QDF_STATUS status;
4656 int ret_val;
Jeff Johnson16528362018-06-14 12:34:16 -07004657 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304658 bool bval = false;
Qun Zhang1b3c85c2019-08-27 16:31:49 +08004659 uint8_t enable_sifs_burst = 0;
Dustin Brownd28772b2017-03-17 14:16:07 -07004660
Dustin Brownd28772b2017-03-17 14:16:07 -07004661 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson16528362018-06-14 12:34:16 -07004662 mac_handle = hdd_ctx->mac_handle;
4663 sme_set_curr_device_mode(mac_handle, adapter->device_mode);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304664 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
4665 if (!QDF_IS_STATUS_SUCCESS(status))
4666 hdd_err("unable to get vht_enable2x2");
4667 sme_set_pdev_ht_vht_ies(mac_handle, bval);
4668
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004669 sme_set_vdev_ies_per_band(mac_handle, adapter->vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004670
Jeff Johnson7f2c5912018-03-23 11:42:28 -07004671 hdd_roam_profile_init(adapter);
4672 hdd_register_wext(adapter->dev);
4673
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -07004674 hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004675
Jeff Johnson0a082d92019-03-04 12:25:49 -08004676 qdf_mem_set(sta_ctx->conn_info.sta_id,
4677 sizeof(sta_ctx->conn_info.sta_id),
4678 HDD_WLAN_INVALID_STA_ID);
Hanumanth Reddy Pothulab2d729c2017-05-30 11:49:53 +05304679
Deepak Dhamdherea2785822016-11-17 01:17:45 -08004680 /* set fast roaming capability in sme session */
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004681 status = sme_config_fast_roaming(mac_handle, adapter->vdev_id,
Abhishek Singh1f217ec2017-12-22 11:48:27 +05304682 true);
sheenam monga67ecb072019-09-20 11:25:23 +05304683 /* Set the default operation channel freq*/
4684 sta_ctx->conn_info.chan_freq = hdd_ctx->config->operating_chan_freq;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004685
4686 /* Make the default Auth Type as OPEN */
Jeff Johnson96e33512019-02-27 15:10:21 -08004687 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004688
4689 status = hdd_init_tx_rx(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304690 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004691 hdd_err("hdd_init_tx_rx() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004692 status, status);
4693 goto error_init_txrx;
4694 }
4695
4696 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4697
4698 status = hdd_wmm_adapter_init(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304699 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004700 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004701 status, status);
4702 goto error_wmm_init;
4703 }
4704
4705 set_bit(WMM_INIT_DONE, &adapter->event_flags);
4706
Qun Zhang1b3c85c2019-08-27 16:31:49 +08004707 status = ucfg_get_enable_sifs_burst(hdd_ctx->psoc, &enable_sifs_burst);
4708 if (!QDF_IS_STATUS_SUCCESS(status))
4709 hdd_err("Failed to get sifs burst value, use default");
4710
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004711 ret_val = sme_cli_set_command(adapter->vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004712 WMI_PDEV_PARAM_BURST_ENABLE,
Qun Zhang1b3c85c2019-08-27 16:31:49 +08004713 enable_sifs_burst,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004714 PDEV_CMD);
Dustin Brownd28772b2017-03-17 14:16:07 -07004715 if (ret_val)
4716 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004717
Poddar, Siddarth4b3f7312017-11-02 17:00:20 +05304718 /*
4719 * In case of USB tethering, LRO is disabled. If SSR happened
4720 * during that time, then as part of SSR init, do not enable
4721 * the LRO again. Keep the LRO state same as before SSR.
4722 */
jitiphil377bcc12018-10-05 19:46:08 +05304723 if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
4724 cfg_dp_lro_enable) &&
4725 !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -07004726 adapter->dev->features |= NETIF_F_LRO;
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05304727
Rakshith Suresh Patkar9f5c5862019-02-04 16:23:02 +05304728 if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
4729 cfg_dp_enable_ip_tcp_udp_checksum_offload))
4730 adapter->dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
4731 adapter->dev->features |= NETIF_F_RXCSUM;
4732
4733 hdd_set_tso_flags(hdd_ctx, adapter->dev);
4734
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05304735 /* rcpi info initialization */
4736 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
4737
Abhinav Kumar523ca372019-08-30 16:28:19 +05304738 if (adapter->device_mode == QDF_STA_MODE)
4739 mlme_set_roam_trigger_bitmap(hdd_ctx->psoc, adapter->vdev_id,
4740 DEFAULT_ROAM_TRIGGER_BITMAP);
4741
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304742 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004743
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004744error_wmm_init:
4745 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4746 hdd_deinit_tx_rx(adapter);
4747error_init_txrx:
Dustin Brownd28772b2017-03-17 14:16:07 -07004748 hdd_unregister_wext(adapter->dev);
Dustin Brownd28772b2017-03-17 14:16:07 -07004749 QDF_BUG(!hdd_vdev_destroy(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004750
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004751 return status;
4752}
4753
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304754/**
Krunal Soni4a020c72017-10-30 20:58:40 -07004755 * hdd_deinit_station_mode() - De-initialize the station adapter
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304756 * @hdd_ctx: global hdd context
4757 * @adapter: HDD adapter
Jeff Johnson590e2012016-10-05 16:16:24 -07004758 * @rtnl_held: Used to indicate whether or not the caller is holding
4759 * the kernel rtnl_mutex
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304760 *
4761 * This function De-initializes the STA/P2P/OCB adapter.
4762 *
4763 * Return: None.
4764 */
Krunal Soni4a020c72017-10-30 20:58:40 -07004765static void hdd_deinit_station_mode(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004766 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004767 bool rtnl_held)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304768{
Dustin Brownfdf17c12018-03-14 12:55:34 -07004769 hdd_enter_dev(adapter->dev);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304770
Hanumanth Reddy Pothula7a657402016-09-07 20:59:18 +05304771 if (adapter->dev) {
4772 if (rtnl_held)
4773 adapter->dev->wireless_handlers = NULL;
4774 else {
4775 rtnl_lock();
4776 adapter->dev->wireless_handlers = NULL;
4777 rtnl_unlock();
4778 }
4779 }
4780
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304781 if (test_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags)) {
4782 hdd_deinit_tx_rx(adapter);
4783 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4784 }
4785
4786 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
4787 hdd_wmm_adapter_close(adapter);
4788 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
4789 }
4790
Krunal Sonib51eec72017-11-20 21:53:01 -08004791
Dustin Browne74003f2018-03-14 12:51:58 -07004792 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304793}
4794
Krunal Sonib51eec72017-11-20 21:53:01 -08004795void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
4796 struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004797 bool rtnl_held)
4798{
Dustin Brown491d54b2018-03-14 12:39:11 -07004799 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304800
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004801 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004802 case QDF_STA_MODE:
4803 case QDF_P2P_CLIENT_MODE:
4804 case QDF_P2P_DEVICE_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08004805 case QDF_IBSS_MODE:
4806 case QDF_NDI_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004807 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004808 hdd_deinit_station_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004809 break;
4810 }
4811
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004812 case QDF_SAP_MODE:
4813 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004814 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004815 hdd_deinit_ap_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004816 break;
4817 }
4818
4819 default:
4820 break;
4821 }
4822
Dustin Browne74003f2018-03-14 12:51:58 -07004823 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004824}
4825
Min Liu8c5d99e2018-09-10 17:18:44 +08004826static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
4827 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004828 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004829{
Jeff Johnson5505db82017-11-02 21:19:23 -07004830 struct net_device *dev = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004831
4832 if (adapter)
Jeff Johnson5505db82017-11-02 21:19:23 -07004833 dev = adapter->dev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004834 else {
Jeff Johnson5880d792016-08-15 13:32:30 -07004835 hdd_err("adapter is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004836 return;
4837 }
4838
Alok Kumarb64650c2018-03-23 17:05:11 +05304839 hdd_nud_deinit_tracking(adapter);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05304840 hdd_mic_deinit_work(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05304841 qdf_mutex_destroy(&adapter->disconnection_status_lock);
Nachiket Kukade5f0ce4f2018-06-15 19:47:37 +05304842 hdd_apf_context_destroy(adapter);
Min Liu8c5d99e2018-09-10 17:18:44 +08004843 qdf_spinlock_destroy(&adapter->vdev_lock);
Alok Kumarb64650c2018-03-23 17:05:11 +05304844
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05304845 wlan_hdd_debugfs_csr_deinit(adapter);
Arunk Khandavallica56d4b2018-11-29 15:46:00 +05304846 if (adapter->device_mode == QDF_STA_MODE)
4847 hdd_sysfs_destroy_adapter_root_obj(adapter);
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05304848
Rajeev Kumardca5f812016-02-04 17:28:06 -08004849 hdd_debugfs_exit(adapter);
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05304850
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004851 /*
4852 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
4853 * the driver is almost closed and cannot handle either control
4854 * messages or data. However, unregister_netdevice() call above will
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004855 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
4856 * to close the active connections(basically excites control path) which
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004857 * is not right. Setting this flag helps hdd_stop() to recognize that
4858 * the interface is closed and restricts any operations on that
4859 */
4860 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
4861
4862 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004863 if (rtnl_held)
Jeff Johnson5505db82017-11-02 21:19:23 -07004864 unregister_netdevice(dev);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004865 else
Jeff Johnson5505db82017-11-02 21:19:23 -07004866 unregister_netdev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004867 /*
4868 * Note that the adapter is no longer valid at this point
4869 * since the memory has been reclaimed
4870 */
4871 }
4872}
4873
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004874static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07004875 tSirMacAddr mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004876{
Jeff Johnson9d295242017-08-29 14:39:48 -07004877 struct hdd_adapter *adapter;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004878
Dustin Brown920397d2017-12-13 16:27:50 -08004879 hdd_for_each_adapter(hdd_ctx, adapter) {
4880 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07004881 mac_addr, sizeof(tSirMacAddr))) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304882 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004883 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004884 }
Dustin Brown920397d2017-12-13 16:27:50 -08004885
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304886 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004887}
Ryan Hsu07495ea2016-01-21 15:25:39 -08004888
Arun Khandavalli2358d522016-05-16 18:05:37 +05304889#ifdef CONFIG_FW_LOGS_BASED_ON_INI
4890/**
4891 * hdd_set_fw_log_params() - Set log parameters to FW
4892 * @hdd_ctx: HDD Context
4893 * @adapter: HDD Adapter
4894 *
4895 * This function set the FW Debug log level based on the INI.
4896 *
4897 * Return: None
4898 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004899static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004900 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304901{
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304902 QDF_STATUS status;
4903 uint16_t enable_fw_log_level, enable_fw_log_type;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304904 int ret;
4905
Arun Khandavallifae92942016-08-01 13:31:08 +05304906 if (QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
4907 (!hdd_ctx->config->enable_fw_log)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004908 hdd_debug("enable_fw_log not enabled in INI or in FTM mode return");
Arun Khandavalli2358d522016-05-16 18:05:37 +05304909 return;
4910 }
4911
Arun Khandavallifae92942016-08-01 13:31:08 +05304912 /* Enable FW logs based on INI configuration */
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304913 status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc,
4914 &enable_fw_log_type);
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_TYPE,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304919 enable_fw_log_type,
Arun Khandavallifae92942016-08-01 13:31:08 +05304920 DBG_CMD);
4921 if (ret != 0)
4922 hdd_err("Failed to enable FW log type ret %d",
4923 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304924
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304925 status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc,
4926 &enable_fw_log_level);
4927 if (QDF_IS_STATUS_ERROR(status))
4928 return;
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004929 ret = sme_cli_set_command(adapter->vdev_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304930 WMI_DBGLOG_LOG_LEVEL,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304931 enable_fw_log_level,
Arun Khandavallifae92942016-08-01 13:31:08 +05304932 DBG_CMD);
4933 if (ret != 0)
4934 hdd_err("Failed to enable FW log level ret %d",
4935 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304936
lifengfaa83cb2018-11-24 01:53:56 +08004937 sme_enable_fw_module_log_level(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004938 adapter->vdev_id);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304939}
4940#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004941static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004942 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304943{
4944}
4945
4946#endif
4947
4948/**
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004949 * hdd_configure_chain_mask() - programs chain mask to firmware
4950 * @adapter: HDD adapter
4951 *
4952 * Return: 0 on success or errno on failure
4953 */
4954static int hdd_configure_chain_mask(struct hdd_adapter *adapter)
4955{
Naveen Rawat98322472018-03-06 10:29:42 -08004956 QDF_STATUS status;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004957 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Naveen Rawatdacb5032018-02-08 15:23:24 -08004958
Dustin Brown1dbefe62018-09-11 16:32:03 -07004959 status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004960 adapter->vdev_id);
gaurank kathpalia7633dfc2019-09-13 20:04:58 +05304961 if (QDF_IS_STATUS_ERROR(status))
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304962 goto error;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004963
4964 return 0;
4965
4966error:
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304967 hdd_err("WMI PDEV set param failed");
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004968 return -EINVAL;
4969}
4970
4971/**
Dundi Raviteja3b637092018-09-12 13:42:50 +05304972 * hdd_send_coex_config_params() - Send coex config params to FW
4973 * @hdd_ctx: HDD context
4974 * @adapter: Primary adapter context
4975 *
4976 * This function is used to send all coex config related params to FW
4977 *
4978 * Return: 0 on success and -EINVAL on failure
4979 */
4980static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx,
4981 struct hdd_adapter *adapter)
4982{
4983 struct coex_config_params coex_cfg_params = {0};
4984 struct wlan_fwol_coex_config config = {0};
Dustin Brown05d81302018-09-11 16:49:22 -07004985 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Dundi Raviteja3b637092018-09-12 13:42:50 +05304986 QDF_STATUS status;
4987
4988 if (!hdd_ctx) {
4989 hdd_err("hdd_ctx is invalid");
4990 goto err;
4991 }
4992
4993 if (!adapter) {
4994 hdd_err("adapter is invalid");
4995 goto err;
4996 }
4997
4998 if (!psoc) {
4999 hdd_err("HDD psoc is invalid");
5000 goto err;
5001 }
5002
5003 status = ucfg_fwol_get_coex_config_params(psoc, &config);
5004 if (QDF_IS_STATUS_ERROR(status)) {
5005 hdd_err("Unable to get coex config params");
5006 goto err;
5007 }
5008
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005009 coex_cfg_params.vdev_id = adapter->vdev_id;
Dundi Raviteja3b637092018-09-12 13:42:50 +05305010 coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER;
5011 coex_cfg_params.config_arg1 = config.max_tx_power_for_btc;
5012
5013 status = sme_send_coex_config_cmd(&coex_cfg_params);
5014 if (QDF_IS_STATUS_ERROR(status)) {
5015 hdd_err("Failed to send coex Tx power");
5016 goto err;
5017 }
5018
5019 coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI;
5020 coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold;
5021
5022 status = sme_send_coex_config_cmd(&coex_cfg_params);
5023 if (QDF_IS_STATUS_ERROR(status)) {
5024 hdd_err("Failed to send coex handover RSSI");
5025 goto err;
5026 }
5027
5028 coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE;
5029 coex_cfg_params.config_arg1 = config.btc_mode;
5030
5031 status = sme_send_coex_config_cmd(&coex_cfg_params);
5032 if (QDF_IS_STATUS_ERROR(status)) {
5033 hdd_err("Failed to send coex BTC mode");
5034 goto err;
5035 }
5036
5037 coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION;
5038 coex_cfg_params.config_arg1 = config.antenna_isolation;
5039
5040 status = sme_send_coex_config_cmd(&coex_cfg_params);
5041 if (QDF_IS_STATUS_ERROR(status)) {
5042 hdd_err("Failed to send coex antenna isolation");
5043 goto err;
5044 }
5045
5046 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD;
5047 coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold;
5048
5049 status = sme_send_coex_config_cmd(&coex_cfg_params);
5050 if (QDF_IS_STATUS_ERROR(status)) {
5051 hdd_err("Failed to send coex BT low RSSI threshold");
5052 goto err;
5053 }
5054
5055 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL;
5056 coex_cfg_params.config_arg1 = config.bt_interference_low_ll;
5057 coex_cfg_params.config_arg2 = config.bt_interference_low_ul;
5058 coex_cfg_params.config_arg3 = config.bt_interference_medium_ll;
5059 coex_cfg_params.config_arg4 = config.bt_interference_medium_ul;
5060 coex_cfg_params.config_arg5 = config.bt_interference_high_ll;
5061 coex_cfg_params.config_arg6 = config.bt_interference_high_ul;
5062
5063 status = sme_send_coex_config_cmd(&coex_cfg_params);
5064 if (QDF_IS_STATUS_ERROR(status)) {
5065 hdd_err("Failed to send coex BT interference level");
5066 goto err;
5067 }
stonezc9936cb2019-03-11 16:41:22 +08005068
5069 if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config))
5070 goto err;
5071
hqu1dd504a2019-06-04 11:24:11 +08005072 coex_cfg_params.config_type =
5073 WMI_COEX_CONFIG_BT_SCO_ALLOW_WLAN_2G_SCAN;
5074 coex_cfg_params.config_arg1 = config.bt_sco_allow_wlan_2g_scan;
5075
5076 status = sme_send_coex_config_cmd(&coex_cfg_params);
5077 if (QDF_IS_STATUS_ERROR(status)) {
5078 hdd_err("Failed to send coex BT sco allow wlan 2g scan");
5079 goto err;
5080 }
5081
Dundi Raviteja3b637092018-09-12 13:42:50 +05305082 return 0;
5083err:
5084 return -EINVAL;
5085}
5086
5087/**
Arun Khandavalli2358d522016-05-16 18:05:37 +05305088 * hdd_set_fw_params() - Set parameters to firmware
5089 * @adapter: HDD adapter
5090 *
5091 * This function Sets various parameters to fw once the
5092 * adapter is started.
5093 *
5094 * Return: 0 on success or errno on failure
5095 */
Jeff Johnson9d295242017-08-29 14:39:48 -07005096int hdd_set_fw_params(struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05305097{
5098 int ret;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05305099 uint16_t upper_brssi_thresh, lower_brssi_thresh, rts_profile;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05305100 bool enable_dtim_1chrx;
5101 QDF_STATUS status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005102 struct hdd_context *hdd_ctx;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05305103 bool bval = false;
Manikandan Mohand350c192018-11-29 14:01:12 -08005104 uint8_t max_amsdu_len, enable_tx_sch_delay;
5105 uint32_t dtim_sel_diversity, enable_secondary_rate;
Arun Khandavalli2358d522016-05-16 18:05:37 +05305106
Dustin Brownfdf17c12018-03-14 12:55:34 -07005107 hdd_enter_dev(adapter->dev);
Arun Khandavalli2358d522016-05-16 18:05:37 +05305108
5109 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
5110 if (!hdd_ctx)
5111 return -EINVAL;
5112
Dustin Brown732ab9c2017-06-15 13:24:09 -07005113 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
5114 hdd_debug("FTM Mode is active; nothing to do");
5115 return 0;
5116 }
5117
Manikandan Mohand350c192018-11-29 14:01:12 -08005118 ret = -1;
5119 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_lprx_enable(hdd_ctx->psoc,
5120 &bval))) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005121 ret = sme_cli_set_command(adapter->vdev_id,
Manikandan Mohand350c192018-11-29 14:01:12 -08005122 WMI_PDEV_PARAM_DTIM_SYNTH,
5123 bval, PDEV_CMD);
5124 }
Ashish Kumar Dhanotiyab8630ab2017-07-21 14:18:14 +05305125 if (ret) {
5126 hdd_err("Failed to set LPRx");
5127 goto error;
5128 }
5129
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +05305130 ucfg_mlme_get_dtim_selection_diversity(hdd_ctx->psoc,
5131 &dtim_sel_diversity);
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05305132
5133 ret = sme_cli_set_command(
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005134 adapter->vdev_id,
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05305135 WMI_PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION,
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +05305136 dtim_sel_diversity, PDEV_CMD);
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05305137 if (ret) {
5138 hdd_err("Failed to set DTIM_OPTIMIZED_CHAIN_SELECTION");
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_tx_sch_delay(
5144 hdd_ctx->psoc, &enable_tx_sch_delay))) {
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_TX_SCH_DELAY,
5147 enable_tx_sch_delay, PDEV_CMD);
5148 }
Ashish Kumar Dhanotiya48dac7d2018-03-28 14:59:50 +05305149 if (ret) {
5150 hdd_err("Failed to set WMI_PDEV_PARAM_TX_SCH_DELAY");
5151 goto error;
5152 }
5153
Manikandan Mohand350c192018-11-29 14:01:12 -08005154 ret = -1;
5155 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_secondary_rate(
5156 hdd_ctx->psoc, &enable_secondary_rate))) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005157 ret = sme_cli_set_command(adapter->vdev_id,
Manikandan Mohand350c192018-11-29 14:01:12 -08005158 WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE,
5159 enable_secondary_rate, PDEV_CMD);
5160 }
Ashish Kumar Dhanotiya959b38c2018-04-06 21:07:57 +05305161 if (ret) {
5162 hdd_err("Failed to set WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE");
5163 goto error;
5164 }
5165
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05305166 if (adapter->device_mode == QDF_STA_MODE) {
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05305167 status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc,
5168 &upper_brssi_thresh);
5169 if (QDF_IS_STATUS_ERROR(status))
5170 return -EINVAL;
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05305171
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005172 sme_set_smps_cfg(adapter->vdev_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05305173 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH,
5174 upper_brssi_thresh);
5175
5176 status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc,
5177 &lower_brssi_thresh);
5178 if (QDF_IS_STATUS_ERROR(status))
5179 return -EINVAL;
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05305180
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005181 sme_set_smps_cfg(adapter->vdev_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05305182 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH,
5183 lower_brssi_thresh);
5184
5185 status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc,
5186 &enable_dtim_1chrx);
5187 if (QDF_IS_STATUS_ERROR(status))
5188 return -EINVAL;
5189
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005190 sme_set_smps_cfg(adapter->vdev_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05305191 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE,
5192 enable_dtim_1chrx);
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05305193 }
5194
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05305195 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
5196 if (!QDF_IS_STATUS_SUCCESS(status))
5197 hdd_err("unable to get vht_enable2x2");
5198
5199 if (bval) {
Dustin Brown732ab9c2017-06-15 13:24:09 -07005200 hdd_debug("configuring 2x2 mode fw params");
5201
Vignesh Viswanathana851d752018-10-03 19:44:38 +05305202 ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005203 adapter->vdev_id);
Dustin Brown732ab9c2017-06-15 13:24:09 -07005204 if (ret) {
5205 hdd_err("WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE set failed %d",
5206 ret);
5207 goto error;
5208 }
Liangwei Dong22810e82018-03-15 03:42:12 -04005209
5210 if (hdd_configure_chain_mask(adapter))
5211 goto error;
Dustin Brown732ab9c2017-06-15 13:24:09 -07005212 } else {
Arun Khandavalli2358d522016-05-16 18:05:37 +05305213#define HDD_DTIM_1CHAIN_RX_ID 0x5
5214#define HDD_SMPS_PARAM_VALUE_S 29
Dustin Brown732ab9c2017-06-15 13:24:09 -07005215 hdd_debug("configuring 1x1 mode fw params");
5216
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07005217 /*
5218 * Disable DTIM 1 chain Rx when in 1x1,
5219 * we are passing two value
5220 * as param_id << 29 | param_value.
5221 * Below param_value = 0(disable)
5222 */
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005223 ret = sme_cli_set_command(adapter->vdev_id,
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07005224 WMI_STA_SMPS_PARAM_CMDID,
5225 HDD_DTIM_1CHAIN_RX_ID <<
5226 HDD_SMPS_PARAM_VALUE_S,
5227 VDEV_CMD);
5228 if (ret) {
5229 hdd_err("DTIM 1 chain set failed %d", ret);
5230 goto error;
5231 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05305232
Arun Khandavalli2358d522016-05-16 18:05:37 +05305233#undef HDD_DTIM_1CHAIN_RX_ID
5234#undef HDD_SMPS_PARAM_VALUE_S
Naveen Rawat269b4ed2017-12-07 06:47:32 -08005235
5236 if (hdd_configure_chain_mask(adapter))
5237 goto error;
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07005238 }
5239
Vignesh Viswanathana851d752018-10-03 19:44:38 +05305240 ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005241 adapter->vdev_id);
Dustin Brown732ab9c2017-06-15 13:24:09 -07005242 if (ret) {
5243 hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d", ret);
5244 goto error;
5245 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05305246
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05305247 status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile);
5248 if (QDF_IS_STATUS_ERROR(status))
5249 return -EINVAL;
5250
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005251 ret = sme_cli_set_command(adapter->vdev_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07005252 WMI_VDEV_PARAM_ENABLE_RTSCTS,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05305253 rts_profile,
Dustin Brown732ab9c2017-06-15 13:24:09 -07005254 VDEV_CMD);
5255 if (ret) {
5256 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
5257 goto error;
Arun Khandavalli2358d522016-05-16 18:05:37 +05305258 }
5259
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05305260 status = ucfg_mlme_get_max_amsdu_num(hdd_ctx->psoc, &max_amsdu_len);
5261 if (QDF_IS_STATUS_ERROR(status)) {
5262 hdd_err("Failed to get Max AMSDU Num");
5263 goto error;
5264 }
5265
5266 hdd_debug("SET AMSDU num %d", max_amsdu_len);
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07005267
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005268 ret = wma_cli_set_command(adapter->vdev_id,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07005269 GEN_VDEV_PARAM_AMSDU,
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05305270 max_amsdu_len,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07005271 GEN_CMD);
5272 if (ret != 0) {
5273 hdd_err("GEN_VDEV_PARAM_AMSDU set failed %d", ret);
5274 goto error;
5275 }
5276
Arun Khandavalli2358d522016-05-16 18:05:37 +05305277 hdd_set_fw_log_params(hdd_ctx, adapter);
Dundi Raviteja3b637092018-09-12 13:42:50 +05305278
5279 ret = hdd_send_coex_config_params(hdd_ctx, adapter);
5280 if (ret) {
5281 hdd_warn("Error initializing coex config params");
5282 goto error;
5283 }
5284
Dustin Browne74003f2018-03-14 12:51:58 -07005285 hdd_exit();
Dustin Brown732ab9c2017-06-15 13:24:09 -07005286
Arun Khandavalli2358d522016-05-16 18:05:37 +05305287 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05305288
Arun Khandavalli2358d522016-05-16 18:05:37 +05305289error:
5290 return -EINVAL;
5291}
5292
Ryan Hsu07495ea2016-01-21 15:25:39 -08005293/**
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305294 * hdd_init_completion() - Initialize Completion Variables
5295 * @adapter: HDD adapter
5296 *
5297 * This function Initialize the completion variables for
5298 * a particular adapter
5299 *
5300 * Return: None
5301 */
5302static void hdd_init_completion(struct hdd_adapter *adapter)
5303{
5304 init_completion(&adapter->disconnect_comp_var);
5305 init_completion(&adapter->roaming_comp_var);
5306 init_completion(&adapter->linkup_event_var);
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305307 init_completion(&adapter->sta_authorized_event);
5308 init_completion(&adapter->offchannel_tx_event);
5309 init_completion(&adapter->tx_action_cnf_event);
5310 init_completion(&adapter->ibss_peer_info_comp);
5311 init_completion(&adapter->lfr_fw_status.disable_lfr_event);
5312}
5313
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305314static void hdd_reset_locally_admin_bit(struct hdd_context *hdd_ctx,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005315 tSirMacAddr mac_addr)
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305316{
5317 int i;
5318 /*
5319 * Reset locally administered bit for dynamic_mac_list
5320 * also as while releasing the MAC address for any
5321 * interface mac will be compared with dynamic mac list
5322 */
5323 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
5324 if (!qdf_mem_cmp(
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005325 mac_addr,
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305326 &hdd_ctx->
5327 dynamic_mac_list[i].dynamic_mac.bytes[0],
5328 sizeof(struct qdf_mac_addr))) {
5329 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(
5330 hdd_ctx->
5331 dynamic_mac_list[i].dynamic_mac.bytes);
5332 break;
5333 }
5334 }
5335 /*
5336 * Reset locally administered bit if the device mode is
5337 * STA
5338 */
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005339 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305340 hdd_debug("locally administered bit reset in sta mode: "
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07005341 QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(mac_addr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305342}
5343
Dustin Brown96b98dd2019-03-06 12:39:37 -08005344static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
5345{
5346 struct hdd_adapter *adapter =
5347 container_of(work, struct hdd_adapter, scan_block_work);
5348 struct osif_vdev_sync *vdev_sync;
5349
5350 if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync))
5351 return;
5352
5353 wlan_hdd_cfg80211_scan_block(adapter);
5354
5355 osif_vdev_sync_op_stop(vdev_sync);
5356}
5357
Rachit Kankane33bf18f2019-06-20 08:05:07 +05305358static u8 hdd_get_mode_specific_interface_count(struct hdd_context *hdd_ctx,
5359 enum QDF_OPMODE mode)
5360{
5361 struct hdd_adapter *adapter = NULL;
5362 u8 intf_count = 0;
5363
5364 hdd_for_each_adapter(hdd_ctx, adapter) {
5365 if (adapter->device_mode == mode)
5366 intf_count++;
5367 }
5368 return intf_count;
5369}
5370
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305371/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08005372 * hdd_open_adapter() - open and setup the hdd adatper
5373 * @hdd_ctx: global hdd context
5374 * @session_type: type of the interface to be created
5375 * @iface_name: User-visible name of the interface
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005376 * @mac_addr: MAC address to assign to the interface
Ryan Hsu07495ea2016-01-21 15:25:39 -08005377 * @name_assign_type: the name of assign type of the netdev
5378 * @rtnl_held: the rtnl lock hold flag
5379 *
5380 * This function open and setup the hdd adpater according to the device
5381 * type request, assign the name, the mac address assigned, and then prepared
5382 * the hdd related parameters, queue, lock and ready to start.
5383 *
5384 * Return: the pointer of hdd adapter, otherwise NULL.
5385 */
Jeff Johnson9d295242017-08-29 14:39:48 -07005386struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t session_type,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005387 const char *iface_name, tSirMacAddr mac_addr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08005388 unsigned char name_assign_type,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08005389 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005390{
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305391 struct net_device *ndev = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07005392 struct hdd_adapter *adapter = NULL;
Rachit Kankane33bf18f2019-06-20 08:05:07 +05305393 u8 intf_count = 0;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305394 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005395
5396 if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
5397 /*
5398 * Max limit reached on the number of vdevs configured by the
5399 * host. Return error
5400 */
Arun Khandavallifae92942016-08-01 13:31:08 +05305401 hdd_err("Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
5402 hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005403 return NULL;
5404 }
5405
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005406 status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)mac_addr);
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05305407 if (QDF_IS_STATUS_ERROR(status)) {
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005408 /* Not received valid mac_addr */
Arun Khandavallifae92942016-08-01 13:31:08 +05305409 hdd_err("Unable to add virtual intf: Not able to get valid mac address");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005410 return NULL;
5411 }
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05305412
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005413 status = hdd_check_for_existing_macaddr(hdd_ctx, mac_addr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305414 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07005415 hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_STR
Arun Khandavallifae92942016-08-01 13:31:08 +05305416 " already exists",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07005417 QDF_MAC_ADDR_ARRAY(mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005418 return NULL;
5419 }
5420
5421 switch (session_type) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005422 case QDF_STA_MODE:
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305423 if (!hdd_ctx->config->mac_provision) {
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005424 hdd_reset_locally_admin_bit(hdd_ctx, mac_addr);
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305425 /*
5426 * After resetting locally administered bit
5427 * again check if the new mac address is already
5428 * exists.
5429 */
5430 status = hdd_check_for_existing_macaddr(hdd_ctx,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005431 mac_addr);
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305432 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -07005433 hdd_err("Duplicate MAC addr: " QDF_MAC_ADDR_STR
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305434 " already exists",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -07005435 QDF_MAC_ADDR_ARRAY(mac_addr));
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305436 return NULL;
5437 }
5438 }
Rachit Kankane33bf18f2019-06-20 08:05:07 +05305439 /* Check for max no of supported VDEVs before creating
5440 * another one.
5441 */
5442 intf_count = hdd_get_mode_specific_interface_count(
5443 hdd_ctx,
5444 session_type);
5445 if (CFG_TGT_DEFAULT_MAX_STA_VDEVS &&
5446 (intf_count >= CFG_TGT_DEFAULT_MAX_STA_VDEVS)) {
5447 hdd_err("Max limit reached sta vdev-current %d max %d",
5448 intf_count, CFG_TGT_DEFAULT_MAX_STA_VDEVS);
5449 return NULL;
5450 }
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05305451
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005452 /* fall through */
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005453 case QDF_P2P_CLIENT_MODE:
5454 case QDF_P2P_DEVICE_MODE:
5455 case QDF_OCB_MODE:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07005456 case QDF_NDI_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305457 case QDF_MONITOR_MODE:
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005458 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08005459 name_assign_type,
5460 iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005461
Jeff Johnsond36fa332019-03-18 13:42:25 -07005462 if (!adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05305463 hdd_err("failed to allocate adapter for session %d",
5464 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005465 return NULL;
5466 }
5467
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305468 ndev = adapter->dev;
5469
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005470 if (QDF_P2P_CLIENT_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005471 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005472 else if (QDF_P2P_DEVICE_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005473 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305474 else if (QDF_MONITOR_MODE == session_type)
5475 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005476 else
5477 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
5478
5479 adapter->device_mode = session_type;
5480
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005481
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005482 /*
5483 * Workqueue which gets scheduled in IPv4 notification
5484 * callback
5485 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005486 INIT_WORK(&adapter->ipv4_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005487 hdd_ipv4_notifier_work_queue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005488
5489#ifdef WLAN_NS_OFFLOAD
5490 /*
5491 * Workqueue which gets scheduled in IPv6
5492 * notification callback.
5493 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005494 INIT_WORK(&adapter->ipv6_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005495 hdd_ipv6_notifier_work_queue);
5496#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005497 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005498 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08005499 goto err_free_netdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005500
5501 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005502 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005503 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305504 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5505 WLAN_CONTROL_PATH);
Arun Khandavallifae92942016-08-01 13:31:08 +05305506
Alok Kumarb64650c2018-03-23 17:05:11 +05305507 hdd_nud_init_tracking(adapter);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05305508 hdd_mic_init_work(adapter);
5509
Arunk Khandavallica56d4b2018-11-29 15:46:00 +05305510 if (adapter->device_mode == QDF_STA_MODE ||
5511 adapter->device_mode == QDF_P2P_DEVICE_MODE)
5512 hdd_sysfs_create_adapter_root_obj(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305513 qdf_mutex_create(&adapter->disconnection_status_lock);
5514
Ravi Joshi1a292562017-05-18 16:28:54 -07005515 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005516
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005517 case QDF_P2P_GO_MODE:
5518 case QDF_SAP_MODE:
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005519 adapter = hdd_wlan_create_ap_dev(hdd_ctx, mac_addr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08005520 name_assign_type,
5521 (uint8_t *) iface_name);
Jeff Johnsond36fa332019-03-18 13:42:25 -07005522 if (!adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005523 hdd_err("failed to allocate adapter for session %d",
Arun Khandavallifae92942016-08-01 13:31:08 +05305524 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005525 return NULL;
5526 }
5527
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305528 ndev = adapter->dev;
5529
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005530 adapter->wdev.iftype =
5531 (session_type ==
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005532 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005533 NL80211_IFTYPE_P2P_GO;
5534 adapter->device_mode = session_type;
5535
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07005536 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005537 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005538 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08005539
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005540 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005541 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305542 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5543 WLAN_CONTROL_PATH);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305544
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05305545 hdd_mic_init_work(adapter);
5546
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305547 /*
5548 * Workqueue which gets scheduled in IPv4 notification
5549 * callback
5550 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005551 INIT_WORK(&adapter->ipv4_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305552 hdd_ipv4_notifier_work_queue);
5553
5554#ifdef WLAN_NS_OFFLOAD
5555 /*
5556 * Workqueue which gets scheduled in IPv6
5557 * notification callback.
5558 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005559 INIT_WORK(&adapter->ipv6_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305560 hdd_ipv6_notifier_work_queue);
5561#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005562 break;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305563 case QDF_FTM_MODE:
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005564 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr,
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305565 name_assign_type,
Lin Bai1c678482017-12-18 18:29:11 +08005566 iface_name);
Jeff Johnsond36fa332019-03-18 13:42:25 -07005567 if (!adapter) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305568 hdd_err("Failed to allocate adapter for FTM mode");
5569 return NULL;
5570 }
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305571
5572 ndev = adapter->dev;
5573
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305574 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
5575 adapter->device_mode = session_type;
5576 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005577 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08005578 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08005579
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305580 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005581 hdd_debug("Disabling queues");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305582 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305583 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5584 WLAN_CONTROL_PATH);
Rakshith Suresh Patkara8405f52019-09-09 17:59:10 +05305585
5586 hdd_mic_init_work(adapter);
5587
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305588 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005589 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005590 hdd_err("Invalid session type %d", session_type);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305591 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005592 return NULL;
5593 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005594
Min Liu8c5d99e2018-09-10 17:18:44 +08005595 qdf_spinlock_create(&adapter->vdev_lock);
5596
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305597 hdd_init_completion(adapter);
hqueaa33ee2017-05-04 17:56:35 +08005598 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
Min Liu9be5d4a2018-05-17 11:51:53 +08005599 qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT);
5600 qdf_mutex_create(&adapter->blocked_scan_request_q_lock);
hqueaa33ee2017-05-04 17:56:35 +08005601
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305602 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005603 /* Add it to the hdd's session list. */
Dustin Brown920397d2017-12-13 16:27:50 -08005604 status = hdd_add_adapter_back(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005605 }
5606
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305607 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsond36fa332019-03-18 13:42:25 -07005608 if (adapter) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005609 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
5610 adapter = NULL;
5611 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005612
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005613 return NULL;
5614 }
Nachiket Kukade5f0ce4f2018-06-15 19:47:37 +05305615 hdd_apf_context_init(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005616
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305617 if (QDF_STATUS_SUCCESS == status) {
Dustin Brown1dbefe62018-09-11 16:32:03 -07005618 policy_mgr_set_concurrency_mode(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005619 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005620
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005621 /* Adapter successfully added. Increment the vdev count */
5622 hdd_ctx->current_intf_count++;
5623
Jeff Johnson5880d792016-08-15 13:32:30 -07005624 hdd_debug("current_intf_count=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005625 hdd_ctx->current_intf_count);
5626
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08005627 hdd_check_and_restart_sap_with_non_dfs_acs();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005628 }
5629
Rajeev Kumardca5f812016-02-04 17:28:06 -08005630 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
Mahesh Kumar Kalikot Veetil80dda9a2017-07-17 11:38:03 -07005631 hdd_err("Interface %s wow debug_fs init failed",
5632 netdev_name(adapter->dev));
5633
5634 hdd_info("%s interface created. iftype: %d", netdev_name(adapter->dev),
5635 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005636
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05305637 if (adapter->device_mode == QDF_STA_MODE)
5638 wlan_hdd_debugfs_csr_init(adapter);
5639
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005640 return adapter;
5641
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005642err_free_netdev:
Jeff Johnson1e851a12017-10-28 14:36:12 -07005643 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305644
5645 if (ndev)
5646 free_netdev(ndev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005647
5648 return NULL;
5649}
5650
Dustin Brown728d65a2018-10-02 16:27:52 -07005651static void __hdd_close_adapter(struct hdd_context *hdd_ctx,
5652 struct hdd_adapter *adapter,
5653 bool rtnl_held)
5654{
5655 qdf_list_destroy(&adapter->blocked_scan_request_q);
5656 qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock);
5657 policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
5658
5659 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
5660
5661 if (hdd_ctx->current_intf_count != 0)
5662 hdd_ctx->current_intf_count--;
5663}
5664
5665void hdd_close_adapter(struct hdd_context *hdd_ctx,
5666 struct hdd_adapter *adapter,
5667 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005668{
Dustin Brown920397d2017-12-13 16:27:50 -08005669 /*
Dustin Brown728d65a2018-10-02 16:27:52 -07005670 * Stop the global bus bandwidth timer while touching the adapter list
5671 * to avoid bad memory access by the timer handler.
Dustin Brown920397d2017-12-13 16:27:50 -08005672 */
Dustin Brown920397d2017-12-13 16:27:50 -08005673 hdd_bus_bw_compute_timer_stop(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005674
Dustin Brown920397d2017-12-13 16:27:50 -08005675 hdd_remove_adapter(hdd_ctx, adapter);
Dustin Brown728d65a2018-10-02 16:27:52 -07005676 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005677
Dustin Brown920397d2017-12-13 16:27:50 -08005678 /* conditionally restart the bw timer */
5679 hdd_bus_bw_compute_timer_try_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005680}
5681
Dustin Brown728d65a2018-10-02 16:27:52 -07005682void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005683{
Dustin Brown920397d2017-12-13 16:27:50 -08005684 struct hdd_adapter *adapter;
Dustin Brown2c5e0482019-02-05 16:14:43 -08005685 struct osif_vdev_sync *vdev_sync;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005686
Dustin Brown491d54b2018-03-14 12:39:11 -07005687 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005688
Dustin Brown728d65a2018-10-02 16:27:52 -07005689 while (QDF_IS_STATUS_SUCCESS(hdd_remove_front_adapter(hdd_ctx,
5690 &adapter))) {
Dustin Brown2c5e0482019-02-05 16:14:43 -08005691 vdev_sync = osif_vdev_sync_unregister(adapter->dev);
Dustin Brown693b5352019-01-17 10:00:31 -08005692 if (vdev_sync)
Dustin Brown2c5e0482019-02-05 16:14:43 -08005693 osif_vdev_sync_wait_for_ops(vdev_sync);
Dustin Brown693b5352019-01-17 10:00:31 -08005694
Dustin Brown728d65a2018-10-02 16:27:52 -07005695 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
5696 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
Dustin Brown693b5352019-01-17 10:00:31 -08005697
5698 if (vdev_sync)
Dustin Brown2c5e0482019-02-05 16:14:43 -08005699 osif_vdev_sync_destroy(vdev_sync);
Dustin Brown728d65a2018-10-02 16:27:52 -07005700 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005701
Dustin Browne74003f2018-03-14 12:51:58 -07005702 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005703}
5704
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005705void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005706{
Anurag Chouhan6d760662016-02-20 16:05:43 +05305707 struct qdf_mac_addr *bssid = NULL;
Jeff Johnsonc565af12019-03-10 21:09:47 -07005708 tSirUpdateIE update_ie;
Jeff Johnson16528362018-06-14 12:34:16 -07005709 mac_handle_t mac_handle;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005710
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005711 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005712 case QDF_STA_MODE:
5713 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005714 {
Jeff Johnsond377dce2017-10-04 10:32:42 -07005715 struct hdd_station_ctx *sta_ctx =
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005716 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnsone04b6992019-02-27 14:06:55 -08005717 bssid = &sta_ctx->conn_info.bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005718 break;
5719 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005720 case QDF_SAP_MODE:
5721 case QDF_P2P_GO_MODE:
5722 case QDF_IBSS_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005723 {
Jeff Johnson1e851a12017-10-28 14:36:12 -07005724 bssid = &adapter->mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005725 break;
5726 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005727 case QDF_FTM_MODE:
5728 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005729 default:
5730 /*
5731 * wlan_hdd_reset_prob_rspies should not have been called
5732 * for these kind of devices
5733 */
Jeff Johnson5880d792016-08-15 13:32:30 -07005734 hdd_err("Unexpected request for the current device type %d",
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005735 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005736 return;
5737 }
5738
Jeff Johnsonc565af12019-03-10 21:09:47 -07005739 qdf_copy_macaddr(&update_ie.bssid, bssid);
5740 update_ie.smeSessionId = adapter->vdev_id;
5741 update_ie.ieBufferlength = 0;
5742 update_ie.pAdditionIEBuffer = NULL;
5743 update_ie.append = true;
5744 update_ie.notify = false;
Jeff Johnson16528362018-06-14 12:34:16 -07005745 mac_handle = hdd_adapter_get_mac_handle(adapter);
5746 if (sme_update_add_ie(mac_handle,
Jeff Johnsonc565af12019-03-10 21:09:47 -07005747 &update_ie,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305748 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005749 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005750 }
5751}
5752
Dustin Browndb2a8be2017-12-20 11:49:56 -08005753QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
5754 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005755{
Dustin Brownd747ecd2018-10-26 16:32:22 -07005756 QDF_STATUS status = QDF_STATUS_SUCCESS;
5757 struct hdd_station_ctx *sta_ctx;
Dustin Brownb4260d52019-01-24 11:53:08 -08005758 struct sap_context *sap_ctx;
Jeff Johnson025618c2018-03-18 14:41:00 -07005759 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005760 union iwreq_data wrqu;
Jeff Johnsonc565af12019-03-10 21:09:47 -07005761 tSirUpdateIE update_ie;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005762 unsigned long rc;
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07005763 struct sap_config *sap_config;
Jeff Johnson16528362018-06-14 12:34:16 -07005764 mac_handle_t mac_handle;
Min Liu8c5d99e2018-09-10 17:18:44 +08005765 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005766
Dustin Brown491d54b2018-03-14 12:39:11 -07005767 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005768
Jeff Johnson912b1bb2019-03-06 10:12:36 -08005769 if (adapter->vdev_id != WLAN_UMAC_VDEV_ID_MAX)
Dustin Browne7e71d32018-05-11 16:00:08 -07005770 wlan_hdd_cfg80211_deregister_frames(adapter);
5771
Alok Kumarb64650c2018-03-23 17:05:11 +05305772 hdd_nud_ignore_tracking(adapter, true);
5773 hdd_nud_reset_tracking(adapter);
Alok Kumar016a1ac2018-09-16 09:55:50 +05305774 hdd_nud_flush_work(adapter);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05305775 hdd_mic_flush_work(adapter);
hangtian9c47aaf2018-11-26 17:59:39 +08005776 hdd_stop_tsf_sync(adapter);
bings6b7c21b2019-07-31 13:57:31 +08005777 cds_flush_work(&adapter->scan_block_work);
5778 wlan_hdd_cfg80211_scan_block(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305779
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005780 hdd_debug("Disabling queues");
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305781 wlan_hdd_netif_queue_control(adapter,
5782 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5783 WLAN_CONTROL_PATH);
Jeff Johnson16528362018-06-14 12:34:16 -07005784
5785 mac_handle = hdd_ctx->mac_handle;
5786
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005787 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005788 case QDF_STA_MODE:
5789 case QDF_P2P_CLIENT_MODE:
5790 case QDF_IBSS_MODE:
5791 case QDF_P2P_DEVICE_MODE:
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005792 case QDF_NDI_MODE:
Dustin Brownd747ecd2018-10-26 16:32:22 -07005793 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5794
5795 if (adapter->device_mode == QDF_NDI_MODE ||
5796 hdd_conn_is_connected(sta_ctx) ||
5797 hdd_is_connecting(sta_ctx)) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005798 INIT_COMPLETION(adapter->disconnect_comp_var);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005799
Jeff Johnson025618c2018-03-18 14:41:00 -07005800 roam_profile = hdd_roam_profile(adapter);
5801 /* For NDI do not use roam_profile */
Dustin Brownd747ecd2018-10-26 16:32:22 -07005802 if (adapter->device_mode == QDF_NDI_MODE)
5803 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005804 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005805 adapter->vdev_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005806 eCSR_DISCONNECT_REASON_NDI_DELETE);
Jeff Johnson025618c2018-03-18 14:41:00 -07005807 else if (roam_profile->BSSType ==
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005808 eCSR_BSS_TYPE_START_IBSS)
Dustin Brownd747ecd2018-10-26 16:32:22 -07005809 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005810 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005811 adapter->vdev_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005812 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Vevek Venkatesane81bca82019-08-12 22:25:15 +05305813 else if (adapter->device_mode == QDF_STA_MODE) {
5814 rc = wlan_hdd_disconnect(
5815 adapter,
5816 eCSR_DISCONNECT_REASON_DEAUTH);
5817 if (rc != 0 && ucfg_ipa_is_enabled()) {
5818 hdd_err("STA disconnect failed");
5819 ucfg_ipa_uc_cleanup_sta(hdd_ctx->pdev,
5820 adapter->dev);
5821 }
5822 } else {
Dustin Brownd747ecd2018-10-26 16:32:22 -07005823 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005824 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005825 adapter->vdev_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005826 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Vevek Venkatesane81bca82019-08-12 22:25:15 +05305827 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005828 /* success implies disconnect is queued */
5829 if (QDF_IS_STATUS_SUCCESS(status) &&
5830 adapter->device_mode != QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005831 rc = wait_for_completion_timeout(
5832 &adapter->disconnect_comp_var,
5833 msecs_to_jiffies
Abhishek Singhd1f21c72019-01-21 15:16:34 +05305834 (SME_DISCONNECT_TIMEOUT));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005835 if (!rc)
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005836 hdd_warn("disconn_comp_var wait fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005837 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005838 if (QDF_IS_STATUS_ERROR(status))
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005839 hdd_warn("failed to post disconnect");
Dustin Brownd747ecd2018-10-26 16:32:22 -07005840
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005841 memset(&wrqu, '\0', sizeof(wrqu));
5842 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
5843 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
5844 wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu,
5845 NULL);
Sachin Ahuja988fd102016-09-15 17:16:25 +05305846 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005847
Dustin Brownd747ecd2018-10-26 16:32:22 -07005848 wlan_hdd_scan_abort(adapter);
Wu Gao4a1ec8c2018-07-23 19:18:40 +08005849 wlan_hdd_cleanup_actionframe(adapter);
Abhishek Singh1e94d7a2015-11-30 17:26:54 +05305850 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05305851 hdd_clear_fils_connection_info(adapter);
Ashish Kumar Dhanotiya36510832019-02-20 22:13:25 +05305852
Liangwei Donga44d55b2019-03-20 03:22:08 -04005853 status = wlan_hdd_flush_pmksa_cache(adapter);
Ashish Kumar Dhanotiya36510832019-02-20 22:13:25 +05305854 if (QDF_IS_STATUS_ERROR(status))
5855 hdd_err("Cannot flush PMKIDCache");
5856
Visweswara Tanukub5a61242019-03-26 12:24:13 +05305857 hdd_deregister_hl_netdev_fc_timer(adapter);
5858
Dustin Brownd747ecd2018-10-26 16:32:22 -07005859 hdd_deregister_tx_flow_control(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005860
5861#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005862 cancel_work_sync(&adapter->ipv4_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005863#ifdef WLAN_NS_OFFLOAD
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005864 cancel_work_sync(&adapter->ipv6_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005865#endif
5866#endif
5867
Min Liu8c5d99e2018-09-10 17:18:44 +08005868 if (adapter->device_mode == QDF_STA_MODE) {
5869 struct wlan_objmgr_vdev *vdev;
5870
5871 vdev = hdd_objmgr_get_vdev(adapter);
5872 if (vdev) {
5873 wlan_cfg80211_sched_scan_stop(vdev);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05305874 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08005875 }
5876 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08005877
Pragaspathi Thilagaraje6f37e02019-01-04 12:24:33 +05305878 /*
5879 * During vdev destroy, if any STA is in connecting state the
5880 * roam command will be in active queue and thus vdev destroy is
5881 * queued in pending queue. In case STA tries to connect to
5882 * multiple BSSID and fails to connect, due to auth/assoc
5883 * timeouts it may take more than vdev destroy time to get
5884 * completed. On vdev destroy timeout vdev is moved to logically
5885 * deleted state. Once connection is completed, vdev destroy is
5886 * activated and to release the self-peer ref count it try to
5887 * get the ref of the vdev, which fails as vdev is logically
5888 * deleted and this leads to peer ref leak. So before vdev
5889 * destroy is queued abort any STA ongoing connection to avoid
5890 * vdev destroy timeout.
5891 */
5892 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags))
5893 hdd_abort_ongoing_sta_connection(hdd_ctx);
Dustin Browndb2a8be2017-12-20 11:49:56 -08005894
Himanshu Agarwalb229a142017-12-21 10:16:45 +05305895 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005896 break;
5897
Rajeev Kumar3b906202018-02-01 10:55:14 -08005898 case QDF_MONITOR_MODE:
5899 wlan_hdd_scan_abort(adapter);
Visweswara Tanukub5a61242019-03-26 12:24:13 +05305900 hdd_deregister_hl_netdev_fc_timer(adapter);
Rajeev Kumar3b906202018-02-01 10:55:14 -08005901 hdd_deregister_tx_flow_control(adapter);
Jinwei Chenbdd977f2019-06-14 15:09:30 +08005902 sme_delete_mon_session(mac_handle, adapter->vdev_id);
Rajeev Kumar3b906202018-02-01 10:55:14 -08005903 hdd_vdev_destroy(adapter);
5904 break;
5905
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005906 case QDF_SAP_MODE:
Will Huang7049bae2018-08-13 17:25:02 +08005907 if (test_bit(ACS_PENDING, &adapter->event_flags)) {
5908 cds_flush_delayed_work(&adapter->acs_pending_work);
5909 clear_bit(ACS_PENDING, &adapter->event_flags);
5910 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005911
wadesongf9b15ed2017-12-14 14:12:32 +08005912 wlan_hdd_scan_abort(adapter);
gaurank kathpaliab7a9f702019-02-15 18:09:58 +05305913 /* Diassociate with all the peers before stop ap post */
5914 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))
5915 wlan_hdd_del_station(adapter);
Arunk Khandavalli96c122f2017-10-17 11:49:36 +05305916 sap_config = &adapter->session.ap.sap_config;
Dustin Brownd747ecd2018-10-26 16:32:22 -07005917 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
5918
Dustin Brown07901ec2018-09-07 11:02:41 -07005919 ucfg_ipa_flush(hdd_ctx->pdev);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005920
Dustin Brownb4260d52019-01-24 11:53:08 -08005921 /* don't flush pre-cac destroy if we are destroying pre-cac */
5922 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
5923 if (!wlan_sap_is_pre_cac_context(sap_ctx))
Liangwei Dongad89c762018-06-01 01:56:23 -04005924 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
Dustin Brownb4260d52019-01-24 11:53:08 -08005925
Jeff Johnson46807cd2018-04-29 21:32:22 -07005926 /* fallthrough */
Dustin Browna5cf8e02017-10-19 16:04:19 -07005927
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005928 case QDF_P2P_GO_MODE:
Krunal Soni22208392017-09-29 18:10:34 -07005929 cds_flush_work(&adapter->sap_stop_bss_work);
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05305930 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Dustin Browna5cf8e02017-10-19 16:04:19 -07005931 wlan_hdd_undo_acs(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005932
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005933 if (adapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005934 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5935
Visweswara Tanukub5a61242019-03-26 12:24:13 +05305936 hdd_deregister_hl_netdev_fc_timer(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005937 hdd_deregister_tx_flow_control(adapter);
Kapil Guptac1224bf2017-06-22 21:22:40 +05305938 hdd_destroy_acs_timer(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005939
Pragaspathi Thilagaraje6f37e02019-01-04 12:24:33 +05305940 /**
5941 * During vdev destroy, If any STA is in connecting state the
5942 * roam command will be in active queue and thus vdev destroy is
5943 * queued in pending queue. In case STA is tries to connected to
5944 * multiple BSSID and fails to connect, due to auth/assoc
5945 * timeouts it may take more than vdev destroy time to get
5946 * completes. If vdev destroy timeout vdev is moved to logically
5947 * deleted state. Once connection is completed, vdev destroy is
5948 * activated and to release the self-peer ref count it try to
5949 * get the ref of the vdev, which fails as vdev is logically
5950 * deleted and this leads to peer ref leak. So before vdev
5951 * destroy is queued abort any STA ongoing connection to avoid
5952 * vdev destroy timeout.
5953 */
5954 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags))
5955 hdd_abort_ongoing_sta_connection(hdd_ctx);
5956
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005957 mutex_lock(&hdd_ctx->sap_lock);
5958 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005959 status = wlansap_stop_bss(
5960 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005961
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305962 if (QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonca2530c2017-09-30 18:25:40 -07005963 struct hdd_hostapd_state *hostapd_state =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005964 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +05305965 qdf_event_reset(&hostapd_state->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305966 qdf_stop_bss_event);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005967 status = qdf_wait_for_event_completion(
Nachiket Kukade0396b732017-11-14 16:35:16 +05305968 &hostapd_state->qdf_stop_bss_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +05305969 SME_CMD_STOP_BSS_TIMEOUT);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005970 if (QDF_IS_STATUS_ERROR(status))
Jeff Johnson5880d792016-08-15 13:32:30 -07005971 hdd_err("failure waiting for wlansap_stop_bss %d",
Dustin Brownd747ecd2018-10-26 16:32:22 -07005972 status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005973 } else {
Jeff Johnson5880d792016-08-15 13:32:30 -07005974 hdd_err("failure in wlansap_stop_bss");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005975 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005976
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005977 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -07005978 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005979 adapter->device_mode,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005980 adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07005981 hdd_green_ap_start_state_mc(hdd_ctx,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305982 adapter->device_mode,
5983 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005984
Jeff Johnsonc565af12019-03-10 21:09:47 -07005985 qdf_copy_macaddr(&update_ie.bssid,
Jeff Johnson1e851a12017-10-28 14:36:12 -07005986 &adapter->mac_addr);
Jeff Johnsonc565af12019-03-10 21:09:47 -07005987 update_ie.smeSessionId = adapter->vdev_id;
5988 update_ie.ieBufferlength = 0;
5989 update_ie.pAdditionIEBuffer = NULL;
5990 update_ie.append = false;
5991 update_ie.notify = false;
Dustin Brownd747ecd2018-10-26 16:32:22 -07005992
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005993 /* Probe bcn reset */
Jeff Johnsonc565af12019-03-10 21:09:47 -07005994 status = sme_update_add_ie(mac_handle, &update_ie,
Dustin Brownd747ecd2018-10-26 16:32:22 -07005995 eUPDATE_IE_PROBE_BCN);
5996 if (status == QDF_STATUS_E_FAILURE)
5997 hdd_err("Could not pass PROBE_RSP_BCN to PE");
5998
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005999 /* Assoc resp reset */
Jeff Johnsonc565af12019-03-10 21:09:47 -07006000 status = sme_update_add_ie(mac_handle, &update_ie,
Dustin Brownd747ecd2018-10-26 16:32:22 -07006001 eUPDATE_IE_ASSOC_RESP);
6002 if (status == QDF_STATUS_E_FAILURE)
6003 hdd_err("Could not pass ASSOC_RSP to PE");
6004
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006005 /* Reset WNI_CFG_PROBE_RSP Flags */
6006 wlan_hdd_reset_prob_rspies(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006007 }
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08006008 clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
Jeff Johnsonb9424862017-10-30 08:49:35 -07006009 qdf_mem_free(adapter->session.ap.beacon);
6010 adapter->session.ap.beacon = NULL;
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08006011
Ajit Pal Singh747b6802017-05-24 15:42:03 +05306012 /*
6013 * If Do_Not_Break_Stream was enabled clear avoid channel list.
6014 */
Min Liu8c5d99e2018-09-10 17:18:44 +08006015 vdev = hdd_objmgr_get_vdev(adapter);
6016 if (vdev) {
6017 if (policy_mgr_is_dnsc_set(vdev))
6018 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05306019 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08006020 }
Ajit Pal Singh747b6802017-05-24 15:42:03 +05306021
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05306022#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07006023 cancel_work_sync(&adapter->ipv4_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05306024#ifdef WLAN_NS_OFFLOAD
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07006025 cancel_work_sync(&adapter->ipv6_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05306026#endif
6027#endif
Dustin Browndb2a8be2017-12-20 11:49:56 -08006028
6029 hdd_vdev_destroy(adapter);
6030
Krunal Sonib51eec72017-11-20 21:53:01 -08006031 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006032 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006033 case QDF_OCB_MODE:
Dustin Brownd747ecd2018-10-26 16:32:22 -07006034 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Krishna Kumaar Natarajane58b4092017-01-25 15:47:35 -08006035 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
Dustin Brownd747ecd2018-10-26 16:32:22 -07006036 cds_get_context(QDF_MODULE_ID_TXRX),
Sourav Mohapatraffbd0272019-07-31 14:18:25 +05306037 sta_ctx->conn_info.peer_macaddr[0]);
Visweswara Tanukub5a61242019-03-26 12:24:13 +05306038 hdd_deregister_hl_netdev_fc_timer(adapter);
Zhang Qian79d0d132018-02-05 13:40:16 +08006039 hdd_deregister_tx_flow_control(adapter);
6040 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006041 break;
6042 default:
6043 break;
6044 }
6045
Dustin Brown04348372017-12-14 16:13:39 -08006046 if (adapter->scan_info.default_scan_ies) {
6047 qdf_mem_free(adapter->scan_info.default_scan_ies);
6048 adapter->scan_info.default_scan_ies = NULL;
Abhishek Singh74d06cf2019-09-06 09:23:22 +05306049 adapter->scan_info.default_scan_ies_len = 0;
Dustin Brown04348372017-12-14 16:13:39 -08006050 }
6051
Dustin Browne74003f2018-03-14 12:51:58 -07006052 hdd_exit();
Dustin Brownd747ecd2018-10-26 16:32:22 -07006053
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306054 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006055}
6056
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306057/**
6058 * hdd_deinit_all_adapters - deinit all adapters
6059 * @hdd_ctx: HDD context
6060 * @rtnl_held: True if RTNL lock held
6061 *
6062 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006063void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306064{
Jeff Johnson9d295242017-08-29 14:39:48 -07006065 struct hdd_adapter *adapter;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306066
Dustin Brown491d54b2018-03-14 12:39:11 -07006067 hdd_enter();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306068
Dustin Brown920397d2017-12-13 16:27:50 -08006069 hdd_for_each_adapter(hdd_ctx, adapter)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306070 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306071
Dustin Browne74003f2018-03-14 12:51:58 -07006072 hdd_exit();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05306073}
6074
Dustin Browndb2a8be2017-12-20 11:49:56 -08006075QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006076{
Jeff Johnson9d295242017-08-29 14:39:48 -07006077 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006078
Dustin Brown491d54b2018-03-14 12:39:11 -07006079 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006080
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05306081 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
6082
Dustin Brown920397d2017-12-13 16:27:50 -08006083 hdd_for_each_adapter(hdd_ctx, adapter)
Dustin Browndb2a8be2017-12-20 11:49:56 -08006084 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006085
Dustin Browne74003f2018-03-14 12:51:58 -07006086 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006087
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306088 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006089}
6090
Paul Zhang84fa9382017-11-10 21:18:21 +08006091static void hdd_reset_scan_operation(struct hdd_context *hdd_ctx,
6092 struct hdd_adapter *adapter)
6093{
6094 switch (adapter->device_mode) {
6095 case QDF_STA_MODE:
6096 case QDF_P2P_CLIENT_MODE:
6097 case QDF_IBSS_MODE:
6098 case QDF_P2P_DEVICE_MODE:
6099 case QDF_NDI_MODE:
6100 wlan_hdd_scan_abort(adapter);
6101 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Min Liu8c5d99e2018-09-10 17:18:44 +08006102 if (adapter->device_mode == QDF_STA_MODE) {
6103 struct wlan_objmgr_vdev *vdev;
6104
6105 vdev = hdd_objmgr_get_vdev(adapter);
6106 if (vdev) {
6107 wlan_cfg80211_sched_scan_stop(vdev);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05306108 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08006109 }
6110 }
Paul Zhang84fa9382017-11-10 21:18:21 +08006111 break;
6112 case QDF_P2P_GO_MODE:
6113 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
6114 break;
6115 case QDF_SAP_MODE:
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05306116 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Paul Zhang84fa9382017-11-10 21:18:21 +08006117 break;
6118 default:
6119 break;
6120 }
6121}
6122
Ke Huangc067b8d2018-05-21 15:50:13 +08006123#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
6124/**
6125 * hdd_adapter_abort_tx_flow() - Abort the tx flow control
6126 * @pAdapter: pointer to hdd_adapter_t
6127 *
6128 * Resume tx and stop the tx flow control timer if the tx is paused
6129 * and the flow control timer is running. This function is called by
6130 * SSR to avoid the inconsistency of tx status before and after SSR.
6131 *
6132 * Return: void
6133 */
6134static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
6135{
6136 if (adapter->hdd_stats.tx_rx_stats.is_txflow_paused &&
6137 QDF_TIMER_STATE_RUNNING ==
6138 qdf_mc_timer_get_current_state(
6139 &adapter->tx_flow_control_timer)) {
6140 hdd_tx_resume_timer_expired_handler(adapter);
6141 qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
6142 }
6143}
6144#endif
6145
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006146QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006147{
Jeff Johnson9d295242017-08-29 14:39:48 -07006148 struct hdd_adapter *adapter;
Jeff Johnsond377dce2017-10-04 10:32:42 -07006149 struct hdd_station_ctx *sta_ctx;
Jeff Johnson2d044612019-02-26 20:08:43 -08006150 struct qdf_mac_addr peer_macaddr;
Yue Ma42654682018-01-11 16:55:24 -08006151 int sta_id;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05306152 bool value;
Min Liu8c5d99e2018-09-10 17:18:44 +08006153 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006154
Dustin Brown491d54b2018-03-14 12:39:11 -07006155 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006156
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05306157 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
6158
Dustin Brown920397d2017-12-13 16:27:50 -08006159 hdd_for_each_adapter(hdd_ctx, adapter) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07006160 hdd_info("[SSR] reset adapter with device mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07006161 qdf_opmode_str(adapter->device_mode),
Dustin Brown5e89ef82018-03-14 11:50:23 -07006162 adapter->device_mode);
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05306163
Ke Huangc067b8d2018-05-21 15:50:13 +08006164#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
6165 hdd_adapter_abort_tx_flow(adapter);
6166#endif
6167
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05306168 if ((adapter->device_mode == QDF_STA_MODE) ||
Paul Zhang679025e2018-03-08 22:39:44 +08006169 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05306170 /* Stop tdls timers */
Min Liu8c5d99e2018-09-10 17:18:44 +08006171 vdev = hdd_objmgr_get_vdev(adapter);
6172 if (vdev) {
6173 hdd_notify_tdls_reset_adapter(vdev);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05306174 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08006175 }
Paul Zhang679025e2018-03-08 22:39:44 +08006176 adapter->session.station.hdd_reassoc_scenario = false;
6177 }
Dustin Brown05d81302018-09-11 16:49:22 -07006178 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05306179 if (value &&
Arun Khandavallicc544b32017-01-30 19:52:16 +05306180 adapter->device_mode == QDF_SAP_MODE) {
6181 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05306182 WLAN_STOP_ALL_NETIF_QUEUE,
Arun Khandavallicc544b32017-01-30 19:52:16 +05306183 WLAN_CONTROL_PATH);
Ashish Kumar Dhanotiyadc3900f2019-01-11 20:42:04 +05306184 if (test_bit(ACS_PENDING, &adapter->event_flags)) {
6185 cds_flush_delayed_work(
6186 &adapter->acs_pending_work);
6187 clear_bit(ACS_PENDING, &adapter->event_flags);
6188 }
6189
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08006190 if (test_bit(SOFTAP_BSS_STARTED,
Ashish Kumar Dhanotiyadc3900f2019-01-11 20:42:04 +05306191 &adapter->event_flags)) {
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08006192 hdd_sap_indicate_disconnect_for_sta(adapter);
Ashish Kumar Dhanotiyadc3900f2019-01-11 20:42:04 +05306193 clear_bit(SOFTAP_BSS_STARTED,
6194 &adapter->event_flags);
6195 }
6196
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08006197 } else {
Arun Khandavallicc544b32017-01-30 19:52:16 +05306198 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05306199 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006200 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08006201 }
Nijun Gong104ccc72018-08-07 10:43:56 +08006202 /*
6203 * Clear fc flag if it was set before SSR to avoid TX queues
6204 * permanently stopped after SSR.
6205 * Here WLAN_START_ALL_NETIF_QUEUE will actually not start any
6206 * queue since it's blocked by reason WLAN_CONTROL_PATH.
6207 */
6208 if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL))
6209 wlan_hdd_netif_queue_control(adapter,
6210 WLAN_START_ALL_NETIF_QUEUE,
6211 WLAN_DATA_FLOW_CONTROL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006212
Paul Zhang84fa9382017-11-10 21:18:21 +08006213 hdd_reset_scan_operation(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006214
6215 hdd_deinit_tx_rx(adapter);
Dustin Brown1dbefe62018-09-11 16:32:03 -07006216 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08006217 adapter->device_mode, adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07006218 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05306219 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006220 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
6221 hdd_wmm_adapter_close(adapter);
6222 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
6223 }
6224
Vignesh Viswanathan2eb18742017-09-08 11:18:59 +05306225 if (adapter->device_mode == QDF_STA_MODE)
6226 hdd_clear_fils_connection_info(adapter);
6227
Wu Gao3545e642017-07-14 19:24:41 +08006228 if (adapter->device_mode == QDF_SAP_MODE) {
Jingxiang Geec113592018-08-09 15:40:39 +08006229 wlansap_cleanup_cac_timer(
6230 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Wu Gao3545e642017-07-14 19:24:41 +08006231 /*
6232 * If adapter is SAP, set session ID to invalid
6233 * since SAP session will be cleanup during SSR.
6234 */
Wu Gao36717432016-11-21 15:09:48 +08006235 wlansap_set_invalid_session(
6236 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Wu Gao3545e642017-07-14 19:24:41 +08006237 }
6238
Abhishek Singh8f4aa182019-03-06 10:29:24 +05306239 /* Release vdev ref count to avoid vdev object leak */
6240 if (adapter->device_mode == QDF_P2P_GO_MODE ||
6241 adapter->device_mode == QDF_SAP_MODE)
6242 wlansap_release_vdev_ref(
6243 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
6244
Yue Ma42654682018-01-11 16:55:24 -08006245 /* Delete connection peers if any to avoid peer object leaks */
Yue Mad5b4b9f2017-05-26 16:23:40 -07006246 if (adapter->device_mode == QDF_STA_MODE ||
6247 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
Jeff Johnsond377dce2017-10-04 10:32:42 -07006248 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnson2d044612019-02-26 20:08:43 -08006249 qdf_copy_macaddr(&peer_macaddr,
Jeff Johnsone04b6992019-02-27 14:06:55 -08006250 &sta_ctx->conn_info.bssid);
Yue Mad5b4b9f2017-05-26 16:23:40 -07006251
Yue Ma42654682018-01-11 16:55:24 -08006252 } else if (adapter->device_mode == QDF_P2P_GO_MODE) {
Wu Gao6b81fc52018-05-24 19:27:27 +08006253 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Sourav Mohapatraffbd0272019-07-31 14:18:25 +05306254 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
6255 sta_id++) {
6256 struct hdd_station_info sta =
6257 adapter->sta_info[sta_id];
6258 if (sta.in_use) {
Yue Ma42654682018-01-11 16:55:24 -08006259 hdd_debug("[SSR] deregister STA with ID %d",
6260 sta_id);
Sourav Mohapatraffbd0272019-07-31 14:18:25 +05306261 /* STA id will be removed */
Yue Ma42654682018-01-11 16:55:24 -08006262 hdd_softap_deregister_sta(adapter,
Sourav Mohapatraffbd0272019-07-31 14:18:25 +05306263 sta_id,
6264 sta.sta_mac);
6265 sta.in_use = 0;
Yue Ma42654682018-01-11 16:55:24 -08006266 }
6267 }
Yue Mad5b4b9f2017-05-26 16:23:40 -07006268 }
6269
Alok Kumarb64650c2018-03-23 17:05:11 +05306270 hdd_nud_ignore_tracking(adapter, true);
Alok Kumar016a1ac2018-09-16 09:55:50 +05306271 hdd_nud_reset_tracking(adapter);
6272 hdd_nud_flush_work(adapter);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05306273 hdd_mic_flush_work(adapter);
Ashish Kumar Dhanotiyadc3900f2019-01-11 20:42:04 +05306274
6275 if (adapter->device_mode != QDF_SAP_MODE &&
6276 adapter->device_mode != QDF_P2P_GO_MODE &&
6277 adapter->device_mode != QDF_FTM_MODE)
6278 hdd_set_disconnect_status(adapter, false);
6279
hangtian9c47aaf2018-11-26 17:59:39 +08006280 hdd_stop_tsf_sync(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05306281
Tiger Yu94a5a5c2018-03-09 21:22:26 +08006282 hdd_softap_deinit_tx_rx(adapter);
Visweswara Tanukub5a61242019-03-26 12:24:13 +05306283 hdd_deregister_hl_netdev_fc_timer(adapter);
Tiger Yu8c387702018-07-06 16:56:42 +08006284 hdd_deregister_tx_flow_control(adapter);
Tiger Yu94a5a5c2018-03-09 21:22:26 +08006285
Yue Maf9782842017-05-08 12:49:49 -07006286 /* Destroy vdev which will be recreated during reinit. */
6287 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006288 }
6289
Dustin Browne74003f2018-03-14 12:51:58 -07006290 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006291
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306292 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006293}
6294
Dustin Brown4c663222018-10-23 14:19:36 -07006295bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05306296{
Dustin Brown920397d2017-12-13 16:27:50 -08006297 struct hdd_adapter *adapter;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05306298
Dustin Brown4c663222018-10-23 14:19:36 -07006299 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
Arun Khandavalliba479c42017-07-26 21:29:40 +05306300 hdd_info("FTM mode, don't close the module");
Dustin Brown4c663222018-10-23 14:19:36 -07006301 return true;
Arun Khandavalliba479c42017-07-26 21:29:40 +05306302 }
6303
Dustin Brown920397d2017-12-13 16:27:50 -08006304 hdd_for_each_adapter(hdd_ctx, adapter) {
6305 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
Dustin Brown4c663222018-10-23 14:19:36 -07006306 test_bit(SME_SESSION_OPENED, &adapter->event_flags))
6307 return true;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05306308 }
6309
Dustin Brown4c663222018-10-23 14:19:36 -07006310 return false;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05306311}
6312
yeshwanth sriram guntukaea63f632017-08-30 19:31:56 +05306313bool hdd_is_interface_up(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05306314{
6315 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
6316 return true;
6317 else
6318 return false;
6319}
6320
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306321#if defined CFG80211_CONNECT_BSS || \
6322 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306323#if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306324 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306325/**
6326 * hdd_convert_timeout_reason() - Convert to kernel specific enum
6327 * @timeout_reason: reason for connect timeout
6328 *
6329 * This function is used to convert host timeout
6330 * reason enum to kernel specific enum.
6331 *
6332 * Return: nl timeout enum
6333 */
6334static enum nl80211_timeout_reason hdd_convert_timeout_reason(
6335 tSirResultCodes timeout_reason)
6336{
6337 switch (timeout_reason) {
6338 case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
6339 return NL80211_TIMEOUT_SCAN;
6340 case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
6341 return NL80211_TIMEOUT_AUTH;
6342 case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
6343 return NL80211_TIMEOUT_ASSOC;
6344 default:
6345 return NL80211_TIMEOUT_UNSPECIFIED;
6346 }
6347}
6348
6349/**
6350 * hdd_cfg80211_connect_timeout() - API to send connection timeout reason
6351 * @dev: network device
6352 * @bssid: bssid to which we want to associate
6353 * @timeout_reason: reason for connect timeout
6354 *
6355 * This API is used to send connection timeout reason to supplicant
6356 *
6357 * Return: void
6358 */
6359static void hdd_cfg80211_connect_timeout(struct net_device *dev,
6360 const u8 *bssid,
6361 tSirResultCodes timeout_reason)
6362{
6363 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006364
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306365 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
6366
6367 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL,
6368 nl_timeout_reason);
6369}
6370
6371/**
6372 * __hdd_connect_bss() - API to send connection status to supplicant
6373 * @dev: network device
6374 * @bssid: bssid to which we want to associate
6375 * @req_ie: Request Information Element
6376 * @req_ie_len: len of the req IE
6377 * @resp_ie: Response IE
6378 * @resp_ie_len: len of ht response IE
6379 * @status: status
6380 * @gfp: Kernel Flag
6381 * @timeout_reason: reason for connect timeout
6382 *
6383 * Return: void
6384 */
6385static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6386 struct cfg80211_bss *bss, const u8 *req_ie,
6387 size_t req_ie_len, const u8 *resp_ie,
6388 size_t resp_ie_len, int status, gfp_t gfp,
6389 tSirResultCodes timeout_reason)
6390{
6391 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006392
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306393 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
6394
6395 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
6396 resp_ie, resp_ie_len, status, gfp,
6397 nl_timeout_reason);
6398}
6399#else
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306400#if defined CFG80211_CONNECT_TIMEOUT || \
6401 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306402static void hdd_cfg80211_connect_timeout(struct net_device *dev,
6403 const u8 *bssid,
6404 tSirResultCodes timeout_reason)
6405{
6406 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL);
6407}
6408#endif
6409
6410static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6411 struct cfg80211_bss *bss, const u8 *req_ie,
6412 size_t req_ie_len, const u8 *resp_ie,
6413 size_t resp_ie_len, int status, gfp_t gfp,
6414 tSirResultCodes timeout_reason)
6415{
6416 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
6417 resp_ie, resp_ie_len, status, gfp);
6418}
6419#endif
6420
Abhishek Singha84d3952016-09-13 13:45:05 +05306421/**
6422 * hdd_connect_bss() - API to send connection status to supplicant
6423 * @dev: network device
6424 * @bssid: bssid to which we want to associate
6425 * @req_ie: Request Information Element
6426 * @req_ie_len: len of the req IE
6427 * @resp_ie: Response IE
6428 * @resp_ie_len: len of ht response IE
6429 * @status: status
6430 * @gfp: Kernel Flag
6431 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306432 * @timeout_reason: reason for connect timeout
Abhishek Singha84d3952016-09-13 13:45:05 +05306433 *
6434 * The API is a wrapper to send connection status to supplicant
6435 *
6436 * Return: Void
6437 */
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306438#if defined CFG80211_CONNECT_TIMEOUT || \
6439 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
Abhishek Singha84d3952016-09-13 13:45:05 +05306440static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6441 struct cfg80211_bss *bss, const u8 *req_ie,
6442 size_t req_ie_len, const u8 *resp_ie,
6443 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306444 bool connect_timeout,
6445 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05306446{
6447 if (connect_timeout)
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306448 hdd_cfg80211_connect_timeout(dev, bssid, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05306449 else
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306450 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
6451 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05306452}
6453#else
6454static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6455 struct cfg80211_bss *bss, const u8 *req_ie,
6456 size_t req_ie_len, const u8 *resp_ie,
6457 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306458 bool connect_timeout,
6459 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05306460{
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306461 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
6462 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05306463}
6464#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05306465
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306466#if defined(WLAN_FEATURE_FILS_SK)
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306467#if (defined(CFG80211_CONNECT_DONE) || \
6468 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))) && \
6469 (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0))
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306470#if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
6471 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306472/**
6473 * hdd_populate_fils_params() - Populate FILS keys to connect response
6474 * @fils_params: connect response to supplicant
6475 * @fils_kek: FILS kek
6476 * @fils_kek_len: FILS kek length
6477 * @pmk: FILS PMK
6478 * @pmk_len: FILS PMK length
6479 * @pmkid: PMKID
6480 * @fils_seq_num: FILS Seq number
6481 *
6482 * Return: None
6483 */
6484static void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6485 *fils_params, const uint8_t *fils_kek,
6486 size_t fils_kek_len, const uint8_t *pmk,
6487 size_t pmk_len, const uint8_t *pmkid,
6488 uint16_t fils_seq_num)
6489{
6490 /* Increament seq number to be used for next FILS */
6491 fils_params->fils_erp_next_seq_num = fils_seq_num + 1;
6492 fils_params->update_erp_next_seq_num = true;
6493 fils_params->fils_kek = fils_kek;
6494 fils_params->fils_kek_len = fils_kek_len;
6495 fils_params->pmk = pmk;
6496 fils_params->pmk_len = pmk_len;
6497 fils_params->pmkid = pmkid;
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306498 hdd_debug("FILS erp_next_seq_num:%d",
6499 fils_params->fils_erp_next_seq_num);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306500}
6501#else
6502static inline void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6503 *fils_params, const uint8_t
6504 *fils_kek, size_t fils_kek_len,
6505 const uint8_t *pmk, size_t pmk_len,
6506 const uint8_t *pmkid,
6507 uint16_t fils_seq_num)
6508{ }
6509#endif
6510
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306511#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
6512/**
6513 * hdd_populate_fils_params() - Populate FILS keys to connect response
6514 * @fils_params: connect response to supplicant
6515 * @fils_kek: FILS kek
6516 * @fils_kek_len: FILS kek length
6517 * @pmk: FILS PMK
6518 * @pmk_len: FILS PMK length
6519 * @pmkid: PMKID
6520 * @fils_seq_num: FILS Seq number
6521 *
6522 * Return: None
6523 */
6524static void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6525 *fils_params, const uint8_t *fils_kek,
6526 size_t fils_kek_len, const uint8_t *pmk,
6527 size_t pmk_len, const uint8_t *pmkid,
6528 uint16_t fils_seq_num)
6529{
6530 /* Increament seq number to be used for next FILS */
6531 fils_params->fils.erp_next_seq_num = fils_seq_num + 1;
6532 fils_params->fils.update_erp_next_seq_num = true;
6533 fils_params->fils.kek = fils_kek;
6534 fils_params->fils.kek_len = fils_kek_len;
6535 fils_params->fils.pmk = pmk;
6536 fils_params->fils.pmk_len = pmk_len;
6537 fils_params->fils.pmkid = pmkid;
6538 hdd_debug("FILS erp_next_seq_num:%d",
6539 fils_params->fils.erp_next_seq_num);
6540}
6541#endif /* CFG80211_CONNECT_DONE */
6542
6543#if defined(CFG80211_CONNECT_DONE) || \
6544 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
6545
Jeff Johnson172237b2017-11-07 15:32:59 -08006546void hdd_update_hlp_info(struct net_device *dev,
6547 struct csr_roam_info *roam_info)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306548{
6549 struct sk_buff *skb;
6550 uint16_t skb_len;
6551 struct llc_snap_hdr_t *llc_hdr;
6552 QDF_STATUS status;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306553 uint8_t *hlp_data;
6554 uint16_t hlp_data_len;
6555 struct fils_join_rsp_params *roam_fils_params
6556 = roam_info->fils_join_rsp;
Jeff Johnsona1382382019-03-31 11:08:27 -07006557 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306558
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306559 if (!roam_fils_params) {
6560 hdd_err("FILS Roam Param NULL");
6561 return;
6562 }
6563
Srinivas Girigowda3cc8e912017-11-28 18:11:57 -08006564 if (!roam_fils_params->hlp_data_len) {
Jianmin Zhucc6b3d02019-03-07 14:19:34 +08006565 hdd_debug("FILS HLP Data NULL, len %d",
6566 roam_fils_params->hlp_data_len);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306567 return;
6568 }
6569
6570 hlp_data = roam_fils_params->hlp_data;
6571 hlp_data_len = roam_fils_params->hlp_data_len;
6572
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306573 /* Calculate skb length */
6574 skb_len = (2 * ETH_ALEN) + hlp_data_len;
6575 skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false);
Jeff Johnsond36fa332019-03-18 13:42:25 -07006576 if (!skb) {
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306577 hdd_err("HLP packet nbuf alloc fails");
6578 return;
6579 }
6580
6581 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->dst_mac.bytes,
6582 QDF_MAC_ADDR_SIZE);
6583 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->src_mac.bytes,
6584 QDF_MAC_ADDR_SIZE);
6585
6586 llc_hdr = (struct llc_snap_hdr_t *) hlp_data;
6587 if (IS_SNAP(llc_hdr)) {
6588 hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
6589 hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
6590 }
6591
6592 qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len);
6593
6594 /*
6595 * This HLP packet is formed from HLP info encapsulated
6596 * in assoc response frame which is AEAD encrypted.
6597 * Hence, this checksum validation can be set unnecessary.
6598 * i.e. network layer need not worry about checksum.
6599 */
6600 skb->ip_summed = CHECKSUM_UNNECESSARY;
6601
Jeff Johnsona1382382019-03-31 11:08:27 -07006602 status = hdd_rx_packet_cbk(adapter, skb);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306603 if (QDF_IS_STATUS_ERROR(status)) {
6604 hdd_err("Sending HLP packet fails");
6605 return;
6606 }
6607 hdd_debug("send HLP packet to netif successfully");
6608}
6609
6610/**
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306611 * hdd_connect_done() - Wrapper API to call cfg80211_connect_done
6612 * @dev: network device
6613 * @bssid: bssid to which we want to associate
6614 * @bss: cfg80211 bss info
6615 * @roam_info: information about connected bss
6616 * @req_ie: Request Information Element
6617 * @req_ie_len: len of the req IE
6618 * @resp_ie: Response IE
6619 * @resp_ie_len: len of ht response IE
6620 * @status: status
6621 * @gfp: allocation flags
6622 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
6623 * @timeout_reason: reason for connect timeout
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306624 *
6625 * This API is used as wrapper to send FILS key/sequence number
6626 * params etc. to supplicant in case of FILS connection
6627 *
6628 * Return: None
6629 */
6630static void hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006631 struct cfg80211_bss *bss,
6632 struct csr_roam_info *roam_info,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306633 const u8 *req_ie, size_t req_ie_len,
6634 const u8 *resp_ie, size_t resp_ie_len, u16 status,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006635 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306636 tSirResultCodes timeout_reason)
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306637{
6638 struct cfg80211_connect_resp_params fils_params;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306639 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6640 struct fils_join_rsp_params *roam_fils_params =
6641 roam_info->fils_join_rsp;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006642
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306643 qdf_mem_zero(&fils_params, sizeof(fils_params));
6644
6645 if (!roam_fils_params) {
6646 fils_params.status = WLAN_STATUS_UNSPECIFIED_FAILURE;
6647 } else {
6648 fils_params.status = status;
6649 fils_params.bssid = bssid;
Srinivas Girigowdae975f532018-01-05 14:03:05 -08006650 fils_params.timeout_reason =
6651 hdd_convert_timeout_reason(timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306652 fils_params.req_ie = req_ie;
6653 fils_params.req_ie_len = req_ie_len;
6654 fils_params.resp_ie = resp_ie;
6655 fils_params.resp_ie_len = resp_ie_len;
6656 fils_params.bss = bss;
6657 hdd_populate_fils_params(&fils_params, roam_fils_params->kek,
6658 roam_fils_params->kek_len,
6659 roam_fils_params->fils_pmk,
6660 roam_fils_params->fils_pmk_len,
6661 roam_fils_params->fils_pmkid,
6662 roam_info->fils_seq_num);
Sridhar Selvaraje5260442017-08-19 10:12:03 +05306663 hdd_save_gtk_params(adapter, roam_info, false);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306664 }
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306665 hdd_debug("FILS indicate connect status %d", fils_params.status);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306666
6667 cfg80211_connect_done(dev, &fils_params, gfp);
6668
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306669 if (roam_fils_params && roam_fils_params->hlp_data_len)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306670 hdd_update_hlp_info(dev, roam_info);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306671
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306672 /* Clear all the FILS key info */
6673 if (roam_fils_params && roam_fils_params->fils_pmk)
6674 qdf_mem_free(roam_fils_params->fils_pmk);
6675 if (roam_fils_params)
6676 qdf_mem_free(roam_fils_params);
6677 roam_info->fils_join_rsp = NULL;
6678}
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306679#else /* CFG80211_CONNECT_DONE */
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006680static inline void
6681hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006682 struct cfg80211_bss *bss, struct csr_roam_info *roam_info,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006683 const u8 *req_ie, size_t req_ie_len,
6684 const u8 *resp_ie, size_t resp_ie_len, u16 status,
6685 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306686 tSirResultCodes timeout_reason)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306687{ }
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306688#endif
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306689#endif /* WLAN_FEATURE_FILS_SK */
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306690
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306691#if defined(WLAN_FEATURE_FILS_SK) && \
6692 (defined(CFG80211_CONNECT_DONE) || \
6693 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306694/**
6695 * hdd_fils_update_connect_results() - API to send fils connection status to
6696 * supplicant.
6697 * @dev: network device
6698 * @bssid: bssid to which we want to associate
6699 * @bss: cfg80211 bss info
6700 * @roam_info: information about connected bss
6701 * @req_ie: Request Information Element
6702 * @req_ie_len: len of the req IE
6703 * @resp_ie: Response IE
6704 * @resp_ie_len: len of ht response IE
6705 * @status: status
6706 * @gfp: allocation flags
6707 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
6708 * @timeout_reason: reason for connect timeout
6709 *
6710 * The API is a wrapper to send connection status to supplicant
6711 *
6712 * Return: 0 if success else failure
6713 */
6714static int hdd_fils_update_connect_results(struct net_device *dev,
6715 const u8 *bssid,
6716 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08006717 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306718 size_t req_ie_len, const u8 *resp_ie,
6719 size_t resp_ie_len, u16 status, gfp_t gfp,
6720 bool connect_timeout,
6721 tSirResultCodes timeout_reason)
6722{
Dustin Brown491d54b2018-03-14 12:39:11 -07006723 hdd_enter();
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306724 if (!roam_info || !roam_info->is_fils_connection)
6725 return -EINVAL;
6726
6727 hdd_connect_done(dev, bssid, bss, roam_info, req_ie, req_ie_len,
6728 resp_ie, resp_ie_len, status, gfp, connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306729 timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306730 return 0;
6731}
6732#else
6733static inline int hdd_fils_update_connect_results(struct net_device *dev,
6734 const u8 *bssid,
6735 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08006736 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306737 size_t req_ie_len, const u8 *resp_ie,
6738 size_t resp_ie_len, u16 status, gfp_t gfp,
6739 bool connect_timeout,
6740 tSirResultCodes timeout_reason)
6741{
6742 return -EINVAL;
6743}
6744#endif
6745
Anurag Chouhanc4092922016-09-08 15:56:11 +05306746/**
6747 * hdd_connect_result() - API to send connection status to supplicant
6748 * @dev: network device
6749 * @bssid: bssid to which we want to associate
6750 * @roam_info: information about connected bss
6751 * @req_ie: Request Information Element
6752 * @req_ie_len: len of the req IE
6753 * @resp_ie: Response IE
6754 * @resp_ie_len: len of ht response IE
6755 * @status: status
6756 * @gfp: Kernel Flag
Abhishek Singha84d3952016-09-13 13:45:05 +05306757 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306758 * @timeout_reason: reason for connect timeout
Anurag Chouhanc4092922016-09-08 15:56:11 +05306759 *
6760 * The API is a wrapper to send connection status to supplicant
6761 * and allow runtime suspend
6762 *
6763 * Return: Void
6764 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05306765void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006766 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306767 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05306768 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306769 bool connect_timeout,
6770 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05306771{
Jeff Johnsona1382382019-03-31 11:08:27 -07006772 struct hdd_adapter *adapter = netdev_priv(dev);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306773 struct cfg80211_bss *bss = NULL;
Jeff Johnsona1382382019-03-31 11:08:27 -07006774 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306775
6776 if (WLAN_STATUS_SUCCESS == status) {
6777 struct ieee80211_channel *chan;
Anurag Chouhanc4092922016-09-08 15:56:11 +05306778
Will Huang65d64252019-07-16 17:57:42 +08006779 chan = ieee80211_get_channel(adapter->wdev.wiphy,
6780 roam_info->bss_desc->chan_freq);
Jeff Johnsona1382382019-03-31 11:08:27 -07006781 bss = wlan_cfg80211_get_bss(adapter->wdev.wiphy, chan, bssid,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306782 roam_info->u.pConnectedProfile->SSID.ssId,
6783 roam_info->u.pConnectedProfile->SSID.length);
6784 }
Komal Seelama89be8d2016-09-29 11:09:26 +05306785
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306786 if (hdd_fils_update_connect_results(dev, bssid, bss,
6787 roam_info, req_ie, req_ie_len, resp_ie,
6788 resp_ie_len, status, gfp, connect_timeout,
6789 timeout_reason) != 0) {
6790 hdd_connect_bss(dev, bssid, bss, req_ie,
6791 req_ie_len, resp_ie, resp_ie_len,
6792 status, gfp, connect_timeout, timeout_reason);
6793 }
Komal Seelama89be8d2016-09-29 11:09:26 +05306794
Jingxiang Geb49aa302018-01-17 20:54:15 +08006795 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07006796 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306797}
6798#else
6799void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006800 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306801 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05306802 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306803 bool connect_timeout,
6804 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05306805{
Jeff Johnsona1382382019-03-31 11:08:27 -07006806 struct hdd_adapter *adapter = netdev_priv(dev);
6807 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Komal Seelama89be8d2016-09-29 11:09:26 +05306808
Anurag Chouhanc4092922016-09-08 15:56:11 +05306809 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
6810 resp_ie, resp_ie_len, status, gfp);
Prashanth Bhatta87b6dc02017-01-19 15:17:58 -08006811
Jingxiang Geb49aa302018-01-17 20:54:15 +08006812 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07006813 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306814}
6815#endif
6816
Nirav Shah73713f72018-05-17 14:50:41 +05306817#ifdef FEATURE_MONITOR_MODE_SUPPORT
Jeff Johnsond9952752018-04-18 12:15:35 -07006818int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
6819 uint32_t bandwidth)
6820{
6821 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6822 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
6823 struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info;
6824 QDF_STATUS status;
Jeff Johnson43837af2018-10-17 12:44:05 -07006825 mac_handle_t mac_handle = hdd_ctx->mac_handle;
Jeff Johnsond9952752018-04-18 12:15:35 -07006826 struct qdf_mac_addr bssid;
6827 struct csr_roam_profile roam_profile;
6828 struct ch_params ch_params;
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006829 eConnectionState connstate;
Jeff Johnsond9952752018-04-18 12:15:35 -07006830
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006831 if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
6832 adapter->device_mode != QDF_STA_MODE) {
6833 hdd_err("Not supported, device is not in monitor mode or sta mission mode");
Jeff Johnsond9952752018-04-18 12:15:35 -07006834 return -EINVAL;
6835 }
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006836 if (adapter->device_mode == QDF_STA_MODE &&
Pragaspathi Thilagaraja8893752019-02-06 19:58:59 +05306837 ucfg_mlme_is_change_channel_bandwidth_enabled(hdd_ctx->psoc)) {
Jeff Johnsone7951512019-02-27 10:02:51 -08006838 connstate = sta_ctx->conn_info.conn_state;
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006839 if (eConnectionState_Associated == connstate ||
6840 eConnectionState_Connecting == connstate) {
6841 return -EINVAL;
6842 }
6843 }
Jeff Johnsond9952752018-04-18 12:15:35 -07006844
Visweswara Tanuku006313a2018-04-12 12:26:34 +05306845 /* Validate Channel */
6846 if (!WLAN_REG_IS_24GHZ_CH(chan) && !WLAN_REG_IS_5GHZ_CH(chan)) {
6847 hdd_err("Channel %d Not supported", chan);
6848 return -EINVAL;
6849 }
6850
6851 if (WLAN_REG_IS_24GHZ_CH(chan)) {
6852 if (bandwidth == CH_WIDTH_80MHZ) {
6853 hdd_err("BW80 not possible in 2.4GHz band");
6854 return -EINVAL;
6855 }
6856 if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 14) &&
6857 (bandwidth != CH_WIDTH_MAX)) {
6858 hdd_err("Only BW20 possible on channel 14");
6859 return -EINVAL;
6860 }
6861 }
6862
6863 if (WLAN_REG_IS_5GHZ_CH(chan)) {
6864 if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 165) &&
6865 (bandwidth != CH_WIDTH_MAX)) {
6866 hdd_err("Only BW20 possible on channel 165");
6867 return -EINVAL;
6868 }
6869 }
6870
Jeff Johnsond9952752018-04-18 12:15:35 -07006871 hdd_debug("Set monitor mode Channel %d", chan);
6872 qdf_mem_zero(&roam_profile, sizeof(roam_profile));
wadesong24c869a2019-07-19 17:38:59 +08006873 roam_profile.ChannelInfo.freq_list = &ch_info->freq;
Jeff Johnsond9952752018-04-18 12:15:35 -07006874 roam_profile.ChannelInfo.numOfChannels = 1;
6875 roam_profile.phyMode = ch_info->phy_mode;
6876 roam_profile.ch_params.ch_width = bandwidth;
6877 hdd_select_cbmode(adapter, chan, &roam_profile.ch_params);
Pragaspathi Thilagaraja8893752019-02-06 19:58:59 +05306878 if (ucfg_mlme_is_change_channel_bandwidth_enabled(hdd_ctx->psoc) &&
Jeff Johnson43837af2018-10-17 12:44:05 -07006879 (!sme_find_session_by_bssid(mac_handle, adapter->mac_addr.bytes))) {
6880 status = sme_create_mon_session(mac_handle,
Rajeev Kumar Sirasanagandlae3b59912018-08-24 15:53:31 +05306881 adapter->mac_addr.bytes,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08006882 adapter->vdev_id);
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006883 if (status != QDF_STATUS_SUCCESS) {
6884 hdd_err("Status: %d Failed to create session.",
6885 status);
6886 return qdf_status_to_os_return(status);
6887 }
6888 }
Jeff Johnsond9952752018-04-18 12:15:35 -07006889 qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
6890 QDF_MAC_ADDR_SIZE);
6891
6892 ch_params.ch_width = bandwidth;
Dustin Brown07901ec2018-09-07 11:02:41 -07006893 wlan_reg_set_channel_params(hdd_ctx->pdev, chan, 0, &ch_params);
Jeff Johnsond9952752018-04-18 12:15:35 -07006894 if (ch_params.ch_width == CH_WIDTH_INVALID) {
6895 hdd_err("Invalid capture channel or bandwidth for a country");
6896 return -EINVAL;
6897 }
6898 if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan,
6899 POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
6900 hdd_err("Failed to change hw mode");
6901 return -EINVAL;
6902 }
6903
Jeff Johnson16528362018-06-14 12:34:16 -07006904 status = sme_roam_channel_change_req(hdd_ctx->mac_handle,
6905 bssid, &ch_params,
Jeff Johnsond9952752018-04-18 12:15:35 -07006906 &roam_profile);
6907 if (status) {
6908 hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
6909 status);
6910 }
6911
Paul Zhang9d117c82019-07-25 15:55:11 +08006912 adapter->mon_chan_freq = wlan_reg_chan_to_freq(hdd_ctx->pdev, chan);
Jeff Johnsond9952752018-04-18 12:15:35 -07006913 adapter->mon_bandwidth = bandwidth;
6914 return qdf_status_to_os_return(status);
6915}
Nirav Shah73713f72018-05-17 14:50:41 +05306916#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05306917
Wu Gaodf929f12018-05-25 18:12:25 +08006918#ifdef MSM_PLATFORM
6919/**
6920 * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO
6921 * @adapter: pointer to adapter
6922 *
6923 * This function calls cfg80211 API to stop P2P GO
6924 *
6925 * Return: None
6926 */
6927static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
6928{
6929 hdd_debug("[SSR] send stop ap to supplicant");
6930 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
6931}
6932
6933static inline void hdd_delete_sta(struct hdd_adapter *adapter)
6934{
6935}
6936#else
6937static inline void hdd_stop_p2p_go(struct hdd_adapter *adapter)
6938{
6939}
6940
6941/**
6942 * hdd_delete_sta() - call cfg80211 API to delete STA
6943 * @adapter: pointer to adapter
6944 *
6945 * This function calls cfg80211 API to delete STA
6946 *
6947 * Return: None
6948 */
6949static void hdd_delete_sta(struct hdd_adapter *adapter)
6950{
6951 struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
6952
6953 hdd_debug("[SSR] send restart supplicant");
6954 /* event supplicant to restart */
6955 cfg80211_del_sta(adapter->dev,
6956 (const u8 *)&bcast_mac.bytes[0],
6957 GFP_KERNEL);
6958}
6959#endif
6960
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006961QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006962{
Jeff Johnson9d295242017-08-29 14:39:48 -07006963 struct hdd_adapter *adapter;
Jeff Johnsone7951512019-02-27 10:02:51 -08006964 eConnectionState conn_state;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05306965 bool value;
Paul Zhang9d117c82019-07-25 15:55:11 +08006966 uint8_t chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006967
Dustin Brown491d54b2018-03-14 12:39:11 -07006968 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006969
Dustin Brown920397d2017-12-13 16:27:50 -08006970 hdd_for_each_adapter(hdd_ctx, adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05306971 if (!hdd_is_interface_up(adapter))
Dustin Brown920397d2017-12-13 16:27:50 -08006972 continue;
Arun Khandavallifae92942016-08-01 13:31:08 +05306973
Yue Ma42654682018-01-11 16:55:24 -08006974 hdd_debug("[SSR] start adapter with device mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07006975 qdf_opmode_str(adapter->device_mode),
Yue Ma42654682018-01-11 16:55:24 -08006976 adapter->device_mode);
6977
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006978 hdd_wmm_init(adapter);
6979
6980 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006981 case QDF_STA_MODE:
6982 case QDF_P2P_CLIENT_MODE:
6983 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006984
Jeff Johnsone7951512019-02-27 10:02:51 -08006985 conn_state = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
6986 ->conn_info.conn_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006987
Krunal Sonib51eec72017-11-20 21:53:01 -08006988 hdd_start_station_adapter(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006989 /* Open the gates for HDD to receive Wext commands */
Jeff Johnsonc72c5732017-10-28 12:49:37 -07006990 adapter->is_link_up_service_needed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006991
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006992 /* Indicate disconnect event to supplicant
6993 * if associated previously
6994 */
Jeff Johnsone7951512019-02-27 10:02:51 -08006995 if (eConnectionState_Associated == conn_state ||
6996 eConnectionState_IbssConnected == conn_state ||
6997 eConnectionState_NotConnected == conn_state ||
6998 eConnectionState_IbssDisconnected == conn_state ||
6999 eConnectionState_Disconnecting == conn_state) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007000 union iwreq_data wrqu;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007001
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007002 memset(&wrqu, '\0', sizeof(wrqu));
7003 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
7004 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
7005 wireless_send_event(adapter->dev, SIOCGIWAP,
7006 &wrqu, NULL);
Jeff Johnsonb9424862017-10-30 08:49:35 -07007007 adapter->session.station.
Jeff Johnson690fe952017-10-25 11:48:39 -07007008 hdd_reassoc_scenario = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007009
7010 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05307011 wlan_hdd_cfg80211_indicate_disconnect(
7012 adapter->dev, false,
Srinivas Dasarid4e87252019-07-01 15:35:52 +05307013 WLAN_REASON_UNSPECIFIED,
7014 NULL, 0);
Jeff Johnsone7951512019-02-27 10:02:51 -08007015 } else if (eConnectionState_Connecting == conn_state) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007016 /*
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007017 * Indicate connect failure to supplicant if we
7018 * were in the process of connecting
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007019 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05307020 hdd_connect_result(adapter->dev, NULL, NULL,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05307021 NULL, 0, NULL, 0,
7022 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007023 GFP_KERNEL, false, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007024 }
7025
7026 hdd_register_tx_flow_control(adapter,
7027 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08007028 hdd_tx_resume_cb,
7029 hdd_tx_flow_control_is_pause);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007030
Visweswara Tanukub5a61242019-03-26 12:24:13 +05307031 hdd_register_hl_netdev_fc_timer(
7032 adapter,
7033 hdd_tx_resume_timer_expired_handler);
7034
Arunk Khandavalli40943af2017-05-15 19:25:34 +05307035 hdd_lpass_notify_start(hdd_ctx, adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05307036 hdd_nud_ignore_tracking(adapter, false);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05307037 hdd_mic_enable_work(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007038 break;
7039
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007040 case QDF_SAP_MODE:
Dustin Brown05d81302018-09-11 16:49:22 -07007041 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05307042 &value);
7043 if (value)
Krunal Sonib51eec72017-11-20 21:53:01 -08007044 hdd_start_ap_adapter(adapter);
Arun Khandavallicc544b32017-01-30 19:52:16 +05307045
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05307046 hdd_mic_enable_work(adapter);
7047
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007048 break;
7049
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007050 case QDF_P2P_GO_MODE:
Wu Gaodf929f12018-05-25 18:12:25 +08007051 hdd_delete_sta(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007052 break;
Arunk Khandavalli062fb032017-10-04 12:18:15 +05307053 case QDF_MONITOR_MODE:
Paul Zhang9d117c82019-07-25 15:55:11 +08007054 chan = wlan_reg_freq_to_chan(hdd_ctx->pdev,
7055 adapter->mon_chan_freq);
Krunal Sonib51eec72017-11-20 21:53:01 -08007056 hdd_start_station_adapter(adapter);
Arunk Khandavalli062fb032017-10-04 12:18:15 +05307057 hdd_set_mon_rx_cb(adapter->dev);
Paul Zhang9d117c82019-07-25 15:55:11 +08007058 wlan_hdd_set_mon_chan(adapter, chan,
Arunk Khandavalli062fb032017-10-04 12:18:15 +05307059 adapter->mon_bandwidth);
7060 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007061 default:
7062 break;
7063 }
Krunal Soni9c2ee032017-07-18 13:49:54 -07007064 /*
7065 * Action frame registered in one adapter which will
7066 * applicable to all interfaces
7067 */
7068 wlan_hdd_cfg80211_register_frames(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007069 }
7070
Wu Gaodf929f12018-05-25 18:12:25 +08007071 hdd_for_each_adapter(hdd_ctx, adapter) {
7072 if (!hdd_is_interface_up(adapter))
7073 continue;
7074
7075 if (adapter->device_mode == QDF_P2P_GO_MODE)
7076 hdd_stop_p2p_go(adapter);
7077 }
7078
Dustin Browne74003f2018-03-14 12:51:58 -07007079 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007080
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307081 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007082}
7083
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007084QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08007085 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007086{
Anurag Chouhanffb21542016-02-17 14:33:03 +05307087 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08007088 qdf_list_node_t *node;
7089
7090 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007091
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007092 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007093 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007094 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007095
7096 if (QDF_IS_STATUS_ERROR(status))
7097 return status;
7098
7099 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
7100
7101 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007102}
7103
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007104QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08007105 struct hdd_adapter *current_adapter,
7106 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007107{
Anurag Chouhanffb21542016-02-17 14:33:03 +05307108 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08007109 qdf_list_node_t *node;
7110
7111 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007112
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007113 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Jeff Johnson19fc8e42017-10-30 19:53:49 -07007114 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
Dustin Brown920397d2017-12-13 16:27:50 -08007115 &current_adapter->node,
7116 &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007117 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007118
7119 if (QDF_IS_STATUS_ERROR(status))
7120 return status;
7121
7122 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
7123
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007124 return status;
7125}
7126
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007127QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08007128 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007129{
Anurag Chouhanffb21542016-02-17 14:33:03 +05307130 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007131
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007132 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007133 status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007134 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007135
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007136 return status;
7137}
7138
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007139QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08007140 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007141{
Anurag Chouhanffb21542016-02-17 14:33:03 +05307142 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08007143 qdf_list_node_t *node;
7144
7145 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007146
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007147 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007148 status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007149 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007150
7151 if (QDF_IS_STATUS_ERROR(status))
7152 return status;
7153
7154 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
7155
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007156 return status;
7157}
7158
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007159QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08007160 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007161{
Anurag Chouhanffb21542016-02-17 14:33:03 +05307162 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007163
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007164 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007165 status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007166 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007167
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007168 return status;
7169}
7170
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007171QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08007172 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007173{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307174 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007175
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007176 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007177 status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08007178 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08007179
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007180 return status;
7181}
7182
Liangwei Dong3abfe8f2018-09-20 02:25:44 -04007183struct hdd_adapter *hdd_get_adapter_by_rand_macaddr(
7184 struct hdd_context *hdd_ctx, tSirMacAddr mac_addr)
7185{
7186 struct hdd_adapter *adapter;
7187
7188 hdd_for_each_adapter(hdd_ctx, adapter) {
7189 if ((adapter->device_mode == QDF_STA_MODE ||
7190 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
7191 adapter->device_mode == QDF_P2P_DEVICE_MODE) &&
7192 ucfg_p2p_check_random_mac(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08007193 adapter->vdev_id, mac_addr))
Liangwei Dong3abfe8f2018-09-20 02:25:44 -04007194 return adapter;
7195 }
7196
7197 return NULL;
7198}
7199
Jeff Johnson9d295242017-08-29 14:39:48 -07007200struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07007201 tSirMacAddr mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007202{
Jeff Johnson9d295242017-08-29 14:39:48 -07007203 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007204
Dustin Brown920397d2017-12-13 16:27:50 -08007205 hdd_for_each_adapter(hdd_ctx, adapter) {
7206 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07007207 mac_addr, sizeof(tSirMacAddr)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007208 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007209 }
7210
7211 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007212}
7213
Jeff Johnson9d295242017-08-29 14:39:48 -07007214struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
Jeff Johnson55d2ab42019-03-06 11:43:49 -08007215 uint32_t vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007216{
Jeff Johnson9d295242017-08-29 14:39:48 -07007217 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007218
Dustin Brown920397d2017-12-13 16:27:50 -08007219 hdd_for_each_adapter(hdd_ctx, adapter) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08007220 if (adapter->vdev_id == vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007221 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007222 }
7223
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007224 return NULL;
7225}
7226
Jeff Johnson9d295242017-08-29 14:39:48 -07007227struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
Naveen Rawat4edb6822017-04-12 10:09:17 -07007228 const char *iface_name)
7229{
Jeff Johnson9d295242017-08-29 14:39:48 -07007230 struct hdd_adapter *adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07007231
Dustin Brown920397d2017-12-13 16:27:50 -08007232 hdd_for_each_adapter(hdd_ctx, adapter) {
7233 if (!qdf_str_cmp(adapter->dev->name, iface_name))
Naveen Rawat4edb6822017-04-12 10:09:17 -07007234 return adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07007235 }
Dustin Brown920397d2017-12-13 16:27:50 -08007236
Naveen Rawat4edb6822017-04-12 10:09:17 -07007237 return NULL;
7238}
7239
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007240/**
7241 * hdd_get_adapter() - to get adapter matching the mode
7242 * @hdd_ctx: hdd context
7243 * @mode: adapter mode
7244 *
7245 * This routine will return the pointer to adapter matching
7246 * with the passed mode.
7247 *
7248 * Return: pointer to adapter or null
7249 */
Jeff Johnson9d295242017-08-29 14:39:48 -07007250struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08007251 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007252{
Jeff Johnson9d295242017-08-29 14:39:48 -07007253 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007254
Dustin Brown920397d2017-12-13 16:27:50 -08007255 hdd_for_each_adapter(hdd_ctx, adapter) {
7256 if (adapter->device_mode == mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007257 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007258 }
7259
7260 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007261}
7262
Jeff Johnson55d2ab42019-03-06 11:43:49 -08007263enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id)
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05307264{
7265 struct hdd_context *hdd_ctx;
7266 struct hdd_adapter *adapter;
7267
7268 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
7269 if (!hdd_ctx) {
7270 hdd_err("Invalid HDD context");
7271 return QDF_MAX_NO_OF_MODE;
7272 }
7273
Jeff Johnson55d2ab42019-03-06 11:43:49 -08007274 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05307275 if (!adapter) {
7276 hdd_err("Invalid HDD adapter");
7277 return QDF_MAX_NO_OF_MODE;
7278 }
7279
7280 return adapter->device_mode;
7281}
7282
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007283/**
7284 * hdd_get_operating_channel() - return operating channel of the device mode
7285 * @hdd_ctx: Pointer to the HDD context.
7286 * @mode: Device mode for which operating channel is required.
Jeff Johnson77f89bb2018-05-06 16:21:36 -07007287 * Supported modes:
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007288 * QDF_STA_MODE,
7289 * QDF_P2P_CLIENT_MODE,
7290 * QDF_SAP_MODE,
7291 * QDF_P2P_GO_MODE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007292 *
7293 * This API returns the operating channel of the requested device mode
7294 *
7295 * Return: channel number. "0" id the requested device is not found OR it is
7296 * not connected.
7297 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007298uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08007299 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007300{
Jeff Johnson9d295242017-08-29 14:39:48 -07007301 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007302 uint8_t operatingChannel = 0;
7303
Dustin Brown920397d2017-12-13 16:27:50 -08007304 hdd_for_each_adapter(hdd_ctx, adapter) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007305 if (mode == adapter->device_mode) {
Jingxiang Geae80dc62019-08-13 17:32:22 +08007306 operatingChannel =
7307 hdd_get_adapter_home_channel(adapter);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07007308 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007309 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007310 }
Dustin Brown920397d2017-12-13 16:27:50 -08007311
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007312 return operatingChannel;
7313}
7314
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007315static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007316 hdd_ctx)
7317{
Jeff Johnson9d295242017-08-29 14:39:48 -07007318 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007319
Dustin Brown491d54b2018-03-14 12:39:11 -07007320 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007321
Dustin Brown920397d2017-12-13 16:27:50 -08007322 hdd_for_each_adapter(hdd_ctx, adapter) {
7323 if (adapter->device_mode == QDF_STA_MODE ||
7324 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
7325 adapter->device_mode == QDF_IBSS_MODE ||
7326 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
7327 adapter->device_mode == QDF_SAP_MODE ||
7328 adapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007329 hdd_unregister_wext(adapter->dev);
7330 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007331 }
7332
Dustin Browne74003f2018-03-14 12:51:58 -07007333 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007334
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307335 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007336}
7337
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007338QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007339{
Jeff Johnson9d295242017-08-29 14:39:48 -07007340 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007341
Dustin Brown491d54b2018-03-14 12:39:11 -07007342 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007343
Dustin Brown920397d2017-12-13 16:27:50 -08007344 hdd_for_each_adapter(hdd_ctx, adapter) {
7345 if (adapter->device_mode == QDF_STA_MODE ||
7346 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
7347 adapter->device_mode == QDF_IBSS_MODE ||
7348 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
7349 adapter->device_mode == QDF_SAP_MODE ||
7350 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brown07901ec2018-09-07 11:02:41 -07007351 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08007352 adapter->vdev_id, INVALID_SCAN_ID,
Vignesh Viswanathan19611c82018-01-16 16:20:40 +05307353 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007354 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007355 }
7356
Dustin Browne74003f2018-03-14 12:51:58 -07007357 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007358
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307359 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007360}
7361
Dustin Brownf27bce82016-11-03 12:52:27 -07007362/**
7363 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
7364 * adapters
7365 * @hdd_ctx: The HDD context containing the adapters to operate on
7366 *
7367 * return: QDF_STATUS_SUCCESS
7368 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007369static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
Dustin Brownf27bce82016-11-03 12:52:27 -07007370{
Jeff Johnson9d295242017-08-29 14:39:48 -07007371 struct hdd_adapter *adapter;
Dustin Brownf27bce82016-11-03 12:52:27 -07007372 int err;
7373
Dustin Brown491d54b2018-03-14 12:39:11 -07007374 hdd_enter();
Dustin Brownf27bce82016-11-03 12:52:27 -07007375
Dustin Brown920397d2017-12-13 16:27:50 -08007376 hdd_for_each_adapter(hdd_ctx, adapter) {
7377 if (adapter->device_mode == QDF_STA_MODE ||
7378 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
7379 adapter->device_mode == QDF_IBSS_MODE ||
7380 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
7381 adapter->device_mode == QDF_SAP_MODE ||
7382 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brownf27bce82016-11-03 12:52:27 -07007383 err = wlan_hdd_sched_scan_stop(adapter->dev);
7384 if (err)
7385 hdd_err("Unable to stop scheduled scan");
7386 }
Dustin Brownf27bce82016-11-03 12:52:27 -07007387 }
7388
Dustin Browne74003f2018-03-14 12:51:58 -07007389 hdd_exit();
Dustin Brownf27bce82016-11-03 12:52:27 -07007390
7391 return QDF_STATUS_SUCCESS;
7392}
7393
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007394#ifdef WLAN_NS_OFFLOAD
7395/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007396 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007397 * @hdd_ctx: Pointer to hdd context
7398 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007399 * Unregister for IPv6 address change notifications.
7400 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007401 * Return: None
7402 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007403static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007404{
7405 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007406}
7407
7408/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007409 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007410 * @hdd_ctx: Pointer to hdd context
7411 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007412 * Register for IPv6 address change notifications.
7413 *
7414 * Return: 0 on success and errno on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007415 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007416static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007417{
7418 int ret;
7419
7420 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
7421 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007422 if (ret) {
7423 hdd_err("Failed to register IPv6 notifier: %d", ret);
7424 goto out;
7425 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007426
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007427 hdd_debug("Registered IPv6 notifier");
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007428out:
7429 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007430}
7431#else
7432/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007433 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007434 * @hdd_ctx: Pointer to hdd context
7435 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007436 * Unregister for IPv6 address change notifications.
7437 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007438 * Return: None
7439 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007440static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007441{
7442}
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007443
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007444/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007445 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007446 * @hdd_ctx: Pointer to hdd context
7447 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007448 * Register for IPv6 address change notifications.
7449 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007450 * Return: None
7451 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007452static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007453{
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007454 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007455}
7456#endif
7457
Alok Kumarb64650c2018-03-23 17:05:11 +05307458void hdd_set_disconnect_status(struct hdd_adapter *adapter, bool status)
7459{
7460 qdf_mutex_acquire(&adapter->disconnection_status_lock);
7461 adapter->disconnection_in_progress = status;
7462 qdf_mutex_release(&adapter->disconnection_status_lock);
7463 hdd_debug("setting disconnection status: %d", status);
7464}
7465
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007466/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007467 * hdd_register_notifiers - Register netdev notifiers.
7468 * @hdd_ctx: HDD context
7469 *
7470 * Register netdev notifiers like IPv4 and IPv6.
7471 *
7472 * Return: 0 on success and errno on failure
7473 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007474static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007475{
7476 int ret;
7477
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007478 ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
7479 if (ret)
Arun Khandavalli08479ba2017-08-07 19:56:23 +05307480 goto out;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007481
7482 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
7483 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
7484 if (ret) {
7485 hdd_err("Failed to register IPv4 notifier: %d", ret);
7486 goto unregister_ip6_notifier;
7487 }
7488
Alok Kumarb64650c2018-03-23 17:05:11 +05307489 ret = hdd_nud_register_netevent_notifier(hdd_ctx);
7490 if (ret) {
7491 hdd_err("Failed to register netevent notifier: %d",
7492 ret);
7493 goto unregister_inetaddr_notifier;
7494 }
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007495 return 0;
7496
Alok Kumarb64650c2018-03-23 17:05:11 +05307497unregister_inetaddr_notifier:
7498 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007499unregister_ip6_notifier:
7500 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007501out:
7502 return ret;
7503
7504}
7505
7506/**
7507 * hdd_unregister_notifiers - Unregister netdev notifiers.
7508 * @hdd_ctx: HDD context
7509 *
7510 * Unregister netdev notifiers like IPv4 and IPv6.
7511 *
7512 * Return: None.
7513 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007514void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007515{
Alok Kumarb64650c2018-03-23 17:05:11 +05307516 hdd_nud_unregister_netevent_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007517 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
7518
7519 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007520}
7521
7522/**
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007523 * hdd_exit_netlink_services - Exit netlink services
7524 * @hdd_ctx: HDD context
7525 *
7526 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
7527 * nl service.
7528 *
7529 * Return: None.
7530 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007531static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007532{
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307533 spectral_scan_deactivate_service();
7534 cnss_diag_deactivate_service();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007535 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007536 ptt_sock_deactivate_svc();
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307537 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007538
7539 nl_srv_exit();
7540}
7541
7542/**
7543 * hdd_init_netlink_services- Init netlink services
7544 * @hdd_ctx: HDD context
7545 *
7546 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
7547 * nl service.
7548 *
7549 * Return: 0 on success and errno on failure.
7550 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007551static int hdd_init_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007552{
7553 int ret;
7554
Ryan Hsuceddceb2016-04-28 10:20:14 -07007555 ret = wlan_hdd_nl_init(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007556 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007557 hdd_err("nl_srv_init failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007558 goto out;
7559 }
Ryan Hsuceddceb2016-04-28 10:20:14 -07007560 cds_set_radio_index(hdd_ctx->radio_index);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007561
Naveen Rawat910726a2017-03-06 11:42:51 -08007562 ret = hdd_activate_wifi_pos(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007563 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007564 hdd_err("hdd_activate_wifi_pos failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007565 goto err_nl_srv;
7566 }
7567
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307568 ptt_sock_activate_svc();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007569
7570 ret = hdd_open_cesium_nl_sock();
Ryan Hsu5e2e2052016-04-28 10:19:38 -07007571 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007572 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007573
7574 ret = cnss_diag_activate_service();
7575 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007576 hdd_err("cnss_diag_activate_service failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007577 goto err_close_cesium;
7578 }
7579
Dustin Brown01520852019-02-27 12:14:16 -08007580 spectral_scan_activate_service(hdd_ctx);
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -08007581
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007582 return 0;
7583
7584err_close_cesium:
7585 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007586 ptt_sock_deactivate_svc();
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307587 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007588err_nl_srv:
7589 nl_srv_exit();
7590out:
7591 return ret;
7592}
7593
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007594/**
7595 * hdd_rx_wake_lock_destroy() - Destroy RX wakelock
7596 * @hdd_ctx: HDD context.
7597 *
7598 * Destroy RX wakelock.
7599 *
7600 * Return: None.
7601 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007602static void hdd_rx_wake_lock_destroy(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007603{
7604 qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
7605}
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007606
7607/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007608 * hdd_rx_wake_lock_create() - Create RX wakelock
7609 * @hdd_ctx: HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007610 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007611 * Create RX wakelock.
7612 *
7613 * Return: None.
7614 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007615static void hdd_rx_wake_lock_create(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007616{
7617 qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
7618}
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007619
7620/**
Houston Hoffman160db392016-10-10 17:37:51 -07007621 * hdd_context_deinit() - Deinitialize HDD context
7622 * @hdd_ctx: HDD context.
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007623 *
Houston Hoffman160db392016-10-10 17:37:51 -07007624 * Deinitialize HDD context along with all the feature specific contexts but
7625 * do not free hdd context itself. Caller of this API is supposed to free
7626 * HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007627 *
Houston Hoffman160db392016-10-10 17:37:51 -07007628 * return: 0 on success and errno on failure.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007629 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007630static int hdd_context_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007631{
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05307632 qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock);
7633
Houston Hoffman160db392016-10-10 17:37:51 -07007634 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007635
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007636 hdd_sap_context_destroy(hdd_ctx);
7637
7638 hdd_rx_wake_lock_destroy(hdd_ctx);
7639
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007640 hdd_scan_context_destroy(hdd_ctx);
7641
Jeff Johnson19fc8e42017-10-30 19:53:49 -07007642 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007643
Houston Hoffman160db392016-10-10 17:37:51 -07007644 return 0;
7645}
7646
Dustin Brown623e7e32018-09-05 14:27:50 -07007647void hdd_context_destroy(struct hdd_context *hdd_ctx)
Houston Hoffman160db392016-10-10 17:37:51 -07007648{
Rajeev Kumar493a31b2017-09-29 14:01:24 -07007649 cds_set_context(QDF_MODULE_ID_HDD, NULL);
Arunk Khandavalli3d267b42017-05-02 18:58:59 +05307650
Dustin Brown623e7e32018-09-05 14:27:50 -07007651 hdd_exit_netlink_services(hdd_ctx);
Hanumantha Reddy Pothula00c74f62016-11-24 20:13:32 +05307652 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
7653
Houston Hoffman160db392016-10-10 17:37:51 -07007654 hdd_context_deinit(hdd_ctx);
7655
Dustin Browndb2df2e2018-10-31 15:29:24 -07007656 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
7657
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307658 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007659 hdd_ctx->config = NULL;
Dustin Brown84f46ea2018-02-15 11:57:36 -08007660 cfg_release();
7661
Min Liu47104042019-04-09 17:49:21 +08007662 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007663 wiphy_free(hdd_ctx->wiphy);
7664}
7665
7666/**
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05307667 * wlan_destroy_bug_report_lock() - Destroy bug report lock
7668 *
7669 * This function is used to destroy bug report lock
7670 *
7671 * Return: None
7672 */
7673static void wlan_destroy_bug_report_lock(void)
7674{
Jeff Johnson2b6982c2018-05-29 14:56:11 -07007675 struct cds_context *p_cds_context;
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05307676
7677 p_cds_context = cds_get_global_context();
7678 if (!p_cds_context) {
7679 hdd_err("cds context is NULL");
7680 return;
7681 }
7682
7683 qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
7684}
7685
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +05307686#ifdef DISABLE_CHANNEL_LIST
7687static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
7688{
7689 qdf_mutex_destroy(&hdd_ctx->cache_channel_lock);
7690}
7691#else
7692static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
7693{
7694}
7695#endif
7696
Dustin Brown92bd8382018-10-31 15:49:46 -07007697void hdd_wlan_exit(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007698{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007699 struct wiphy *wiphy = hdd_ctx->wiphy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007700
Dustin Brown491d54b2018-03-14 12:39:11 -07007701 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007702
Arun Kumar Khandavallideda5a82019-03-11 15:32:19 +05307703 hdd_debugfs_mws_coex_info_deinit(hdd_ctx);
Dustin Brown4c663222018-10-23 14:19:36 -07007704 hdd_psoc_idle_timer_stop(hdd_ctx);
Dustin Brown6470aba2018-09-05 09:49:58 -07007705
Arun Khandavallifae92942016-08-01 13:31:08 +05307706 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007707
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007708 /*
7709 * Powersave Offload Case
7710 * Disable Idle Power Save Mode
7711 */
7712 hdd_set_idle_ps_config(hdd_ctx, false);
Sandeep Puligilla8fa28fd2017-11-02 12:19:33 -07007713 /* clear the scan queue in all the scenarios */
Dustin Brown07901ec2018-09-07 11:02:41 -07007714 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007715
Dustin Brownf688ea12019-03-19 17:02:32 -07007716 if (hdd_ctx->driver_status != DRIVER_MODULES_CLOSED) {
Arun Khandavallifae92942016-08-01 13:31:08 +05307717 hdd_unregister_wext_all_adapters(hdd_ctx);
7718 /*
7719 * Cancel any outstanding scan requests. We are about to close
7720 * all of our adapters, but an adapter structure is what SME
7721 * passes back to our callback function. Hence if there
7722 * are any outstanding scan requests then there is a
7723 * race condition between when the adapter is closed and
7724 * when the callback is invoked. We try to resolve that
7725 * race condition here by canceling any outstanding scans
7726 * before we close the adapters.
7727 * Note that the scans may be cancelled in an asynchronous
7728 * manner, so ideally there needs to be some kind of
7729 * synchronization. Rather than introduce a new
7730 * synchronization here, we will utilize the fact that we are
7731 * about to Request Full Power, and since that is synchronized,
7732 * the expectation is that by the time Request Full Power has
7733 * completed, all scans will be cancelled
7734 */
7735 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Dustin Brownf27bce82016-11-03 12:52:27 -07007736 hdd_abort_sched_scan_all_adapters(hdd_ctx);
Dustin Browndb2a8be2017-12-20 11:49:56 -08007737 hdd_stop_all_adapters(hdd_ctx);
bings29c99862017-11-01 13:54:13 +08007738 hdd_deinit_all_adapters(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007739 }
7740
Arun Khandavalli08479ba2017-08-07 19:56:23 +05307741 unregister_netdevice_notifier(&hdd_netdev_notifier);
7742
Rachit Kankane30807332018-06-27 18:39:36 +05307743 qdf_dp_trace_deinit();
7744
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07007745 hdd_wlan_stop_modules(hdd_ctx, false);
Hanumanth Reddy Pothula709a6362016-10-18 18:19:44 +05307746
Visweswara Tanukuc029a202018-11-27 10:42:10 +05307747 hdd_bus_bw_compute_timer_stop(hdd_ctx);
Dustin Brown86d196b2018-08-02 11:51:49 -07007748 hdd_bus_bandwidth_deinit(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -08007749 hdd_driver_memdump_deinit();
7750
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +05307751 qdf_nbuf_deinit_replenish_timer();
7752
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05307753 if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) {
7754 hdd_info("Release wakelock for monitor mode!");
7755 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
7756 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
7757 }
7758
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307759 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307760 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +05307761 wlan_hdd_cache_chann_mutex_destroy(hdd_ctx);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307762
Naveen Rawate02f8f52018-04-05 11:58:04 -07007763 osif_request_manager_deinit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007764
Dustin Brownd005ad82018-01-19 10:32:13 -08007765 hdd_close_all_adapters(hdd_ctx, false);
7766
Manishekar Chandrasekaranf7a1dad2016-06-23 06:43:47 +05307767 wlansap_global_deinit();
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05307768 /*
7769 * If there is re_init failure wiphy would have already de-registered
7770 * check the wiphy status before un-registering again
7771 */
Ashish Kumar Dhanotiyae16feb72017-03-31 19:39:37 +05307772 if (wiphy && wiphy->registered) {
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05307773 wiphy_unregister(wiphy);
7774 wlan_hdd_cfg80211_deinit(wiphy);
7775 hdd_lpass_notify_stop(hdd_ctx);
7776 }
Yuanyuan Liu3e918e52016-08-17 15:41:35 -07007777
Arun Khandavallifae92942016-08-01 13:31:08 +05307778 hdd_exit_netlink_services(hdd_ctx);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05307779#ifdef FEATURE_WLAN_CH_AVOID
7780 mutex_destroy(&hdd_ctx->avoid_freq_lock);
7781#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007782}
7783
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007784/**
7785 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
7786 * @state: state
7787 *
7788 * This function notifies FW with modem power status
7789 *
7790 * Return: 0 if successful, error number otherwise
7791 */
7792int hdd_wlan_notify_modem_power_state(int state)
7793{
7794 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307795 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007796 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -07007797 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007798
Anurag Chouhan6d760662016-02-20 16:05:43 +05307799 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007800 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307801 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007802 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307803
Jeff Johnson16528362018-06-14 12:34:16 -07007804 mac_handle = hdd_ctx->mac_handle;
7805 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007806 return -EINVAL;
7807
Jeff Johnson16528362018-06-14 12:34:16 -07007808 qdf_status = sme_notify_modem_power_state(mac_handle, state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307809 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007810 hdd_err("Fail to send notification with modem power state %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007811 state);
7812 return -EINVAL;
7813 }
7814 return 0;
7815}
7816
7817/**
7818 *
7819 * hdd_post_cds_enable_config() - HDD post cds start config helper
7820 * @adapter - Pointer to the HDD
7821 *
7822 * Return: None
7823 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007824QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007825{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307826 QDF_STATUS qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007827
7828 /*
7829 * Send ready indication to the HDD. This will kick off the MAC
7830 * into a 'running' state and should kick off an initial scan.
7831 */
Jeff Johnson16528362018-06-14 12:34:16 -07007832 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307833 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007834 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
7835 qdf_ret_status, qdf_ret_status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307836 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007837 }
7838
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307839 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007840}
7841
Sourav Mohapatra92ea8d62018-02-05 10:03:10 +05307842struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx)
7843{
7844 struct hdd_adapter *adapter;
7845
7846 hdd_for_each_adapter(hdd_ctx, adapter) {
7847 if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC)
7848 return adapter;
7849 }
7850
7851 return NULL;
7852}
7853
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +05307854/**
7855 * hdd_rx_mic_error_ind() - MIC error indication handler
7856 * @scn_handle: pdev handle from osif layer
7857 * @info: mic failure information
7858 *
7859 * This function indicates the Mic failure to the supplicant
7860 *
7861 * Return: None
7862 */
7863static void
7864hdd_rx_mic_error_ind(void *scn_handle,
7865 struct cdp_rx_mic_err_info *mic_failure_info)
7866{
7867 struct wiphy *wiphy;
7868 struct pdev_osif_priv *pdev_priv;
7869 struct hdd_context *hdd_ctx;
7870 struct hdd_adapter *adapter;
7871 struct hdd_mic_error_info *hdd_mic_info;
7872 struct wlan_objmgr_pdev *pdev;
7873
7874 pdev = (struct wlan_objmgr_pdev *)scn_handle;
7875 pdev_priv = wlan_pdev_get_ospriv(pdev);
7876 wiphy = pdev_priv->wiphy;
7877 hdd_ctx = wiphy_priv(wiphy);
7878
7879 if (wlan_hdd_validate_context(hdd_ctx))
7880 return;
7881
7882 adapter = hdd_get_adapter_by_vdev(hdd_ctx, mic_failure_info->vdev_id);
7883 if (hdd_validate_adapter(adapter))
7884 return;
7885
7886 hdd_mic_info = qdf_mem_malloc(sizeof(*hdd_mic_info));
7887 if (!hdd_mic_info)
7888 return;
7889
7890 qdf_copy_macaddr(&hdd_mic_info->ta_mac_addr,
7891 &mic_failure_info->ta_mac_addr);
7892 hdd_mic_info->multicast = mic_failure_info->multicast;
7893 hdd_mic_info->key_id = mic_failure_info->key_id;
7894 qdf_mem_copy(&hdd_mic_info->tsc, &mic_failure_info->tsc,
7895 SIR_CIPHER_SEQ_CTR_SIZE);
7896 hdd_mic_info->vdev_id = mic_failure_info->vdev_id;
7897
7898 qdf_spin_lock_bh(&adapter->mic_work.lock);
7899 if (adapter->mic_work.status != MIC_INITIALIZED) {
7900 qdf_spin_unlock_bh(&adapter->mic_work.lock);
7901 qdf_mem_free(hdd_mic_info);
7902 return;
7903 }
7904 /*
7905 * Store mic error info pointer in adapter
7906 * for freeing up the alocated memory in case
7907 * the work scheduled below is flushed or deinitialized.
7908 */
7909 adapter->mic_work.status = MIC_SCHEDULED;
7910 adapter->mic_work.info = hdd_mic_info;
7911 qdf_sched_work(0, &adapter->mic_work.work);
7912 qdf_spin_unlock_bh(&adapter->mic_work.lock);
7913}
7914
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007915/* wake lock APIs for HDD */
7916void hdd_prevent_suspend(uint32_t reason)
7917{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05307918 qdf_wake_lock_acquire(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007919}
7920
7921void hdd_allow_suspend(uint32_t reason)
7922{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05307923 qdf_wake_lock_release(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007924}
7925
7926void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
7927{
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05307928 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
7929 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007930}
7931
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007932/* Initialize channel list in sme based on the country code */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007933QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007934{
Jeff Johnson16528362018-06-14 12:34:16 -07007935 return sme_init_chan_list(hdd_ctx->mac_handle,
Amar Singhal6f8592b2017-04-26 14:31:58 -07007936 hdd_ctx->reg.alpha2,
7937 hdd_ctx->reg.cc_src);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007938}
7939
7940/**
7941 * hdd_is_5g_supported() - check if hardware supports 5GHz
7942 * @hdd_ctx: Pointer to the hdd context
7943 *
7944 * HDD function to know if hardware supports 5GHz
7945 *
7946 * Return: true if hardware supports 5GHz
7947 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007948bool hdd_is_5g_supported(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007949{
Amar Singhal58b45ef2017-08-01 13:43:54 -07007950 if (!hdd_ctx)
zdingf54169a2016-10-12 17:08:45 +08007951 return true;
7952
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08007953 if (hdd_ctx->curr_band != BAND_2G)
zdingf54169a2016-10-12 17:08:45 +08007954 return true;
7955 else
7956 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007957}
7958
Ashish Kumar Dhanotiya34507e02019-06-12 12:53:59 +05307959bool hdd_is_2g_supported(struct hdd_context *hdd_ctx)
7960{
7961 if (!hdd_ctx)
7962 return false;
7963
7964 if (hdd_ctx->curr_band != BAND_5G)
7965 return true;
7966 else
7967 return false;
7968}
7969
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007970static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007971{
7972 struct wiphy *wiphy;
Amar Singhale4f28ee2015-10-21 14:36:56 -07007973 int ret_val;
Wu Gaoed616a12019-01-16 15:19:21 +08007974 uint32_t channel_bonding_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007975
7976 wiphy = hdd_ctx->wiphy;
7977
7978 /*
7979 * The channel information in
7980 * wiphy needs to be initialized before wiphy registration
7981 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07007982 ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
7983 if (ret_val) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007984 hdd_err("regulatory init failed");
Amar Singhale4f28ee2015-10-21 14:36:56 -07007985 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007986 }
7987
7988#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
7989 wiphy->wowlan = &wowlan_support_reg_init;
7990#else
7991 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
7992 WIPHY_WOWLAN_MAGIC_PKT |
7993 WIPHY_WOWLAN_DISCONNECT |
7994 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
7995 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
7996 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
7997 WIPHY_WOWLAN_4WAY_HANDSHAKE |
7998 WIPHY_WOWLAN_RFKILL_RELEASE;
7999
8000 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
8001 WOW_MAX_FILTERS_PER_LIST);
8002 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
8003 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
8004#endif
Wu Gaoed616a12019-01-16 15:19:21 +08008005 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
8006 &channel_bonding_mode);
Liangwei Dong0da14262018-07-03 03:30:23 -04008007 if (hdd_ctx->obss_scan_offload) {
8008 hdd_debug("wmi_service_obss_scan supported");
Wu Gaoed616a12019-01-16 15:19:21 +08008009 } else if (channel_bonding_mode) {
Liangwei Dong0da14262018-07-03 03:30:23 -04008010 hdd_debug("enable wpa_supp obss_scan");
8011 wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN;
8012 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008013
8014 /* registration of wiphy dev with cfg80211 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07008015 ret_val = wlan_hdd_cfg80211_register(wiphy);
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05308016 if (0 > ret_val) {
Amar Singhale4f28ee2015-10-21 14:36:56 -07008017 hdd_err("wiphy registration failed");
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05308018 return ret_val;
8019 }
Amar Singhalac26de22018-06-22 12:53:06 -07008020
Kiran Kumar Lokere0508af92018-04-23 18:38:32 -07008021 /* Check the kernel version for upstream commit aced43ce780dc5 that
8022 * has support for processing user cell_base hints when wiphy is
8023 * self managed or check the backport flag for the same.
8024 */
Amar Singhalac26de22018-06-22 12:53:06 -07008025#if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
8026 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
Kiran Kumar Lokere0508af92018-04-23 18:38:32 -07008027 hdd_send_wiphy_regd_sync_event(hdd_ctx);
8028#endif
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05308029
Amar Singhal2d812012018-02-03 15:06:47 +08008030 pld_increment_driver_load_cnt(hdd_ctx->parent_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008031
Amar Singhale4f28ee2015-10-21 14:36:56 -07008032 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008033}
8034
Tiger Yu8b119e92019-04-09 13:55:07 +08008035#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
Mohit Khannaca4173b2017-09-12 21:52:19 -07008036/**
8037 * hdd_display_periodic_stats() - Function to display periodic stats
8038 * @hdd_ctx - handle to hdd context
8039 * @bool data_in_interval - true, if data detected in bw time interval
8040 *
8041 * The periodicity is determined by hdd_ctx->config->periodic_stats_disp_time.
8042 * Stats show up in wlan driver logs.
8043 *
8044 * Returns: None
8045 */
Mohit Khanna70322002018-05-15 19:21:32 -07008046static void hdd_display_periodic_stats(struct hdd_context *hdd_ctx,
8047 bool data_in_interval)
Mohit Khannaca4173b2017-09-12 21:52:19 -07008048{
Mohit Khanna70322002018-05-15 19:21:32 -07008049 static uint32_t counter;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008050 static bool data_in_time_period;
8051 ol_txrx_pdev_handle pdev;
Mohit Khanna81418772018-10-30 14:14:46 -07008052 ol_txrx_soc_handle soc;
Arif Hussaincca60432018-12-03 19:45:12 -08008053 uint32_t periodic_stats_disp_time = 0;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008054
Arif Hussaincca60432018-12-03 19:45:12 -08008055 ucfg_mlme_stats_get_periodic_display_time(hdd_ctx->psoc,
8056 &periodic_stats_disp_time);
8057 if (!periodic_stats_disp_time)
Mohit Khannaca4173b2017-09-12 21:52:19 -07008058 return;
8059
Mohit Khanna81418772018-10-30 14:14:46 -07008060 soc = cds_get_context(QDF_MODULE_ID_SOC);
8061 if (!soc) {
8062 hdd_err("soc is NULL");
8063 return;
8064 }
8065
Mohit Khannaca4173b2017-09-12 21:52:19 -07008066 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
8067 if (!pdev) {
8068 hdd_err("pdev is NULL");
8069 return;
8070 }
8071
8072 counter++;
8073 if (data_in_interval)
8074 data_in_time_period = data_in_interval;
8075
jitiphil869b9f72018-09-25 17:14:01 +05308076 if (counter * hdd_ctx->config->bus_bw_compute_interval >=
Arif Hussaincca60432018-12-03 19:45:12 -08008077 periodic_stats_disp_time * 1000) {
Mohit Khannaca4173b2017-09-12 21:52:19 -07008078 if (data_in_time_period) {
Mohit Khanna70322002018-05-15 19:21:32 -07008079 wlan_hdd_display_txrx_stats(hdd_ctx);
Mohit Khannac9649652018-11-28 18:10:28 -08008080 dp_txrx_ext_dump_stats(soc, CDP_DP_RX_THREAD_STATS);
Mohit Khanna81418772018-10-30 14:14:46 -07008081 cdp_display_stats(soc,
Mohit Khanna70322002018-05-15 19:21:32 -07008082 CDP_RX_RING_STATS,
8083 QDF_STATS_VERBOSITY_LEVEL_LOW);
Mohit Khanna81418772018-10-30 14:14:46 -07008084 cdp_display_stats(soc,
Mohit Khannaca4173b2017-09-12 21:52:19 -07008085 CDP_TXRX_PATH_STATS,
8086 QDF_STATS_VERBOSITY_LEVEL_LOW);
8087 wlan_hdd_display_netif_queue_history
8088 (hdd_ctx, QDF_STATS_VERBOSITY_LEVEL_LOW);
8089 qdf_dp_trace_dump_stats();
8090 }
8091 counter = 0;
8092 data_in_time_period = false;
8093 }
8094}
8095
Ravi Joshie2331e82015-07-01 18:18:54 -07008096/**
Tang Yingying5a4ccf22018-03-30 15:58:27 +08008097 * hdd_clear_rps_cpu_mask - clear RPS CPU mask for interfaces
8098 * @hdd_ctx: pointer to struct hdd_context
8099 *
8100 * Return: none
8101 */
8102static void hdd_clear_rps_cpu_mask(struct hdd_context *hdd_ctx)
8103{
8104 struct hdd_adapter *adapter;
8105
8106 hdd_for_each_adapter(hdd_ctx, adapter)
8107 hdd_send_rps_disable_ind(adapter);
8108}
8109
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008110#ifdef CLD_PM_QOS
8111#define PLD_REMOVE_PM_QOS(x)
8112#define PLD_REQUEST_PM_QOS(x, y)
8113/**
8114 * hdd_pm_qos_update_cpu_mask() - Prepare CPU mask for PM_qos voting
8115 * @mask: return variable of cpumask for the TPUT
8116 * @high_throughput: only update high cores mask for high TPUT
8117 *
8118 * Return: none
8119 */
8120static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask,
8121 bool high_throughput)
8122{
8123 cpumask_set_cpu(0, mask);
8124 cpumask_set_cpu(1, mask);
8125 cpumask_set_cpu(2, mask);
8126 cpumask_set_cpu(3, mask);
8127
8128 if (high_throughput) {
8129 /* For high TPUT include GOLD mask also */
8130 cpumask_set_cpu(4, mask);
8131 cpumask_set_cpu(5, mask);
8132 cpumask_set_cpu(6, mask);
8133 }
8134}
8135
8136/**
8137 * hdd_pm_qos_update_request() - API to request for pm_qos
8138 * @hdd_ctx: handle to hdd context
8139 * @pm_qos_cpu_mask: cpu_mask to apply
8140 *
8141 * Return: none
8142 */
8143static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
8144 cpumask_t *pm_qos_cpu_mask)
8145{
8146 cpumask_copy(&hdd_ctx->pm_qos_req.cpus_affine, pm_qos_cpu_mask);
8147 /* Latency value to be read from INI */
8148 pm_qos_update_request(&hdd_ctx->pm_qos_req, 1);
8149}
8150
8151#ifdef CONFIG_SMP
8152/**
8153 * hdd_update_pm_qos_affine_cores() - Update PM_qos request for AFFINE_CORES
8154 * @hdd_ctx: handle to hdd context
8155 *
8156 * Return: none
8157 */
8158static inline void hdd_update_pm_qos_affine_cores(struct hdd_context *hdd_ctx)
8159{
8160 hdd_ctx->pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES;
8161}
8162#else
8163static inline void hdd_update_pm_qos_affine_cores(struct hdd_context *hdd_ctx)
8164{
8165}
8166#endif
8167static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
8168{
8169 hdd_update_pm_qos_affine_cores(hdd_ctx);
8170 pm_qos_add_request(&hdd_ctx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
8171 PM_QOS_DEFAULT_VALUE);
8172}
8173
8174static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
8175{
8176 pm_qos_remove_request(&hdd_ctx->pm_qos_req);
8177}
8178#else
8179#define PLD_REMOVE_PM_QOS(x) pld_remove_pm_qos(x)
8180#define PLD_REQUEST_PM_QOS(x, y) pld_request_pm_qos(x, y)
8181
8182static inline void hdd_pm_qos_add_request(struct hdd_context *hdd_ctx)
8183{
8184}
8185
8186static inline void hdd_pm_qos_remove_request(struct hdd_context *hdd_ctx)
8187{
8188}
8189
8190static inline void hdd_pm_qos_update_cpu_mask(cpumask_t *mask,
8191 bool high_throughput)
8192{
8193}
8194
8195static inline void hdd_pm_qos_update_request(struct hdd_context *hdd_ctx,
8196 cpumask_t *pm_qos_cpu_mask)
8197{
8198}
8199#endif
8200
Tang Yingying5a4ccf22018-03-30 15:58:27 +08008201/**
Yuanyuan Liu13738502016-04-06 17:41:37 -07008202 * hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
Ravi Joshie2331e82015-07-01 18:18:54 -07008203 * @hdd_ctx - handle to hdd context
8204 * @tx_packets - transmit packet count
8205 * @rx_packets - receive packet count
8206 *
8207 * The function controls the bus bandwidth and dynamic control of
8208 * tcp delayed ack configuration
8209 *
8210 * Returns: None
8211 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07008212
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008213static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07008214 const uint64_t tx_packets,
8215 const uint64_t rx_packets)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008216{
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008217 uint16_t index = 0;
8218 bool vote_level_change = false;
8219 bool rx_level_change = false;
8220 bool tx_level_change = false;
8221 bool rxthread_high_tput_req = false;
8222 bool dptrace_high_tput_req;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008223 u64 total_pkts = tx_packets + rx_packets;
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008224 uint64_t temp_tx = 0, avg_rx = 0;
8225 uint64_t no_rx_offload_pkts = 0, avg_no_rx_offload_pkts = 0;
8226 uint64_t rx_offload_pkts = 0, avg_rx_offload_pkts = 0;
Mahesh Kumar Kalikot Veetil64a88692019-07-03 13:57:34 -07008227 enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_IDLE;
Mohit Khannac3da7062017-02-08 21:08:56 -08008228 static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
Mohit Khannae71e2262015-11-10 09:37:24 -08008229 enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
Ravi Joshib89e7f72016-09-07 13:43:15 -07008230 uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count;
Jinwei Chen0dc383e2019-08-23 00:43:04 +08008231 uint32_t bus_low_cnt_threshold = hdd_ctx->config->bus_low_cnt_threshold;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008232 cpumask_t pm_qos_cpu_mask;
8233 bool enable_pm_qos_high = false;
8234
8235 cpumask_clear(&pm_qos_cpu_mask);
Srinivas Girigowda50335342018-09-07 15:21:01 -07008236
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008237 if (total_pkts > hdd_ctx->config->bus_bw_very_high_threshold)
8238 next_vote_level = PLD_BUS_WIDTH_VERY_HIGH;
8239 else if (total_pkts > hdd_ctx->config->bus_bw_high_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07008240 next_vote_level = PLD_BUS_WIDTH_HIGH;
jitiphil869b9f72018-09-25 17:14:01 +05308241 else if (total_pkts > hdd_ctx->config->bus_bw_medium_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07008242 next_vote_level = PLD_BUS_WIDTH_MEDIUM;
jitiphil869b9f72018-09-25 17:14:01 +05308243 else if (total_pkts > hdd_ctx->config->bus_bw_low_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07008244 next_vote_level = PLD_BUS_WIDTH_LOW;
Yue Mad6478e42015-10-20 18:49:24 -07008245 else
Mahesh Kumar Kalikot Veetil64a88692019-07-03 13:57:34 -07008246 next_vote_level = PLD_BUS_WIDTH_IDLE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008247
Mohit Khannaf7562c32018-07-05 17:42:36 -07008248 dptrace_high_tput_req =
Mahesh Kumar Kalikot Veetil64a88692019-07-03 13:57:34 -07008249 next_vote_level > PLD_BUS_WIDTH_IDLE ? true : false;
Mohit Khannaf7562c32018-07-05 17:42:36 -07008250
Jinwei Chen0dc383e2019-08-23 00:43:04 +08008251 if (next_vote_level == PLD_BUS_WIDTH_LOW) {
8252 if (++hdd_ctx->bus_low_vote_cnt >= bus_low_cnt_threshold)
8253 qdf_atomic_set(&hdd_ctx->low_tput_gro_enable, 1);
8254 } else {
8255 hdd_ctx->bus_low_vote_cnt = 0;
8256 qdf_atomic_set(&hdd_ctx->low_tput_gro_enable, 0);
8257 }
8258
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008259 if (hdd_ctx->cur_vote_level != next_vote_level) {
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008260 hdd_debug("BW Vote level %d, tx_packets: %lld, rx_packets: %lld",
8261 next_vote_level, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008262 hdd_ctx->cur_vote_level = next_vote_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008263 vote_level_change = true;
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008264
Yuanyuan Liu13738502016-04-06 17:41:37 -07008265 pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level);
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008266
Tang Yingying5a4ccf22018-03-30 15:58:27 +08008267 if ((next_vote_level == PLD_BUS_WIDTH_LOW) ||
Mahesh Kumar Kalikot Veetil64a88692019-07-03 13:57:34 -07008268 (next_vote_level == PLD_BUS_WIDTH_IDLE)) {
Nirav Shahffc6a092016-06-09 16:09:08 +05308269 if (hdd_ctx->hbw_requested) {
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008270 PLD_REMOVE_PM_QOS(hdd_ctx->parent_dev);
Nirav Shahffc6a092016-06-09 16:09:08 +05308271 hdd_ctx->hbw_requested = false;
8272 }
Tang Yingying5a4ccf22018-03-30 15:58:27 +08008273 if (hdd_ctx->dynamic_rps)
8274 hdd_clear_rps_cpu_mask(hdd_ctx);
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07008275 } else {
Nirav Shahffc6a092016-06-09 16:09:08 +05308276 if (!hdd_ctx->hbw_requested) {
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008277 PLD_REQUEST_PM_QOS(hdd_ctx->parent_dev, 1);
Nirav Shahffc6a092016-06-09 16:09:08 +05308278 hdd_ctx->hbw_requested = true;
8279 }
Tang Yingying5a4ccf22018-03-30 15:58:27 +08008280 if (hdd_ctx->dynamic_rps)
8281 hdd_set_rps_cpu_mask(hdd_ctx);
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07008282 }
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008283
Manjunathappa Prakashcb6df762018-05-29 18:54:58 -07008284 if (hdd_ctx->config->napi_cpu_affinity_mask)
8285 hdd_napi_apply_throughput_policy(hdd_ctx,
8286 tx_packets,
8287 rx_packets);
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008288
jitiphil869b9f72018-09-25 17:14:01 +05308289 if (rx_packets < hdd_ctx->config->bus_bw_low_threshold)
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008290 hdd_disable_rx_ol_for_low_tput(hdd_ctx, true);
8291 else
8292 hdd_disable_rx_ol_for_low_tput(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008293 }
Mohit Khannae71e2262015-11-10 09:37:24 -08008294
Mohit Khannaf7562c32018-07-05 17:42:36 -07008295 qdf_dp_trace_apply_tput_policy(dptrace_high_tput_req);
8296
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008297 /*
8298 * Includes tcp+udp, if perf core is required for tcp, then
8299 * perf core is also required for udp.
8300 */
8301 no_rx_offload_pkts = hdd_ctx->no_rx_offload_pkt_cnt;
8302 hdd_ctx->no_rx_offload_pkt_cnt = 0;
8303 rx_offload_pkts = rx_packets - no_rx_offload_pkts;
Mohit Khannae71e2262015-11-10 09:37:24 -08008304
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008305 avg_no_rx_offload_pkts = (no_rx_offload_pkts +
8306 hdd_ctx->prev_no_rx_offload_pkts) / 2;
8307 hdd_ctx->prev_no_rx_offload_pkts = no_rx_offload_pkts;
Mohit Khannab1dd1e82017-02-04 15:14:38 -08008308
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008309 avg_rx_offload_pkts = (rx_offload_pkts +
8310 hdd_ctx->prev_rx_offload_pkts) / 2;
8311 hdd_ctx->prev_rx_offload_pkts = rx_offload_pkts;
8312
8313 avg_rx = avg_no_rx_offload_pkts + avg_rx_offload_pkts;
8314 /*
8315 * Takes care to set Rx_thread affinity for below case
8316 * 1)LRO/GRO not supported ROME case
8317 * 2)when rx_ol is disabled in cases like concurrency etc
8318 * 3)For UDP cases
8319 */
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008320 if (avg_no_rx_offload_pkts > hdd_ctx->config->bus_bw_high_threshold) {
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008321 rxthread_high_tput_req = true;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008322 enable_pm_qos_high = true;
8323 } else {
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008324 rxthread_high_tput_req = false;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008325 enable_pm_qos_high = false;
8326 }
8327
8328 hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, enable_pm_qos_high);
Poddar, Siddarth47c23402017-10-25 12:17:39 +05308329
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07008330 if (cds_sched_handle_throughput_req(rxthread_high_tput_req))
8331 hdd_warn("Rx thread high_tput(%d) affinity request failed",
8332 rxthread_high_tput_req);
8333
8334 /* fine-tuning parameters for RX Flows */
jitiphil869b9f72018-09-25 17:14:01 +05308335 if (avg_rx > hdd_ctx->config->tcp_delack_thres_high) {
Ravi Joshifed83572016-10-07 16:20:37 -07008336 if ((hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH) &&
8337 (++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt)) {
8338 next_rx_level = WLAN_SVC_TP_HIGH;
8339 }
Ravi Joshib89e7f72016-09-07 13:43:15 -07008340 } else {
Ravi Joshib89e7f72016-09-07 13:43:15 -07008341 hdd_ctx->rx_high_ind_cnt = 0;
Mohit Khannac3da7062017-02-08 21:08:56 -08008342 next_rx_level = WLAN_SVC_TP_LOW;
Ravi Joshib89e7f72016-09-07 13:43:15 -07008343 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008344
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008345 if (hdd_ctx->cur_rx_level != next_rx_level) {
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07008346 struct wlan_rx_tp_data rx_tp_data = {0};
8347
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008348 hdd_ctx->cur_rx_level = next_rx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008349 rx_level_change = true;
Ravi Joshie2331e82015-07-01 18:18:54 -07008350 /* Send throughput indication only if it is enabled.
8351 * Disabling tcp_del_ack will revert the tcp stack behavior
8352 * to default delayed ack. Note that this will disable the
8353 * dynamic delayed ack mechanism across the system
8354 */
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008355 if (hdd_ctx->en_tcp_delack_no_lro) {
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07008356 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
Mohit Khanna6dbf9c82019-07-12 17:23:28 -07008357 hdd_debug("TCP DELACK trigger level %d, average_rx: %llu",
8358 next_rx_level, avg_rx);
8359 }
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07008360
Mohit Khanna6272fb682017-04-13 09:34:36 -07008361 if (hdd_ctx->config->enable_tcp_adv_win_scale)
8362 rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
8363
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07008364 rx_tp_data.level = next_rx_level;
Alok Kumar2fad6442018-11-08 19:19:28 +05308365 wlan_hdd_update_tcp_rx_param(hdd_ctx, &rx_tp_data);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008366 }
8367
Mohit Khannae71e2262015-11-10 09:37:24 -08008368 /* fine-tuning parameters for TX Flows */
8369 temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2;
8370 hdd_ctx->prev_tx = tx_packets;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008371
8372 if (temp_tx > hdd_ctx->config->bus_bw_high_threshold)
8373 enable_pm_qos_high = true;
8374 else
8375 enable_pm_qos_high = false;
8376
8377 hdd_pm_qos_update_cpu_mask(&pm_qos_cpu_mask, enable_pm_qos_high);
8378
Mohit Khannae71e2262015-11-10 09:37:24 -08008379 if (temp_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
8380 next_tx_level = WLAN_SVC_TP_HIGH;
8381 else
8382 next_tx_level = WLAN_SVC_TP_LOW;
8383
Prakash Manjunathappae73e3b52018-02-27 18:56:22 -08008384 if ((hdd_ctx->config->enable_tcp_limit_output) &&
8385 (hdd_ctx->cur_tx_level != next_tx_level)) {
Alok Kumar2fad6442018-11-08 19:19:28 +05308386 struct wlan_tx_tp_data tx_tp_data = {0};
8387
Mohit Khannae71e2262015-11-10 09:37:24 -08008388 hdd_debug("change TCP TX trigger level %d, average_tx: %llu",
8389 next_tx_level, temp_tx);
8390 hdd_ctx->cur_tx_level = next_tx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008391 tx_level_change = true;
Alok Kumar2fad6442018-11-08 19:19:28 +05308392 tx_tp_data.level = next_tx_level;
8393 tx_tp_data.tcp_limit_output = true;
8394 wlan_hdd_update_tcp_tx_param(hdd_ctx, &tx_tp_data);
Mohit Khannae71e2262015-11-10 09:37:24 -08008395 }
8396
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008397 index = hdd_ctx->hdd_txrx_hist_idx;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008398 if (vote_level_change || tx_level_change || rx_level_change) {
8399 hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level;
8400 hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level;
8401 hdd_ctx->hdd_txrx_hist[index].next_vote_level = next_vote_level;
8402 hdd_ctx->hdd_txrx_hist[index].interval_rx = rx_packets;
8403 hdd_ctx->hdd_txrx_hist[index].interval_tx = tx_packets;
8404 hdd_ctx->hdd_txrx_hist[index].qtime = qdf_get_log_timestamp();
8405 hdd_ctx->hdd_txrx_hist_idx++;
8406 hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008407
8408 /* Clear all the mask if no silver/gold vote is required */
8409 if (next_vote_level < PLD_BUS_WIDTH_MEDIUM)
8410 cpumask_clear(&pm_qos_cpu_mask);
8411
8412 hdd_pm_qos_update_request(hdd_ctx, &pm_qos_cpu_mask);
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008413 }
Mohit Khannaca4173b2017-09-12 21:52:19 -07008414
8415 hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008416}
8417
Tiger Yue40e7832019-04-25 10:46:53 +08008418#ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK
8419/**
8420 * hdd_set_driver_del_ack_enable() - set driver delayed ack enabled flag
8421 * @vdev_id: vdev id
8422 * @hdd_ctx: handle to hdd context
8423 * @rx_packets: receive packet count
8424 *
8425 * Return: none
8426 */
8427static inline
8428void hdd_set_driver_del_ack_enable(uint16_t vdev_id,
8429 struct hdd_context *hdd_ctx,
8430 uint64_t rx_packets)
8431{
8432 struct hdd_config *cfg = hdd_ctx->config;
8433
8434 cdp_vdev_set_driver_del_ack_enable(cds_get_context(QDF_MODULE_ID_SOC),
8435 vdev_id, rx_packets,
8436 cfg->bus_bw_compute_interval,
8437 cfg->del_ack_threshold_high,
8438 cfg->del_ack_threshold_low);
8439}
8440#else
8441static inline
8442void hdd_set_driver_del_ack_enable(uint16_t vdev_id,
8443 struct hdd_context *hdd_ctx,
8444 uint64_t rx_packets)
8445{
8446}
8447#endif
8448
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008449#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
Dustin Browna20bad52019-03-05 12:03:30 -08008450static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008451{
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05308452 struct hdd_adapter *adapter = NULL, *con_sap_adapter = NULL;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308453 uint64_t tx_packets = 0, rx_packets = 0;
Himanshu Agarwala6cedee2016-06-08 14:50:00 +05308454 uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
8455 uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008456 uint64_t total_tx = 0, total_rx = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308457 A_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008458 bool connected = false;
8459 uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
8460
Prashanth Bhattaab004382016-10-11 16:08:11 -07008461 if (wlan_hdd_validate_context(hdd_ctx))
Dustin Browna20bad52019-03-05 12:03:30 -08008462 goto stop_work;
Prashanth Bhattaab004382016-10-11 16:08:11 -07008463
Jeff Johnson214671b2017-10-30 19:45:23 -07008464 if (hdd_ctx->is_wiphy_suspended)
Dustin Browna20bad52019-03-05 12:03:30 -08008465 return;
Jingxiang Gec64e1932017-08-22 14:38:59 +08008466
Dustin Brown920397d2017-12-13 16:27:50 -08008467 hdd_for_each_adapter(hdd_ctx, adapter) {
Manjeet Singh01327cc2016-09-03 12:14:25 +05308468 /*
8469 * Validate magic so we don't end up accessing
8470 * an invalid adapter.
8471 */
8472 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
8473 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008474
Krunal Soni9b04c9b2016-03-10 13:08:05 -08008475 if ((adapter->device_mode == QDF_STA_MODE ||
8476 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
Jeff Johnsone7951512019-02-27 10:02:51 -08008477 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.conn_state
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008478 != eConnectionState_Associated) {
8479
8480 continue;
8481 }
8482
Krunal Soni9b04c9b2016-03-10 13:08:05 -08008483 if ((adapter->device_mode == QDF_SAP_MODE ||
8484 adapter->device_mode == QDF_P2P_GO_MODE) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -07008485 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008486
8487 continue;
8488 }
8489
8490 tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets,
8491 adapter->prev_tx_packets);
8492 rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets,
8493 adapter->prev_rx_packets);
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308494
8495 if (adapter->device_mode == QDF_SAP_MODE ||
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +05308496 adapter->device_mode == QDF_P2P_GO_MODE ||
8497 adapter->device_mode == QDF_IBSS_MODE ||
8498 adapter->device_mode == QDF_NDI_MODE) {
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308499
Dhanashri Atrea8f82f22017-01-23 12:58:24 -08008500 ret = cdp_get_intra_bss_fwd_pkts_count(
8501 cds_get_context(QDF_MODULE_ID_SOC),
Jeff Johnson5a6fc962019-02-04 14:20:25 -08008502 adapter->vdev_id,
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308503 &fwd_tx_packets, &fwd_rx_packets);
8504 if (ret == A_OK) {
8505 fwd_tx_packets_diff += HDD_BW_GET_DIFF(
8506 fwd_tx_packets,
8507 adapter->prev_fwd_tx_packets);
8508 fwd_rx_packets_diff += HDD_BW_GET_DIFF(
8509 fwd_tx_packets,
8510 adapter->prev_fwd_rx_packets);
8511 }
8512 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008513
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05308514 if (adapter->device_mode == QDF_SAP_MODE)
8515 con_sap_adapter = adapter;
8516
Tiger Yue40e7832019-04-25 10:46:53 +08008517 hdd_set_driver_del_ack_enable(adapter->vdev_id, hdd_ctx,
8518 rx_packets);
8519
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008520 total_rx += adapter->stats.rx_packets;
8521 total_tx += adapter->stats.tx_packets;
8522
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +05308523 qdf_spin_lock_bh(&hdd_ctx->bus_bw_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008524 adapter->prev_tx_packets = adapter->stats.tx_packets;
8525 adapter->prev_rx_packets = adapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308526 adapter->prev_fwd_tx_packets = fwd_tx_packets;
8527 adapter->prev_fwd_rx_packets = fwd_rx_packets;
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +05308528 qdf_spin_unlock_bh(&hdd_ctx->bus_bw_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008529 connected = true;
8530 }
8531
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008532 if (!connected) {
Jeff Johnson760350b2016-08-15 14:01:52 -07008533 hdd_err("bus bandwidth timer running in disconnected state");
Dustin Browna20bad52019-03-05 12:03:30 -08008534 goto stop_work;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008535 }
8536
Yun Parka29974a2018-04-09 12:05:49 -07008537 /* add intra bss forwarded tx and rx packets */
8538 tx_packets += fwd_tx_packets_diff;
8539 rx_packets += fwd_rx_packets_diff;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008540
Dustin Brown07901ec2018-09-07 11:02:41 -07008541 if (ucfg_ipa_is_fw_wdi_activated(hdd_ctx->pdev)) {
8542 ucfg_ipa_uc_stat_query(hdd_ctx->pdev, &ipa_tx_packets,
8543 &ipa_rx_packets);
Yun Parka29974a2018-04-09 12:05:49 -07008544 tx_packets += (uint64_t)ipa_tx_packets;
8545 rx_packets += (uint64_t)ipa_rx_packets;
8546
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05308547 if (con_sap_adapter) {
8548 con_sap_adapter->stats.tx_packets += ipa_tx_packets;
8549 con_sap_adapter->stats.rx_packets += ipa_rx_packets;
8550 }
8551
Dustin Brown07901ec2018-09-07 11:02:41 -07008552 ucfg_ipa_set_perf_level(hdd_ctx->pdev, tx_packets, rx_packets);
8553 ucfg_ipa_uc_stat_request(hdd_ctx->pdev, 2);
Yun Parka29974a2018-04-09 12:05:49 -07008554 }
8555
8556 hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008557
Dustin Browna20bad52019-03-05 12:03:30 -08008558 return;
8559
8560stop_work:
8561 qdf_periodic_work_stop_async(&hdd_ctx->bus_bw_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008562}
Prashanth Bhattaab004382016-10-11 16:08:11 -07008563
Dustin Browna20bad52019-03-05 12:03:30 -08008564static void hdd_bus_bw_work_handler(void *context)
Rajeev Kumarb2b5e692018-08-31 15:12:40 -07008565{
Dustin Brown3fdaaf62019-03-18 14:00:16 -07008566 struct hdd_context *hdd_ctx = context;
8567 struct qdf_op_sync *op_sync;
Dustin Browna20bad52019-03-05 12:03:30 -08008568
Dustin Brown3fdaaf62019-03-18 14:00:16 -07008569 if (qdf_op_protect(&op_sync))
8570 return;
8571
8572 __hdd_bus_bw_work_handler(hdd_ctx);
8573
8574 qdf_op_unprotect(op_sync);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05308575}
8576
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008577int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07008578{
Dustin Browna20bad52019-03-05 12:03:30 -08008579 QDF_STATUS status;
8580
Dustin Brown35008ba2018-08-23 14:34:21 -07008581 hdd_enter();
8582
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +05308583 qdf_spinlock_create(&hdd_ctx->bus_bw_lock);
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008584
8585 hdd_pm_qos_add_request(hdd_ctx);
8586
Dustin Browna20bad52019-03-05 12:03:30 -08008587 status = qdf_periodic_work_create(&hdd_ctx->bus_bw_work,
8588 hdd_bus_bw_work_handler,
Dustin Brown3fdaaf62019-03-18 14:00:16 -07008589 hdd_ctx);
Dustin Brown35008ba2018-08-23 14:34:21 -07008590
8591 hdd_exit();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008592
Dustin Browna20bad52019-03-05 12:03:30 -08008593 return qdf_status_to_os_return(status);
Prashanth Bhattaab004382016-10-11 16:08:11 -07008594}
8595
Dustin Brown86d196b2018-08-02 11:51:49 -07008596void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07008597{
Dustin Brown35008ba2018-08-23 14:34:21 -07008598 hdd_enter();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008599
Dustin Browna20bad52019-03-05 12:03:30 -08008600 QDF_BUG(!qdf_periodic_work_stop_sync(&hdd_ctx->bus_bw_work));
8601 qdf_periodic_work_destroy(&hdd_ctx->bus_bw_work);
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +05308602 qdf_spinlock_destroy(&hdd_ctx->bus_bw_lock);
Manjunathappa Prakasheb1ec862019-07-28 00:01:18 -07008603 hdd_pm_qos_remove_request(hdd_ctx);
Dustin Brown35008ba2018-08-23 14:34:21 -07008604
8605 hdd_exit();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008606}
Tiger Yu8b119e92019-04-09 13:55:07 +08008607#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008608
8609/**
Nirav Shahed34b212016-04-25 10:59:16 +05308610 * wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
8611 * @hdd_ctx: hdd context
8612 *
8613 * Return: 0 for success or error code
8614 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008615static int wlan_hdd_init_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05308616{
8617 hdd_ctx->hdd_txrx_hist = qdf_mem_malloc(
8618 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Min Liu74a1a502018-10-10 19:59:07 +08008619 if (!hdd_ctx->hdd_txrx_hist)
Nirav Shahed34b212016-04-25 10:59:16 +05308620 return -ENOMEM;
Nirav Shahed34b212016-04-25 10:59:16 +05308621 return 0;
8622}
8623
8624/**
8625 * wlan_hdd_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
8626 * @hdd_ctx: hdd context
8627 *
8628 * Return: none
8629 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008630void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05308631{
Jeff Johnsond36fa332019-03-18 13:42:25 -07008632 if (!hdd_ctx || !hdd_ctx->hdd_txrx_hist)
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05308633 return;
8634
8635 qdf_mem_free(hdd_ctx->hdd_txrx_hist);
8636 hdd_ctx->hdd_txrx_hist = NULL;
Nirav Shahed34b212016-04-25 10:59:16 +05308637}
8638
Nirav Shahda008342016-05-17 18:50:40 +05308639static uint8_t *convert_level_to_string(uint32_t level)
8640{
8641 switch (level) {
8642 /* initialize the wlan sub system */
8643 case WLAN_SVC_TP_NONE:
8644 return "NONE";
8645 case WLAN_SVC_TP_LOW:
8646 return "LOW";
8647 case WLAN_SVC_TP_MEDIUM:
8648 return "MED";
8649 case WLAN_SVC_TP_HIGH:
8650 return "HIGH";
8651 default:
8652 return "INVAL";
8653 }
8654}
8655
Nirav Shahed34b212016-04-25 10:59:16 +05308656
8657/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008658 * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram
8659 * @hdd_ctx: hdd context
8660 *
8661 * Return: none
8662 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008663void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008664{
8665 int i;
8666
Tiger Yu8b119e92019-04-09 13:55:07 +08008667#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308668 hdd_nofl_debug("BW compute Interval: %d ms",
8669 hdd_ctx->config->bus_bw_compute_interval);
8670 hdd_nofl_debug("BW TH - Very High: %d High: %d Med: %d Low: %d",
8671 hdd_ctx->config->bus_bw_very_high_threshold,
8672 hdd_ctx->config->bus_bw_high_threshold,
8673 hdd_ctx->config->bus_bw_medium_threshold,
8674 hdd_ctx->config->bus_bw_low_threshold);
8675 hdd_nofl_debug("Enable TCP DEL ACK: %d",
8676 hdd_ctx->en_tcp_delack_no_lro);
8677 hdd_nofl_debug("TCP DEL High TH: %d TCP DEL Low TH: %d",
8678 hdd_ctx->config->tcp_delack_thres_high,
8679 hdd_ctx->config->tcp_delack_thres_low);
8680 hdd_nofl_debug("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_limit)",
8681 hdd_ctx->config->tcp_tx_high_tput_thres);
Tiger Yu8b119e92019-04-09 13:55:07 +08008682#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008683
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308684 hdd_nofl_debug("Total entries: %d Current index: %d",
8685 NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
Nirav Shahda008342016-05-17 18:50:40 +05308686
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308687 hdd_nofl_debug("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008688
8689 for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008690 /* using hdd_log to avoid printing function name */
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008691 if (hdd_ctx->hdd_txrx_hist[i].qtime > 0)
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308692 hdd_nofl_debug("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s",
8693 i, hdd_ctx->hdd_txrx_hist[i].qtime,
8694 hdd_ctx->hdd_txrx_hist[i].interval_rx,
8695 hdd_ctx->hdd_txrx_hist[i].interval_tx,
8696 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008697 hdd_ctx->hdd_txrx_hist[i].
8698 next_vote_level),
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308699 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008700 hdd_ctx->hdd_txrx_hist[i].
8701 next_rx_level),
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308702 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008703 hdd_ctx->hdd_txrx_hist[i].
8704 next_tx_level));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008705 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008706}
8707
8708/**
8709 * wlan_hdd_clear_tx_rx_histogram() - clear tx rx histogram
8710 * @hdd_ctx: hdd context
8711 *
8712 * Return: none
8713 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008714void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008715{
8716 hdd_ctx->hdd_txrx_hist_idx = 0;
Nirav Shahed34b212016-04-25 10:59:16 +05308717 qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
8718 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008719}
8720
Mohit Khannaca4173b2017-09-12 21:52:19 -07008721/* length of the netif queue log needed per adapter */
8722#define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
8723
8724/**
8725 *
8726 * hdd_display_netif_queue_history_compact() - display compact netifq history
8727 * @hdd_ctx: hdd context
8728 *
8729 * Return: none
8730 */
8731static void
8732hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
8733{
8734 int adapter_num = 0;
8735 int i;
8736 int bytes_written;
8737 u32 tbytes;
8738 qdf_time_t total, pause, unpause, curr_time, delta;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008739 char temp_str[20 * WLAN_REASON_TYPE_MAX];
jiadbdefb252018-01-03 14:27:06 +08008740 char *comb_log_str;
8741 uint32_t comb_log_str_size;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008742 struct hdd_adapter *adapter = NULL;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008743
Dustin Brownad06be62019-02-04 14:52:56 -08008744 comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * WLAN_MAX_VDEVS) + 1;
jiadbdefb252018-01-03 14:27:06 +08008745 comb_log_str = qdf_mem_malloc(comb_log_str_size);
Min Liu74a1a502018-10-10 19:59:07 +08008746 if (!comb_log_str)
jiadbdefb252018-01-03 14:27:06 +08008747 return;
jiadbdefb252018-01-03 14:27:06 +08008748
Mohit Khannaca4173b2017-09-12 21:52:19 -07008749 bytes_written = 0;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008750
Dustin Brown920397d2017-12-13 16:27:50 -08008751 hdd_for_each_adapter(hdd_ctx, adapter) {
Mohit Khannaca4173b2017-09-12 21:52:19 -07008752 curr_time = qdf_system_ticks();
8753 total = curr_time - adapter->start_time;
8754 delta = curr_time - adapter->last_time;
8755
8756 if (adapter->pause_map) {
8757 pause = adapter->total_pause_time + delta;
8758 unpause = adapter->total_unpause_time;
8759 } else {
8760 unpause = adapter->total_unpause_time + delta;
8761 pause = adapter->total_pause_time;
8762 }
8763
8764 tbytes = 0;
hangtian127c9532019-01-12 13:29:07 +08008765 qdf_mem_zero(temp_str, sizeof(temp_str));
Mohit Khannaca4173b2017-09-12 21:52:19 -07008766 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
8767 if (adapter->queue_oper_stats[i].pause_count == 0)
8768 continue;
8769 tbytes +=
8770 snprintf(
8771 &temp_str[tbytes],
8772 (tbytes >= sizeof(temp_str) ?
8773 0 : sizeof(temp_str) - tbytes),
8774 "%d(%d,%d) ",
8775 i,
8776 adapter->queue_oper_stats[i].
8777 pause_count,
8778 adapter->queue_oper_stats[i].
8779 unpause_count);
8780 }
8781 if (tbytes >= sizeof(temp_str))
8782 hdd_warn("log truncated");
8783
8784 bytes_written += snprintf(&comb_log_str[bytes_written],
jiadbdefb252018-01-03 14:27:06 +08008785 bytes_written >= comb_log_str_size ? 0 :
8786 comb_log_str_size - bytes_written,
Mohit Khannaca4173b2017-09-12 21:52:19 -07008787 "[%d %d] (%d) %u/%ums %s|",
Jeff Johnson5a6fc962019-02-04 14:20:25 -08008788 adapter->vdev_id, adapter->device_mode,
Mohit Khannaca4173b2017-09-12 21:52:19 -07008789 adapter->pause_map,
8790 qdf_system_ticks_to_msecs(pause),
8791 qdf_system_ticks_to_msecs(total),
8792 temp_str);
8793
Mohit Khannaca4173b2017-09-12 21:52:19 -07008794 adapter_num++;
8795 }
8796
8797 /* using QDF_TRACE to avoid printing function name */
8798 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
8799 "STATS |%s", comb_log_str);
8800
jiadbdefb252018-01-03 14:27:06 +08008801 if (bytes_written >= comb_log_str_size)
Mohit Khannaca4173b2017-09-12 21:52:19 -07008802 hdd_warn("log string truncated");
jiadbdefb252018-01-03 14:27:06 +08008803
8804 qdf_mem_free(comb_log_str);
Mohit Khannaca4173b2017-09-12 21:52:19 -07008805}
8806
Mohit Khannaf7e7b342019-04-08 11:54:21 -07008807/* Max size of a single netdev tx queue state string. e.g. "1: 0x1" */
8808#define HDD_NETDEV_TX_Q_STATE_STRLEN 15
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008809/**
Srinivas Girigowdab841da72017-03-25 18:04:39 -07008810 * wlan_hdd_display_netif_queue_history() - display netif queue history
Jeff Johnson58adbcf2017-09-03 08:53:31 -07008811 * @hdd_ctx: hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008812 *
8813 * Return: none
8814 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07008815void
8816wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
8817 enum qdf_stats_verbosity_level verb_lvl)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008818{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008819 int i;
Mohit Khannaf7e7b342019-04-08 11:54:21 -07008820 struct hdd_adapter *adapter = NULL;
Nirav Shahda008342016-05-17 18:50:40 +05308821 qdf_time_t total, pause, unpause, curr_time, delta;
Mohit Khannaf7e7b342019-04-08 11:54:21 -07008822 struct hdd_netif_queue_history *q_hist_ptr;
8823 char q_status_buf[NUM_TX_QUEUES * HDD_NETDEV_TX_Q_STATE_STRLEN] = {0};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008824
Mohit Khannaca4173b2017-09-12 21:52:19 -07008825 if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
8826 hdd_display_netif_queue_history_compact(hdd_ctx);
8827 return;
8828 }
8829
Dustin Brown920397d2017-12-13 16:27:50 -08008830 hdd_for_each_adapter(hdd_ctx, adapter) {
Mohit Khannaf7e7b342019-04-08 11:54:21 -07008831 if (adapter->vdev_id == CDP_INVALID_VDEV_ID)
8832 continue;
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308833 hdd_nofl_debug("Netif queue operation statistics:");
8834 hdd_nofl_debug("vdev_id %d device mode %d",
8835 adapter->vdev_id, adapter->device_mode);
8836 hdd_nofl_debug("Current pause_map %x", adapter->pause_map);
Nirav Shah617cff92016-04-25 10:24:24 +05308837 curr_time = qdf_system_ticks();
8838 total = curr_time - adapter->start_time;
Nirav Shahda008342016-05-17 18:50:40 +05308839 delta = curr_time - adapter->last_time;
Nirav Shah617cff92016-04-25 10:24:24 +05308840 if (adapter->pause_map) {
Nirav Shahda008342016-05-17 18:50:40 +05308841 pause = adapter->total_pause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05308842 unpause = adapter->total_unpause_time;
8843 } else {
Nirav Shahda008342016-05-17 18:50:40 +05308844 unpause = adapter->total_unpause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05308845 pause = adapter->total_pause_time;
8846 }
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308847 hdd_nofl_debug("Total: %ums Pause: %ums Unpause: %ums",
8848 qdf_system_ticks_to_msecs(total),
8849 qdf_system_ticks_to_msecs(pause),
8850 qdf_system_ticks_to_msecs(unpause));
8851 hdd_nofl_debug("reason_type: pause_cnt: unpause_cnt: pause_time");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008852
Nirav Shahda008342016-05-17 18:50:40 +05308853 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
8854 qdf_time_t pause_delta = 0;
8855
8856 if (adapter->pause_map & (1 << i))
8857 pause_delta = delta;
8858
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008859 /* using hdd_log to avoid printing function name */
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308860 hdd_nofl_debug("%s: %d: %d: %ums",
8861 hdd_reason_type_to_string(i),
8862 adapter->queue_oper_stats[i].pause_count,
8863 adapter->queue_oper_stats[i].
Nirav Shahe6194ac2018-07-13 11:04:41 +05308864 unpause_count,
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308865 qdf_system_ticks_to_msecs(
8866 adapter->queue_oper_stats[i].
Nirav Shahe6194ac2018-07-13 11:04:41 +05308867 total_pause_time + pause_delta));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008868 }
8869
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308870 hdd_nofl_debug("Netif queue operation history: Total entries: %d current index %d(-1) time %u",
8871 WLAN_HDD_MAX_HISTORY_ENTRY,
8872 adapter->history_index,
8873 qdf_system_ticks_to_msecs(qdf_system_ticks()));
Nirav Shahda008342016-05-17 18:50:40 +05308874
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308875 hdd_nofl_debug("%2s%20s%50s%30s%10s %s",
8876 "#", "time(ms)", "action_type", "reason_type",
8877 "pause_map", "netdev-queue-status");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008878
8879 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008880 /* using hdd_log to avoid printing function name */
8881 if (adapter->queue_oper_history[i].time == 0)
8882 continue;
Mohit Khannaf7e7b342019-04-08 11:54:21 -07008883 q_hist_ptr = &adapter->queue_oper_history[i];
8884 wlan_hdd_dump_queue_history_state(q_hist_ptr,
8885 q_status_buf,
8886 sizeof(q_status_buf));
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308887 hdd_nofl_debug("%2d%20u%50s%30s%10x %s",
8888 i, qdf_system_ticks_to_msecs(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008889 adapter->queue_oper_history[i].time),
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308890 hdd_action_type_to_string(
Nirav Shahe6194ac2018-07-13 11:04:41 +05308891 adapter->queue_oper_history[i].
8892 netif_action),
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308893 hdd_reason_type_to_string(
Nirav Shahe6194ac2018-07-13 11:04:41 +05308894 adapter->queue_oper_history[i].
8895 netif_reason),
Rakesh Pillai70f1f542019-09-10 20:26:54 +05308896 adapter->queue_oper_history[i].pause_map,
8897 q_status_buf);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008898 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008899 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008900}
8901
8902/**
8903 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
8904 * @hdd_ctx: hdd context
8905 *
8906 * Return: none
8907 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008908void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008909{
Jeff Johnson9d295242017-08-29 14:39:48 -07008910 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008911
Dustin Brown920397d2017-12-13 16:27:50 -08008912 hdd_for_each_adapter(hdd_ctx, adapter) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308913 qdf_mem_zero(adapter->queue_oper_stats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008914 sizeof(adapter->queue_oper_stats));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308915 qdf_mem_zero(adapter->queue_oper_history,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008916 sizeof(adapter->queue_oper_history));
Nirav Shah617cff92016-04-25 10:24:24 +05308917 adapter->history_index = 0;
8918 adapter->start_time = adapter->last_time = qdf_system_ticks();
8919 adapter->total_pause_time = 0;
8920 adapter->total_unpause_time = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008921 }
8922}
8923
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008924#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8925/**
8926 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
8927 * @hdd_ctx: hdd global context
8928 *
8929 * Return: none
8930 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008931static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008932{
8933 uint8_t i;
8934
8935 mutex_init(&hdd_ctx->op_ctx.op_lock);
8936 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
8937 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
8938 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
8939 }
8940}
8941#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008942static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008943{
8944}
8945#endif
8946
Yingying Tang95409972016-10-20 15:16:15 +08008947#ifdef WLAN_FEATURE_WOW_PULSE
8948/**
8949 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008950 * @hdd_ctx: struct hdd_context structure pointer
Yingying Tang95409972016-10-20 15:16:15 +08008951 * @enable: enable or disable this behaviour
8952 *
8953 * Return: int
8954 */
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008955static int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08008956{
Yingying Tang95409972016-10-20 15:16:15 +08008957 struct wow_pulse_mode wow_pulse_set_info;
8958 QDF_STATUS status;
8959
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008960 hdd_debug("wow pulse enable flag is %d", enable);
Yingying Tang95409972016-10-20 15:16:15 +08008961
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008962 if (!ucfg_pmo_is_wow_pulse_enabled(hdd_ctx->psoc))
Yingying Tang95409972016-10-20 15:16:15 +08008963 return 0;
8964
8965 /* prepare the request to send to SME */
8966 if (enable == true) {
8967 wow_pulse_set_info.wow_pulse_enable = true;
8968 wow_pulse_set_info.wow_pulse_pin =
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008969 ucfg_pmo_get_wow_pulse_pin(hdd_ctx->psoc);
Wu Gao66454f12018-09-26 19:55:41 +08008970
Yingying Tang95409972016-10-20 15:16:15 +08008971 wow_pulse_set_info.wow_pulse_interval_high =
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008972 ucfg_pmo_get_wow_pulse_interval_high(hdd_ctx->psoc);
Wu Gao66454f12018-09-26 19:55:41 +08008973
8974 wow_pulse_set_info.wow_pulse_interval_low =
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008975 ucfg_pmo_get_wow_pulse_interval_low(hdd_ctx->psoc);
Yingying Tang95409972016-10-20 15:16:15 +08008976 } else {
8977 wow_pulse_set_info.wow_pulse_enable = false;
8978 wow_pulse_set_info.wow_pulse_pin = 0;
8979 wow_pulse_set_info.wow_pulse_interval_low = 0;
8980 wow_pulse_set_info.wow_pulse_interval_high = 0;
8981 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008982 hdd_debug("enable %d pin %d low %d high %d",
Yingying Tang95409972016-10-20 15:16:15 +08008983 wow_pulse_set_info.wow_pulse_enable,
8984 wow_pulse_set_info.wow_pulse_pin,
8985 wow_pulse_set_info.wow_pulse_interval_low,
8986 wow_pulse_set_info.wow_pulse_interval_high);
8987
8988 status = sme_set_wow_pulse(&wow_pulse_set_info);
8989 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008990 hdd_debug("sme_set_wow_pulse failure!");
Yingying Tang95409972016-10-20 15:16:15 +08008991 return -EIO;
8992 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008993 hdd_debug("sme_set_wow_pulse success!");
Yingying Tang95409972016-10-20 15:16:15 +08008994 return 0;
8995}
8996#else
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008997static inline int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08008998{
8999 return 0;
9000}
9001#endif
9002
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009003#ifdef WLAN_FEATURE_FASTPATH
jitiphil377bcc12018-10-05 19:46:08 +05309004
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009005/**
9006 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
9007 * @hdd_cfg: hdd config
9008 * @context: lower layer context
9009 *
9010 * Return: none
9011 */
jitiphil377bcc12018-10-05 19:46:08 +05309012void hdd_enable_fastpath(struct hdd_context *hdd_ctx,
9013 void *context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009014{
jitiphil377bcc12018-10-05 19:46:08 +05309015 if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009016 hif_enable_fastpath(context);
9017}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009018#endif
9019
Yuanyuan Liu13738502016-04-06 17:41:37 -07009020#if defined(FEATURE_WLAN_CH_AVOID)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009021/**
9022 * hdd_set_thermal_level_cb() - set thermal level callback function
Jeff Johnson0e963082018-07-04 19:39:20 -07009023 * @hdd_handle: opaque handle for the hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009024 * @level: thermal level
9025 *
9026 * Change IPA data path to SW path when the thermal throttle level greater
9027 * than 0, and restore the original data path when throttle level is 0
9028 *
9029 * Return: none
9030 */
Jeff Johnson0e963082018-07-04 19:39:20 -07009031static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009032{
Jeff Johnson0e963082018-07-04 19:39:20 -07009033 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009034
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009035 /* Change IPA to SW path when throttle level greater than 0 */
9036 if (level > THROTTLE_LEVEL_0)
Dustin Brown07901ec2018-09-07 11:02:41 -07009037 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009038 else
9039 /* restore original concurrency mode */
Dustin Brown07901ec2018-09-07 11:02:41 -07009040 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009041}
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05309042#else
9043/**
9044 * hdd_set_thermal_level_cb() - set thermal level callback function
9045 * @hdd_handle: opaque handle for the hdd context
9046 * @level: thermal level
9047 *
9048 * Change IPA data path to SW path when the thermal throttle level greater
9049 * than 0, and restore the original data path when throttle level is 0
9050 *
9051 * Return: none
9052 */
9053static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
9054{
9055}
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05309056#endif
9057
9058/**
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08009059 * hdd_switch_sap_channel() - Move SAP to the given channel
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309060 * @adapter: AP adapter
9061 * @channel: Channel
Min Liu2fef5792018-01-19 17:59:42 +08009062 * @forced: Force to switch channel, ignore SCC/MCC check
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309063 *
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08009064 * Moves the SAP interface by invoking the function which
9065 * executes the callback to perform channel switch using (E)CSA.
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309066 *
9067 * Return: None
9068 */
Min Liu2fef5792018-01-19 17:59:42 +08009069void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel,
9070 bool forced)
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309071{
Jeff Johnson87251032017-08-29 13:31:11 -07009072 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009073 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -07009074 mac_handle_t mac_handle;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309075
9076 if (!adapter) {
9077 hdd_err("invalid adapter");
9078 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009079 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309080
9081 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
9082
Jeff Johnson16528362018-06-14 12:34:16 -07009083 mac_handle = hdd_adapter_get_mac_handle(adapter);
9084 if (!mac_handle) {
9085 hdd_err("invalid MAC handle");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309086 return;
9087 }
9088
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08009089 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9090
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009091 hdd_debug("chan:%d width:%d",
Jeff Johnson91df29d2017-10-27 19:29:50 -07009092 channel, hdd_ap_ctx->sap_config.ch_width_orig);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05309093
Dustin Brown1dbefe62018-09-11 16:32:03 -07009094 policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08009095 adapter->vdev_id, channel,
Min Liu2fef5792018-01-19 17:59:42 +08009096 hdd_ap_ctx->sap_config.ch_width_orig, forced);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009097}
Kapil Gupta8878ad92017-02-13 11:56:04 +05309098
Jeff Johnson9d295242017-08-29 14:39:48 -07009099int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
Kapil Gupta8878ad92017-02-13 11:56:04 +05309100{
9101 struct hdd_external_acs_timer_context *timer_context;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05309102 int status;
9103 QDF_STATUS qdf_status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05309104
9105 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
9106
9107 if (QDF_TIMER_STATE_RUNNING ==
Jeff Johnsonb9424862017-10-30 08:49:35 -07009108 qdf_mc_timer_get_current_state(&adapter->session.
Kapil Gupta8878ad92017-02-13 11:56:04 +05309109 ap.vendor_acs_timer)) {
Jeff Johnsonb9424862017-10-30 08:49:35 -07009110 qdf_mc_timer_stop(&adapter->session.ap.vendor_acs_timer);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309111 }
9112 timer_context = (struct hdd_external_acs_timer_context *)
Jeff Johnsonb9424862017-10-30 08:49:35 -07009113 adapter->session.ap.vendor_acs_timer.user_data;
Kapil Gupta8878ad92017-02-13 11:56:04 +05309114 timer_context->reason = reason;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05309115 qdf_status =
Jeff Johnsonb9424862017-10-30 08:49:35 -07009116 qdf_mc_timer_start(&adapter->session.ap.vendor_acs_timer,
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05309117 WLAN_VENDOR_ACS_WAIT_TIME);
9118 if (qdf_status != QDF_STATUS_SUCCESS) {
9119 hdd_err("failed to start external acs timer");
9120 return -ENOSPC;
9121 }
9122 /* Update config to application */
9123 status = hdd_cfg80211_update_acs_config(adapter, reason);
Dustin Brown5e89ef82018-03-14 11:50:23 -07009124 hdd_info("Updated ACS config to nl with reason %d", reason);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309125
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05309126 return status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05309127}
9128
Nirav Shaheb017be2018-02-15 11:20:58 +05309129#if defined(FEATURE_WLAN_CH_AVOID)
Agrawal Ashish467dde42016-09-08 18:44:22 +05309130/**
hqu54e6ba12019-08-01 21:11:12 +08009131 * hdd_store_sap_restart_channel() - store sap restart channel
9132 * @restart_chan: restart channel
9133 * @restart_chan_store: pointer to restart channel store
9134 *
9135 * The function will store new sap restart channel.
9136 *
9137 * Return - none
9138 */
9139static void
9140hdd_store_sap_restart_channel(uint8_t restart_chan, uint8_t *restart_chan_store)
9141{
9142 uint8_t i;
9143
9144 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
9145 if (*(restart_chan_store + i) == restart_chan)
9146 return;
9147
9148 if (*(restart_chan_store + i))
9149 continue;
9150
9151 *(restart_chan_store + i) = restart_chan;
9152 return;
9153 }
9154}
9155
9156/**
Agrawal Ashish467dde42016-09-08 18:44:22 +05309157 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
9158 * @hdd_ctx: hdd context pointer
9159 *
9160 * hdd_unsafe_channel_restart_sap check all unsafe channel list
9161 * and if ACS is enabled, driver will ask userspace to restart the
9162 * sap. User space on LTE coex indication restart driver.
9163 *
9164 * Return - none
9165 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009166void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
Agrawal Ashish467dde42016-09-08 18:44:22 +05309167{
Dustin Brown920397d2017-12-13 16:27:50 -08009168 struct hdd_adapter *adapter;
Agrawal Ashish467dde42016-09-08 18:44:22 +05309169 uint32_t i;
9170 bool found = false;
hqu54e6ba12019-08-01 21:11:12 +08009171 uint8_t restart_chan_store[SAP_MAX_NUM_SESSION] = {0};
Agrawal Ashish467dde42016-09-08 18:44:22 +05309172 uint8_t restart_chan;
Krunal Sonidf29bc42018-11-15 13:26:29 -08009173 uint8_t scc_on_lte_coex = 0;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309174 bool value;
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07009175 QDF_STATUS status;
9176 bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE);
9177 bool is_vendor_acs_support =
9178 cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009179
Dustin Brown920397d2017-12-13 16:27:50 -08009180 hdd_for_each_adapter(hdd_ctxt, adapter) {
9181 if (!(adapter->device_mode == QDF_SAP_MODE &&
9182 adapter->session.ap.sap_config.acs_cfg.acs_mode)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009183 hdd_debug("skip device mode:%d acs:%d",
Dustin Brown920397d2017-12-13 16:27:50 -08009184 adapter->device_mode,
9185 adapter->session.ap.sap_config.
9186 acs_cfg.acs_mode);
9187 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05309188 }
9189
9190 found = false;
Krunal Sonidf29bc42018-11-15 13:26:29 -08009191 status =
9192 ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctxt->psoc,
9193 &scc_on_lte_coex);
9194 if (!QDF_IS_STATUS_SUCCESS(status))
9195 hdd_err("can't get scc on lte coex chnl, use def");
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07009196 /*
9197 * If STA+SAP is doing SCC & g_sta_sap_scc_on_lte_coex_chan
9198 * is set, no need to move SAP.
9199 */
Manikandan Mohan956b69e2019-02-14 13:08:14 -08009200 if ((policy_mgr_is_sta_sap_scc(
9201 hdd_ctxt->psoc,
9202 adapter->session.ap.operating_channel) &&
9203 scc_on_lte_coex) ||
9204 policy_mgr_nan_sap_scc_on_unsafe_ch_chk(
9205 hdd_ctxt->psoc,
9206 adapter->session.ap.operating_channel)) {
9207 hdd_debug("SAP allowed in unsafe SCC channel");
9208 } else {
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07009209 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
9210 if (adapter->session.ap.operating_channel ==
9211 hdd_ctxt->unsafe_channel_list[i]) {
9212 found = true;
9213 hdd_debug("operating ch:%d is unsafe",
9214 adapter->session.ap.operating_channel);
9215 break;
9216 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05309217 }
9218 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05309219 if (!found) {
hqu54e6ba12019-08-01 21:11:12 +08009220 hdd_store_sap_restart_channel(
9221 adapter->session.ap.operating_channel,
9222 restart_chan_store);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009223 hdd_debug("ch:%d is safe. no need to change channel",
Dustin Brown920397d2017-12-13 16:27:50 -08009224 adapter->session.ap.operating_channel);
9225 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05309226 }
9227
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07009228 status = ucfg_mlme_get_acs_support_for_dfs_ltecoex(
9229 hdd_ctxt->psoc,
9230 &is_acs_support_for_dfs_ltecoex);
9231 if (!QDF_IS_STATUS_SUCCESS(status))
9232 hdd_err("get_acs_support_for_dfs_ltecoex failed,set def");
9233
9234 status = ucfg_mlme_get_vendor_acs_support(
9235 hdd_ctxt->psoc,
9236 &is_vendor_acs_support);
9237 if (!QDF_IS_STATUS_SUCCESS(status))
9238 hdd_err("get_vendor_acs_support failed, set default");
9239
9240 if (is_vendor_acs_support && is_acs_support_for_dfs_ltecoex) {
Dustin Brown920397d2017-12-13 16:27:50 -08009241 hdd_update_acs_timer_reason(adapter,
Kapil Gupta8878ad92017-02-13 11:56:04 +05309242 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
Dustin Brown920397d2017-12-13 16:27:50 -08009243 continue;
hqu54e6ba12019-08-01 21:11:12 +08009244 }
9245
9246 restart_chan = 0;
9247 for (i = 0; i < SAP_MAX_NUM_SESSION; i++) {
9248 if (!restart_chan_store[i])
9249 continue;
9250
9251 if (policy_mgr_is_force_scc(hdd_ctxt->psoc) &&
9252 WLAN_REG_IS_SAME_BAND_CHANNELS(
9253 restart_chan_store[i],
9254 adapter->session.ap.
9255 operating_channel)) {
9256 restart_chan = restart_chan_store[i];
9257 break;
9258 }
9259 }
9260 if (!restart_chan)
Kapil Gupta8878ad92017-02-13 11:56:04 +05309261 restart_chan =
bings6c4672b2019-03-19 16:00:19 +08009262 wlansap_get_safe_channel_from_pcl_and_acs_range(
9263 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
hqu54e6ba12019-08-01 21:11:12 +08009264
Agrawal Ashish467dde42016-09-08 18:44:22 +05309265 if (!restart_chan) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009266 hdd_err("fail to restart SAP");
Agrawal Ashish467dde42016-09-08 18:44:22 +05309267 } else {
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08009268 /*
9269 * SAP restart due to unsafe channel. While
9270 * restarting the SAP, make sure to clear
9271 * acs_channel, channel to reset to
9272 * 0. Otherwise these settings will override
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05309273 * the ACS while restart.
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08009274 */
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05309275 hdd_ctxt->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Dustin Brown05d81302018-09-11 16:49:22 -07009276 ucfg_mlme_get_sap_internal_restart(hdd_ctxt->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309277 &value);
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +05309278 if (value) {
9279 wlan_hdd_set_sap_csa_reason(hdd_ctxt->psoc,
9280 adapter->vdev_id,
9281 CSA_REASON_UNSAFE_CHANNEL);
Min Liu2fef5792018-01-19 17:59:42 +08009282 hdd_switch_sap_channel(adapter, restart_chan,
9283 true);
Will Huangc3fb27d2019-08-16 16:34:25 +08009284 return;
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +05309285 }
hqu1d1b9222019-06-11 20:00:55 +08009286 else {
9287 hdd_debug("sending coex indication");
9288 wlan_hdd_send_svc_nlink_msg(
9289 hdd_ctxt->radio_index,
9290 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Liangwei Dong6663d162017-07-10 03:29:36 -04009291 return;
hqu1d1b9222019-06-11 20:00:55 +08009292 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05309293 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05309294 }
9295}
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05309296
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009297/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009298 * hdd_init_channel_avoidance() - Initialize channel avoidance
9299 * @hdd_ctx: HDD global context
9300 *
9301 * Initialize the channel avoidance logic by retrieving the unsafe
Yuanyuan Liu13738502016-04-06 17:41:37 -07009302 * channel list from the platform driver and plumbing the data
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009303 * down to the lower layers. Then subscribe to subsequent channel
9304 * avoidance events.
9305 *
9306 * Return: None
9307 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009308static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009309{
9310 uint16_t unsafe_channel_count;
9311 int index;
9312
Yuanyuan Liu13738502016-04-06 17:41:37 -07009313 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
9314 hdd_ctx->unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009315 &(hdd_ctx->unsafe_channel_count),
Amar Singhalb8d4f152016-02-10 10:21:43 -08009316 sizeof(uint16_t) * NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009317
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009318 hdd_debug("num of unsafe channels is %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009319 hdd_ctx->unsafe_channel_count);
9320
Anurag Chouhan6d760662016-02-20 16:05:43 +05309321 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
Amar Singhalb8d4f152016-02-10 10:21:43 -08009322 (uint16_t)NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009323
9324 for (index = 0; index < unsafe_channel_count; index++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009325 hdd_debug("channel %d is not safe",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009326 hdd_ctx->unsafe_channel_list[index]);
9327
9328 }
9329
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009330}
Dustin Brown676a2322017-08-15 13:16:13 -07009331
Jeff Johnson9d295242017-08-29 14:39:48 -07009332static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009333 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07009334{
9335 uint8_t restart_chan;
9336
bings6c4672b2019-03-19 16:00:19 +08009337 restart_chan = wlansap_get_safe_channel_from_pcl_and_acs_range(
9338 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Dustin Brown676a2322017-08-15 13:16:13 -07009339 if (!restart_chan) {
9340 hdd_alert("fail to restart SAP");
9341 return;
9342 }
9343
9344 /* SAP restart due to unsafe channel. While restarting
9345 * the SAP, make sure to clear acs_channel, channel to
9346 * reset to 0. Otherwise these settings will override
9347 * the ACS while restart.
9348 */
9349 hdd_ctx->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Dustin Brown676a2322017-08-15 13:16:13 -07009350
9351 hdd_debug("sending coex indication");
9352
9353 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
9354 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +05309355 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, adapter->vdev_id,
9356 CSA_REASON_LTE_COEX);
Min Liu2fef5792018-01-19 17:59:42 +08009357 hdd_switch_sap_channel(adapter, restart_chan, true);
Dustin Brown676a2322017-08-15 13:16:13 -07009358}
Liangwei Dong6e1a2092017-08-30 16:29:06 +08009359
9360int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
9361 uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count)
9362{
9363 uint32_t size;
9364 uint16_t *unsafe_list;
9365 uint16_t chan_count;
9366
9367 if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count)
9368 return -EINVAL;
9369
9370 chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count,
9371 NUM_CHANNELS);
9372 if (chan_count) {
9373 size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]);
9374 unsafe_list = qdf_mem_malloc(size);
Min Liu74a1a502018-10-10 19:59:07 +08009375 if (!unsafe_list)
Liangwei Dong6e1a2092017-08-30 16:29:06 +08009376 return -ENOMEM;
Liangwei Dong6e1a2092017-08-30 16:29:06 +08009377 qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size);
9378 } else {
9379 unsafe_list = NULL;
9380 }
9381
9382 *local_unsafe_list = unsafe_list;
9383 *local_unsafe_list_count = chan_count;
9384
9385 return 0;
9386}
9387
9388bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
9389 uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count)
9390{
9391 int i, j;
9392
9393 if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count)
9394 return true;
9395 if (local_unsafe_list_count == 0)
9396 return false;
9397 for (i = 0; i < local_unsafe_list_count; i++) {
9398 for (j = 0; j < local_unsafe_list_count; j++)
9399 if (local_unsafe_list[i] ==
9400 hdd_ctx->unsafe_channel_list[j])
9401 break;
9402 if (j >= local_unsafe_list_count)
9403 break;
9404 }
9405 if (i >= local_unsafe_list_count) {
9406 hdd_info("unsafe chan list same");
9407 return false;
9408 }
9409
9410 return true;
9411}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009412#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009413static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009414{
9415}
Dustin Brown676a2322017-08-15 13:16:13 -07009416
Jeff Johnson9d295242017-08-29 14:39:48 -07009417static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009418 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07009419{
9420 hdd_debug("Channel avoidance is not enabled; Abort SAP restart");
9421}
Yuanyuan Liu13738502016-04-06 17:41:37 -07009422#endif /* defined(FEATURE_WLAN_CH_AVOID) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009423
9424/**
Rajeev Kumard004abc2016-02-17 12:09:56 -08009425 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
9426 * user space
9427 * @frame_ind: Management frame data to be informed.
9428 *
9429 * This function is used to indicate management frame to
9430 * user space
9431 *
9432 * Return: None
9433 *
9434 */
9435void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
9436{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009437 struct hdd_context *hdd_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07009438 struct hdd_adapter *adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08009439 int i;
Pragaspathi Thilagaraj28ffc042018-07-18 15:19:36 +05309440 struct ieee80211_mgmt *mgmt =
9441 (struct ieee80211_mgmt *)frame_ind->frameBuf;
Rajeev Kumard004abc2016-02-17 12:09:56 -08009442
Dustin Browne7e71d32018-05-11 16:00:08 -07009443 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
9444 if (wlan_hdd_validate_context(hdd_ctx))
Rajeev Kumard004abc2016-02-17 12:09:56 -08009445 return;
9446
Pragaspathi Thilagaraj28ffc042018-07-18 15:19:36 +05309447 if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) {
9448 hdd_err(" Invalid frame length");
9449 return;
9450 }
9451
Rajeev Kumard004abc2016-02-17 12:09:56 -08009452 if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
Dustin Brownad06be62019-02-04 14:52:56 -08009453 for (i = 0; i < WLAN_MAX_VDEVS; i++) {
Rajeev Kumard004abc2016-02-17 12:09:56 -08009454 adapter =
Jeff Johnson55d2ab42019-03-06 11:43:49 -08009455 hdd_get_adapter_by_vdev(hdd_ctx, i);
Rajeev Kumard004abc2016-02-17 12:09:56 -08009456 if (adapter)
9457 break;
9458 }
Wu Gaoa0230a62018-01-04 20:56:57 +08009459 } else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) {
9460 hdd_for_each_adapter(hdd_ctx, adapter) {
Jeff Johnsond36fa332019-03-18 13:42:25 -07009461 if ((adapter) &&
Wu Gaoa0230a62018-01-04 20:56:57 +08009462 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)) {
9463 __hdd_indicate_mgmt_frame(adapter,
9464 frame_ind->frame_len,
9465 frame_ind->frameBuf,
9466 frame_ind->frameType,
9467 frame_ind->rxChan,
Srinivas Dasariea1c1332019-02-18 12:43:23 +05309468 frame_ind->rxRssi,
9469 frame_ind->rx_flags);
Wu Gaoa0230a62018-01-04 20:56:57 +08009470 }
9471 }
9472 adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08009473 } else {
Jeff Johnson55d2ab42019-03-06 11:43:49 -08009474 adapter = hdd_get_adapter_by_vdev(hdd_ctx,
9475 frame_ind->sessionId);
Rajeev Kumard004abc2016-02-17 12:09:56 -08009476 }
9477
Jeff Johnsond36fa332019-03-18 13:42:25 -07009478 if ((adapter) &&
Rajeev Kumard004abc2016-02-17 12:09:56 -08009479 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
9480 __hdd_indicate_mgmt_frame(adapter,
9481 frame_ind->frame_len,
9482 frame_ind->frameBuf,
9483 frame_ind->frameType,
9484 frame_ind->rxChan,
Srinivas Dasariea1c1332019-02-18 12:43:23 +05309485 frame_ind->rxRssi,
9486 frame_ind->rx_flags);
Rajeev Kumard004abc2016-02-17 12:09:56 -08009487}
9488
Kapil Gupta8878ad92017-02-13 11:56:04 +05309489void hdd_acs_response_timeout_handler(void *context)
9490{
9491 struct hdd_external_acs_timer_context *timer_context =
9492 (struct hdd_external_acs_timer_context *)context;
Jeff Johnson9d295242017-08-29 14:39:48 -07009493 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009494 struct hdd_context *hdd_ctx;
Kapil Gupta8878ad92017-02-13 11:56:04 +05309495 uint8_t reason;
9496
Dustin Brown491d54b2018-03-14 12:39:11 -07009497 hdd_enter();
Kapil Gupta8878ad92017-02-13 11:56:04 +05309498 if (!timer_context) {
9499 hdd_err("invlaid timer context");
9500 return;
9501 }
9502 adapter = timer_context->adapter;
9503 reason = timer_context->reason;
9504
9505
9506 if ((!adapter) ||
9507 (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
9508 hdd_err("invalid adapter or adapter has invalid magic");
9509 return;
9510 }
9511 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9512 if (wlan_hdd_validate_context(hdd_ctx))
9513 return;
9514
9515 if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags))
9516 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
9517 else
9518 return;
9519
9520 hdd_err("ACS timeout happened for %s reason %d",
9521 adapter->dev->name, reason);
Jeff Johnson16528362018-06-14 12:34:16 -07009522
Kapil Gupta8878ad92017-02-13 11:56:04 +05309523 switch (reason) {
9524 /* SAP init case */
9525 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
9526 wlan_sap_set_vendor_acs(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
9527 false);
9528 wlan_hdd_cfg80211_start_acs(adapter);
9529 break;
9530 /* DFS detected on current channel */
9531 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
9532 wlan_sap_update_next_channel(
9533 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 0, 0);
Jeff Johnson16528362018-06-14 12:34:16 -07009534 sme_update_new_channel_event(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08009535 adapter->vdev_id);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309536 break;
9537 /* LTE coex event on current channel */
9538 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
9539 hdd_lte_coex_restart_sap(adapter, hdd_ctx);
9540 break;
9541 default:
9542 hdd_info("invalid reason for timer invoke");
9543
9544 }
9545}
9546
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009547/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009548 * hdd_override_ini_config - Override INI config
9549 * @hdd_ctx: HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009550 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009551 * Override INI config based on module parameter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009552 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009553 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009554 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009555static void hdd_override_ini_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009556{
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309557 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009558
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009559 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
gaurank kathpalia97c070b2019-01-07 17:23:06 +05309560 ucfg_scan_cfg_set_dfs_chan_scan_allowed(hdd_ctx->psoc,
9561 enable_dfs_chan_scan);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009562 hdd_debug("Module enable_dfs_chan_scan set to %d",
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009563 enable_dfs_chan_scan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009564 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009565 if (0 == enable_11d || 1 == enable_11d) {
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309566 status = ucfg_mlme_set_11d_enabled(hdd_ctx->psoc, enable_11d);
9567 if (!QDF_IS_STATUS_SUCCESS(status))
9568 hdd_err("Failed to set 11d_enable flag");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009569 }
Leo Chang11545d62016-10-17 14:53:50 -07009570
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +05309571 if (hdd_ctx->config->action_oui_enable && !ucfg_action_oui_enabled()) {
9572 hdd_ctx->config->action_oui_enable = 0;
Sourav Mohapatra58841062018-11-19 16:33:27 +05309573 hdd_err("Ignore action oui ini, since no action_oui component");
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +05309574 }
Will Huang14b120f2019-01-14 17:26:14 +08009575
9576 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
9577 hdd_override_all_ps(hdd_ctx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009578}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009579
Ashish Kumar Dhanotiya12f68212018-09-04 22:00:14 +05309580#ifdef ENABLE_MTRACE_LOG
9581static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
9582{
9583 uint8_t module_id = 0;
9584 int qdf_print_idx = -1;
9585
9586 qdf_print_idx = qdf_get_pidx();
9587 for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++)
9588 qdf_print_set_category_verbose(
9589 qdf_print_idx,
9590 module_id, QDF_TRACE_LEVEL_TRACE,
9591 hdd_ctx->config->enable_mtrace);
9592}
9593#else
9594static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
9595{
9596}
9597
9598#endif
9599
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009600/**
Wu Gao8dd9f502019-04-26 15:04:28 +08009601 * hdd_log_level_to_bitmask() - user space log level to host log bitmask
9602 * @user_log_level: user space log level
9603 *
9604 * Convert log level from user space to host log level bitmask.
9605 *
9606 * Return: Bitmask of log levels to be enabled
9607 */
9608static uint32_t hdd_log_level_to_bitmask(enum host_log_level user_log_level)
9609{
9610 QDF_TRACE_LEVEL host_trace_level;
9611 uint32_t bitmask;
9612
9613 switch (user_log_level) {
9614 case HOST_LOG_LEVEL_NONE:
9615 host_trace_level = QDF_TRACE_LEVEL_NONE;
9616 break;
9617 case HOST_LOG_LEVEL_FATAL:
9618 host_trace_level = QDF_TRACE_LEVEL_FATAL;
9619 break;
9620 case HOST_LOG_LEVEL_ERROR:
9621 host_trace_level = QDF_TRACE_LEVEL_ERROR;
9622 break;
9623 case HOST_LOG_LEVEL_WARN:
9624 host_trace_level = QDF_TRACE_LEVEL_WARN;
9625 break;
9626 case HOST_LOG_LEVEL_INFO:
9627 host_trace_level = QDF_TRACE_LEVEL_INFO_LOW;
9628 break;
9629 case HOST_LOG_LEVEL_DEBUG:
9630 host_trace_level = QDF_TRACE_LEVEL_DEBUG;
9631 break;
9632 case HOST_LOG_LEVEL_TRACE:
9633 host_trace_level = QDF_TRACE_LEVEL_TRACE;
9634 break;
9635 default:
9636 host_trace_level = QDF_TRACE_LEVEL_TRACE;
9637 break;
9638 }
9639
9640 bitmask = (1 << (host_trace_level + 1)) - 1;
9641
9642 return bitmask;
9643}
9644
9645/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009646 * hdd_set_trace_level_for_each - Set trace level for each INI config
9647 * @hdd_ctx - HDD context
9648 *
9649 * Set trace level for each module based on INI config.
9650 *
9651 * Return: None
9652 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009653static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009654{
Wu Gao8dd9f502019-04-26 15:04:28 +08009655 uint8_t host_module_log[QDF_MODULE_ID_MAX * 2];
9656 qdf_size_t host_module_log_num = 0;
9657 QDF_MODULE_ID module_id;
9658 uint32_t bitmask;
9659 uint32_t i;
9660
Wu Gaobc6eaa12018-11-30 14:17:45 +08009661 hdd_qdf_trace_enable(QDF_MODULE_ID_DP, 0x7f);
Wu Gao8dd9f502019-04-26 15:04:28 +08009662
9663 qdf_uint8_array_parse(cfg_get(hdd_ctx->psoc,
9664 CFG_ENABLE_HOST_MODULE_LOG_LEVEL),
9665 host_module_log,
9666 QDF_MODULE_ID_MAX * 2,
9667 &host_module_log_num);
9668
9669 for (i = 0; i + 1 < host_module_log_num; i += 2) {
9670 module_id = host_module_log[i];
9671 bitmask = hdd_log_level_to_bitmask(host_module_log[i + 1]);
9672 if (module_id < QDF_MODULE_ID_MAX &&
9673 module_id >= QDF_MODULE_ID_MIN)
9674 hdd_qdf_trace_enable(module_id, bitmask);
9675 }
Kiran Kumar Lokere798de7e2017-03-30 14:01:12 -07009676
Ashish Kumar Dhanotiya12f68212018-09-04 22:00:14 +05309677 hdd_set_mtrace_for_each(hdd_ctx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009678}
9679
9680/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009681 * hdd_context_init() - Initialize HDD context
9682 * @hdd_ctx: HDD context.
9683 *
9684 * Initialize HDD context along with all the feature specific contexts.
9685 *
9686 * return: 0 on success and errno on failure.
9687 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009688static int hdd_context_init(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009689{
9690 int ret;
9691
9692 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
Dustin Brownad06be62019-02-04 14:52:56 -08009693 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009694
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009695 init_completion(&hdd_ctx->mc_sus_event_var);
9696 init_completion(&hdd_ctx->ready_to_suspend);
9697
9698 qdf_spinlock_create(&hdd_ctx->connection_status_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009699 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05309700
Dustin Brownbee82832018-07-23 10:10:51 -07009701 qdf_list_create(&hdd_ctx->hdd_adapters, 0);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009702
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009703 ret = hdd_scan_context_init(hdd_ctx);
9704 if (ret)
9705 goto list_destroy;
9706
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009707 hdd_rx_wake_lock_create(hdd_ctx);
9708
9709 ret = hdd_sap_context_init(hdd_ctx);
9710 if (ret)
9711 goto scan_destroy;
9712
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009713 wlan_hdd_cfg80211_extscan_init(hdd_ctx);
9714
9715 hdd_init_offloaded_packets_ctx(hdd_ctx);
9716
9717 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
9718 hdd_ctx->config);
9719 if (ret)
Wu Gao02bd75b2017-10-13 18:34:02 +08009720 goto sap_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009721
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05309722 qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock,
9723 "monitor_mode_wakelock");
9724
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009725 return 0;
9726
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009727sap_destroy:
9728 hdd_sap_context_destroy(hdd_ctx);
9729
9730scan_destroy:
9731 hdd_scan_context_destroy(hdd_ctx);
9732 hdd_rx_wake_lock_destroy(hdd_ctx);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009733list_destroy:
Jeff Johnson19fc8e42017-10-30 19:53:49 -07009734 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Sandeep Puligillad0004212017-02-26 18:34:56 -08009735
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009736 return ret;
9737}
9738
Dustin Brown4c663222018-10-23 14:19:36 -07009739void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx)
9740{
9741 uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time;
9742 enum wake_lock_reason reason =
9743 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER;
9744
Rajeev Kumar7b7bb3f2018-12-20 12:09:54 -08009745 if (!timeout_ms) {
9746 hdd_info("psoc idle timer is disabled");
9747 return;
9748 }
9749
Dustin Brown4c663222018-10-23 14:19:36 -07009750 hdd_debug("Starting psoc idle timer");
Alan Chen5b19c212019-07-19 10:44:42 -07009751 timeout_ms += HDD_PSOC_IDLE_SHUTDOWN_SUSPEND_DELAY;
Dustin Brown8d8ab302019-03-05 16:19:36 -08009752 qdf_delayed_work_start(&hdd_ctx->psoc_idle_timeout_work, timeout_ms);
Dustin Brown4c663222018-10-23 14:19:36 -07009753 hdd_prevent_suspend_timeout(timeout_ms, reason);
9754}
9755
9756void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx)
9757{
Dustin Brown8d8ab302019-03-05 16:19:36 -08009758 qdf_delayed_work_stop_sync(&hdd_ctx->psoc_idle_timeout_work);
Dustin Brown4c663222018-10-23 14:19:36 -07009759 hdd_debug("Stopped psoc idle timer");
9760}
9761
Sourav Mohapatra698d6f62019-01-29 14:49:52 +05309762/*
9763 * enum hdd_block_shutdown - Control if driver allows modem shutdown
9764 * @HDD_UNBLOCK_MODEM_SHUTDOWN: Unblock shutdown
9765 * @HDD_BLOCK_MODEM_SHUTDOWN: Block shutdown
9766 *
9767 * On calling pld_block_shutdown API with the given values, modem
9768 * graceful shutdown is blocked/unblocked.
9769 */
9770enum hdd_block_shutdown {
9771 HDD_UNBLOCK_MODEM_SHUTDOWN,
9772 HDD_BLOCK_MODEM_SHUTDOWN,
9773};
9774
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009775/**
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009776 * __hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc
Dustin Brown3ecc8782018-09-19 16:37:13 -07009777 * @hdd_ctx: the hdd context which should be shutdown
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309778 *
Dustin Brown3ecc8782018-09-19 16:37:13 -07009779 * When no interfaces are "up" on a psoc, an idle shutdown timer is started.
9780 * If no interfaces are brought up before the timer expires, we do an
9781 * "idle shutdown," cutting power to the physical SoC to save power. This is
9782 * done completely transparently from the perspective of userspace.
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309783 *
Dustin Brown3ecc8782018-09-19 16:37:13 -07009784 * Return: None
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309785 */
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009786static int __hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309787{
Dustin Brown363b4792019-02-05 16:11:55 -08009788 struct osif_psoc_sync *psoc_sync;
Dustin Browncfcb5762019-01-31 15:43:45 -08009789 int errno;
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309790
Dustin Brown491d54b2018-03-14 12:39:11 -07009791 hdd_enter();
Dustin Brown3ecc8782018-09-19 16:37:13 -07009792
Dustin Brown363b4792019-02-05 16:11:55 -08009793 errno = osif_psoc_sync_trans_start(hdd_ctx->parent_dev, &psoc_sync);
Dustin Browncfcb5762019-01-31 15:43:45 -08009794 if (errno) {
9795 hdd_info("psoc busy, abort idle shutdown; errno:%d", errno);
9796 goto exit;
Dustin Brown3ecc8782018-09-19 16:37:13 -07009797 }
Sourav Mohapatra698d6f62019-01-29 14:49:52 +05309798 /* Block the modem graceful shutdown till stop modules is completed */
9799 pld_block_shutdown(hdd_ctx->parent_dev, HDD_BLOCK_MODEM_SHUTDOWN);
Dustin Brown3ecc8782018-09-19 16:37:13 -07009800
Dustin Brown363b4792019-02-05 16:11:55 -08009801 osif_psoc_sync_wait_for_ops(psoc_sync);
Dustin Browncfcb5762019-01-31 15:43:45 -08009802
Alan Chend841bcc2019-08-30 12:17:22 -07009803 errno = hdd_wlan_stop_modules(hdd_ctx, false);
Dustin Brown3ecc8782018-09-19 16:37:13 -07009804
Dustin Brown363b4792019-02-05 16:11:55 -08009805 osif_psoc_sync_trans_stop(psoc_sync);
Dustin Brown3ecc8782018-09-19 16:37:13 -07009806
Sourav Mohapatra698d6f62019-01-29 14:49:52 +05309807 pld_block_shutdown(hdd_ctx->parent_dev, HDD_UNBLOCK_MODEM_SHUTDOWN);
9808
Dustin Browncfcb5762019-01-31 15:43:45 -08009809exit:
Dustin Browne74003f2018-03-14 12:51:58 -07009810 hdd_exit();
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009811 return errno;
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309812}
9813
Rajeev Kumar588a2542019-04-08 10:57:19 -07009814static int __hdd_mode_change_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
9815{
9816 is_mode_change_psoc_idle_shutdown = false;
9817 return hdd_wlan_stop_modules(hdd_ctx, true);
9818}
9819
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009820int hdd_psoc_idle_shutdown(struct device *dev)
9821{
Alan Chen6a5eb932019-08-12 17:08:22 -07009822 int ret;
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009823 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
9824
Rajeev Kumard62104a2019-05-31 12:04:27 -07009825 if (!hdd_ctx) {
9826 hdd_err_rl("hdd ctx is null");
9827 return -EINVAL;
9828 }
9829
Rajeev Kumar588a2542019-04-08 10:57:19 -07009830 if (is_mode_change_psoc_idle_shutdown)
Alan Chen6a5eb932019-08-12 17:08:22 -07009831 ret = __hdd_mode_change_psoc_idle_shutdown(hdd_ctx);
Rajeev Kumar588a2542019-04-08 10:57:19 -07009832 else
Alan Chen6a5eb932019-08-12 17:08:22 -07009833 ret = __hdd_psoc_idle_shutdown(hdd_ctx);
9834
Alan Chen6a5eb932019-08-12 17:08:22 -07009835 return ret;
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009836}
9837
9838static int __hdd_psoc_idle_restart(struct hdd_context *hdd_ctx)
9839{
Alan Chene523cd92019-07-15 16:45:09 -07009840 int ret;
9841
Alan Chen0f29e972019-09-04 12:04:22 -07009842 ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev);
9843 if (ret)
9844 return ret;
Alan Chene523cd92019-07-15 16:45:09 -07009845
9846 ret = hdd_wlan_start_modules(hdd_ctx, false);
9847
9848 hdd_soc_idle_restart_unlock();
9849
9850 return ret;
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009851}
9852
9853int hdd_psoc_idle_restart(struct device *dev)
9854{
9855 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
9856
Rajeev Kumard62104a2019-05-31 12:04:27 -07009857 if (!hdd_ctx) {
9858 hdd_err_rl("hdd ctx is null");
9859 return -EINVAL;
9860 }
9861
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009862 return __hdd_psoc_idle_restart(hdd_ctx);
9863}
9864
9865int hdd_trigger_psoc_idle_restart(struct hdd_context *hdd_ctx)
Dustin Brown3ecc8782018-09-19 16:37:13 -07009866{
Jingxiang Geccd7fdc2019-06-21 16:04:55 +08009867 int ret;
9868
Dustin Brown693b5352019-01-17 10:00:31 -08009869 QDF_BUG(rtnl_is_locked());
Dustin Brown3ecc8782018-09-19 16:37:13 -07009870
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009871 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
9872 hdd_psoc_idle_timer_stop(hdd_ctx);
9873 hdd_info("Driver modules already Enabled");
9874 return 0;
9875 }
9876
Alan Chen0f29e972019-09-04 12:04:22 -07009877 ret = hdd_soc_idle_restart_lock(hdd_ctx->parent_dev);
9878 if (ret)
9879 return ret;
Jingxiang Geccd7fdc2019-06-21 16:04:55 +08009880 ret = pld_idle_restart(hdd_ctx->parent_dev, hdd_psoc_idle_restart);
Alan Chene523cd92019-07-15 16:45:09 -07009881 hdd_soc_idle_restart_unlock();
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009882
Jingxiang Geccd7fdc2019-06-21 16:04:55 +08009883 return ret;
Dustin Brown3ecc8782018-09-19 16:37:13 -07009884}
9885
9886/**
9887 * hdd_psoc_idle_timeout_callback() - Handler for psoc idle timeout
9888 * @priv: pointer to hdd context
9889 *
9890 * Return: None
9891 */
9892static void hdd_psoc_idle_timeout_callback(void *priv)
9893{
Alan Chen5b19c212019-07-19 10:44:42 -07009894 int ret;
Dustin Brown3ecc8782018-09-19 16:37:13 -07009895 struct hdd_context *hdd_ctx = priv;
9896
9897 if (wlan_hdd_validate_context(hdd_ctx))
9898 return;
9899
Rajeev Kumar473f9af2019-04-05 14:25:56 -07009900 hdd_info("Psoc idle timeout elapsed; starting psoc shutdown");
9901
Alan Chen5b19c212019-07-19 10:44:42 -07009902 ret = pld_idle_shutdown(hdd_ctx->parent_dev, hdd_psoc_idle_shutdown);
9903 if (-EAGAIN == ret || hdd_ctx->is_wiphy_suspended) {
9904 hdd_debug("System suspend in progress. Restart idle shutdown timer");
9905 hdd_psoc_idle_timer_start(hdd_ctx);
9906 }
Alan Chen50582ca2019-09-12 15:45:21 -07009907
9908 /* Clear the recovery flag for PCIe discrete soc after idle shutdown*/
9909 if (PLD_BUS_TYPE_PCIE == pld_get_bus_type(hdd_ctx->parent_dev))
9910 cds_set_recovery_in_progress(false);
Dustin Brown3ecc8782018-09-19 16:37:13 -07009911}
9912
Nirav Shaheb017be2018-02-15 11:20:58 +05309913#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9914static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
9915{
9916 wlan_logging_set_log_to_console(hdd_ctx->config->
9917 wlan_logging_to_console);
9918 wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable);
9919}
9920#else
9921static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
9922{ }
9923#endif
9924
Dundi Raviteja8e338282018-09-25 17:16:04 +05309925#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9926static void hdd_init_wlan_logging_params(struct hdd_config *config,
9927 struct wlan_objmgr_psoc *psoc)
9928{
9929 config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT);
9930
9931 config->wlan_logging_to_console =
9932 cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT);
Hangtian Zhuc7642602019-09-11 17:47:43 +08009933 config->host_log_custom_nl_proto =
9934 cfg_get(psoc, CFG_HOST_LOG_CUSTOM_NETLINK_PROTO);
Dundi Raviteja8e338282018-09-25 17:16:04 +05309935}
9936#else
9937static void hdd_init_wlan_logging_params(struct hdd_config *config,
9938 struct wlan_objmgr_psoc *psoc)
9939{
9940}
9941#endif
9942
9943#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
9944static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
9945 struct wlan_objmgr_psoc *psoc)
9946{
9947 config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN);
9948}
9949#else
9950static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
9951 struct wlan_objmgr_psoc *psoc)
9952{
9953}
9954#endif
9955
9956#ifndef REMOVE_PKT_LOG
9957static void hdd_init_packet_log(struct hdd_config *config,
9958 struct wlan_objmgr_psoc *psoc)
9959{
9960 config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG);
9961}
9962#else
9963static void hdd_init_packet_log(struct hdd_config *config,
9964 struct wlan_objmgr_psoc *psoc)
9965{
9966}
9967#endif
9968
Sandeep Puligilla43b6d1a2018-12-03 09:16:13 -08009969#ifdef ENABLE_MTRACE_LOG
9970static void hdd_init_mtrace_log(struct hdd_config *config,
9971 struct wlan_objmgr_psoc *psoc)
9972{
9973 config->enable_mtrace = cfg_get(psoc, CFG_ENABLE_MTRACE);
9974}
9975#else
9976static void hdd_init_mtrace_log(struct hdd_config *config,
9977 struct wlan_objmgr_psoc *psoc)
9978{
9979}
9980#endif
9981
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +05309982#ifdef FEATURE_RUNTIME_PM
9983static void hdd_init_runtime_pm(struct hdd_config *config,
9984 struct wlan_objmgr_psoc *psoc)
9985{
9986 config->runtime_pm = cfg_get(psoc, CFG_ENABLE_RUNTIME_PM);
9987}
9988#else
9989static void hdd_init_runtime_pm(struct hdd_config *config,
9990 struct wlan_objmgr_psoc *psoc)
9991
9992{
9993}
9994#endif
9995
9996#ifdef FEATURE_WLAN_DYNAMIC_CVM
9997static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
9998 struct wlan_objmgr_psoc *psoc)
9999{
10000 config->vc_mode_cfg_bitmap = cfg_get(psoc, CFG_VC_MODE_BITMAP);
10001}
10002#else
10003static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
10004 struct wlan_objmgr_psoc *psoc)
10005{
10006}
10007#endif
10008
gaurank kathpalia566c81b2019-02-20 14:31:45 +053010009#ifdef DHCP_SERVER_OFFLOAD
10010static void
10011hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx)
10012{
10013 uint8_t num_entries;
10014
10015 hdd_ctx->config->dhcp_server_ip.is_dhcp_server_ip_valid = true;
10016 hdd_string_to_u8_array(cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME),
10017 hdd_ctx->config->dhcp_server_ip.dhcp_server_ip,
10018 &num_entries, IPADDR_NUM_ENTRIES);
10019
10020 if (num_entries != IPADDR_NUM_ENTRIES) {
10021 hdd_err("Incorrect IP address (%s) assigned for DHCP server!",
10022 cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME));
10023 hdd_config->dhcp_server_ip.is_dhcp_server_ip_valid = false;
10024 }
10025}
10026#else
10027static void
10028hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx)
10029{
10030}
10031#endif
10032
Dundi Raviteja8e338282018-09-25 17:16:04 +053010033/**
10034 * hdd_cfg_params_init() - Initialize hdd params in hdd_config strucuture
10035 * @hdd_ctx - Pointer to HDD context
10036 *
10037 * Return: None
10038 */
10039static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
10040{
10041 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
10042 struct hdd_config *config = hdd_ctx->config;
Dundi Raviteja8e338282018-09-25 17:16:04 +053010043 if (!psoc) {
10044 hdd_err("Invalid psoc");
10045 return;
10046 }
10047
10048 if (!config) {
10049 hdd_err("Invalid hdd config");
10050 return;
10051 }
10052
gaurank kathpalia43c52622019-02-11 12:30:05 +053010053 config->dot11Mode = cfg_get(psoc, CFG_HDD_DOT11_MODE);
Dundi Raviteja8e338282018-09-25 17:16:04 +053010054 config->bug_on_reinit_failure = cfg_get(psoc,
10055 CFG_BUG_ON_REINIT_FAILURE);
10056
10057 config->is_ramdump_enabled = cfg_get(psoc,
10058 CFG_ENABLE_RAMDUMP_COLLECTION);
10059
10060 config->iface_change_wait_time = cfg_get(psoc,
10061 CFG_INTERFACE_CHANGE_WAIT);
10062
10063 config->multicast_host_fw_msgs = cfg_get(psoc,
10064 CFG_MULTICAST_HOST_FW_MSGS);
10065
10066 config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL);
Dundi Raviteja8e338282018-09-25 17:16:04 +053010067 config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT);
10068 config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG);
sheenam monga67ecb072019-09-20 11:25:23 +053010069 config->operating_chan_freq = cfg_get(psoc, CFG_OPERATING_FREQUENCY);
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +053010070 config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE);
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +053010071 qdf_str_lcopy(config->enable_concurrent_sta,
10072 cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA),
10073 CFG_CONCURRENT_IFACE_MAX_LEN);
10074 qdf_str_lcopy(config->dbs_scan_selection,
10075 cfg_get(psoc, CFG_DBS_SCAN_SELECTION),
10076 CFG_DBS_SCAN_PARAM_LENGTH);
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +053010077 config->inform_bss_rssi_raw = cfg_get(psoc, CFG_INFORM_BSS_RSSI_RAW);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010078 config->mac_provision = cfg_get(psoc, CFG_ENABLE_MAC_PROVISION);
10079 config->provisioned_intf_pool =
10080 cfg_get(psoc, CFG_PROVISION_INTERFACE_POOL);
10081 config->derived_intf_pool = cfg_get(psoc, CFG_DERIVED_INTERFACE_POOL);
Sourav Mohapatra58841062018-11-19 16:33:27 +053010082 config->action_oui_enable = cfg_get(psoc, CFG_ENABLE_ACTION_OUI);
Jeff Johnson15a88ac2019-03-11 14:35:25 -070010083 config->advertise_concurrent_operation =
Sandeep Puligilladc6d68a2019-01-04 16:57:12 -080010084 cfg_get(psoc,
10085 CFG_ADVERTISE_CONCURRENT_OPERATION);
Sourav Mohapatra58841062018-11-19 16:33:27 +053010086 qdf_str_lcopy(config->action_oui_str[0],
10087 cfg_get(psoc, CFG_ACTION_OUI_CONNECT_1X1),
10088 ACTION_OUI_MAX_STR_LEN);
10089 qdf_str_lcopy(config->action_oui_str[1],
10090 cfg_get(psoc, CFG_ACTION_OUI_ITO_EXTENSION),
10091 ACTION_OUI_MAX_STR_LEN);
10092 qdf_str_lcopy(config->action_oui_str[2],
10093 cfg_get(psoc, CFG_ACTION_OUI_CCKM_1X1),
10094 ACTION_OUI_MAX_STR_LEN);
10095 qdf_str_lcopy(config->action_oui_str[3],
10096 cfg_get(psoc, CFG_ACTION_OUI_ITO_ALTERNATE),
10097 ACTION_OUI_MAX_STR_LEN);
10098 qdf_str_lcopy(config->action_oui_str[4],
10099 cfg_get(psoc, CFG_ACTION_OUI_SWITCH_TO_11N_MODE),
10100 ACTION_OUI_MAX_STR_LEN);
10101 qdf_str_lcopy(config->action_oui_str[5],
10102 cfg_get(psoc,
10103 CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN),
10104 ACTION_OUI_MAX_STR_LEN);
Rajeev Kumar Sirasanagandlad7987f12018-12-08 23:24:04 +053010105 qdf_str_lcopy(config->action_oui_str[6],
10106 cfg_get(psoc,
10107 CFG_ACTION_OUI_DISABLE_AGGRESSIVE_TX),
10108 ACTION_OUI_MAX_STR_LEN);
Yeshwanth Sriram Guntuka22ed8002019-05-07 15:08:09 +053010109 qdf_str_lcopy(config->action_oui_str[ACTION_OUI_FORCE_MAX_NSS],
10110 cfg_get(psoc, CFG_ACTION_OUI_FORCE_MAX_NSS),
10111 ACTION_OUI_MAX_STR_LEN);
Sourav Mohapatra9e014cf2018-12-11 09:39:33 +053010112 config->enable_rtt_support = cfg_get(psoc, CFG_ENABLE_RTT_SUPPORT);
Sandeep Puligillaefeb4a92019-01-08 00:06:51 -080010113 config->is_unit_test_framework_enabled =
10114 cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK);
Ashish Kumar Dhanotiyad63d6862019-03-14 18:54:10 +053010115 config->disable_channel = cfg_get(psoc, CFG_ENABLE_DISABLE_CHANNEL);
Ashish Kumar Dhanotiya95498182019-04-29 13:59:20 +053010116 config->sar_version = cfg_get(psoc, CFG_SAR_VERSION);
Rajeev Kumar3a7c3402019-05-02 16:02:20 -070010117 config->is_wow_disabled = cfg_get(psoc, CFG_WOW_DISABLE);
Dundi Raviteja8e338282018-09-25 17:16:04 +053010118
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +053010119 hdd_init_vc_mode_cfg_bitmap(config, psoc);
10120 hdd_init_runtime_pm(config, psoc);
Dundi Raviteja8e338282018-09-25 17:16:04 +053010121 hdd_init_wlan_auto_shutdown(config, psoc);
10122 hdd_init_wlan_logging_params(config, psoc);
10123 hdd_init_packet_log(config, psoc);
Sandeep Puligilla43b6d1a2018-12-03 09:16:13 -080010124 hdd_init_mtrace_log(config, psoc);
gaurank kathpalia566c81b2019-02-20 14:31:45 +053010125 hdd_init_dhcp_server_ip(hdd_ctx);
jitiphil869b9f72018-09-25 17:14:01 +053010126 hdd_dp_cfg_update(psoc, hdd_ctx);
Dundi Raviteja8e338282018-09-25 17:16:04 +053010127}
10128
Dustin Brown623e7e32018-09-05 14:27:50 -070010129struct hdd_context *hdd_context_create(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010130{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010131 QDF_STATUS status;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010132 int ret = 0;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010133 struct hdd_context *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010134
Dustin Brown491d54b2018-03-14 12:39:11 -070010135 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010136
Dustin Brown92bd8382018-10-31 15:49:46 -070010137 hdd_ctx = hdd_cfg80211_wiphy_alloc();
10138 if (!hdd_ctx) {
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010139 ret = -ENOMEM;
10140 goto err_out;
10141 }
10142
Dustin Brown8d8ab302019-03-05 16:19:36 -080010143 status = qdf_delayed_work_create(&hdd_ctx->psoc_idle_timeout_work,
10144 hdd_psoc_idle_timeout_callback,
10145 hdd_ctx);
10146 if (QDF_IS_STATUS_ERROR(status)) {
10147 ret = qdf_status_to_os_return(status);
10148 goto wiphy_dealloc;
10149 }
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +053010150
Prashanth Bhatta527fd752016-04-28 12:35:23 -070010151 hdd_ctx->parent_dev = dev;
Jeff Johnson995fd512019-03-06 08:45:10 -080010152 hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010153
Anurag Chouhan600c3a02016-03-01 10:33:54 +053010154 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
Min Liu74a1a502018-10-10 19:59:07 +080010155 if (!hdd_ctx->config) {
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010156 ret = -ENOMEM;
10157 goto err_free_hdd_context;
10158 }
10159
Dustin Brown84f46ea2018-02-15 11:57:36 -080010160 status = cfg_parse(WLAN_INI_FILE);
nakul kachhwahaed09dc92019-05-21 14:20:06 +053010161 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Brown84f46ea2018-02-15 11:57:36 -080010162 hdd_err("Failed to parse cfg %s; status:%d\n",
10163 WLAN_INI_FILE, status);
nakul kachhwahaed09dc92019-05-21 14:20:06 +053010164 ret = qdf_status_to_os_return(status);
10165 goto err_free_config;
10166 }
Dustin Brown84f46ea2018-02-15 11:57:36 -080010167
Dundi Ravitejafb9357a2018-09-25 12:16:03 +053010168 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID);
10169 if (ret) {
Dundi Raviteja8e338282018-09-25 17:16:04 +053010170 QDF_DEBUG_PANIC("Psoc creation fails!");
nakul kachhwahaed09dc92019-05-21 14:20:06 +053010171 goto err_release_store;
Dundi Ravitejafb9357a2018-09-25 12:16:03 +053010172 }
10173
Dundi Raviteja8e338282018-09-25 17:16:04 +053010174 hdd_cfg_params_init(hdd_ctx);
10175
Dustin Brown4bbd5462019-03-22 11:18:13 -070010176 /* apply multiplier config, if not already set via module parameter */
10177 if (qdf_timer_get_multiplier() == 1)
10178 qdf_timer_set_multiplier(cfg_get(hdd_ctx->psoc,
10179 CFG_TIMER_MULTIPLIER));
Dustin Browna9a84522019-02-04 12:25:40 -080010180 hdd_debug("set timer multiplier: %u", qdf_timer_get_multiplier());
Dustin Brown7f939932017-05-18 15:02:17 -070010181
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010182 cds_set_fatal_event(cfg_get(hdd_ctx->psoc,
10183 CFG_ENABLE_FATAL_EVENT_TRIGGER));
Abhishek Singh5ea86532016-04-27 14:10:53 +053010184
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010185 hdd_override_ini_config(hdd_ctx);
10186
Prashanth Bhatta527fd752016-04-28 12:35:23 -070010187 ret = hdd_context_init(hdd_ctx);
10188
10189 if (ret)
Dundi Ravitejafb9357a2018-09-25 12:16:03 +053010190 goto err_hdd_objmgr_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -070010191
Nirav Shah6aeecf92019-02-13 14:05:03 +053010192 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE ||
10193 hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010194 goto skip_multicast_logging;
10195
10196 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
10197
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -070010198 ret = wlan_hdd_init_tx_rx_histogram(hdd_ctx);
10199 if (ret)
10200 goto err_deinit_hdd_context;
Nirav Shahed34b212016-04-25 10:59:16 +053010201
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -070010202 ret = hdd_init_netlink_services(hdd_ctx);
10203 if (ret)
10204 goto err_deinit_txrx_histogram;
10205
Nirav Shaheb017be2018-02-15 11:20:58 +053010206 hdd_set_wlan_logging(hdd_ctx);
Nirav Shahed34b212016-04-25 10:59:16 +053010207
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010208skip_multicast_logging:
10209 hdd_set_trace_level_for_each(hdd_ctx);
10210
Rajeev Kumar493a31b2017-09-29 14:01:24 -070010211 cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx);
10212
Dustin Browne74003f2018-03-14 12:51:58 -070010213 hdd_exit();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -070010214
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010215 return hdd_ctx;
10216
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -070010217err_deinit_txrx_histogram:
10218 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
10219
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -070010220err_deinit_hdd_context:
10221 hdd_context_deinit(hdd_ctx);
10222
Dundi Ravitejafb9357a2018-09-25 12:16:03 +053010223err_hdd_objmgr_destroy:
10224 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
10225
nakul kachhwahaed09dc92019-05-21 14:20:06 +053010226err_release_store:
10227 cfg_release();
10228
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010229err_free_config:
Anurag Chouhan600c3a02016-03-01 10:33:54 +053010230 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010231
10232err_free_hdd_context:
Dustin Brown8d8ab302019-03-05 16:19:36 -080010233 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
10234
10235wiphy_dealloc:
Rajeev Kumarfa55a692018-01-09 14:12:41 -080010236 wiphy_free(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080010237
10238err_out:
10239 return ERR_PTR(ret);
10240}
10241
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010242/**
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010243 * hdd_start_station_adapter()- Start the Station Adapter
10244 * @adapter: HDD adapter
10245 *
10246 * This function initializes the adapter for the station mode.
10247 *
10248 * Return: 0 on success or errno on failure.
10249 */
Jeff Johnson9d295242017-08-29 14:39:48 -070010250int hdd_start_station_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010251{
10252 QDF_STATUS status;
Krunal Sonib51eec72017-11-20 21:53:01 -080010253 int ret;
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010254
Dustin Brownfdf17c12018-03-14 12:55:34 -070010255 hdd_enter_dev(adapter->dev);
Krunal Sonib51eec72017-11-20 21:53:01 -080010256 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
10257 hdd_err("session is already opened, %d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -080010258 adapter->vdev_id);
Krunal Sonib51eec72017-11-20 21:53:01 -080010259 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
10260 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010261
Krunal Sonib51eec72017-11-20 21:53:01 -080010262 ret = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
10263 if (ret) {
10264 hdd_err("failed to create vdev: %d", ret);
10265 return ret;
10266 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010267 status = hdd_init_station_mode(adapter);
10268
10269 if (QDF_STATUS_SUCCESS != status) {
10270 hdd_err("Error Initializing station mode: %d", status);
10271 return qdf_status_to_os_return(status);
10272 }
10273
Arun Khandavallifae92942016-08-01 13:31:08 +053010274 hdd_register_tx_flow_control(adapter,
10275 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +080010276 hdd_tx_resume_cb,
10277 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +053010278
Visweswara Tanukub5a61242019-03-26 12:24:13 +053010279 hdd_register_hl_netdev_fc_timer(adapter,
10280 hdd_tx_resume_timer_expired_handler);
10281
Dustin Browne74003f2018-03-14 12:51:58 -070010282 hdd_exit();
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053010283
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010284 return 0;
10285}
10286
10287/**
10288 * hdd_start_ap_adapter()- Start AP Adapter
10289 * @adapter: HDD adapter
10290 *
10291 * This function initializes the adapter for the AP mode.
10292 *
10293 * Return: 0 on success errno on failure.
10294 */
Jeff Johnson9d295242017-08-29 14:39:48 -070010295int hdd_start_ap_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010296{
10297 QDF_STATUS status;
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -080010298 bool is_ssr = false;
Krunal Sonib51eec72017-11-20 21:53:01 -080010299 int ret;
Naveen Rawat1af09392018-01-03 17:28:21 -080010300 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Arif Hussainbd5194c2018-11-27 19:01:15 -080010301 uint32_t fine_time_meas_cap = 0;
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010302
Dustin Brown491d54b2018-03-14 12:39:11 -070010303 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010304
Krunal Sonib51eec72017-11-20 21:53:01 -080010305 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
10306 hdd_err("session is already opened, %d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -080010307 adapter->vdev_id);
Krunal Sonib51eec72017-11-20 21:53:01 -080010308 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
10309 }
10310 /*
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -080010311 * In SSR case no need to create new sap context.
10312 * Otherwise create sap context first and then create
10313 * vdev as while creating the vdev, driver needs to
10314 * register SAP callback and that callback uses sap context
Krunal Sonib51eec72017-11-20 21:53:01 -080010315 */
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -080010316 if (adapter->session.ap.sap_context) {
10317 is_ssr = true;
10318 } else if (!hdd_sap_create_ctx(adapter)) {
Krunal Sonib51eec72017-11-20 21:53:01 -080010319 hdd_err("sap creation failed");
10320 return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
10321 }
10322
10323 ret = hdd_vdev_create(adapter, wlansap_roam_callback,
10324 adapter->session.ap.sap_context);
10325 if (ret) {
10326 hdd_err("failed to create vdev, status:%d", ret);
10327 hdd_sap_destroy_ctx(adapter);
10328 return ret;
10329 }
Naveen Rawat1af09392018-01-03 17:28:21 -080010330
Arif Hussainbd5194c2018-11-27 19:01:15 -080010331 if (adapter->device_mode == QDF_SAP_MODE) {
10332 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
10333 &fine_time_meas_cap);
Jeff Johnson5a6fc962019-02-04 14:20:25 -080010334 sme_cli_set_command(adapter->vdev_id,
Naveen Rawat1af09392018-01-03 17:28:21 -080010335 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE,
Arif Hussainbd5194c2018-11-27 19:01:15 -080010336 (bool)(fine_time_meas_cap & WMI_FW_AP_RTT_RESPR),
Naveen Rawat1af09392018-01-03 17:28:21 -080010337 VDEV_CMD);
Arif Hussainbd5194c2018-11-27 19:01:15 -080010338 }
Naveen Rawat1af09392018-01-03 17:28:21 -080010339
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -080010340 status = hdd_init_ap_mode(adapter, is_ssr);
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010341
10342 if (QDF_STATUS_SUCCESS != status) {
10343 hdd_err("Error Initializing the AP mode: %d", status);
10344 return qdf_status_to_os_return(status);
10345 }
10346
Arun Khandavallifae92942016-08-01 13:31:08 +053010347 hdd_register_tx_flow_control(adapter,
10348 hdd_softap_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +080010349 hdd_softap_tx_resume_cb,
10350 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +053010351
Visweswara Tanukub5a61242019-03-26 12:24:13 +053010352 hdd_register_hl_netdev_fc_timer(adapter,
10353 hdd_tx_resume_timer_expired_handler);
10354
Dustin Browne74003f2018-03-14 12:51:58 -070010355 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +053010356 return 0;
10357}
10358
hangtianb9c91362019-06-07 10:39:38 +080010359#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010360/**
10361 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
10362 * @cds_cfg: CDS Configuration
10363 * @hdd_ctx: Pointer to hdd context
10364 *
10365 * Return: none
10366 */
10367static inline void hdd_txrx_populate_cds_config(struct cds_config_info
10368 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010369 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010370{
10371 cds_cfg->tx_flow_stop_queue_th =
jitiphil47c3d9a2018-11-08 18:30:55 +053010372 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010373 cds_cfg->tx_flow_start_queue_offset =
jitiphil47c3d9a2018-11-08 18:30:55 +053010374 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
Mohit Khanna70322002018-05-15 19:21:32 -070010375 /* configuration for DP RX Threads */
10376 cds_cfg->enable_dp_rx_threads = hdd_ctx->enable_dp_rx_threads;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010377}
hangtianb9c91362019-06-07 10:39:38 +080010378#else
10379static inline void hdd_txrx_populate_cds_config(struct cds_config_info
10380 *cds_cfg,
10381 struct hdd_context *hdd_ctx)
10382{
10383}
10384#endif
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010385
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010386/**
10387 * hdd_update_cds_config() - API to update cds configuration parameters
10388 * @hdd_ctx: HDD Context
10389 *
10390 * Return: 0 for Success, errno on failure
10391 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010392static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010393{
10394 struct cds_config_info *cds_cfg;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053010395 int value;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053010396 uint8_t band_capability;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010397 uint8_t ito_repeat_count;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053010398 bool crash_inject;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010399 bool self_recovery;
10400 bool fw_timeout_crash;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053010401 QDF_STATUS status;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010402
Min Liu74a1a502018-10-10 19:59:07 +080010403 cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg));
10404 if (!cds_cfg)
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010405 return -ENOMEM;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010406
Srinivas Girigowda35b00312017-06-27 21:52:03 -070010407 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
Bala Venkatesh46e29032018-11-14 18:24:55 +053010408 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
10409 &cds_cfg->sta_maxlimod_dtim);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010410
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010411 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
Vignesh Viswanathana851d752018-10-03 19:44:38 +053010412 if (QDF_IS_STATUS_ERROR(status)) {
10413 hdd_err("Failed to get crash inject ini config");
10414 goto exit;
10415 }
10416
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010417 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
10418 if (QDF_IS_STATUS_ERROR(status)) {
10419 hdd_err("Failed to get self recovery ini config");
10420 goto exit;
10421 }
10422
10423 status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc,
10424 &fw_timeout_crash);
10425 if (QDF_IS_STATUS_ERROR(status)) {
10426 hdd_err("Failed to get fw timeout crash ini config");
10427 goto exit;
10428 }
10429
10430 status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc,
10431 &ito_repeat_count);
10432 if (QDF_IS_STATUS_ERROR(status)) {
10433 hdd_err("Failed to get ITO repeat count ini config");
10434 goto exit;
10435 }
10436
Vignesh Viswanathana851d752018-10-03 19:44:38 +053010437 cds_cfg->force_target_assert_enabled = crash_inject;
SaidiReddy Yenugacc733af2016-11-09 17:45:42 +053010438
Dustin Brown05d81302018-09-11 16:49:22 -070010439 ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053010440 cds_cfg->ap_maxoffload_peers = value;
Dustin Brown05d81302018-09-11 16:49:22 -070010441 ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053010442 &value);
10443 cds_cfg->ap_maxoffload_reorderbuffs = value;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010444
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010445 cds_cfg->reorder_offload =
jitiphil47c3d9a2018-11-08 18:30:55 +053010446 cfg_get(hdd_ctx->psoc, CFG_DP_REORDER_OFFLOAD_SUPPORT);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010447
10448 /* IPA micro controller data path offload resource config item */
Sravan Kumar Kairam5214f652018-03-13 09:52:31 +053010449 cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled();
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010450
Jeff Johnsone2ba3cd2017-10-30 20:02:09 -070010451 cds_cfg->enable_rxthread = hdd_ctx->enable_rxthread;
Dustin Brown05d81302018-09-11 16:49:22 -070010452 ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053010453 cds_cfg->max_station = value;
Naveen Rawat64e477e2016-05-20 10:34:56 -070010454 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
Orhan K AKYILDIZ30e8cbc2017-08-11 18:00:28 -070010455 cds_cfg->max_msdus_per_rxinorderind =
jitiphil8e15ea62018-11-16 18:05:34 +053010456 cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND);
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010457 cds_cfg->self_recovery_enabled = self_recovery;
10458 cds_cfg->fw_timeout_crash = fw_timeout_crash;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010459
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010460 cds_cfg->ito_repeat_count = ito_repeat_count;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053010461
10462 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
10463 if (QDF_IS_STATUS_ERROR(status))
10464 goto exit;
10465
10466 cds_cfg->bandcapability = band_capability;
Rachit Kankane0106e382018-05-16 18:59:28 +053010467 cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs;
Jiani Liu6d3b6a12019-05-08 15:15:06 +080010468 cds_cfg->enable_tx_compl_tsf64 =
10469 hdd_tsf_is_tsf64_tx_set(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010470 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
Jeff Johnson9078bdc2016-09-23 17:18:11 -070010471 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010472 cds_init_ini_config(cds_cfg);
10473 return 0;
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +053010474
10475exit:
10476 qdf_mem_free(cds_cfg);
10477 return -EINVAL;
Arun Khandavallic811dcc2016-06-26 07:37:21 +053010478}
10479
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010480/**
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080010481 * hdd_update_user_config() - API to update user configuration
10482 * parameters to obj mgr which are used by multiple components
10483 * @hdd_ctx: HDD Context
10484 *
10485 * Return: 0 for Success, errno on failure
10486 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010487static int hdd_update_user_config(struct hdd_context *hdd_ctx)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080010488{
10489 struct wlan_objmgr_psoc_user_config *user_config;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053010490 uint8_t band_capability;
10491 QDF_STATUS status;
Abhinav Kumard4d6eb72018-12-04 20:30:37 +053010492 bool value = false;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053010493
10494 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
10495 if (QDF_IS_STATUS_ERROR(status))
10496 return -EIO;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080010497
10498 user_config = qdf_mem_malloc(sizeof(*user_config));
Min Liu74a1a502018-10-10 19:59:07 +080010499 if (!user_config)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080010500 return -ENOMEM;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080010501
10502 user_config->dot11_mode = hdd_ctx->config->dot11Mode;
Abhinav Kumard4d6eb72018-12-04 20:30:37 +053010503 status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value);
10504 if (!QDF_IS_STATUS_SUCCESS(status))
10505 hdd_err("Invalid 11d_enable flag");
10506 user_config->is_11d_support_enabled = value;
10507
10508 value = false;
10509 status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value);
10510 if (!QDF_IS_STATUS_SUCCESS(status))
10511 hdd_err("Invalid 11h_enable flag");
10512 user_config->is_11h_support_enabled = value;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +053010513 user_config->band_capability = band_capability;
Dustin Brown1dbefe62018-09-11 16:32:03 -070010514 wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080010515
10516 qdf_mem_free(user_config);
10517 return 0;
10518}
10519
10520/**
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010521 * hdd_init_thermal_info - Initialize thermal level
10522 * @hdd_ctx: HDD context
10523 *
10524 * Initialize thermal level at SME layer and set the thermal level callback
10525 * which would be called when a configured thermal threshold is hit.
10526 *
10527 * Return: 0 on success and errno on failure
10528 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010529static int hdd_init_thermal_info(struct hdd_context *hdd_ctx)
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010530{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010531 QDF_STATUS status;
Manikandan Mohan9045e2e2018-11-26 16:44:19 -080010532 mac_handle_t mac_handle = hdd_ctx->mac_handle;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010533
Manikandan Mohan9045e2e2018-11-26 16:44:19 -080010534 status = sme_init_thermal_info(mac_handle);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010535
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053010536 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanc5548422016-02-24 18:33:27 +053010537 return qdf_status_to_os_return(status);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010538
Jeff Johnson16528362018-06-14 12:34:16 -070010539 sme_add_set_thermal_level_callback(mac_handle,
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -080010540 hdd_set_thermal_level_cb);
10541
10542 return 0;
10543
10544}
10545
Prashanth Bhatta98f04d22016-01-08 16:46:21 -080010546#if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
10547/**
10548 * hdd_hold_rtnl_lock - Hold RTNL lock
10549 *
10550 * Hold RTNL lock
10551 *
10552 * Return: True if held and false otherwise
10553 */
10554static inline bool hdd_hold_rtnl_lock(void)
10555{
10556 rtnl_lock();
10557 return true;
10558}
10559
10560/**
10561 * hdd_release_rtnl_lock - Release RTNL lock
10562 *
10563 * Release RTNL lock
10564 *
10565 * Return: None
10566 */
10567static inline void hdd_release_rtnl_lock(void)
10568{
10569 rtnl_unlock();
10570}
10571#else
10572static inline bool hdd_hold_rtnl_lock(void) { return false; }
10573static inline void hdd_release_rtnl_lock(void) { }
10574#endif
10575
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010576#if !defined(REMOVE_PKT_LOG)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010577
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010578/* MAX iwpriv command support */
10579#define PKTLOG_SET_BUFF_SIZE 3
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010580#define PKTLOG_CLEAR_BUFF 4
Venkata Sharath Chandra Manchala27e44902019-01-28 11:29:18 -080010581/* Set Maximum pktlog file size to 64MB */
10582#define MAX_PKTLOG_SIZE 64
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010583
10584/**
10585 * hdd_pktlog_set_buff_size() - set pktlog buffer size
10586 * @hdd_ctx: hdd context
10587 * @set_value2: pktlog buffer size value
10588 *
10589 *
10590 * Return: 0 for success or error.
10591 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010592static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010593{
10594 struct sir_wifi_start_log start_log = { 0 };
10595 QDF_STATUS status;
10596
10597 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10598 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
10599 start_log.ini_triggered = cds_is_packet_log_enabled();
10600 start_log.user_triggered = 1;
10601 start_log.size = set_value2;
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010602 start_log.is_pktlog_buff_clear = false;
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010603
Jeff Johnson16528362018-06-14 12:34:16 -070010604 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010605 if (!QDF_IS_STATUS_SUCCESS(status)) {
10606 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010607 hdd_exit();
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010608 return -EINVAL;
10609 }
10610
10611 return 0;
10612}
10613
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010614/**
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010615 * hdd_pktlog_clear_buff() - clear pktlog buffer
10616 * @hdd_ctx: hdd context
10617 *
10618 * Return: 0 for success or error.
10619 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010620static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010621{
10622 struct sir_wifi_start_log start_log;
10623 QDF_STATUS status;
10624
10625 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10626 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
10627 start_log.ini_triggered = cds_is_packet_log_enabled();
10628 start_log.user_triggered = 1;
10629 start_log.size = 0;
10630 start_log.is_pktlog_buff_clear = true;
10631
Jeff Johnson16528362018-06-14 12:34:16 -070010632 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010633 if (!QDF_IS_STATUS_SUCCESS(status)) {
10634 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010635 hdd_exit();
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010636 return -EINVAL;
10637 }
10638
10639 return 0;
10640}
10641
10642
10643/**
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010644 * hdd_process_pktlog_command() - process pktlog command
10645 * @hdd_ctx: hdd context
10646 * @set_value: value set by user
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010647 * @set_value2: pktlog buffer size value
10648 *
10649 * This function process pktlog command.
10650 * set_value2 only matters when set_value is 3 (set buff size)
10651 * otherwise we ignore it.
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010652 *
10653 * Return: 0 for success or error.
10654 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010655int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010656 int set_value2)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010657{
10658 int ret;
10659 bool enable;
10660 uint8_t user_triggered = 0;
10661
10662 ret = wlan_hdd_validate_context(hdd_ctx);
10663 if (0 != ret)
10664 return ret;
10665
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010666 hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010667
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010668 if (set_value > PKTLOG_CLEAR_BUFF) {
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010669 hdd_err("invalid pktlog value %d", set_value);
10670 return -EINVAL;
10671 }
10672
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010673 if (set_value == PKTLOG_SET_BUFF_SIZE) {
10674 if (set_value2 <= 0) {
10675 hdd_err("invalid pktlog size %d", set_value2);
10676 return -EINVAL;
10677 } else if (set_value2 > MAX_PKTLOG_SIZE) {
Venkata Sharath Chandra Manchala27e44902019-01-28 11:29:18 -080010678 hdd_err_rl("Pktlog size is large. max value is %uMB.",
10679 MAX_PKTLOG_SIZE);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010680 return -EINVAL;
10681 }
10682 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010683 } else if (set_value == PKTLOG_CLEAR_BUFF) {
10684 return hdd_pktlog_clear_buff(hdd_ctx);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010685 }
10686
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010687 /*
10688 * set_value = 0 then disable packetlog
10689 * set_value = 1 enable packetlog forcefully
10690 * set_vlaue = 2 then disable packetlog if disabled through ini or
10691 * enable packetlog with AUTO type.
10692 */
10693 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
10694 true : false;
10695
10696 if (1 == set_value) {
10697 enable = true;
10698 user_triggered = 1;
10699 }
10700
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010701 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010702}
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070010703
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010704/**
10705 * hdd_pktlog_enable_disable() - Enable/Disable packet logging
10706 * @hdd_ctx: HDD context
10707 * @enable: Flag to enable/disable
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010708 * @user_triggered: triggered through iwpriv
10709 * @size: buffer size to be used for packetlog
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010710 *
10711 * Return: 0 on success; error number otherwise
10712 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010713int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, bool enable,
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010714 uint8_t user_triggered, int size)
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010715{
10716 struct sir_wifi_start_log start_log;
10717 QDF_STATUS status;
10718
10719 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10720 start_log.verbose_level =
10721 enable ? WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010722 start_log.ini_triggered = cds_is_packet_log_enabled();
10723 start_log.user_triggered = user_triggered;
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010724 start_log.size = size;
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010725 start_log.is_pktlog_buff_clear = false;
Poddar, Siddartheefe3482016-09-21 18:12:59 +053010726 /*
10727 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
10728 * commands. Host uses this flag to decide whether to send pktlog
10729 * disable command to fw without sending pktlog enable command
10730 * previously. For eg, If vendor sends pktlog disable command without
10731 * sending pktlog enable command, then host discards the packet
10732 * but for iwpriv command, host will send it to fw.
10733 */
10734 start_log.is_iwpriv_command = 1;
Jeff Johnson16528362018-06-14 12:34:16 -070010735 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010736 if (!QDF_IS_STATUS_SUCCESS(status)) {
10737 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010738 hdd_exit();
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010739 return -EINVAL;
10740 }
10741
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053010742 if (enable == true)
10743 hdd_ctx->is_pktlog_enabled = 1;
10744 else
10745 hdd_ctx->is_pktlog_enabled = 0;
10746
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010747 return 0;
10748}
10749#endif /* REMOVE_PKT_LOG */
10750
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010751void hdd_free_mac_address_lists(struct hdd_context *hdd_ctx)
10752{
10753 hdd_debug("Resetting MAC address lists");
hangtian127c9532019-01-12 13:29:07 +080010754 qdf_mem_zero(hdd_ctx->provisioned_mac_addr,
10755 sizeof(hdd_ctx->provisioned_mac_addr));
10756 qdf_mem_zero(hdd_ctx->derived_mac_addr,
10757 sizeof(hdd_ctx->derived_mac_addr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010758 hdd_ctx->num_provisioned_addr = 0;
10759 hdd_ctx->num_derived_addr = 0;
10760 hdd_ctx->provisioned_intf_addr_mask = 0;
10761 hdd_ctx->derived_intf_addr_mask = 0;
10762}
10763
Komal Seelam92fff912016-03-24 11:51:41 +053010764/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010765 * hdd_get_platform_wlan_mac_buff() - API to query platform driver
10766 * for MAC address
Komal Seelam92fff912016-03-24 11:51:41 +053010767 * @dev: Device Pointer
10768 * @num: Number of Valid Mac address
10769 *
10770 * Return: Pointer to MAC address buffer
10771 */
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010772static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
10773 uint32_t *num)
Komal Seelam92fff912016-03-24 11:51:41 +053010774{
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010775 return pld_get_wlan_mac_address(dev, num);
Komal Seelam92fff912016-03-24 11:51:41 +053010776}
Komal Seelam92fff912016-03-24 11:51:41 +053010777
10778/**
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010779 * hdd_get_platform_wlan_derived_mac_buff() - API to query platform driver
10780 * for derived MAC address
10781 * @dev: Device Pointer
10782 * @num: Number of Valid Mac address
10783 *
10784 * Return: Pointer to MAC address buffer
10785 */
10786static uint8_t *hdd_get_platform_wlan_derived_mac_buff(struct device *dev,
10787 uint32_t *num)
10788{
10789 return pld_get_wlan_derived_mac_address(dev, num);
10790}
10791
10792/**
Komal Seelam92fff912016-03-24 11:51:41 +053010793 * hdd_populate_random_mac_addr() - API to populate random mac addresses
10794 * @hdd_ctx: HDD Context
10795 * @num: Number of random mac addresses needed
10796 *
10797 * Generate random addresses using bit manipulation on the base mac address
10798 *
10799 * Return: None
10800 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010801void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
Komal Seelam92fff912016-03-24 11:51:41 +053010802{
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010803 uint32_t idx = hdd_ctx->num_derived_addr;
Komal Seelam92fff912016-03-24 11:51:41 +053010804 uint32_t iter;
Komal Seelam92fff912016-03-24 11:51:41 +053010805 uint8_t *buf = NULL;
10806 uint8_t macaddr_b3, tmp_br3;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010807 /*
10808 * Consider first provisioned mac address as source address to derive
10809 * remaining addresses
10810 */
Komal Seelam92fff912016-03-24 11:51:41 +053010811
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010812 uint8_t *src = hdd_ctx->provisioned_mac_addr[0].bytes;
10813
10814 for (iter = 0; iter < num; ++iter, ++idx) {
10815 buf = hdd_ctx->derived_mac_addr[idx].bytes;
Komal Seelam92fff912016-03-24 11:51:41 +053010816 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
10817 macaddr_b3 = buf[3];
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010818 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + idx) &
Komal Seelam92fff912016-03-24 11:51:41 +053010819 INTF_MACADDR_MASK;
10820 macaddr_b3 += tmp_br3;
10821 macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
10822 buf[0] |= 0x02;
10823 buf[3] = macaddr_b3;
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070010824 hdd_debug(QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(buf));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010825 hdd_ctx->num_derived_addr++;
Komal Seelam92fff912016-03-24 11:51:41 +053010826 }
10827}
10828
10829/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010830 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
Komal Seelam92fff912016-03-24 11:51:41 +053010831 * @hdd_ctx: HDD Context
10832 *
10833 * API to get mac addresses from platform driver and update the driver
10834 * structures and configure FW with the base mac address.
10835 * Return: int
10836 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010837static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +053010838{
10839 uint32_t no_of_mac_addr, iter;
10840 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
10841 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
10842 uint8_t *addr, *buf;
10843 struct device *dev = hdd_ctx->parent_dev;
Komal Seelam92fff912016-03-24 11:51:41 +053010844 tSirMacAddr mac_addr;
10845 QDF_STATUS status;
10846
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010847 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
Komal Seelam92fff912016-03-24 11:51:41 +053010848
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010849 if (no_of_mac_addr == 0 || !addr) {
10850 hdd_debug("No mac configured from platform driver");
Komal Seelam92fff912016-03-24 11:51:41 +053010851 return -EINVAL;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010852 }
10853
10854 hdd_free_mac_address_lists(hdd_ctx);
Komal Seelam92fff912016-03-24 11:51:41 +053010855
10856 if (no_of_mac_addr > max_mac_addr)
10857 no_of_mac_addr = max_mac_addr;
10858
10859 qdf_mem_copy(&mac_addr, addr, mac_addr_size);
10860
10861 for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010862 buf = hdd_ctx->provisioned_mac_addr[iter].bytes;
Komal Seelam92fff912016-03-24 11:51:41 +053010863 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070010864 hdd_info("provisioned MAC Addr [%d]" QDF_MAC_ADDR_STR, iter,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070010865 QDF_MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +053010866 }
10867
Komal Seelam92fff912016-03-24 11:51:41 +053010868
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010869 hdd_ctx->num_provisioned_addr = no_of_mac_addr;
Srinivas Girigowdab841da72017-03-25 18:04:39 -070010870
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010871 if (hdd_ctx->config->mac_provision) {
10872 addr = hdd_get_platform_wlan_derived_mac_buff(dev,
10873 &no_of_mac_addr);
10874
10875 if (no_of_mac_addr == 0 || !addr)
10876 hdd_warn("No derived address from platform driver");
10877 else if (no_of_mac_addr >
10878 (max_mac_addr - hdd_ctx->num_provisioned_addr))
10879 no_of_mac_addr = (max_mac_addr -
10880 hdd_ctx->num_provisioned_addr);
10881
10882 for (iter = 0; iter < no_of_mac_addr; ++iter,
10883 addr += mac_addr_size) {
10884 buf = hdd_ctx->derived_mac_addr[iter].bytes;
10885 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070010886 hdd_debug("derived MAC Addr [%d]" QDF_MAC_ADDR_STR, iter,
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070010887 QDF_MAC_ADDR_ARRAY(buf));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010888 }
10889 hdd_ctx->num_derived_addr = no_of_mac_addr;
10890 }
10891
10892 no_of_mac_addr = hdd_ctx->num_provisioned_addr +
10893 hdd_ctx->num_derived_addr;
Komal Seelam92fff912016-03-24 11:51:41 +053010894 if (no_of_mac_addr < max_mac_addr)
10895 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
10896 no_of_mac_addr);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010897
10898 status = sme_set_custom_mac_addr(mac_addr);
10899 if (!QDF_IS_STATUS_SUCCESS(status))
10900 return -EAGAIN;
10901
Komal Seelam92fff912016-03-24 11:51:41 +053010902 return 0;
10903}
10904
10905/**
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010906 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
10907 * @hdd_ctx: HDD Context
10908 *
10909 * Update MAC address to FW. If MAC address passed by FW is invalid, host
10910 * will generate its own MAC and update it to FW.
10911 *
10912 * Return: 0 for success
10913 * Non-zero error code for failure
10914 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010915static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010916{
Jeff Johnson374c0852019-03-10 19:02:07 -070010917 tSirMacAddr custom_mac_addr;
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010918 QDF_STATUS status;
10919
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010920 if (hdd_ctx->num_provisioned_addr)
Jeff Johnson374c0852019-03-10 19:02:07 -070010921 qdf_mem_copy(&custom_mac_addr,
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010922 &hdd_ctx->provisioned_mac_addr[0].bytes[0],
10923 sizeof(tSirMacAddr));
10924 else
Jeff Johnson374c0852019-03-10 19:02:07 -070010925 qdf_mem_copy(&custom_mac_addr,
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010926 &hdd_ctx->derived_mac_addr[0].bytes[0],
10927 sizeof(tSirMacAddr));
Jeff Johnson374c0852019-03-10 19:02:07 -070010928 status = sme_set_custom_mac_addr(custom_mac_addr);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010929 if (!QDF_IS_STATUS_SUCCESS(status))
10930 return -EAGAIN;
10931 return 0;
10932}
10933
10934/**
Komal Seelam92fff912016-03-24 11:51:41 +053010935 * hdd_initialize_mac_address() - API to get wlan mac addresses
10936 * @hdd_ctx: HDD Context
10937 *
10938 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
10939 * is provisioned with mac addresses, driver uses it, else it will use
10940 * wlan_mac.bin to update HW MAC addresses.
10941 *
10942 * Return: None
10943 */
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010944static int hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +053010945{
10946 QDF_STATUS status;
10947 int ret;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010948 bool update_mac_addr_to_fw = true;
Komal Seelam92fff912016-03-24 11:51:41 +053010949
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010950 ret = hdd_platform_wlan_mac(hdd_ctx);
Jingxiang Gec2ac79b2019-09-20 09:42:45 +080010951 if (!ret) {
Dustin Brown7e761c72018-07-31 13:50:17 -070010952 hdd_info("using MAC address from platform driver");
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010953 return ret;
Jingxiang Gec2ac79b2019-09-20 09:42:45 +080010954 } else if (hdd_ctx->config->mac_provision) {
10955 hdd_err("getting MAC address from platform driver failed");
10956 return ret;
Dustin Brown7e761c72018-07-31 13:50:17 -070010957 }
Komal Seelam92fff912016-03-24 11:51:41 +053010958
10959 status = hdd_update_mac_config(hdd_ctx);
Dustin Brown7e761c72018-07-31 13:50:17 -070010960 if (QDF_IS_STATUS_SUCCESS(status)) {
10961 hdd_info("using MAC address from wlan_mac.bin");
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010962 return 0;
Dustin Brown7e761c72018-07-31 13:50:17 -070010963 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010964
Dustin Brown7e761c72018-07-31 13:50:17 -070010965 hdd_info("using default MAC address");
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010966
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010967 /* Use fw provided MAC */
10968 if (!qdf_is_macaddr_zero(&hdd_ctx->hw_macaddr)) {
10969 hdd_update_macaddr(hdd_ctx, hdd_ctx->hw_macaddr, false);
10970 update_mac_addr_to_fw = false;
10971 return 0;
10972 } else if (hdd_generate_macaddr_auto(hdd_ctx) != 0) {
10973 struct qdf_mac_addr mac_addr;
10974
10975 hdd_err("MAC failure from device serial no.");
Jeff Johnson51a80522018-12-11 20:19:44 -080010976 qdf_get_random_bytes(&mac_addr, sizeof(mac_addr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010977 /*
10978 * Reset multicast bit (bit-0) and set
10979 * locally-administered bit
10980 */
10981 mac_addr.bytes[0] = 0x2;
10982 hdd_update_macaddr(hdd_ctx, mac_addr, true);
10983 }
10984
10985 if (update_mac_addr_to_fw) {
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010986 ret = hdd_update_mac_addr_to_fw(hdd_ctx);
Dustin Brown7e761c72018-07-31 13:50:17 -070010987 if (ret)
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -080010988 hdd_err("MAC address out-of-sync, ret:%d", ret);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010989 }
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010990 return ret;
Komal Seelam92fff912016-03-24 11:51:41 +053010991}
10992
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010993static int hdd_set_smart_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010994{
10995 int vdev_id = 0;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053010996 QDF_STATUS status;
10997 bool smart_chainmask_enabled;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010998 int param_id = WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010999 int vpdev = PDEV_CMD;
11000 int ret;
11001
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053011002 status = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc,
11003 &smart_chainmask_enabled);
11004 if (QDF_IS_STATUS_ERROR(status))
11005 return -EINVAL;
11006
11007 ret = sme_cli_set_command(vdev_id, param_id,
11008 (int)smart_chainmask_enabled, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011009 if (ret)
11010 hdd_err("WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME failed %d", ret);
11011
11012 return ret;
11013}
11014
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011015static int hdd_set_alternative_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011016{
11017 int vdev_id = 0;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011018 QDF_STATUS status;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011019 int param_id = WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011020 bool alternative_chainmask_enabled;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011021 int vpdev = PDEV_CMD;
11022 int ret;
11023
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011024 status = ucfg_get_alternative_chainmask_enabled(
11025 hdd_ctx->psoc,
11026 &alternative_chainmask_enabled);
11027 if (QDF_IS_STATUS_ERROR(status))
11028 return -EINVAL;
11029
11030 ret = sme_cli_set_command(vdev_id, param_id,
11031 (int)alternative_chainmask_enabled, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011032 if (ret)
11033 hdd_err("WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME failed %d",
11034 ret);
11035
11036 return ret;
11037}
11038
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011039static int hdd_set_ani_enabled(struct hdd_context *hdd_ctx)
Jeff Johnson12a744b2017-04-04 08:19:37 -070011040{
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011041 QDF_STATUS status;
Jeff Johnson12a744b2017-04-04 08:19:37 -070011042 int vdev_id = 0;
11043 int param_id = WMI_PDEV_PARAM_ANI_ENABLE;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011044 bool value;
Jeff Johnson12a744b2017-04-04 08:19:37 -070011045 int vpdev = PDEV_CMD;
11046 int ret;
11047
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011048 status = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &value);
11049 if (QDF_IS_STATUS_ERROR(status))
11050 return -EINVAL;
11051
11052 ret = sme_cli_set_command(vdev_id, param_id, (int)value, vpdev);
Jeff Johnson12a744b2017-04-04 08:19:37 -070011053 if (ret)
11054 hdd_err("WMI_PDEV_PARAM_ANI_ENABLE failed %d", ret);
11055
11056 return ret;
11057}
11058
Jeff Johnson89c66ff2016-04-22 15:21:37 -070011059/**
Prashanth Bhatta07998752016-04-28 12:35:33 -070011060 * hdd_pre_enable_configure() - Configurations prior to cds_enable
11061 * @hdd_ctx: HDD context
11062 *
11063 * Pre configurations to be done at lower layer before calling cds enable.
11064 *
11065 * Return: 0 on success and errno on failure.
11066 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011067static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
Prashanth Bhatta07998752016-04-28 12:35:33 -070011068{
11069 int ret;
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011070 uint8_t val = 0;
Prashanth Bhatta07998752016-04-28 12:35:33 -070011071 QDF_STATUS status;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011072 uint32_t arp_ac_category;
Leo Changfdb45c32016-10-28 11:09:23 -070011073 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prashanth Bhatta07998752016-04-28 12:35:33 -070011074
Leo Changfdb45c32016-10-28 11:09:23 -070011075 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
Ajit Pal Singh5d269612018-04-19 16:29:12 +053011076 /* Register HL netdev flow control callback */
11077 cdp_hl_fc_register(soc, wlan_hdd_txrx_pause_cb);
Rakshith Suresh Patkardb53c8f2019-06-07 17:11:31 +053011078 /* Register rx mic error indication handler */
11079 cdp_register_rx_mic_error_ind_handler(soc, hdd_rx_mic_error_ind);
Prashanth Bhatta07998752016-04-28 12:35:33 -070011080
11081 /*
11082 * Note that the cds_pre_enable() sequence triggers the cfg download.
11083 * The cfg download must occur before we update the SME config
11084 * since the SME config operation must access the cfg database
11085 */
11086 status = hdd_set_sme_config(hdd_ctx);
11087
11088 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011089 hdd_err("Failed hdd_set_sme_config: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -070011090 ret = qdf_status_to_os_return(status);
11091 goto out;
11092 }
11093
Tushnim Bhattacharyyaba8ee932017-03-23 09:27:40 -070011094 status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
11095 if (QDF_STATUS_SUCCESS != status) {
11096 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
11097 ret = qdf_status_to_os_return(status);
11098 goto out;
11099 }
11100
Dustin Brown1dbefe62018-09-11 16:32:03 -070011101 status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val);
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011102 if (QDF_STATUS_SUCCESS != status) {
11103 hdd_err("Get tx_chainmask_1ss from mlme failed");
11104 ret = qdf_status_to_os_return(status);
11105 goto out;
11106 }
11107 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, val,
Prashanth Bhatta07998752016-04-28 12:35:33 -070011108 PDEV_CMD);
11109 if (0 != ret) {
11110 hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret);
11111 goto out;
11112 }
11113
Jeff Johnsona89e25d2017-02-24 12:25:07 -080011114 ret = hdd_set_smart_chainmask_enabled(hdd_ctx);
11115 if (ret)
11116 goto out;
11117
11118 ret = hdd_set_alternative_chainmask_enabled(hdd_ctx);
11119 if (ret)
11120 goto out;
11121
Jeff Johnson12a744b2017-04-04 08:19:37 -070011122 ret = hdd_set_ani_enabled(hdd_ctx);
11123 if (ret)
11124 goto out;
11125
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011126 status = ucfg_get_arp_ac_category(hdd_ctx->psoc, &arp_ac_category);
11127
11128 if (QDF_IS_STATUS_ERROR(status))
11129 return -EINVAL;
11130
Naveen Rawat247a8682017-06-05 15:00:31 -070011131 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011132 arp_ac_category,
Srinivas Girigowda70e169a2017-03-07 23:55:57 -080011133 PDEV_CMD);
11134 if (0 != ret) {
11135 hdd_err("WMI_PDEV_PARAM_ARP_AC_OVERRIDE ac: %d ret: %d",
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011136 arp_ac_category, ret);
Srinivas Girigowda70e169a2017-03-07 23:55:57 -080011137 goto out;
11138 }
11139
Prashanth Bhatta07998752016-04-28 12:35:33 -070011140 status = hdd_set_sme_chan_list(hdd_ctx);
11141 if (status != QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011142 hdd_err("Failed to init channel list: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -070011143 ret = qdf_status_to_os_return(status);
11144 goto out;
11145 }
11146
Krunal Sonidf0f8742016-09-26 14:56:31 -070011147 if (!hdd_update_config_cfg(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011148 hdd_err("config update failed");
Prashanth Bhatta07998752016-04-28 12:35:33 -070011149 ret = -EINVAL;
11150 goto out;
11151 }
Prashanth Bhatta07998752016-04-28 12:35:33 -070011152 hdd_init_channel_avoidance(hdd_ctx);
11153
11154out:
11155 return ret;
11156}
11157
Rachit Kankane026e77a2018-07-31 16:21:09 +053011158#ifdef FEATURE_P2P_LISTEN_OFFLOAD
Prashanth Bhatta07998752016-04-28 12:35:33 -070011159/**
Peng Xu8fdaa492016-06-22 10:20:47 -070011160 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070011161 * @context: context registered with sme_register_p2p_lo_event(). HDD
11162 * always registers a hdd context pointer
11163 * @evt:event structure pointer
Peng Xu8fdaa492016-06-22 10:20:47 -070011164 *
11165 * This is the p2p listen offload stop event handler, it sends vendor
11166 * event back to supplicant to notify the stop reason.
11167 *
11168 * Return: None
11169 */
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070011170static void wlan_hdd_p2p_lo_event_callback(void *context,
11171 struct sir_p2p_lo_event *evt)
Peng Xu8fdaa492016-06-22 10:20:47 -070011172{
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070011173 struct hdd_context *hdd_ctx = context;
Peng Xu8fdaa492016-06-22 10:20:47 -070011174 struct sk_buff *vendor_event;
Jeff Johnson9d295242017-08-29 14:39:48 -070011175 struct hdd_adapter *adapter;
Peng Xu8fdaa492016-06-22 10:20:47 -070011176
Dustin Brown491d54b2018-03-14 12:39:11 -070011177 hdd_enter();
Peng Xu8fdaa492016-06-22 10:20:47 -070011178
Jeff Johnsond36fa332019-03-18 13:42:25 -070011179 if (!hdd_ctx) {
Peng Xu8fdaa492016-06-22 10:20:47 -070011180 hdd_err("Invalid HDD context pointer");
11181 return;
11182 }
11183
Peng Xu5c682812017-08-06 07:39:13 -070011184 adapter = hdd_get_adapter_by_vdev(hdd_ctx, evt->vdev_id);
11185 if (!adapter) {
11186 hdd_err("Cannot find adapter by vdev_id = %d",
11187 evt->vdev_id);
11188 return;
11189 }
11190
Peng Xu8fdaa492016-06-22 10:20:47 -070011191 vendor_event =
11192 cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
Peng Xu5c682812017-08-06 07:39:13 -070011193 &(adapter->wdev), sizeof(uint32_t) + NLMSG_HDRLEN,
Peng Xu8fdaa492016-06-22 10:20:47 -070011194 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX,
11195 GFP_KERNEL);
11196
11197 if (!vendor_event) {
11198 hdd_err("cfg80211_vendor_event_alloc failed");
11199 return;
11200 }
11201
11202 if (nla_put_u32(vendor_event,
11203 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
11204 evt->reason_code)) {
11205 hdd_err("nla put failed");
11206 kfree_skb(vendor_event);
11207 return;
11208 }
11209
11210 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Peng Xu5c682812017-08-06 07:39:13 -070011211 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
11212 evt->vdev_id);
Peng Xu8fdaa492016-06-22 10:20:47 -070011213}
Rachit Kankane026e77a2018-07-31 16:21:09 +053011214#else
11215static void wlan_hdd_p2p_lo_event_callback(void *context,
11216 struct sir_p2p_lo_event *evt)
11217{
11218}
11219#endif
Peng Xu8fdaa492016-06-22 10:20:47 -070011220
Rachit Kankanef6834c42018-08-02 18:47:50 +053011221#ifdef FEATURE_WLAN_DYNAMIC_CVM
11222static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
11223{
11224 return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap);
11225}
11226#else
11227static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
11228{
11229 return QDF_STATUS_SUCCESS;
11230}
11231#endif
11232
Peng Xu8fdaa492016-06-22 10:20:47 -070011233/**
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053011234 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
11235 * @hdd_ctx: HDD context
11236 *
11237 * This function sends the adaptive dwell time config configuration to the
11238 * firmware via WMA
11239 *
11240 * Return: 0 - success, < 0 - failure
11241 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011242static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053011243{
11244 QDF_STATUS status;
11245 struct adaptive_dwelltime_params dwelltime_params;
11246
Harprit Chhabadad59ae762019-01-08 16:40:43 -080011247 status = ucfg_fwol_get_all_adaptive_dwelltime_params(hdd_ctx->psoc,
11248 &dwelltime_params);
11249 status = ucfg_fwol_set_adaptive_dwelltime_config(&dwelltime_params);
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053011250
11251 hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
11252 if (!QDF_IS_STATUS_SUCCESS(status)) {
11253 hdd_err("Failed to send Adaptive Dwelltime configuration!");
11254 return -EAGAIN;
11255 }
11256 return 0;
11257}
11258
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011259int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011260{
11261 QDF_STATUS status;
11262 struct wmi_dbs_scan_sel_params dbs_scan_params;
11263 uint32_t i = 0;
11264 uint8_t count = 0, numentries = 0;
Krunal Sonidf29bc42018-11-15 13:26:29 -080011265 uint8_t dual_mac_feature;
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011266 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
11267 * CDS_DBS_SCAN_CLIENTS_MAX];
11268
Krunal Sonidf29bc42018-11-15 13:26:29 -080011269 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
11270 &dual_mac_feature);
11271
11272 if (status != QDF_STATUS_SUCCESS) {
11273 hdd_err("can't get dual mac feature flag");
11274 return -EINVAL;
11275 }
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011276 /* check if DBS is enabled or supported */
Krunal Sonidf29bc42018-11-15 13:26:29 -080011277 if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) ||
11278 (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN))
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011279 return -EINVAL;
11280
11281 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
11282 dbs_scan_config, &numentries,
11283 (CDS_DBS_SCAN_PARAM_PER_CLIENT
11284 * CDS_DBS_SCAN_CLIENTS_MAX));
11285
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011286 if (!numentries) {
Dustin Brown6a8d39b2018-08-14 15:27:26 -070011287 hdd_debug("Do not send scan_selection_config");
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011288 return 0;
11289 }
11290
11291 /* hdd_set_fw_log_params */
11292 dbs_scan_params.num_clients = 0;
11293 while (count < (numentries - 2)) {
11294 dbs_scan_params.module_id[i] = dbs_scan_config[count];
11295 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
11296 dbs_scan_params.num_non_dbs_scans[i] =
11297 dbs_scan_config[count + 2];
11298 dbs_scan_params.num_clients++;
11299 hdd_debug("module:%d NDS:%d NNDS:%d",
11300 dbs_scan_params.module_id[i],
11301 dbs_scan_params.num_dbs_scans[i],
11302 dbs_scan_params.num_non_dbs_scans[i]);
11303 count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
11304 i++;
11305 }
11306
11307 dbs_scan_params.pdev_id = 0;
11308
11309 hdd_debug("clients:%d pdev:%d",
11310 dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
11311
Jeff Johnson16528362018-06-14 12:34:16 -070011312 status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle,
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011313 &dbs_scan_params);
11314 hdd_debug("Sending DBS Scan Selection Configuration to fw");
11315 if (!QDF_IS_STATUS_SUCCESS(status)) {
11316 hdd_err("Failed to send DBS Scan selection configuration!");
11317 return -EAGAIN;
11318 }
11319 return 0;
11320}
11321
Arun Khandavallid4349a92016-07-25 11:10:43 +053011322#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
11323/**
11324 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
11325 * @hdd_ctx: HDD context
11326 *
11327 * Set auto shutdown callback to get indications from firmware to indicate
11328 * userspace to shutdown WLAN after a configured amount of inactivity.
11329 *
11330 * Return: 0 on success and errno on failure.
11331 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011332static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053011333{
11334 QDF_STATUS status;
11335
Dundi Raviteja8e338282018-09-25 17:16:04 +053011336 if (!hdd_ctx->config->wlan_auto_shutdown)
Arun Khandavallid4349a92016-07-25 11:10:43 +053011337 return 0;
11338
Jeff Johnson16528362018-06-14 12:34:16 -070011339 status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle,
Arun Khandavallid4349a92016-07-25 11:10:43 +053011340 wlan_hdd_auto_shutdown_cb);
11341 if (status != QDF_STATUS_SUCCESS)
11342 hdd_err("Auto shutdown feature could not be enabled: %d",
11343 status);
11344
11345 return qdf_status_to_os_return(status);
11346}
11347#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011348static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053011349{
11350 return 0;
11351}
11352#endif
11353
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011354#ifdef MWS_COEX
11355/**
11356 * hdd_set_mws_coex() - Set MWS coex configurations
11357 * @hdd_ctx: HDD context
11358 *
11359 * This function sends MWS-COEX 4G quick FTDM and
11360 * MWS-COEX 5G-NR power limit to FW
11361 *
11362 * Return: 0 on success and errno on failure.
11363 */
11364static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
11365{
11366 int ret = 0;
lifengdb340e72018-11-20 00:50:20 +080011367 uint32_t mws_coex_4g_quick_tdm = 0, mws_coex_5g_nr_pwr_limit = 0;
11368
11369 ucfg_mlme_get_mws_coex_4g_quick_tdm(hdd_ctx->psoc,
11370 &mws_coex_4g_quick_tdm);
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011371
11372 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM,
lifengdb340e72018-11-20 00:50:20 +080011373 mws_coex_4g_quick_tdm,
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011374 PDEV_CMD);
11375 if (ret) {
11376 hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy");
11377 return ret;
11378 }
11379
lifengdb340e72018-11-20 00:50:20 +080011380 ucfg_mlme_get_mws_coex_5g_nr_pwr_limit(hdd_ctx->psoc,
11381 &mws_coex_5g_nr_pwr_limit);
11382
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011383 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT,
lifengdb340e72018-11-20 00:50:20 +080011384 mws_coex_5g_nr_pwr_limit,
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011385 PDEV_CMD);
11386 if (ret) {
11387 hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy");
11388 return ret;
11389 }
lifengdb340e72018-11-20 00:50:20 +080011390
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011391 return ret;
11392}
11393#else
11394static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
11395{
11396 return 0;
11397}
11398#endif
11399
Arun Khandavallid4349a92016-07-25 11:10:43 +053011400/**
11401 * hdd_features_init() - Init features
11402 * @hdd_ctx: HDD context
Arun Khandavallid4349a92016-07-25 11:10:43 +053011403 *
11404 * Initialize features and their feature context after WLAN firmware is up.
11405 *
11406 * Return: 0 on success and errno on failure.
11407 */
Dustin Browne7e71d32018-05-11 16:00:08 -070011408static int hdd_features_init(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053011409{
Jeff Johnson19ce8d02019-02-08 22:56:23 -080011410 struct tx_power_limit hddtxlimit;
Arun Khandavallid4349a92016-07-25 11:10:43 +053011411 QDF_STATUS status;
11412 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -070011413 mac_handle_t mac_handle;
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070011414 struct hdd_config *cfg;
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +053011415 bool b_cts2self, is_imps_enabled;
Arun Khandavallid4349a92016-07-25 11:10:43 +053011416
Dustin Brown491d54b2018-03-14 12:39:11 -070011417 hdd_enter();
Arun Khandavallid4349a92016-07-25 11:10:43 +053011418
Dustin Brownad698ae2018-09-05 17:19:30 -070011419 ret = hdd_update_country_code(hdd_ctx);
11420 if (ret) {
11421 hdd_err("Failed to update country code; errno:%d", ret);
11422 return -EINVAL;
11423 }
11424
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053011425 ret = hdd_init_mws_coex(hdd_ctx);
11426 if (ret)
11427 hdd_warn("Error initializing mws-coex");
11428
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070011429 cfg = hdd_ctx->config;
Arun Khandavallid4349a92016-07-25 11:10:43 +053011430 /* FW capabilities received, Set the Dot11 mode */
Jeff Johnson16528362018-06-14 12:34:16 -070011431 mac_handle = hdd_ctx->mac_handle;
11432 sme_setdef_dot11mode(mac_handle);
Arun Khandavallid4349a92016-07-25 11:10:43 +053011433
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +053011434 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
11435 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
Arun Khandavallid4349a92016-07-25 11:10:43 +053011436
Poddar, Siddarth37033032017-10-11 15:47:40 +053011437 /* Send Enable/Disable data stall detection cmd to FW */
11438 sme_cli_set_command(0, WMI_PDEV_PARAM_DATA_STALL_DETECT_ENABLE,
jitiphil377bcc12018-10-05 19:46:08 +053011439 cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
11440 cfg_dp_enable_data_stall), PDEV_CMD);
Poddar, Siddarth37033032017-10-11 15:47:40 +053011441
Dustin Brown1dbefe62018-09-11 16:32:03 -070011442 ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self);
Wu Gao93816212018-08-31 16:49:54 +080011443 if (b_cts2self)
Jeff Johnson16528362018-06-14 12:34:16 -070011444 sme_set_cts2self_for_p2p_go(mac_handle);
Agrawal Ashish642ec9b2017-02-22 14:45:30 +053011445
Rachit Kankanef6834c42018-08-02 18:47:50 +053011446 if (hdd_set_vc_mode_config(hdd_ctx))
Nachiket Kukade8983cf62017-10-12 18:14:48 +053011447 hdd_warn("Error in setting Voltage Corner mode config to FW");
11448
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070011449 if (hdd_rx_ol_init(hdd_ctx))
11450 hdd_err("Unable to initialize Rx LRO/GRO in fw");
Arun Khandavallid4349a92016-07-25 11:10:43 +053011451
11452 if (hdd_adaptive_dwelltime_init(hdd_ctx))
11453 hdd_err("Unable to send adaptive dwelltime setting to FW");
11454
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053011455 if (hdd_dbs_scan_selection_init(hdd_ctx))
11456 hdd_err("Unable to send DBS scan selection setting to FW");
11457
Arun Khandavallid4349a92016-07-25 11:10:43 +053011458 ret = hdd_init_thermal_info(hdd_ctx);
11459 if (ret) {
11460 hdd_err("Error while initializing thermal information");
Dustin Browne7e71d32018-05-11 16:00:08 -070011461 return ret;
Arun Khandavallid4349a92016-07-25 11:10:43 +053011462 }
11463
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053011464 /**
11465 * In case of SSR/PDR, if pktlog was enabled manually before
Rakshith Suresh Patkar6d955262019-03-13 16:51:50 +053011466 * SSR/PDR, then enable it again automatically after Wlan
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053011467 * device up.
Rakshith Suresh Patkar6d955262019-03-13 16:51:50 +053011468 * During SSR/PDR, pktlog will be disabled as part of
11469 * hdd_features_deinit if pktlog is enabled in ini.
11470 * Re-enable pktlog in SSR case, if pktlog is enabled in ini.
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053011471 */
Rakshith Suresh Patkar6d955262019-03-13 16:51:50 +053011472 if (cds_is_packet_log_enabled() ||
11473 (cds_is_driver_recovering() && hdd_ctx->is_pktlog_enabled))
Alok Kumar5a75b9d2018-08-31 10:55:43 +053011474 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
Poddar, Siddarth66a46592017-02-22 11:44:44 +053011475
gaurank kathpalia3d2e3852018-10-03 22:03:23 +053011476 hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G);
11477 hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G);
Jeff Johnson16528362018-06-14 12:34:16 -070011478 status = sme_txpower_limit(mac_handle, &hddtxlimit);
Arun Khandavallid4349a92016-07-25 11:10:43 +053011479 if (!QDF_IS_STATUS_SUCCESS(status))
11480 hdd_err("Error setting txlimit in sme: %d", status);
11481
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011482 wlan_hdd_tsf_init(hdd_ctx);
Arun Khandavallid4349a92016-07-25 11:10:43 +053011483
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053011484 status = sme_enable_disable_chanavoidind_event(mac_handle, 0);
11485 if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) {
11486 hdd_err("Failed to disable Chan Avoidance Indication");
Sourav Mohapatra674925f2018-04-16 11:16:58 +053011487 return -EINVAL;
Selvaraj, Sridhar371f55e2017-02-21 10:36:15 +053011488 }
Arun Khandavallid4349a92016-07-25 11:10:43 +053011489
11490 /* register P2P Listen Offload event callback */
11491 if (wma_is_p2p_lo_capable())
Jeff Johnson16528362018-06-14 12:34:16 -070011492 sme_register_p2p_lo_event(mac_handle, hdd_ctx,
11493 wlan_hdd_p2p_lo_event_callback);
Arun Khandavallid4349a92016-07-25 11:10:43 +053011494
11495 ret = hdd_set_auto_shutdown_cb(hdd_ctx);
11496
11497 if (ret)
Sourav Mohapatra674925f2018-04-16 11:16:58 +053011498 return -EINVAL;
Arun Khandavallid4349a92016-07-25 11:10:43 +053011499
Dustin Brown11638b72018-01-25 17:37:25 +053011500 wlan_hdd_init_chan_info(hdd_ctx);
Varun Reddy Yeturu3c9f89c2018-04-18 19:10:34 -070011501 wlan_hdd_twt_init(hdd_ctx);
Dustin Brown11638b72018-01-25 17:37:25 +053011502
Dustin Browne74003f2018-03-14 12:51:58 -070011503 hdd_exit();
Arun Khandavallid4349a92016-07-25 11:10:43 +053011504 return 0;
Arun Khandavallid4349a92016-07-25 11:10:43 +053011505}
11506
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011507/**
11508 * hdd_features_deinit() - Deinit features
11509 * @hdd_ctx: HDD context
11510 *
11511 * De-Initialize features and their feature context.
11512 *
11513 * Return: none.
11514 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011515static void hdd_features_deinit(struct hdd_context *hdd_ctx)
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011516{
Varun Reddy Yeturu3c9f89c2018-04-18 19:10:34 -070011517 wlan_hdd_twt_deinit(hdd_ctx);
Dustin Brown11638b72018-01-25 17:37:25 +053011518 wlan_hdd_deinit_chan_info(hdd_ctx);
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011519 wlan_hdd_tsf_deinit(hdd_ctx);
jitiphil4e3bef42018-11-14 14:31:13 +053011520 if (cds_is_packet_log_enabled())
11521 hdd_pktlog_enable_disable(hdd_ctx, false, 0, 0);
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011522}
11523
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011524/**
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070011525 * hdd_register_bcn_cb() - register scan beacon callback
11526 * @hdd_ctx - Pointer to the HDD context
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011527 *
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070011528 * Return: QDF_STATUS
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011529 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011530static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011531{
11532 QDF_STATUS status;
11533
Dustin Brown1dbefe62018-09-11 16:32:03 -070011534 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011535 wlan_cfg80211_inform_bss_frame,
11536 SCAN_CB_TYPE_INFORM_BCN);
11537 if (!QDF_IS_STATUS_SUCCESS(status)) {
Abhishek Singh5ffe9de2019-03-05 15:42:43 +053011538 hdd_err("failed to register SCAN_CB_TYPE_INFORM_BCN with status code %08d [x%08x]",
11539 status, status);
11540 return status;
11541 }
11542
11543 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
11544 wlan_cfg80211_unlink_bss_list,
11545 SCAN_CB_TYPE_UNLINK_BSS);
11546 if (!QDF_IS_STATUS_SUCCESS(status)) {
11547 hdd_err("failed to refister SCAN_CB_TYPE_FLUSH_BSS with status code %08d [x%08x]",
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011548 status, status);
11549 return status;
11550 }
11551
11552 return QDF_STATUS_SUCCESS;
11553}
Arun Khandavallid4349a92016-07-25 11:10:43 +053011554
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053011555/**
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070011556 * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active
11557 * @vdev_id: vdev_id, corresponds to flow_pool
11558 *
11559 * Return: none.
11560 */
11561static void hdd_v2_flow_pool_map(int vdev_id)
11562{
11563 QDF_STATUS status;
11564
11565 status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC),
11566 cds_get_context(QDF_MODULE_ID_TXRX),
11567 vdev_id);
11568 /*
11569 * For Adrastea flow control v2 is based on FW MAP events,
11570 * so this above callback is not implemented.
11571 * Hence this is not actual failure. Dont return failure
11572 */
11573 if ((status != QDF_STATUS_SUCCESS) &&
11574 (status != QDF_STATUS_E_INVAL)) {
11575 hdd_err("vdev_id: %d, failed to create flow pool status %d",
11576 vdev_id, status);
11577 }
11578}
11579
11580/**
11581 * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active
11582 * @vdev_id: vdev_id, corresponds to flow_pool
11583 *
11584 * Return: none.
11585 */
11586static void hdd_v2_flow_pool_unmap(int vdev_id)
11587{
11588 cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC),
11589 cds_get_context(QDF_MODULE_ID_TXRX), vdev_id);
11590}
11591
11592/**
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011593 * hdd_action_oui_config() - Configure action_oui strings
11594 * @hdd_ctx: pointer to hdd context
11595 *
11596 * This is a HDD wrapper function which invokes ucfg api
11597 * of action_oui component to parse action oui strings.
11598 *
11599 * Return: None
11600 */
11601static void hdd_action_oui_config(struct hdd_context *hdd_ctx)
11602{
11603 QDF_STATUS status;
11604 uint32_t id;
11605 uint8_t *str;
11606
11607 if (!hdd_ctx->config->action_oui_enable)
11608 return;
11609
11610 for (id = 0; id < ACTION_OUI_MAXIMUM_ID; id++) {
11611 str = hdd_ctx->config->action_oui_str[id];
11612 if (!qdf_str_len(str))
11613 continue;
11614
Dustin Brown1dbefe62018-09-11 16:32:03 -070011615 status = ucfg_action_oui_parse(hdd_ctx->psoc, str, id);
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011616 if (!QDF_IS_STATUS_SUCCESS(status))
11617 hdd_err("Failed to parse action_oui str: %u", id);
11618 }
11619}
11620
11621/**
11622 * hdd_action_oui_send() - Send action_oui extensions to firmware
11623 * @hdd_ctx: pointer to hdd context
11624 *
11625 * This is a HDD wrapper function which invokes ucfg api
11626 * of action_oui component to send action oui extensions to firmware.
11627 *
11628 * Return: None
11629 */
11630static void hdd_action_oui_send(struct hdd_context *hdd_ctx)
11631{
11632 QDF_STATUS status;
11633
11634 if (!hdd_ctx->config->action_oui_enable)
11635 return;
11636
Dustin Brown1dbefe62018-09-11 16:32:03 -070011637 status = ucfg_action_oui_send(hdd_ctx->psoc);
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011638 if (!QDF_IS_STATUS_SUCCESS(status))
11639 hdd_err("Failed to send one or all action_ouis");
11640}
11641
Jeff Johnson0187c622019-01-04 06:39:44 -080011642static void hdd_hastings_bt_war_initialize(struct hdd_context *hdd_ctx)
11643{
11644 if (hdd_ctx->config->iface_change_wait_time)
11645 hdd_hastings_bt_war_disable_fw(hdd_ctx);
11646 else
11647 hdd_hastings_bt_war_enable_fw(hdd_ctx);
11648}
11649
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011650/**
Arun Khandavallifae92942016-08-01 13:31:08 +053011651 * hdd_configure_cds() - Configure cds modules
11652 * @hdd_ctx: HDD context
11653 * @adapter: Primary adapter context
11654 *
11655 * Enable Cds modules after WLAN firmware is up.
11656 *
11657 * Return: 0 on success and errno on failure.
11658 */
Dustin Browne7e71d32018-05-11 16:00:08 -070011659int hdd_configure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053011660{
11661 int ret;
11662 QDF_STATUS status;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011663 int set_value;
Jeff Johnson16528362018-06-14 12:34:16 -070011664 mac_handle_t mac_handle;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011665 bool enable_rts_sifsbursting;
11666 uint8_t enable_phy_reg_retention;
Krunal Sonidf29bc42018-11-15 13:26:29 -080011667 uint8_t max_mpdus_inampdu, is_force_1x1 = 0;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011668 uint32_t num_abg_tx_chains = 0;
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011669 uint16_t num_11b_tx_chains = 0;
11670 uint16_t num_11ag_tx_chains = 0;
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070011671 struct policy_mgr_dp_cbacks dp_cbs = {0};
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053011672 bool value;
Wu Gao66454f12018-09-26 19:55:41 +080011673 enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053011674 bool bval = false;
Varuneshwar Petlozuf8766672019-07-02 15:50:42 +053011675 qdf_device_t qdf_ctx;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011676
Jeff Johnson16528362018-06-14 12:34:16 -070011677 mac_handle = hdd_ctx->mac_handle;
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011678
11679 hdd_action_oui_send(hdd_ctx);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011680 status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1);
11681 if (status != QDF_STATUS_SUCCESS) {
11682 hdd_err("Failed to get force 1x1 value");
11683 goto out;
11684 }
11685 if (is_force_1x1)
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011686 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_SET_IOT_PATTERN,
11687 1, PDEV_CMD);
11688 /* set chip power save failure detected callback */
Jeff Johnson16528362018-06-14 12:34:16 -070011689 sme_set_chip_pwr_save_fail_cb(mac_handle,
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011690 hdd_chip_pwr_save_fail_detected_cb);
11691
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011692 status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc,
11693 &max_mpdus_inampdu);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011694 if (status) {
11695 hdd_err("Failed to get max mpdus in ampdu value");
11696 goto out;
11697 }
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011698
11699 if (max_mpdus_inampdu) {
11700 set_value = max_mpdus_inampdu;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011701 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU,
11702 set_value, PDEV_CMD);
11703 }
11704
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011705 status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc,
11706 &enable_rts_sifsbursting);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011707 if (status) {
11708 hdd_err("Failed to get rts sifs bursting value");
11709 goto out;
11710 }
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011711
11712 if (enable_rts_sifsbursting) {
11713 set_value = enable_rts_sifsbursting;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011714 sme_cli_set_command(0,
11715 (int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING,
11716 set_value, PDEV_CMD);
11717 }
11718
Dustin Brown05d81302018-09-11 16:49:22 -070011719 ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053011720 if (value) {
11721 set_value = value;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011722 sme_cli_set_command(0,
11723 (int)WMI_PDEV_PARAM_PEER_STATS_INFO_ENABLE,
11724 set_value, PDEV_CMD);
11725 }
11726
Dustin Brown1dbefe62018-09-11 16:32:03 -070011727 status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc,
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011728 &num_11b_tx_chains);
11729 if (status != QDF_STATUS_SUCCESS) {
11730 hdd_err("Failed to get num_11b_tx_chains");
11731 goto out;
11732 }
11733
Dustin Brown1dbefe62018-09-11 16:32:03 -070011734 status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc,
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011735 &num_11ag_tx_chains);
11736 if (status != QDF_STATUS_SUCCESS) {
11737 hdd_err("Failed to get num_11ag_tx_chains");
11738 goto out;
11739 }
11740
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053011741 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
11742 if (!QDF_IS_STATUS_SUCCESS(status))
11743 hdd_err("unable to get vht_enable2x2");
11744
11745 if (!bval) {
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011746 if (num_11b_tx_chains > 1)
11747 num_11b_tx_chains = 1;
11748 if (num_11ag_tx_chains > 1)
11749 num_11ag_tx_chains = 1;
11750 }
11751 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
11752 num_11b_tx_chains);
11753 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
11754 num_11ag_tx_chains);
11755 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM,
11756 num_abg_tx_chains, PDEV_CMD);
Arun Khandavallifae92942016-08-01 13:31:08 +053011757
Paul Zhang02526cd2018-09-20 17:47:46 +080011758 if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc))
11759 ucfg_reg_program_default_cc(hdd_ctx->pdev,
11760 hdd_ctx->reg.reg_domain);
11761
Arun Khandavallifae92942016-08-01 13:31:08 +053011762 ret = hdd_pre_enable_configure(hdd_ctx);
11763 if (ret) {
11764 hdd_err("Failed to pre-configure cds");
11765 goto out;
11766 }
11767
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080011768 /* Always get latest IPA resources allocated from cds_open and configure
11769 * IPA module before configuring them to FW. Sequence required as crash
11770 * observed otherwise.
11771 */
Varuneshwar Petlozuf8766672019-07-02 15:50:42 +053011772
11773 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
11774 if (!qdf_ctx) {
11775 hdd_err("QDF device context is NULL");
11776 goto out;
11777 }
11778
11779 if (ucfg_ipa_uc_ol_init(hdd_ctx->pdev, qdf_ctx)) {
Manikandan Mohan2e803a02017-02-14 14:57:53 -080011780 hdd_err("Failed to setup pipes");
11781 goto out;
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080011782 }
11783
Arun Khandavallifae92942016-08-01 13:31:08 +053011784 /*
11785 * Start CDS which starts up the SME/MAC/HAL modules and everything
11786 * else
11787 */
Dustin Brown1dbefe62018-09-11 16:32:03 -070011788 status = cds_enable(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053011789
11790 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011791 hdd_err("cds_enable failed");
Arun Khandavallifae92942016-08-01 13:31:08 +053011792 goto out;
11793 }
11794
11795 status = hdd_post_cds_enable_config(hdd_ctx);
11796 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011797 hdd_err("hdd_post_cds_enable_config failed");
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011798 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053011799 }
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011800 status = hdd_register_bcn_cb(hdd_ctx);
11801 if (!QDF_IS_STATUS_SUCCESS(status)) {
Paul Zhange03cf4c2018-01-19 18:33:22 +080011802 hdd_err("hdd_register_bcn_cb failed");
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011803 goto cds_disable;
11804 }
Arun Khandavallifae92942016-08-01 13:31:08 +053011805
Dustin Browne7e71d32018-05-11 16:00:08 -070011806 ret = hdd_features_init(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053011807 if (ret)
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011808 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053011809
Mohit Khanna81418772018-10-30 14:14:46 -070011810 /* Donot disable rx offload on concurrency for lithium based targets */
11811 if (!(hdd_ctx->target_type == TARGET_TYPE_QCA6290 ||
11812 hdd_ctx->target_type == TARGET_TYPE_QCA6390))
11813 if (hdd_ctx->ol_enable)
11814 dp_cbs.hdd_disable_rx_ol_in_concurrency =
11815 hdd_disable_rx_ol_in_concurrency;
Yun Parkff6a16a2017-09-26 16:38:18 -070011816 dp_cbs.hdd_set_rx_mode_rps_cb = hdd_set_rx_mode_rps;
jiadbb47e132018-03-30 16:28:30 +080011817 dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070011818 dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map;
11819 dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap;
Dustin Brown1dbefe62018-09-11 16:32:03 -070011820 status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs);
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011821 if (!QDF_IS_STATUS_SUCCESS(status)) {
Yun Parkff6a16a2017-09-26 16:38:18 -070011822 hdd_debug("Failed to register DP cb with Policy Manager");
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011823 goto cds_disable;
11824 }
Dustin Brown1dbefe62018-09-11 16:32:03 -070011825 status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc,
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011826 wlan_hdd_send_mode_change_event);
11827 if (!QDF_IS_STATUS_SUCCESS(status)) {
11828 hdd_debug("Failed to register mode change cb with Policy Manager");
11829 goto cds_disable;
11830 }
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011831
Jeff Johnson8bb61112018-03-31 13:33:54 -070011832 if (hdd_green_ap_enable_egap(hdd_ctx))
Nachiket Kukadefbd1afc2017-07-12 17:41:54 +053011833 hdd_debug("enhance green ap is not enabled");
11834
Nachiket Kukadedd302662017-07-13 17:31:44 +053011835 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
11836 hdd_debug("Failed to set wow pulse");
11837
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053011838 sme_cli_set_command(0, WMI_PDEV_PARAM_GCMP_SUPPORT_ENABLE,
Manikandan Mohan66df7fc2019-01-08 17:57:05 -080011839 ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc), PDEV_CMD);
Wu Gao66454f12018-09-26 19:55:41 +080011840
11841 auto_power_fail_mode =
11842 ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc);
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +053011843 sme_cli_set_command(0, WMI_PDEV_AUTO_DETECT_POWER_FAILURE,
Wu Gao66454f12018-09-26 19:55:41 +080011844 auto_power_fail_mode, PDEV_CMD);
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +053011845
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011846 status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc,
11847 &enable_phy_reg_retention);
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053011848
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011849 if (QDF_IS_STATUS_ERROR(status))
11850 return -EINVAL;
11851
11852 if (enable_phy_reg_retention)
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053011853 wma_cli_set_command(0, WMI_PDEV_PARAM_FAST_PWR_TRANSITION,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011854 enable_phy_reg_retention, PDEV_CMD);
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053011855
Jeff Johnson0187c622019-01-04 06:39:44 -080011856 hdd_hastings_bt_war_initialize(hdd_ctx);
11857
Arun Khandavallifae92942016-08-01 13:31:08 +053011858 return 0;
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011859
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011860cds_disable:
Dustin Brown1dbefe62018-09-11 16:32:03 -070011861 cds_disable(hdd_ctx->psoc);
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011862
Arun Khandavallifae92942016-08-01 13:31:08 +053011863out:
11864 return -EINVAL;
11865}
11866
11867/**
11868 * hdd_deconfigure_cds() -De-Configure cds
11869 * @hdd_ctx: HDD context
11870 *
11871 * Deconfigure Cds modules before WLAN firmware is down.
11872 *
11873 * Return: 0 on success and errno on failure.
11874 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011875static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053011876{
11877 QDF_STATUS qdf_status;
Houston Hoffman6640cf32016-10-10 16:44:29 -070011878 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053011879
Dustin Brown491d54b2018-03-14 12:39:11 -070011880 hdd_enter();
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011881
11882 /* De-init features */
11883 hdd_features_deinit(hdd_ctx);
11884
Dustin Brown1dbefe62018-09-11 16:32:03 -070011885 qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc);
Srinivas Girigowdad2412882018-09-07 15:42:04 -070011886 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011887 hdd_debug("Failed to deregister mode change cb with Policy Manager");
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011888
Dustin Brown1dbefe62018-09-11 16:32:03 -070011889 qdf_status = cds_disable(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053011890 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11891 hdd_err("Failed to Disable the CDS Modules! :%d",
11892 qdf_status);
Houston Hoffman6640cf32016-10-10 16:44:29 -070011893 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011894 }
11895
Dustin Brown07901ec2018-09-07 11:02:41 -070011896 if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) {
Sravan Kumar Kairam71121712017-04-15 00:34:42 +053011897 hdd_err("Failed to disconnect pipes");
11898 ret = -EINVAL;
11899 }
11900
Dustin Browne74003f2018-03-14 12:51:58 -070011901 hdd_exit();
Houston Hoffman6640cf32016-10-10 16:44:29 -070011902 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053011903}
11904
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070011905#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
11906static void hdd_deregister_policy_manager_callback(
11907 struct wlan_objmgr_psoc *psoc)
11908{
11909 if (QDF_STATUS_SUCCESS !=
11910 policy_mgr_deregister_hdd_cb(psoc)) {
11911 hdd_err("HDD callback deregister with policy manager failed");
11912 }
11913}
11914#else
11915static void hdd_deregister_policy_manager_callback(
11916 struct wlan_objmgr_psoc *psoc)
11917{
11918}
11919#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053011920
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011921int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
Arun Khandavallifae92942016-08-01 13:31:08 +053011922{
11923 void *hif_ctx;
11924 qdf_device_t qdf_ctx;
11925 QDF_STATUS qdf_status;
Dustin Brown4bc0a622017-12-06 15:56:50 -080011926 bool is_recovery_stop = cds_is_driver_recovering();
Sourav Mohapatra808e3d42018-07-04 09:34:23 +053011927 int ret = 0;
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053011928 int debugfs_threads;
Arunk Khandavallia6305a32018-01-25 11:19:18 +053011929 struct target_psoc_info *tgt_hdl;
Arun Khandavallifae92942016-08-01 13:31:08 +053011930
Dustin Brown491d54b2018-03-14 12:39:11 -070011931 hdd_enter();
Arun Khandavallifae92942016-08-01 13:31:08 +053011932 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
11933 if (!qdf_ctx) {
11934 hdd_err("QDF device context NULL");
11935 return -EINVAL;
11936 }
11937
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070011938 cds_set_module_stop_in_progress(true);
Arun Khandavallifae92942016-08-01 13:31:08 +053011939
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053011940 debugfs_threads = hdd_return_debugfs_threads_count();
Dustin Brown70111822017-03-30 15:31:40 -070011941
Dustin Brown3fdaaf62019-03-18 14:00:16 -070011942 if (debugfs_threads > 0 || hdd_ctx->is_wiphy_suspended) {
11943 hdd_warn("Debugfs threads %d, wiphy suspend %d",
11944 debugfs_threads, hdd_ctx->is_wiphy_suspended);
Dustin Brown70111822017-03-30 15:31:40 -070011945
Sourav Mohapatra808e3d42018-07-04 09:34:23 +053011946 if (IS_IDLE_STOP && !ftm_mode) {
Dustin Brown4c663222018-10-23 14:19:36 -070011947 hdd_psoc_idle_timer_start(hdd_ctx);
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070011948 cds_set_module_stop_in_progress(false);
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011949
Alan Chend841bcc2019-08-30 12:17:22 -070011950 return -EAGAIN;
Dustin Brown70111822017-03-30 15:31:40 -070011951 }
Rajeev Kumar86177c22017-03-16 19:44:39 -070011952 }
11953
Liangwei Dong857cb842019-04-28 04:55:17 -040011954 hdd_deregister_policy_manager_callback(hdd_ctx->psoc);
11955
Kabilan Kannan6edafeb2017-11-16 16:34:34 -080011956 /* free user wowl patterns */
11957 hdd_free_user_wowl_ptrns();
11958
Arun Khandavallifae92942016-08-01 13:31:08 +053011959 switch (hdd_ctx->driver_status) {
11960 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011961 hdd_debug("Modules not initialized just return");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011962 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053011963 case DRIVER_MODULES_CLOSED:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011964 hdd_debug("Modules already closed");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011965 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053011966 case DRIVER_MODULES_ENABLED:
Dustin Brown1a20b082018-08-03 17:27:15 -070011967 hdd_info("Wlan transitioning (CLOSED <- ENABLED)");
11968
Nirav Shah6aeecf92019-02-13 14:05:03 +053011969 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE ||
11970 hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
Dustin Brown1a20b082018-08-03 17:27:15 -070011971 break;
Dustin Brown550f6d22017-12-14 15:44:01 -080011972
Lin Bai56386f52019-08-08 13:58:23 +080011973 hdd_skip_acs_scan_timer_deinit(hdd_ctx);
11974
Komal Seelamf2136bb2016-09-28 18:30:44 +053011975 hdd_disable_power_management();
Arun Khandavallifae92942016-08-01 13:31:08 +053011976 if (hdd_deconfigure_cds(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011977 hdd_err("Failed to de-configure CDS");
Arun Khandavallifae92942016-08-01 13:31:08 +053011978 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011979 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011980 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011981 hdd_debug("successfully Disabled the CDS modules!");
Dustin Brown550f6d22017-12-14 15:44:01 -080011982
Arun Khandavallifae92942016-08-01 13:31:08 +053011983 break;
11984 default:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011985 QDF_DEBUG_PANIC("Unknown driver state:%d",
Arun Khandavallifae92942016-08-01 13:31:08 +053011986 hdd_ctx->driver_status);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011987 ret = -EINVAL;
11988 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053011989 }
11990
Arunk Khandavalli890f6d92018-10-30 20:18:28 +053011991 hdd_sysfs_destroy_powerstats_interface();
Amar Singhal18081642018-01-26 16:04:13 -080011992 hdd_sysfs_destroy_version_interface();
Arunk Khandavalli890f6d92018-10-30 20:18:28 +053011993 hdd_sysfs_destroy_driver_root_obj();
Dustin Brown550f6d22017-12-14 15:44:01 -080011994 hdd_debug("Closing CDS modules!");
Amar Singhal18081642018-01-26 16:04:13 -080011995
Nirav Shah6aeecf92019-02-13 14:05:03 +053011996 if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) {
11997 qdf_status = cds_post_disable();
11998 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11999 hdd_err("Failed to process post CDS disable! :%d",
12000 qdf_status);
12001 ret = -EINVAL;
12002 QDF_ASSERT(0);
12003 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070012004
Nirav Shah6aeecf92019-02-13 14:05:03 +053012005 /* De-register the SME callbacks */
12006 hdd_deregister_cb(hdd_ctx);
Sourav Mohapatra674925f2018-04-16 11:16:58 +053012007
Nirav Shah6aeecf92019-02-13 14:05:03 +053012008 hdd_runtime_suspend_context_deinit(hdd_ctx);
psimhadeea0a12017-12-18 14:50:02 -080012009
Nirav Shah6aeecf92019-02-13 14:05:03 +053012010 qdf_status = cds_dp_close(hdd_ctx->psoc);
12011 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
12012 hdd_warn("Failed to stop CDS DP: %d", qdf_status);
12013 ret = -EINVAL;
12014 QDF_ASSERT(0);
12015 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070012016
Nirav Shah6aeecf92019-02-13 14:05:03 +053012017 qdf_status = cds_close(hdd_ctx->psoc);
12018 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
12019 hdd_warn("Failed to stop CDS: %d", qdf_status);
12020 ret = -EINVAL;
12021 QDF_ASSERT(0);
12022 }
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053012023
Nirav Shah6aeecf92019-02-13 14:05:03 +053012024 qdf_status = wbuff_module_deinit();
12025 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
12026 hdd_err("WBUFF de-init unsuccessful; status: %d",
12027 qdf_status);
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053012028
Nirav Shah6aeecf92019-02-13 14:05:03 +053012029 hdd_component_pdev_close(hdd_ctx->pdev);
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053012030
Nirav Shah6aeecf92019-02-13 14:05:03 +053012031 hdd_component_psoc_close(hdd_ctx->psoc);
12032 dispatcher_pdev_close(hdd_ctx->pdev);
12033 ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
12034 if (ret) {
12035 hdd_err("Failed to destroy pdev; errno:%d", ret);
12036 QDF_ASSERT(0);
12037 }
Liangwei Dong50a64a72018-01-11 01:17:00 -050012038 }
12039
12040 /*
12041 * Reset total mac phy during module stop such that during
12042 * next module start same psoc is used to populate new service
12043 * ready data
12044 */
Dustin Brown1dbefe62018-09-11 16:32:03 -070012045 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
Arunk Khandavallia6305a32018-01-25 11:19:18 +053012046 if (tgt_hdl)
12047 target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0);
12048
Liangwei Dong50a64a72018-01-11 01:17:00 -050012049
Arun Khandavallifae92942016-08-01 13:31:08 +053012050 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
12051 if (!hif_ctx) {
12052 hdd_err("Hif context is Null");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053012053 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053012054 }
12055
Arunk Khandavalli4b404332017-09-26 12:46:00 +053012056 if (hdd_ctx->target_hw_name) {
12057 qdf_mem_free(hdd_ctx->target_hw_name);
12058 hdd_ctx->target_hw_name = NULL;
12059 }
12060
Lin Bai7bae1032019-04-30 12:29:36 +080012061 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
Visweswara Tanukuc949ad22019-03-20 13:00:30 +053012062 epping_disable();
12063 epping_close();
12064 }
12065
Sravan Kumar Kairam27296782017-04-21 22:04:18 +053012066 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053012067
12068 ol_cds_free();
12069
Dustin Brownc2a156e2018-10-25 16:56:27 -070012070 if (IS_IDLE_STOP) {
Arun Khandavallifae92942016-08-01 13:31:08 +053012071 ret = pld_power_off(qdf_ctx->dev);
12072 if (ret)
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070012073 hdd_err("Failed to power down device; errno:%d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053012074 }
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070012075
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012076 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
12077 wlan_hdd_free_cache_channels(hdd_ctx);
Ashish Kumar Dhanotiya64b3fa92019-07-23 15:50:10 +053012078 hdd_driver_mem_cleanup();
Arunk Khandavalli847969d2017-09-25 15:15:36 +053012079
Sourav Mohapatra9036f652019-04-02 15:02:59 +053012080 /* Free the resources allocated while storing SAR config. These needs
12081 * to be freed only in the case when it is not SSR. As in the case of
12082 * SSR, the values needs to be intact so that it can be restored during
12083 * reinit path.
12084 */
12085 if (!is_recovery_stop)
12086 wlan_hdd_free_sar_config(hdd_ctx);
12087
Jingxiang Ge3de02752019-01-29 15:47:03 +080012088 hdd_sap_destroy_ctx_all(hdd_ctx, is_recovery_stop);
12089
Dustin Brown29533f22018-07-24 13:11:56 -070012090 hdd_check_for_leaks(hdd_ctx, is_recovery_stop);
Dustin Brown26b3d042017-12-21 11:13:27 -080012091 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -080012092
Arunk Khandavalli847969d2017-09-25 15:15:36 +053012093 /* Once the firmware sequence is completed reset this flag */
12094 hdd_ctx->imps_enabled = false;
Arun Khandavallifae92942016-08-01 13:31:08 +053012095 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -080012096 hdd_info("Wlan transitioned (now CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +053012097
Kai Liueabb1df2018-11-08 14:58:54 +080012098 pld_request_bus_bandwidth(hdd_ctx->parent_dev, PLD_BUS_WIDTH_NONE);
12099
Arun Khandavallia172c3e2016-08-26 17:33:13 +053012100done:
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070012101 cds_set_module_stop_in_progress(false);
Dustin Brown4bc0a622017-12-06 15:56:50 -080012102
Dustin Browne74003f2018-03-14 12:51:58 -070012103 hdd_exit();
Arun Khandavallifae92942016-08-01 13:31:08 +053012104
Arun Khandavallia172c3e2016-08-26 17:33:13 +053012105 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053012106}
12107
Wen Gong3f003382018-05-14 14:26:37 +080012108#ifdef WLAN_FEATURE_MEMDUMP_ENABLE
Arun Khandavallifae92942016-08-01 13:31:08 +053012109/**
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012110 * hdd_state_info_dump() - prints state information of hdd layer
12111 * @buf: buffer pointer
12112 * @size: size of buffer to be filled
12113 *
12114 * This function is used to dump state information of hdd layer
12115 *
12116 * Return: None
12117 */
12118static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
12119{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012120 struct hdd_context *hdd_ctx;
Jeff Johnson40dae4e2017-08-29 14:00:25 -070012121 struct hdd_station_ctx *hdd_sta_ctx;
Jeff Johnson9d295242017-08-29 14:39:48 -070012122 struct hdd_adapter *adapter;
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012123 uint16_t len = 0;
12124 char *buf = *buf_ptr;
12125
12126 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12127 if (!hdd_ctx) {
12128 hdd_err("Failed to get hdd context ");
12129 return;
12130 }
12131
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012132 hdd_debug("size of buffer: %d", *size);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012133
12134 len += scnprintf(buf + len, *size - len,
Jeff Johnson214671b2017-10-30 19:45:23 -070012135 "\n is_wiphy_suspended %d", hdd_ctx->is_wiphy_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012136 len += scnprintf(buf + len, *size - len,
Rajeev Kumareada0d02016-12-08 17:44:17 -080012137 "\n is_scheduler_suspended %d",
12138 hdd_ctx->is_scheduler_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012139
Dustin Brown920397d2017-12-13 16:27:50 -080012140 hdd_for_each_adapter(hdd_ctx, adapter) {
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012141 if (adapter->dev)
12142 len += scnprintf(buf + len, *size - len,
12143 "\n device name: %s", adapter->dev->name);
wadesong42968e92017-06-08 14:11:21 +080012144 len += scnprintf(buf + len, *size - len,
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012145 "\n device_mode: %d", adapter->device_mode);
12146 switch (adapter->device_mode) {
12147 case QDF_STA_MODE:
12148 case QDF_P2P_CLIENT_MODE:
12149 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
12150 len += scnprintf(buf + len, *size - len,
Jeff Johnsone7951512019-02-27 10:02:51 -080012151 "\n conn_state: %d",
12152 hdd_sta_ctx->conn_info.conn_state);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012153 break;
12154
12155 default:
12156 break;
12157 }
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012158 }
12159
12160 *size -= len;
12161 *buf_ptr += len;
12162}
12163
12164/**
12165 * hdd_register_debug_callback() - registration function for hdd layer
12166 * to print hdd state information
12167 *
12168 * Return: None
12169 */
12170static void hdd_register_debug_callback(void)
12171{
12172 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
12173}
Wen Gong3f003382018-05-14 14:26:37 +080012174#else /* WLAN_FEATURE_MEMDUMP_ENABLE */
Wen Gongaa6d55d2018-04-26 16:33:21 +080012175static void hdd_register_debug_callback(void)
12176{
12177}
Wen Gong3f003382018-05-14 14:26:37 +080012178#endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012179
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053012180/*
12181 * wlan_init_bug_report_lock() - Initialize bug report lock
12182 *
12183 * This function is used to create bug report lock
12184 *
12185 * Return: None
12186 */
12187static void wlan_init_bug_report_lock(void)
12188{
Jeff Johnson2b6982c2018-05-29 14:56:11 -070012189 struct cds_context *p_cds_context;
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053012190
12191 p_cds_context = cds_get_global_context();
12192 if (!p_cds_context) {
12193 hdd_err("cds context is NULL");
12194 return;
12195 }
12196
12197 qdf_spinlock_create(&p_cds_context->bug_report_lock);
12198}
12199
Nirav Shahd21a2e32018-04-20 16:34:43 +053012200#ifdef CONFIG_DP_TRACE
Mohit Khannaf8f96822017-05-17 17:11:59 -070012201void hdd_dp_trace_init(struct hdd_config *config)
12202{
Mohit Khannaf8f96822017-05-17 17:11:59 -070012203 bool live_mode = DP_TRACE_CONFIG_DEFAULT_LIVE_MODE;
12204 uint8_t thresh = DP_TRACE_CONFIG_DEFAULT_THRESH;
12205 uint16_t thresh_time_limit = DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT;
12206 uint8_t verbosity = DP_TRACE_CONFIG_DEFAULT_VERBOSTY;
12207 uint8_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP;
12208 uint8_t config_params[DP_TRACE_CONFIG_NUM_PARAMS];
12209 uint8_t num_entries = 0;
Lin Baiaa7f8d72017-10-18 17:23:45 +080012210 uint32_t bw_compute_interval;
Mohit Khannaf8f96822017-05-17 17:11:59 -070012211
Nirav Shahd21a2e32018-04-20 16:34:43 +053012212 if (!config->enable_dp_trace) {
12213 hdd_err("dp trace is disabled from ini");
12214 return;
12215 }
12216
Mohit Khannaf8f96822017-05-17 17:11:59 -070012217 hdd_string_to_u8_array(config->dp_trace_config, config_params,
12218 &num_entries, sizeof(config_params));
12219
12220 /* calculating, num bw timer intervals in a second (1000ms) */
Lin Baiaa7f8d72017-10-18 17:23:45 +080012221 bw_compute_interval = GET_BW_COMPUTE_INTV(config);
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080012222 if (bw_compute_interval <= 1000 && bw_compute_interval > 0)
Lin Baiaa7f8d72017-10-18 17:23:45 +080012223 thresh_time_limit = 1000 / bw_compute_interval;
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080012224 else if (bw_compute_interval > 1000) {
12225 hdd_err("busBandwidthComputeInterval > 1000, using 1000");
12226 thresh_time_limit = 1;
12227 } else
Mohit Khannaf8f96822017-05-17 17:11:59 -070012228 hdd_err("busBandwidthComputeInterval is 0, using defaults");
12229
12230 switch (num_entries) {
12231 case 4:
12232 proto_bitmap = config_params[3];
Alok Kumarb5a33a22018-05-07 18:09:14 +053012233 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070012234 case 3:
12235 verbosity = config_params[2];
Alok Kumarb5a33a22018-05-07 18:09:14 +053012236 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070012237 case 2:
12238 thresh = config_params[1];
Alok Kumarb5a33a22018-05-07 18:09:14 +053012239 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070012240 case 1:
12241 live_mode = config_params[0];
Alok Kumarb5a33a22018-05-07 18:09:14 +053012242 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070012243 default:
Dustin Browna7bb6ae2018-08-16 16:51:50 -070012244 hdd_debug("live_mode %u thresh %u time_limit %u verbosity %u bitmap 0x%x",
12245 live_mode, thresh, thresh_time_limit,
12246 verbosity, proto_bitmap);
Mohit Khannaf8f96822017-05-17 17:11:59 -070012247 };
12248
12249 qdf_dp_trace_init(live_mode, thresh, thresh_time_limit,
12250 verbosity, proto_bitmap);
12251
12252}
Nirav Shahd21a2e32018-04-20 16:34:43 +053012253#endif
12254
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012255#ifdef DISABLE_CHANNEL_LIST
Dustin Brown623e7e32018-09-05 14:27:50 -070012256static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012257{
12258 return qdf_mutex_create(&hdd_ctx->cache_channel_lock);
12259}
12260#else
Dustin Brown623e7e32018-09-05 14:27:50 -070012261static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012262{
Dustin Brown623e7e32018-09-05 14:27:50 -070012263 return QDF_STATUS_SUCCESS;
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012264}
12265#endif
12266
Dustin Brown693b5352019-01-17 10:00:31 -080012267static QDF_STATUS hdd_open_adapter_no_trans(struct hdd_context *hdd_ctx,
12268 enum QDF_OPMODE op_mode,
12269 const char *iface_name,
12270 uint8_t *mac_addr_bytes)
12271{
Dustin Brown2c5e0482019-02-05 16:14:43 -080012272 struct osif_vdev_sync *vdev_sync;
Dustin Brown693b5352019-01-17 10:00:31 -080012273 struct hdd_adapter *adapter;
12274 QDF_STATUS status;
12275 int errno;
12276
12277 QDF_BUG(rtnl_is_locked());
Dustin Brown693b5352019-01-17 10:00:31 -080012278
Dustin Brown2c5e0482019-02-05 16:14:43 -080012279 errno = osif_vdev_sync_create(hdd_ctx->parent_dev, &vdev_sync);
Dustin Brown693b5352019-01-17 10:00:31 -080012280 if (errno)
12281 return qdf_status_from_os_return(errno);
12282
12283 adapter = hdd_open_adapter(hdd_ctx, op_mode, iface_name,
12284 mac_addr_bytes, NET_NAME_UNKNOWN, true);
12285 if (!adapter) {
12286 status = QDF_STATUS_E_INVAL;
12287 goto destroy_sync;
12288 }
12289
Dustin Brown2c5e0482019-02-05 16:14:43 -080012290 osif_vdev_sync_register(adapter->dev, vdev_sync);
Dustin Brown693b5352019-01-17 10:00:31 -080012291
12292 return QDF_STATUS_SUCCESS;
12293
12294destroy_sync:
Dustin Brown2c5e0482019-02-05 16:14:43 -080012295 osif_vdev_sync_destroy(vdev_sync);
Dustin Brown693b5352019-01-17 10:00:31 -080012296
12297 return status;
12298}
12299
12300#ifdef WLAN_OPEN_P2P_INTERFACE
12301/**
12302 * hdd_open_p2p_interface - Open P2P interface
12303 * @hdd_ctx: HDD context
12304 *
12305 * Return: QDF_STATUS
12306 */
12307static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
12308{
12309 QDF_STATUS status;
12310 bool p2p_dev_addr_admin;
12311 bool is_p2p_locally_administered = false;
12312
12313 cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
12314
12315 if (p2p_dev_addr_admin) {
12316 if (hdd_ctx->num_provisioned_addr &&
12317 !(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) {
12318 hdd_ctx->p2p_device_address =
12319 hdd_ctx->provisioned_mac_addr[0];
12320
12321 /*
12322 * Generate the P2P Device Address. This consists of
12323 * the device's primary MAC address with the locally
12324 * administered bit set.
12325 */
12326
12327 hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
12328 is_p2p_locally_administered = true;
12329 } else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) {
12330 hdd_ctx->p2p_device_address =
12331 hdd_ctx->derived_mac_addr[0];
12332 /*
12333 * Generate the P2P Device Address. This consists of
12334 * the device's primary MAC address with the locally
12335 * administered bit set.
12336 */
12337 hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
12338 is_p2p_locally_administered = true;
12339 }
12340 }
12341 if (!is_p2p_locally_administered) {
12342 uint8_t *p2p_dev_addr;
12343
12344 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx,
12345 QDF_P2P_DEVICE_MODE);
12346 if (!p2p_dev_addr) {
12347 hdd_err("Failed to get MAC address for new p2p device");
12348 return QDF_STATUS_E_INVAL;
12349 }
12350
12351 qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
12352 p2p_dev_addr, QDF_MAC_ADDR_SIZE);
12353 }
12354
12355 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_P2P_DEVICE_MODE,
12356 "p2p%d",
12357 hdd_ctx->p2p_device_address.bytes);
12358 if (QDF_IS_STATUS_ERROR(status)) {
12359 hdd_err("Failed to open p2p interface");
12360 return QDF_STATUS_E_INVAL;
12361 }
12362
12363 return QDF_STATUS_SUCCESS;
12364}
12365#else
12366static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
12367{
12368 return QDF_STATUS_SUCCESS;
12369}
12370#endif
12371
12372static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
12373{
12374 QDF_STATUS status;
12375 uint8_t *mac_addr;
12376
12377 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE);
12378 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE,
12379 "wlanocb%d", mac_addr);
12380 if (QDF_IS_STATUS_ERROR(status))
12381 hdd_err("Failed to open 802.11p interface");
12382
12383 return status;
12384}
12385
12386static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
12387{
12388 QDF_STATUS status;
12389 const char *iface_name;
12390 uint8_t *mac_addr;
12391
12392 if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, ""))
12393 return QDF_STATUS_SUCCESS;
12394
12395 iface_name = hdd_ctx->config->enable_concurrent_sta;
12396 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
12397 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
12398 iface_name, mac_addr);
12399 if (QDF_IS_STATUS_ERROR(status))
12400 hdd_err("Failed to open concurrent station interface");
12401
12402 return status;
12403}
12404
Dustin Brown61cc3932018-10-18 16:12:13 -070012405static QDF_STATUS
12406hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
Dustin Browna2deeb72018-10-18 14:19:27 -070012407{
Dustin Browna2deeb72018-10-18 14:19:27 -070012408 enum dot11p_mode dot11p_mode;
Dustin Brown61cc3932018-10-18 16:12:13 -070012409 QDF_STATUS status;
Dustin Brown693b5352019-01-17 10:00:31 -080012410 uint8_t *mac_addr;
Dustin Browna2deeb72018-10-18 14:19:27 -070012411
12412 ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode);
12413
12414 /* Create only 802.11p interface? */
12415 if (dot11p_mode == CFG_11P_STANDALONE)
Dustin Brown61cc3932018-10-18 16:12:13 -070012416 return hdd_open_ocb_interface(hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070012417
Dustin Brown693b5352019-01-17 10:00:31 -080012418 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
12419 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
12420 "wlan%d", mac_addr);
12421 if (QDF_IS_STATUS_ERROR(status))
12422 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070012423
Dustin Brown61cc3932018-10-18 16:12:13 -070012424 /* opening concurrent STA is best effort, continue on error */
12425 hdd_open_concurrent_interface(hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070012426
Dustin Brown61cc3932018-10-18 16:12:13 -070012427 status = hdd_open_p2p_interface(hdd_ctx);
12428 if (status)
Dustin Browna2deeb72018-10-18 14:19:27 -070012429 goto err_close_adapters;
12430
12431 /* Open 802.11p Interface */
12432 if (dot11p_mode == CFG_11P_CONCURRENT) {
Dustin Brown61cc3932018-10-18 16:12:13 -070012433 status = hdd_open_ocb_interface(hdd_ctx);
12434 if (QDF_IS_STATUS_ERROR(status))
Dustin Browna2deeb72018-10-18 14:19:27 -070012435 goto err_close_adapters;
12436 }
12437
Dustin Brown61cc3932018-10-18 16:12:13 -070012438 return QDF_STATUS_SUCCESS;
Dustin Browna2deeb72018-10-18 14:19:27 -070012439
12440err_close_adapters:
12441 hdd_close_all_adapters(hdd_ctx, true);
12442
Dustin Brown61cc3932018-10-18 16:12:13 -070012443 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070012444}
12445
Dustin Brown61cc3932018-10-18 16:12:13 -070012446static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx)
Dustin Browna2deeb72018-10-18 14:19:27 -070012447{
Dustin Brown693b5352019-01-17 10:00:31 -080012448 uint8_t *mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE);
Dustin Brown61cc3932018-10-18 16:12:13 -070012449
Dustin Brown693b5352019-01-17 10:00:31 -080012450 return hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE,
12451 "wlan%d", mac_addr);
Dustin Brown61cc3932018-10-18 16:12:13 -070012452}
12453
12454static QDF_STATUS
12455hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx)
12456{
Dustin Brown693b5352019-01-17 10:00:31 -080012457 uint8_t *mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE);
Dustin Brown61cc3932018-10-18 16:12:13 -070012458
Dustin Brown693b5352019-01-17 10:00:31 -080012459 return hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE,
12460 "wlan%d", mac_addr);
Dustin Brown61cc3932018-10-18 16:12:13 -070012461}
12462
12463static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx)
12464{
Nirav Shah6aeecf92019-02-13 14:05:03 +053012465 epping_enable_adapter();
Dustin Brown61cc3932018-10-18 16:12:13 -070012466 return QDF_STATUS_SUCCESS;
Dustin Brown61cc3932018-10-18 16:12:13 -070012467}
12468
12469typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx);
12470
12471static const hdd_open_mode_handler
12472hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = {
12473 [QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode,
12474 [QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode,
12475 [QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode,
12476 [QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode,
12477};
12478
Dustin Brown92bd8382018-10-31 15:49:46 -070012479static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
12480 enum QDF_GLOBAL_MODE driver_mode)
Dustin Brown61cc3932018-10-18 16:12:13 -070012481{
12482 QDF_STATUS status;
12483
12484 if (driver_mode < 0 ||
12485 driver_mode >= QDF_GLOBAL_MAX_MODE ||
12486 !hdd_open_mode_handlers[driver_mode]) {
12487 hdd_err("Driver mode %d not supported", driver_mode);
12488 return -ENOTSUPP;
12489 }
Dustin Browna2deeb72018-10-18 14:19:27 -070012490
12491 hdd_hold_rtnl_lock();
Dustin Brown61cc3932018-10-18 16:12:13 -070012492 status = hdd_open_mode_handlers[driver_mode](hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070012493 hdd_release_rtnl_lock();
12494
Dustin Brown92bd8382018-10-31 15:49:46 -070012495 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070012496}
12497
Dustin Brown623e7e32018-09-05 14:27:50 -070012498int hdd_wlan_startup(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080012499{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012500 QDF_STATUS status;
Dustin Brown623e7e32018-09-05 14:27:50 -070012501 int errno;
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +053012502 bool is_imps_enabled;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080012503
Dustin Brown491d54b2018-03-14 12:39:11 -070012504 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080012505
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053012506 hdd_action_oui_config(hdd_ctx);
12507
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +053012508 qdf_nbuf_init_replenish_timer();
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012509
Dustin Brown623e7e32018-09-05 14:27:50 -070012510 status = wlan_hdd_cache_chann_mutex_create(hdd_ctx);
12511 if (QDF_IS_STATUS_ERROR(status))
12512 return qdf_status_to_os_return(status);
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053012513
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +053012514#ifdef FEATURE_WLAN_CH_AVOID
12515 mutex_init(&hdd_ctx->avoid_freq_lock);
12516#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053012517
Naveen Rawate02f8f52018-04-05 11:58:04 -070012518 osif_request_manager_init();
Dustin Brown021cecd2017-12-11 13:56:43 -080012519 hdd_driver_memdump_init();
Dustin Brown86d196b2018-08-02 11:51:49 -070012520 hdd_bus_bandwidth_init(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -080012521
Dustin Brown623e7e32018-09-05 14:27:50 -070012522 errno = hdd_wlan_start_modules(hdd_ctx, false);
12523 if (errno) {
12524 hdd_err("Failed to start modules; errno:%d", errno);
12525 goto memdump_deinit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012526 }
12527
Nirav Shah6aeecf92019-02-13 14:05:03 +053012528 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
12529 return 0;
12530
Yingying Tang80e15f32016-09-27 18:23:01 +080012531 wlan_hdd_update_wiphy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012532
Dustin Brown623e7e32018-09-05 14:27:50 -070012533 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
12534 if (!hdd_ctx->mac_handle) {
Jeff Johnson16528362018-06-14 12:34:16 -070012535 hdd_err("Mac Handle is null");
Dustin Brown623e7e32018-09-05 14:27:50 -070012536 goto stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012537 }
12538
Dustin Brown623e7e32018-09-05 14:27:50 -070012539 errno = hdd_wiphy_init(hdd_ctx);
12540 if (errno) {
12541 hdd_err("Failed to initialize wiphy; errno:%d", errno);
12542 goto stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012543 }
12544
Nirav Shahd21a2e32018-04-20 16:34:43 +053012545 hdd_dp_trace_init(hdd_ctx->config);
Nirav Shahcc1f1ae2016-04-26 11:41:29 +053012546
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053012547 errno = hdd_initialize_mac_address(hdd_ctx);
12548 if (errno) {
12549 hdd_err("MAC initializtion failed: %d", errno);
12550 goto unregister_wiphy;
12551 }
Prashanth Bhatta75fa9a12016-01-11 18:30:08 -080012552
Dustin Brown623e7e32018-09-05 14:27:50 -070012553 errno = register_netdevice_notifier(&hdd_netdev_notifier);
12554 if (errno) {
12555 hdd_err("register_netdevice_notifier failed; errno:%d", errno);
12556 goto unregister_wiphy;
Paul Zhangfb02f452017-12-22 11:58:43 +080012557 }
Arun Khandavalli08479ba2017-08-07 19:56:23 +053012558
Sandeep Puligilla34618782019-01-04 17:42:42 -080012559 wlan_hdd_update_11n_mode(hdd_ctx);
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080012560
Arunk Khandavalli40943af2017-05-15 19:25:34 +053012561 hdd_lpass_notify_wlan_version(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012562
Dustin Brown623e7e32018-09-05 14:27:50 -070012563 errno = hdd_register_notifiers(hdd_ctx);
12564 if (errno)
Arun Kumar Khandavalli4b6e2182019-04-29 18:32:09 +053012565 goto unregister_netdev;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -070012566
Paul Zhangfb02f452017-12-22 11:58:43 +080012567 status = wlansap_global_init();
Dustin Brown92bd8382018-10-31 15:49:46 -070012568 if (QDF_IS_STATUS_ERROR(status))
12569 goto unregister_notifiers;
Paul Zhangfb02f452017-12-22 11:58:43 +080012570
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +053012571 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
12572 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
Arun Kumar Khandavallideda5a82019-03-11 15:32:19 +053012573 hdd_debugfs_mws_coex_info_init(hdd_ctx);
Paul Zhang37185672019-05-14 11:20:14 +080012574 wlan_cfg80211_init_interop_issues_ap(hdd_ctx->pdev);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012575
Dustin Brown92bd8382018-10-31 15:49:46 -070012576 hdd_exit();
12577
12578 return 0;
12579
12580unregister_notifiers:
12581 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012582
Dustin Brown623e7e32018-09-05 14:27:50 -070012583unregister_netdev:
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053012584 unregister_netdevice_notifier(&hdd_netdev_notifier);
12585
Dustin Brown623e7e32018-09-05 14:27:50 -070012586unregister_wiphy:
Rachit Kankane30807332018-06-27 18:39:36 +053012587 qdf_dp_trace_deinit();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080012588 wiphy_unregister(hdd_ctx->wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012589
Dustin Brown623e7e32018-09-05 14:27:50 -070012590stop_modules:
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070012591 hdd_wlan_stop_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +053012592
Dustin Brown623e7e32018-09-05 14:27:50 -070012593memdump_deinit:
Dustin Brown86d196b2018-08-02 11:51:49 -070012594 hdd_bus_bandwidth_deinit(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -080012595 hdd_driver_memdump_deinit();
Naveen Rawate02f8f52018-04-05 11:58:04 -070012596 osif_request_manager_deinit();
Dustin Brown623e7e32018-09-05 14:27:50 -070012597 qdf_nbuf_deinit_replenish_timer();
Ryan Hsucfef0ae2016-04-28 10:20:46 -070012598
Nachiket Kukade8003d252017-03-30 15:55:58 +053012599 if (cds_is_fw_down())
12600 hdd_err("Not setting the complete event as fw is down");
12601 else
Dustin Brown623e7e32018-09-05 14:27:50 -070012602 hdd_start_complete(errno);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012603
Dustin Browne74003f2018-03-14 12:51:58 -070012604 hdd_exit();
Dustin Brown92bd8382018-10-31 15:49:46 -070012605
Dustin Brown623e7e32018-09-05 14:27:50 -070012606 return errno;
Dustin Brown92bd8382018-10-31 15:49:46 -070012607}
12608
12609QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx)
12610{
12611 enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam();
12612 QDF_STATUS status;
12613
12614 status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode);
12615 if (QDF_IS_STATUS_ERROR(status)) {
12616 hdd_err("Failed to create vdevs; status:%d", status);
12617 return status;
12618 }
12619
12620 if (hdd_ctx->rps)
12621 hdd_set_rps_cpu_mask(hdd_ctx);
12622
Guisen Yang2780b922019-06-03 16:21:39 +080012623 if (driver_mode != QDF_GLOBAL_FTM_MODE &&
12624 driver_mode != QDF_GLOBAL_EPPING_MODE)
Dustin Brown92bd8382018-10-31 15:49:46 -070012625 hdd_psoc_idle_timer_start(hdd_ctx);
12626
12627 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012628}
12629
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012630/**
Arun Khandavallifae92942016-08-01 13:31:08 +053012631 * hdd_wlan_update_target_info() - update target type info
12632 * @hdd_ctx: HDD context
12633 * @context: hif context
12634 *
12635 * Update target info received from firmware in hdd context
12636 * Return:None
12637 */
12638
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012639void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
Arun Khandavallifae92942016-08-01 13:31:08 +053012640{
12641 struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
12642
12643 if (!tgt_info) {
12644 hdd_err("Target info is Null");
12645 return;
12646 }
12647
12648 hdd_ctx->target_type = tgt_info->target_type;
12649}
12650
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053012651void hdd_get_nud_stats_cb(void *data, struct rsp_stats *rsp, void *context)
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012652{
12653 struct hdd_context *hdd_ctx = (struct hdd_context *)data;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012654 int status;
12655 struct hdd_adapter *adapter = NULL;
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012656 struct osif_request *request = NULL;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012657
Dustin Brown491d54b2018-03-14 12:39:11 -070012658 hdd_enter();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012659
12660 if (!rsp) {
12661 hdd_err("data is null");
12662 return;
12663 }
12664
12665 status = wlan_hdd_validate_context(hdd_ctx);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053012666 if (status != 0)
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012667 return;
12668
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012669 request = osif_request_get(context);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053012670 if (!request) {
12671 hdd_err("obselete request");
12672 return;
12673 }
12674
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012675 adapter = hdd_get_adapter_by_vdev(hdd_ctx, rsp->vdev_id);
Jeff Johnsond36fa332019-03-18 13:42:25 -070012676 if ((!adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012677 hdd_err("Invalid adapter or adapter has invalid magic");
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012678 osif_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012679 return;
12680 }
12681
Alok Kumarce2c29a2018-10-12 15:44:02 +053012682 hdd_debug("rsp->arp_req_enqueue :%x", rsp->arp_req_enqueue);
12683 hdd_debug("rsp->arp_req_tx_success :%x", rsp->arp_req_tx_success);
12684 hdd_debug("rsp->arp_req_tx_failure :%x", rsp->arp_req_tx_failure);
12685 hdd_debug("rsp->arp_rsp_recvd :%x", rsp->arp_rsp_recvd);
12686 hdd_debug("rsp->out_of_order_arp_rsp_drop_cnt :%x",
12687 rsp->out_of_order_arp_rsp_drop_cnt);
12688 hdd_debug("rsp->dad_detected :%x", rsp->dad_detected);
12689 hdd_debug("rsp->connect_status :%x", rsp->connect_status);
12690 hdd_debug("rsp->ba_session_establishment_status :%x",
12691 rsp->ba_session_establishment_status);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012692
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012693 adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012694 adapter->dad |= rsp->dad_detected;
12695 adapter->con_status = rsp->connect_status;
12696
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053012697 /* Flag true indicates connectivity check stats present. */
12698 if (rsp->connect_stats_present) {
Alok Kumarce2c29a2018-10-12 15:44:02 +053012699 hdd_debug("rsp->tcp_ack_recvd :%x", rsp->tcp_ack_recvd);
12700 hdd_debug("rsp->icmpv4_rsp_recvd :%x", rsp->icmpv4_rsp_recvd);
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053012701 adapter->hdd_stats.hdd_tcp_stats.rx_fw_cnt = rsp->tcp_ack_recvd;
12702 adapter->hdd_stats.hdd_icmpv4_stats.rx_fw_cnt =
12703 rsp->icmpv4_rsp_recvd;
12704 }
12705
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012706 osif_request_complete(request);
12707 osif_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012708
Dustin Browne74003f2018-03-14 12:51:58 -070012709 hdd_exit();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012710}
12711
Visweswara Tanuku633976b2019-01-07 16:13:12 +053012712#ifdef WLAN_FEATURE_MOTION_DETECTION
12713/**
12714 * hdd_md_host_evt_cb - Callback for Motion Detection Event
12715 * @ctx: HDD context
12716 * @event: motion detect event
12717 *
12718 * Callback for Motion Detection Event. Re-enables Motion
12719 * Detection again upon event
12720 *
12721 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
12722 * QDF_STATUS_E_FAILURE on failure
12723 */
12724QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event)
12725{
12726 struct hdd_adapter *adapter = NULL;
12727 struct hdd_context *hdd_ctx;
12728 QDF_STATUS status;
12729 struct sme_motion_det_en motion_det;
12730
12731 if (!ctx || !event)
12732 return QDF_STATUS_E_INVAL;
12733
12734 hdd_ctx = (struct hdd_context *)ctx;
12735 status = wlan_hdd_validate_context(hdd_ctx);
12736 if (0 != status)
12737 return QDF_STATUS_E_INVAL;
12738
12739 adapter = hdd_get_adapter_by_vdev(hdd_ctx, event->vdev_id);
12740 if (!adapter || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
12741 hdd_err("Invalid adapter or adapter has invalid magic");
12742 return QDF_STATUS_E_INVAL;
12743 }
12744
12745 hdd_debug("Motion Detection CB vdev_id=%u, status=%u",
12746 event->vdev_id, event->status);
12747
12748 if (adapter->motion_detection_mode) {
12749 motion_det.vdev_id = event->vdev_id;
12750 motion_det.enable = 1;
12751 hdd_debug("Motion Detect CB -> Enable Motion Detection again");
12752 sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det);
12753 }
12754
12755 return QDF_STATUS_SUCCESS;
12756}
12757#endif /* WLAN_FEATURE_MOTION_DETECTION */
12758
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012759/**
Arun Khandavallifae92942016-08-01 13:31:08 +053012760 * hdd_register_cb - Register HDD callbacks.
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012761 * @hdd_ctx: HDD context
12762 *
12763 * Register the HDD callbacks to CDS/SME.
12764 *
12765 * Return: 0 for success or Error code for failure
12766 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012767int hdd_register_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012768{
12769 QDF_STATUS status;
12770 int ret = 0;
Jeff Johnson16528362018-06-14 12:34:16 -070012771 mac_handle_t mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012772
Dustin Brown491d54b2018-03-14 12:39:11 -070012773 hdd_enter();
Sourav Mohapatra674925f2018-04-16 11:16:58 +053012774 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
12775 hdd_err("in ftm mode, no need to register callbacks");
12776 return ret;
12777 }
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012778
Jeff Johnson16528362018-06-14 12:34:16 -070012779 mac_handle = hdd_ctx->mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012780
Jeff Johnson16528362018-06-14 12:34:16 -070012781 sme_register_oem_data_rsp_callback(mac_handle,
12782 hdd_send_oem_data_rsp_msg);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012783
Jeff Johnson16528362018-06-14 12:34:16 -070012784 sme_register_mgmt_frame_ind_callback(mac_handle,
Deepthi Gowrid5a58fe2016-09-03 16:01:28 +053012785 hdd_indicate_mgmt_frame);
Jeff Johnson16528362018-06-14 12:34:16 -070012786 sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx);
Jeff Johnson16528362018-06-14 12:34:16 -070012787 sme_stats_ext_register_callback(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012788 wlan_hdd_cfg80211_stats_ext_callback);
12789
Jeff Johnson16528362018-06-14 12:34:16 -070012790 sme_ext_scan_register_callback(mac_handle,
12791 wlan_hdd_cfg80211_extscan_callback);
12792 sme_stats_ext2_register_callback(mac_handle,
lifeng66831662017-05-19 16:01:35 +080012793 wlan_hdd_cfg80211_stats_ext2_callback);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012794
Jeff Johnson16528362018-06-14 12:34:16 -070012795 sme_set_rssi_threshold_breached_cb(mac_handle,
12796 hdd_rssi_threshold_breached);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012797
Jeff Johnson16528362018-06-14 12:34:16 -070012798 sme_set_link_layer_stats_ind_cb(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012799 wlan_hdd_cfg80211_link_layer_stats_callback);
12800
Jeff Johnson16528362018-06-14 12:34:16 -070012801 sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb);
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +053012802
Jeff Johnson16528362018-06-14 12:34:16 -070012803 sme_set_link_layer_ext_cb(mac_handle,
Zhang Qianca38fb12016-12-23 11:10:48 +080012804 wlan_hdd_cfg80211_link_layer_stats_ext_callback);
Abhinav Kumar338e57d2019-02-04 17:30:10 +053012805 sme_update_hidden_ssid_status_cb(mac_handle,
12806 hdd_hidden_ssid_enable_roaming);
Zhang Qianca38fb12016-12-23 11:10:48 +080012807
Jeff Johnson16528362018-06-14 12:34:16 -070012808 status = sme_set_lost_link_info_cb(mac_handle,
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +053012809 hdd_lost_link_info_cb);
Ashish Kumar Dhanotiya017e5022019-07-23 20:58:11 +053012810
12811 wlan_hdd_register_cp_stats_cb(hdd_ctx);
12812
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +053012813 /* print error and not block the startup process */
12814 if (!QDF_IS_STATUS_SUCCESS(status))
12815 hdd_err("set lost link info callback failed");
12816
Poddar, Siddarth34872782017-08-10 14:08:51 +053012817 ret = hdd_register_data_stall_detect_cb();
12818 if (ret) {
12819 hdd_err("Register data stall detect detect callback failed.");
12820 return ret;
12821 }
12822
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012823 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
12824
Jeff Johnson16528362018-06-14 12:34:16 -070012825 sme_register_set_connection_info_cb(mac_handle,
12826 hdd_set_connection_in_progress,
12827 hdd_is_connection_in_progress);
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +053012828
Jeff Johnson16528362018-06-14 12:34:16 -070012829 status = sme_set_bt_activity_info_cb(mac_handle,
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053012830 hdd_bt_activity_cb);
12831 if (!QDF_IS_STATUS_SUCCESS(status))
12832 hdd_err("set bt activity info callback failed");
12833
Jeff Johnson16528362018-06-14 12:34:16 -070012834 status = sme_register_tx_queue_cb(mac_handle,
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -080012835 hdd_tx_queue_cb);
12836 if (!QDF_IS_STATUS_SUCCESS(status))
12837 hdd_err("Register tx queue callback failed");
12838
Visweswara Tanuku633976b2019-01-07 16:13:12 +053012839#ifdef WLAN_FEATURE_MOTION_DETECTION
12840 sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx);
12841#endif /* WLAN_FEATURE_MOTION_DETECTION */
12842
Dustin Browne74003f2018-03-14 12:51:58 -070012843 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012844
12845 return ret;
12846}
12847
12848/**
12849 * hdd_deregister_cb() - De-Register HDD callbacks.
12850 * @hdd_ctx: HDD context
12851 *
12852 * De-Register the HDD callbacks to CDS/SME.
12853 *
12854 * Return: void
12855 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012856void hdd_deregister_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012857{
12858 QDF_STATUS status;
Poddar, Siddarth34872782017-08-10 14:08:51 +053012859 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -070012860 mac_handle_t mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012861
Dustin Brown491d54b2018-03-14 12:39:11 -070012862 hdd_enter();
Sourav Mohapatra674925f2018-04-16 11:16:58 +053012863 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
12864 hdd_err("in ftm mode, no need to deregister callbacks");
12865 return;
12866 }
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012867
Jeff Johnson16528362018-06-14 12:34:16 -070012868 mac_handle = hdd_ctx->mac_handle;
12869 sme_deregister_tx_queue_cb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012870
Jeff Johnson16528362018-06-14 12:34:16 -070012871 sme_reset_link_layer_stats_ind_cb(mac_handle);
12872 sme_reset_rssi_threshold_breached_cb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012873
Min Liud35ae312019-05-08 15:43:13 +080012874 sme_stats_ext_deregister_callback(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012875
Jeff Johnson16528362018-06-14 12:34:16 -070012876 status = sme_reset_tsfcb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012877 if (!QDF_IS_STATUS_SUCCESS(status))
12878 hdd_err("Failed to de-register tsfcb the callback:%d",
12879 status);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012880
Poddar, Siddarth34872782017-08-10 14:08:51 +053012881 ret = hdd_deregister_data_stall_detect_cb();
12882 if (ret)
12883 hdd_err("Failed to de-register data stall detect event callback");
12884
Jeff Johnson16528362018-06-14 12:34:16 -070012885 sme_deregister_oem_data_rsp_callback(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012886
Dustin Browne74003f2018-03-14 12:51:58 -070012887 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012888}
12889
12890/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012891 * hdd_softap_sta_deauth() - handle deauth req from HDD
Jeff Johnson50e37e92019-03-08 11:32:25 -080012892 * @adapter: Pointer to the HDD adapter
12893 * @param: Params to the operation
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012894 *
12895 * This to take counter measure to handle deauth req from HDD
12896 *
12897 * Return: None
12898 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012899QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
Jeff Johnson50e37e92019-03-08 11:32:25 -080012900 struct csr_del_sta_params *param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012901{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012902 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012903
Dustin Brown491d54b2018-03-14 12:39:11 -070012904 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012905
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012906 /* Ignore request to deauth bcmc station */
Jeff Johnson50e37e92019-03-08 11:32:25 -080012907 if (param->peerMacAddr.bytes[0] & 0x1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012908 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012909
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012910 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012911 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Jeff Johnson50e37e92019-03-08 11:32:25 -080012912 param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012913
Dustin Browne74003f2018-03-14 12:51:58 -070012914 hdd_exit();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012915 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012916}
12917
12918/**
12919 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
Jeff Johnson50e37e92019-03-08 11:32:25 -080012920 * @adapter: Pointer to the HDD
12921 * @param: pointer to station deletion parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012922 *
12923 * This to take counter measure to handle deauth req from HDD
12924 *
12925 * Return: None
12926 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012927void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
Jeff Johnson50e37e92019-03-08 11:32:25 -080012928 struct csr_del_sta_params *param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012929{
Dustin Brown491d54b2018-03-14 12:39:11 -070012930 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012931
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012932 /* Ignore request to disassoc bcmc station */
Jeff Johnson50e37e92019-03-08 11:32:25 -080012933 if (param->peerMacAddr.bytes[0] & 0x1)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012934 return;
12935
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012936 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Jeff Johnson50e37e92019-03-08 11:32:25 -080012937 param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012938}
12939
Abhinav Kumar523ca372019-08-30 16:28:19 +053012940void wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter,
12941 uint32_t mlme_operation_requestor)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012942{
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012943 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
12944 struct hdd_adapter *adapter = NULL;
12945 struct csr_roam_profile *roam_profile;
12946 struct hdd_station_ctx *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012947
Dustin Brown1dbefe62018-09-11 16:32:03 -070012948 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012949 hdd_debug("No active sta session");
12950 return;
12951 }
12952
12953 hdd_for_each_adapter(hdd_ctx, adapter) {
12954 roam_profile = hdd_roam_profile(adapter);
12955 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
12956
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012957 if (cur_adapter->vdev_id != adapter->vdev_id &&
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012958 adapter->device_mode == QDF_STA_MODE &&
12959 hdd_conn_is_connected(sta_ctx)) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012960 hdd_debug("%d Disable roaming", adapter->vdev_id);
Jeff Johnson16528362018-06-14 12:34:16 -070012961 sme_stop_roaming(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012962 adapter->vdev_id,
Abhinav Kumar523ca372019-08-30 16:28:19 +053012963 REASON_DRIVER_DISABLED,
12964 mlme_operation_requestor);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012965 }
12966 }
12967}
12968
Abhinav Kumar523ca372019-08-30 16:28:19 +053012969void wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter,
12970 uint32_t mlme_operation_requestor)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012971{
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012972 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
12973 struct hdd_adapter *adapter = NULL;
12974 struct csr_roam_profile *roam_profile;
12975 struct hdd_station_ctx *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012976
Dustin Brown1dbefe62018-09-11 16:32:03 -070012977 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012978 hdd_debug("No active sta session");
12979 return;
12980 }
12981
12982 hdd_for_each_adapter(hdd_ctx, adapter) {
12983 roam_profile = hdd_roam_profile(adapter);
12984 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
12985
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012986 if (cur_adapter->vdev_id != adapter->vdev_id &&
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012987 adapter->device_mode == QDF_STA_MODE &&
12988 hdd_conn_is_connected(sta_ctx)) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012989 hdd_debug("%d Enable roaming", adapter->vdev_id);
Jeff Johnson16528362018-06-14 12:34:16 -070012990 sme_start_roaming(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012991 adapter->vdev_id,
Abhinav Kumar523ca372019-08-30 16:28:19 +053012992 REASON_DRIVER_ENABLED,
12993 mlme_operation_requestor);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012994 }
12995 }
12996}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012997
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053012998/**
12999 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
13000 * @skb: sk buffer pointer
13001 *
13002 * Sends the bcast message to SVC multicast group with generic nl socket
13003 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
13004 *
13005 * Return: None
13006 */
13007static void nl_srv_bcast_svc(struct sk_buff *skb)
13008{
13009#ifdef CNSS_GENL
13010 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
13011#else
13012 nl_srv_bcast(skb);
13013#endif
13014}
13015
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013016void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013017{
13018 struct sk_buff *skb;
13019 struct nlmsghdr *nlh;
13020 tAniMsgHdr *ani_hdr;
13021 void *nl_data = NULL;
13022 int flags = GFP_KERNEL;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013023 struct radio_index_tlv *radio_info;
13024 int tlv_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013025
13026 if (in_interrupt() || irqs_disabled() || in_atomic())
13027 flags = GFP_ATOMIC;
13028
13029 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
13030
Jeff Johnsond36fa332019-03-18 13:42:25 -070013031 if (!skb)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013032 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013033
13034 nlh = (struct nlmsghdr *)skb->data;
13035 nlh->nlmsg_pid = 0; /* from kernel */
13036 nlh->nlmsg_flags = 0;
13037 nlh->nlmsg_seq = 0;
13038 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
13039
13040 ani_hdr = NLMSG_DATA(nlh);
13041 ani_hdr->type = type;
13042
13043 switch (type) {
13044 case WLAN_SVC_FW_CRASHED_IND:
Komal Seelam78ff65a2016-08-18 15:25:24 +053013045 case WLAN_SVC_FW_SHUTDOWN_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013046 case WLAN_SVC_LTE_COEX_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013047 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070013048 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013049 ani_hdr->length = 0;
13050 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013051 break;
13052 case WLAN_SVC_WLAN_STATUS_IND:
13053 case WLAN_SVC_WLAN_VERSION_IND:
13054 case WLAN_SVC_DFS_CAC_START_IND:
13055 case WLAN_SVC_DFS_CAC_END_IND:
13056 case WLAN_SVC_DFS_RADAR_DETECT_IND:
13057 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
13058 case WLAN_SVC_WLAN_TP_IND:
Mohit Khannae71e2262015-11-10 09:37:24 -080013059 case WLAN_SVC_WLAN_TP_TX_IND:
Nirav Shahbd36b062016-07-18 11:12:59 +053013060 case WLAN_SVC_RPS_ENABLE_IND:
Orhan K AKYILDIZe7445a22017-01-19 21:21:47 -080013061 case WLAN_SVC_CORE_MINFREQ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013062 ani_hdr->length = len;
13063 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
13064 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
13065 memcpy(nl_data, data, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013066 break;
13067
13068 default:
Jeff Johnson34c88b72016-08-15 14:27:11 -070013069 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013070 type);
13071 kfree_skb(skb);
13072 return;
13073 }
13074
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013075 /*
Jeff Johnson0d52c7a2017-01-12 08:46:55 -080013076 * Add radio index at the end of the svc event in TLV format
13077 * to maintain the backward compatibility with userspace
13078 * applications.
13079 */
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013080
13081 tlv_len = 0;
13082
13083 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
13084 < WLAN_NL_MAX_PAYLOAD) {
13085 radio_info = (struct radio_index_tlv *)((char *) ani_hdr +
13086 sizeof(*ani_hdr) + len);
13087 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
13088 radio_info->length = (unsigned short) sizeof(radio_info->radio);
13089 radio_info->radio = radio;
13090 tlv_len = sizeof(*radio_info);
Dustin Browna2868622018-03-20 11:38:14 -070013091 hdd_debug("Added radio index tlv - radio index %d",
13092 radio_info->radio);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013093 }
13094
13095 nlh->nlmsg_len += tlv_len;
13096 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
13097
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053013098 nl_srv_bcast_svc(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013099}
13100
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013101#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
13102void wlan_hdd_auto_shutdown_cb(void)
13103{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013104 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013105
13106 if (!hdd_ctx)
13107 return;
13108
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013109 hdd_debug("Wlan Idle. Sending Shutdown event..");
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013110 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
13111 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013112}
13113
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013114void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013115{
Jeff Johnson9d295242017-08-29 14:39:48 -070013116 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013117 bool ap_connected = false, sta_connected = false;
Jeff Johnson16528362018-06-14 12:34:16 -070013118 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013119
Jeff Johnson16528362018-06-14 12:34:16 -070013120 mac_handle = hdd_ctx->mac_handle;
13121 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013122 return;
13123
Dundi Raviteja8e338282018-09-25 17:16:04 +053013124 if (hdd_ctx->config->wlan_auto_shutdown == 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013125 return;
13126
13127 if (enable == false) {
Jeff Johnson16528362018-06-14 12:34:16 -070013128 if (sme_set_auto_shutdown_timer(mac_handle, 0) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053013129 QDF_STATUS_SUCCESS) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070013130 hdd_err("Failed to stop wlan auto shutdown timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013131 }
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053013132 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070013133 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013134 return;
13135 }
13136
13137 /* To enable shutdown timer check conncurrency */
Dustin Brown1dbefe62018-09-11 16:32:03 -070013138 if (policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc)) {
Dustin Brown920397d2017-12-13 16:27:50 -080013139 hdd_for_each_adapter(hdd_ctx, adapter) {
13140 if (adapter->device_mode == QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013141 if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
Jeff Johnsone7951512019-02-27 10:02:51 -080013142 conn_info.conn_state ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013143 eConnectionState_Associated) {
13144 sta_connected = true;
13145 break;
13146 }
13147 }
Dustin Brown920397d2017-12-13 16:27:50 -080013148
13149 if (adapter->device_mode == QDF_SAP_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013150 if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
Jeff Johnson136c51b2017-10-27 20:02:41 -070013151 ap_active == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013152 ap_connected = true;
13153 break;
13154 }
13155 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013156 }
13157 }
13158
13159 if (ap_connected == true || sta_connected == true) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013160 hdd_debug("CC Session active. Shutdown timer not enabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013161 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013162 }
Jeff Johnson68755312017-02-10 11:46:55 -080013163
Jeff Johnson16528362018-06-14 12:34:16 -070013164 if (sme_set_auto_shutdown_timer(mac_handle,
Dundi Raviteja8e338282018-09-25 17:16:04 +053013165 hdd_ctx->config->wlan_auto_shutdown)
Jeff Johnson68755312017-02-10 11:46:55 -080013166 != QDF_STATUS_SUCCESS)
13167 hdd_err("Failed to start wlan auto shutdown timer");
13168 else
Dustin Brown5e89ef82018-03-14 11:50:23 -070013169 hdd_info("Auto Shutdown timer for %d seconds enabled",
Dundi Raviteja8e338282018-09-25 17:16:04 +053013170 hdd_ctx->config->wlan_auto_shutdown);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013171}
13172#endif
13173
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070013174struct hdd_adapter *
13175hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
13176 bool check_start_bss)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013177{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013178 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070013179 struct hdd_adapter *adapter, *con_sap_adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013180
13181 con_sap_adapter = NULL;
13182
Dustin Brown920397d2017-12-13 16:27:50 -080013183 hdd_for_each_adapter(hdd_ctx, adapter) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080013184 if (adapter && ((adapter->device_mode == QDF_SAP_MODE) ||
13185 (adapter->device_mode == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013186 adapter != this_sap_adapter) {
13187 if (check_start_bss) {
13188 if (test_bit(SOFTAP_BSS_STARTED,
13189 &adapter->event_flags)) {
13190 con_sap_adapter = adapter;
13191 break;
13192 }
13193 } else {
13194 con_sap_adapter = adapter;
13195 break;
13196 }
13197 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013198 }
13199
13200 return con_sap_adapter;
13201}
13202
Tiger Yu8b119e92019-04-09 13:55:07 +080013203#ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH
Jeff Johnson9d295242017-08-29 14:39:48 -070013204static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013205{
Dustin Brown5ec6b552017-03-31 12:11:40 -070013206 return adapter->device_mode == QDF_STA_MODE ||
13207 adapter->device_mode == QDF_P2P_CLIENT_MODE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013208}
13209
Jeff Johnson9d295242017-08-29 14:39:48 -070013210static inline bool hdd_adapter_is_ap(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013211{
Dustin Brown5ec6b552017-03-31 12:11:40 -070013212 return adapter->device_mode == QDF_SAP_MODE ||
13213 adapter->device_mode == QDF_P2P_GO_MODE;
13214}
13215
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013216static bool hdd_any_adapter_is_assoc(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013217{
Dustin Brown920397d2017-12-13 16:27:50 -080013218 struct hdd_adapter *adapter;
Dustin Brown5ec6b552017-03-31 12:11:40 -070013219
Dustin Brown920397d2017-12-13 16:27:50 -080013220 hdd_for_each_adapter(hdd_ctx, adapter) {
13221 if (hdd_adapter_is_sta(adapter) &&
Dustin Brown5ec6b552017-03-31 12:11:40 -070013222 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
Jeff Johnsone7951512019-02-27 10:02:51 -080013223 conn_info.conn_state == eConnectionState_Associated) {
Dustin Brown5ec6b552017-03-31 12:11:40 -070013224 return true;
13225 }
13226
Dustin Brown920397d2017-12-13 16:27:50 -080013227 if (hdd_adapter_is_ap(adapter) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -070013228 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active) {
Dustin Brown5ec6b552017-03-31 12:11:40 -070013229 return true;
13230 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070013231 }
13232
13233 return false;
13234}
13235
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013236static void __hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013237{
Dustin Browna20bad52019-03-05 12:03:30 -080013238 qdf_periodic_work_start(&hdd_ctx->bus_bw_work,
13239 hdd_ctx->config->bus_bw_compute_interval);
Dustin Brown5ec6b552017-03-31 12:11:40 -070013240}
13241
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013242void hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013243{
Dustin Brown491d54b2018-03-14 12:39:11 -070013244 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013245
Dustin Brown5ec6b552017-03-31 12:11:40 -070013246 __hdd_bus_bw_compute_timer_start(hdd_ctx);
13247
Dustin Browne74003f2018-03-14 12:51:58 -070013248 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013249}
13250
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013251void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013252{
Dustin Brown491d54b2018-03-14 12:39:11 -070013253 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013254
Dustin Brown5ec6b552017-03-31 12:11:40 -070013255 if (hdd_any_adapter_is_assoc(hdd_ctx))
13256 __hdd_bus_bw_compute_timer_start(hdd_ctx);
13257
Dustin Browne74003f2018-03-14 12:51:58 -070013258 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013259}
13260
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013261static void __hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013262{
Dustin Browna20bad52019-03-05 12:03:30 -080013263 if (!qdf_periodic_work_stop_sync(&hdd_ctx->bus_bw_work))
13264 return;
13265
Dustin Brown07901ec2018-09-07 11:02:41 -070013266 ucfg_ipa_set_perf_level(hdd_ctx->pdev, 0, 0);
Dustin Brown5ec6b552017-03-31 12:11:40 -070013267 hdd_reset_tcp_delack(hdd_ctx);
Tiger Yue40e7832019-04-25 10:46:53 +080013268 cdp_pdev_reset_driver_del_ack(cds_get_context(QDF_MODULE_ID_SOC),
13269 cds_get_context(QDF_MODULE_ID_TXRX));
Dustin Brown5ec6b552017-03-31 12:11:40 -070013270}
13271
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013272void hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013273{
Dustin Brown491d54b2018-03-14 12:39:11 -070013274 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013275
Dustin Brown5ec6b552017-03-31 12:11:40 -070013276 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
13277
Dustin Browne74003f2018-03-14 12:51:58 -070013278 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013279}
13280
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013281void hdd_bus_bw_compute_timer_try_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070013282{
Dustin Brown491d54b2018-03-14 12:39:11 -070013283 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070013284
Dustin Brown5ec6b552017-03-31 12:11:40 -070013285 if (!hdd_any_adapter_is_assoc(hdd_ctx))
13286 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
13287
Dustin Browne74003f2018-03-14 12:51:58 -070013288 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013289}
Sravan Kumar Kairam777a7dd2019-08-01 21:46:30 +053013290
13291void hdd_bus_bw_compute_prev_txrx_stats(struct hdd_adapter *adapter)
13292{
13293 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13294
13295 qdf_spin_lock_bh(&hdd_ctx->bus_bw_lock);
13296 adapter->prev_tx_packets = adapter->stats.tx_packets;
13297 adapter->prev_rx_packets = adapter->stats.rx_packets;
13298 cdp_get_intra_bss_fwd_pkts_count(cds_get_context(QDF_MODULE_ID_SOC),
13299 adapter->vdev_id,
13300 &adapter->prev_fwd_tx_packets,
13301 &adapter->prev_fwd_rx_packets);
13302 qdf_spin_unlock_bh(&hdd_ctx->bus_bw_lock);
13303}
13304
13305void hdd_bus_bw_compute_reset_prev_txrx_stats(struct hdd_adapter *adapter)
13306{
13307 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
13308
13309 qdf_spin_lock_bh(&hdd_ctx->bus_bw_lock);
13310 adapter->prev_tx_packets = 0;
13311 adapter->prev_rx_packets = 0;
13312 adapter->prev_fwd_tx_packets = 0;
13313 adapter->prev_fwd_rx_packets = 0;
13314 qdf_spin_unlock_bh(&hdd_ctx->bus_bw_lock);
13315}
13316
Tiger Yu8b119e92019-04-09 13:55:07 +080013317#endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013318
13319/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013320 * wlan_hdd_stop_sap() - This function stops bss of SAP.
13321 * @ap_adapter: SAP adapter
13322 *
13323 * This function will process the stopping of sap adapter.
13324 *
13325 * Return: None
13326 */
Jeff Johnson9d295242017-08-29 14:39:48 -070013327void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013328{
Jeff Johnson87251032017-08-29 13:31:11 -070013329 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070013330 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053013331 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013332 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013333
Jeff Johnsond36fa332019-03-18 13:42:25 -070013334 if (!ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070013335 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013336 return;
13337 }
13338
13339 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
13340 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Abhishek Singh23edd1c2016-05-05 11:56:06 +053013341 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013342 return;
Abhishek Singh23edd1c2016-05-05 11:56:06 +053013343
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013344 mutex_lock(&hdd_ctx->sap_lock);
13345 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080013346 wlan_hdd_del_station(ap_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013347 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013348 hdd_debug("Now doing SAP STOPBSS");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053013349 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053013350 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070013351 sap_context)) {
Nachiket Kukade0396b732017-11-14 16:35:16 +053013352 qdf_status = qdf_wait_for_event_completion(&hostapd_state->
Naveen Rawatb56880c2016-12-13 17:56:03 -080013353 qdf_stop_bss_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053013354 SME_CMD_STOP_BSS_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +053013355 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013356 mutex_unlock(&hdd_ctx->sap_lock);
Jeff Johnson28f8a772016-08-15 15:30:36 -070013357 hdd_err("SAP Stop Failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013358 return;
13359 }
13360 }
13361 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -070013362 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013363 ap_adapter->device_mode,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080013364 ap_adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070013365 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053013366 false);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013367 hdd_debug("SAP Stop Success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013368 } else {
Jeff Johnson28f8a772016-08-15 15:30:36 -070013369 hdd_err("Can't stop ap because its not started");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013370 }
13371 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013372}
13373
13374/**
13375 * wlan_hdd_start_sap() - this function starts bss of SAP.
13376 * @ap_adapter: SAP adapter
13377 *
13378 * This function will process the starting of sap adapter.
13379 *
13380 * Return: None
13381 */
Jeff Johnson9d295242017-08-29 14:39:48 -070013382void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013383{
Jeff Johnson87251032017-08-29 13:31:11 -070013384 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070013385 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053013386 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013387 struct hdd_context *hdd_ctx;
Jeff Johnson8f8ceb92019-03-24 08:16:55 -070013388 struct sap_config *sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013389
Jeff Johnsond36fa332019-03-18 13:42:25 -070013390 if (!ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070013391 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013392 return;
13393 }
13394
Krunal Soni9b04c9b2016-03-10 13:08:05 -080013395 if (QDF_SAP_MODE != ap_adapter->device_mode) {
Peng Xuf5d60c82015-10-02 17:17:03 -070013396 hdd_err("SoftAp role has not been enabled");
13397 return;
13398 }
13399
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013400 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
13401 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
13402 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -070013403 sap_config = &ap_adapter->session.ap.sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013404
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013405 mutex_lock(&hdd_ctx->sap_lock);
13406 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
13407 goto end;
13408
13409 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070013410 hdd_err("SAP Not able to set AP IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013411 goto end;
13412 }
Dustin Brown07901ec2018-09-07 11:02:41 -070013413 wlan_reg_set_channel_params(hdd_ctx->pdev,
Kiran Kumar Lokere229212a2019-08-20 19:03:30 -070013414 wlan_reg_freq_to_chan(hdd_ctx->pdev,
13415 hdd_ap_ctx->sap_config.chan_freq),
13416 0,
Abhinav Kumar6f694482018-09-04 16:07:39 +053013417 &hdd_ap_ctx->sap_config.ch_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013418
Wei Song2f76f642016-11-18 16:32:53 +080013419 qdf_event_reset(&hostapd_state->qdf_event);
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070013420 if (wlansap_start_bss(hdd_ap_ctx->sap_context, hdd_hostapd_sap_event_cb,
Jeff Johnson91df29d2017-10-27 19:29:50 -070013421 &hdd_ap_ctx->sap_config,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013422 ap_adapter->dev)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053013423 != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013424 goto end;
13425
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080013426 hdd_debug("Waiting for SAP to start");
Nachiket Kukade0396b732017-11-14 16:35:16 +053013427 qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053013428 SME_CMD_START_BSS_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +053013429 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070013430 hdd_err("SAP Start failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013431 goto end;
13432 }
Jeff Johnson28f8a772016-08-15 15:30:36 -070013433 hdd_info("SAP Start Success");
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053013434 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013435 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053013436 if (hostapd_state->bss_state == BSS_START) {
Dustin Brown1dbefe62018-09-11 16:32:03 -070013437 policy_mgr_incr_active_session(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080013438 ap_adapter->device_mode,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080013439 ap_adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070013440 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053013441 true);
13442 }
Sourav Mohapatra9bc67112017-11-08 09:36:11 +053013443 mutex_unlock(&hdd_ctx->sap_lock);
13444
13445 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013446end:
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053013447 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013448 mutex_unlock(&hdd_ctx->sap_lock);
Manikandan Mohan3dad1a42017-06-14 10:50:18 -070013449 /* SAP context and beacon cleanup will happen during driver unload
13450 * in hdd_stop_adapter
13451 */
13452 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
13453
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013454}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013455
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013456#ifdef QCA_CONFIG_SMP
13457/**
13458 * wlan_hdd_get_cpu() - get cpu_index
13459 *
13460 * Return: cpu_index
13461 */
13462int wlan_hdd_get_cpu(void)
13463{
13464 int cpu_index = get_cpu();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070013465
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080013466 put_cpu();
13467 return cpu_index;
13468}
13469#endif
13470
13471/**
13472 * hdd_get_fwpath() - get framework path
13473 *
13474 * This function is used to get the string written by
13475 * userspace to start the wlan driver
13476 *
13477 * Return: string
13478 */
13479const char *hdd_get_fwpath(void)
13480{
13481 return fwpath.string;
13482}
13483
Dustin Brown94ce20f2018-09-04 13:11:38 -070013484static inline int hdd_state_query_cb(void)
13485{
13486 return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD));
13487}
13488
Dustin Brown265e82b2019-03-18 11:07:32 -070013489static int __hdd_op_protect_cb(void **out_sync, const char *func)
13490{
13491 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13492
13493 if (!hdd_ctx)
13494 return -EAGAIN;
13495
13496 return __osif_psoc_sync_op_start(hdd_ctx->parent_dev,
13497 (struct osif_psoc_sync **)out_sync,
13498 func);
13499}
13500
13501static void __hdd_op_unprotect_cb(void *sync, const char *func)
13502{
13503 __osif_psoc_sync_op_stop(sync, func);
13504}
13505
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013506/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013507 * hdd_init() - Initialize Driver
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013508 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013509 * This function initilizes CDS global context with the help of cds_init. This
13510 * has to be the first function called after probe to get a valid global
13511 * context.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013512 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013513 * Return: 0 for success, errno on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013514 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013515int hdd_init(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013516{
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070013517 QDF_STATUS status;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013518
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070013519 status = cds_init();
wadesongae4ffd12017-10-24 16:45:54 +080013520 if (QDF_IS_STATUS_ERROR(status)) {
13521 hdd_err("Failed to allocate CDS context");
Dustin Brownc1d81af2019-03-01 13:43:43 -080013522 return -ENOMEM;
wadesongae4ffd12017-10-24 16:45:54 +080013523 }
Dustin Brownc1d81af2019-03-01 13:43:43 -080013524
Dustin Brown265e82b2019-03-18 11:07:32 -070013525 qdf_op_callbacks_register(__hdd_op_protect_cb, __hdd_op_unprotect_cb);
Hanumanth Reddy Pothula788a37e2017-08-17 18:40:11 +053013526
13527 wlan_init_bug_report_lock();
13528
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013529#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13530 wlan_logging_sock_init_svc();
13531#endif
13532
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013533 hdd_trace_init();
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053013534 hdd_register_debug_callback();
Qiwei Caiad9b01c2018-07-09 17:21:31 +080013535 wlan_roam_debug_init();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013536
Dustin Brownfe50cef2018-12-10 10:42:37 -080013537 return 0;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013538}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013539
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013540/**
13541 * hdd_deinit() - Deinitialize Driver
13542 *
13543 * This function frees CDS global context with the help of cds_deinit. This
13544 * has to be the last function call in remove callback to free the global
13545 * context.
13546 */
13547void hdd_deinit(void)
13548{
Qiwei Caiad9b01c2018-07-09 17:21:31 +080013549 wlan_roam_debug_deinit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013550
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013551#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
13552 wlan_logging_sock_deinit_svc();
13553#endif
Qiwei Caiad9b01c2018-07-09 17:21:31 +080013554
13555 wlan_destroy_bug_report_lock();
Dustin Brown265e82b2019-03-18 11:07:32 -070013556 qdf_op_callbacks_register(NULL, NULL);
Qiwei Caiad9b01c2018-07-09 17:21:31 +080013557 cds_deinit();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013558}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013559
Yue Ma6e7b1a02017-04-03 14:17:46 -070013560#ifdef QCA_WIFI_NAPIER_EMULATION
13561#define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
13562#else
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013563#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
Yue Ma6e7b1a02017-04-03 14:17:46 -070013564#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013565
Sachin Ahujadddd2632017-03-07 19:07:24 +053013566static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
13567 struct file *file)
13568{
13569 return 0;
13570}
13571
gaurank kathpaliafc166a12019-06-19 15:07:27 +053013572static void hdd_inform_wifi_off(void)
13573{
13574 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13575
13576 if (!hdd_ctx) {
13577 hdd_err("Invalid hdd/pdev context");
13578 return;
13579 }
13580 ucfg_blm_wifi_off(hdd_ctx->pdev);
13581}
13582
Sachin Ahujadddd2632017-03-07 19:07:24 +053013583static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
13584 const char __user *user_buf,
13585 size_t count,
13586 loff_t *f_pos)
13587{
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053013588 char buf[3];
Sachin Ahujadddd2632017-03-07 19:07:24 +053013589 static const char wlan_off_str[] = "OFF";
13590 static const char wlan_on_str[] = "ON";
13591 int ret;
13592 unsigned long rc;
13593
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053013594 if (copy_from_user(buf, user_buf, 3)) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053013595 pr_err("Failed to read buffer\n");
13596 return -EINVAL;
13597 }
13598
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053013599 if (strncmp(buf, wlan_off_str, strlen(wlan_off_str)) == 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053013600 pr_debug("Wifi turning off from UI\n");
gaurank kathpaliafc166a12019-06-19 15:07:27 +053013601 hdd_inform_wifi_off();
Sachin Ahujadddd2632017-03-07 19:07:24 +053013602 goto exit;
13603 }
13604
Srinivas Girigowdad2412882018-09-07 15:42:04 -070013605 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) == 0)
Sachin Ahuja16904db2017-12-13 19:56:57 +053013606 pr_info("Wifi Turning On from UI\n");
Sachin Ahuja16904db2017-12-13 19:56:57 +053013607
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053013608 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) != 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053013609 pr_err("Invalid value received from framework");
13610 goto exit;
13611 }
13612
13613 if (!cds_is_driver_loaded()) {
Sachin Ahujaee62b542017-04-21 14:14:16 +053013614 init_completion(&wlan_start_comp);
Sachin Ahujadddd2632017-03-07 19:07:24 +053013615 rc = wait_for_completion_timeout(&wlan_start_comp,
13616 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
13617 if (!rc) {
Srinivas Girigowda09625b02018-09-10 15:28:09 -070013618 hdd_alert("Timed-out!!");
Sachin Ahujadddd2632017-03-07 19:07:24 +053013619 ret = -EINVAL;
Sachin Ahujadddd2632017-03-07 19:07:24 +053013620 return ret;
13621 }
13622
13623 hdd_start_complete(0);
13624 }
13625
13626exit:
13627 return count;
13628}
13629
13630
13631const struct file_operations wlan_hdd_state_fops = {
13632 .owner = THIS_MODULE,
13633 .open = wlan_hdd_state_ctrl_param_open,
13634 .write = wlan_hdd_state_ctrl_param_write,
13635};
13636
13637static int wlan_hdd_state_ctrl_param_create(void)
13638{
13639 unsigned int wlan_hdd_state_major = 0;
13640 int ret;
13641 struct device *dev;
13642
13643 device = MKDEV(wlan_hdd_state_major, 0);
13644
13645 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
13646 if (ret) {
13647 pr_err("Failed to register qcwlanstate");
13648 goto dev_alloc_err;
13649 }
13650 wlan_hdd_state_major = MAJOR(device);
13651
13652 class = class_create(THIS_MODULE, WLAN_MODULE_NAME);
13653 if (IS_ERR(class)) {
13654 pr_err("wlan_hdd_state class_create error");
13655 goto class_err;
13656 }
13657
13658 dev = device_create(class, NULL, device, NULL, WLAN_MODULE_NAME);
13659 if (IS_ERR(dev)) {
13660 pr_err("wlan_hdd_statedevice_create error");
13661 goto err_class_destroy;
13662 }
13663
13664 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
13665 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
13666 if (ret) {
13667 pr_err("Failed to add cdev error");
13668 goto cdev_add_err;
13669 }
13670
13671 pr_info("wlan_hdd_state %s major(%d) initialized",
13672 WLAN_MODULE_NAME, wlan_hdd_state_major);
13673
13674 return 0;
13675
13676cdev_add_err:
13677 device_destroy(class, device);
13678err_class_destroy:
13679 class_destroy(class);
13680class_err:
13681 unregister_chrdev_region(device, dev_num);
13682dev_alloc_err:
13683 return -ENODEV;
13684}
13685
13686static void wlan_hdd_state_ctrl_param_destroy(void)
13687{
13688 cdev_del(&wlan_hdd_state_cdev);
13689 device_destroy(class, device);
13690 class_destroy(class);
13691 unregister_chrdev_region(device, dev_num);
13692
13693 pr_info("Device node unregistered");
13694}
13695
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013696/**
Dustin Brownd585cb32018-09-12 17:12:23 -070013697 * hdd_component_init() - Initialize all components
Mukul Sharmad75a6672017-06-22 15:40:53 +053013698 *
Dustin Brownd585cb32018-09-12 17:12:23 -070013699 * Return: QDF_STATUS
Mukul Sharmad75a6672017-06-22 15:40:53 +053013700 */
Dustin Brownd585cb32018-09-12 17:12:23 -070013701static QDF_STATUS hdd_component_init(void)
Mukul Sharmad75a6672017-06-22 15:40:53 +053013702{
Dustin Brownd585cb32018-09-12 17:12:23 -070013703 QDF_STATUS status;
13704
13705 /* initialize converged components */
Abhishek Singhd5cf22d2019-01-08 19:51:09 +053013706 status = ucfg_mlme_global_init();
Arif Hussain49698112018-07-31 00:32:50 -070013707 if (QDF_IS_STATUS_ERROR(status))
Wu Gaob4944be2019-08-15 15:23:07 +080013708 return status;
Arif Hussain49698112018-07-31 00:32:50 -070013709
Abhishek Singhd5cf22d2019-01-08 19:51:09 +053013710 status = dispatcher_init();
13711 if (QDF_IS_STATUS_ERROR(status))
13712 goto mlme_global_deinit;
13713
Wu Gaob4944be2019-08-15 15:23:07 +080013714 status = target_if_init(wma_get_psoc_from_scn_handle);
13715 if (QDF_IS_STATUS_ERROR(status))
13716 goto dispatcher_deinit;
13717
Dustin Brownd585cb32018-09-12 17:12:23 -070013718 /* initialize non-converged components */
13719 status = ucfg_mlme_init();
13720 if (QDF_IS_STATUS_ERROR(status))
Wu Gaob4944be2019-08-15 15:23:07 +080013721 goto target_if_deinit;
Dustin Brownd585cb32018-09-12 17:12:23 -070013722
13723 status = ucfg_fwol_init();
13724 if (QDF_IS_STATUS_ERROR(status))
13725 goto mlme_deinit;
13726
13727 status = disa_init();
13728 if (QDF_IS_STATUS_ERROR(status))
13729 goto fwol_deinit;
13730
13731 status = pmo_init();
13732 if (QDF_IS_STATUS_ERROR(status))
13733 goto disa_deinit;
13734
13735 status = ucfg_ocb_init();
13736 if (QDF_IS_STATUS_ERROR(status))
13737 goto pmo_deinit;
13738
13739 status = ipa_init();
13740 if (QDF_IS_STATUS_ERROR(status))
13741 goto ocb_deinit;
13742
13743 status = ucfg_action_oui_init();
13744 if (QDF_IS_STATUS_ERROR(status))
13745 goto ipa_deinit;
13746
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013747 status = nan_init();
13748 if (QDF_IS_STATUS_ERROR(status))
13749 goto action_oui_deinit;
13750
Wu Gao637d58a2018-12-08 10:37:34 +080013751 status = ucfg_p2p_init();
13752 if (QDF_IS_STATUS_ERROR(status))
13753 goto nan_deinit;
13754
Paul Zhang37185672019-05-14 11:20:14 +080013755 status = ucfg_interop_issues_ap_init();
Wu Gaod6b5e402018-12-03 22:09:24 +080013756 if (QDF_IS_STATUS_ERROR(status))
13757 goto p2p_deinit;
13758
Paul Zhang37185672019-05-14 11:20:14 +080013759 status = policy_mgr_init();
13760 if (QDF_IS_STATUS_ERROR(status))
13761 goto interop_issues_ap_deinit;
13762
Wu Gao5f793402018-12-08 11:04:00 +080013763 status = ucfg_tdls_init();
13764 if (QDF_IS_STATUS_ERROR(status))
13765 goto policy_deinit;
13766
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +053013767 status = ucfg_blm_init();
13768 if (QDF_IS_STATUS_ERROR(status))
13769 goto tdls_deinit;
13770
Dustin Brownd585cb32018-09-12 17:12:23 -070013771 return QDF_STATUS_SUCCESS;
13772
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +053013773tdls_deinit:
13774 ucfg_tdls_deinit();
13775
Wu Gao5f793402018-12-08 11:04:00 +080013776policy_deinit:
13777 policy_mgr_deinit();
Paul Zhang37185672019-05-14 11:20:14 +080013778interop_issues_ap_deinit:
13779 ucfg_interop_issues_ap_deinit();
Wu Gaod6b5e402018-12-03 22:09:24 +080013780p2p_deinit:
13781 ucfg_p2p_deinit();
Wu Gao637d58a2018-12-08 10:37:34 +080013782nan_deinit:
13783 nan_deinit();
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013784action_oui_deinit:
13785 ucfg_action_oui_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013786ipa_deinit:
13787 ipa_deinit();
13788ocb_deinit:
13789 ucfg_ocb_deinit();
13790pmo_deinit:
13791 pmo_deinit();
13792disa_deinit:
13793 disa_deinit();
13794fwol_deinit:
13795 ucfg_fwol_deinit();
13796mlme_deinit:
13797 ucfg_mlme_deinit();
Wu Gaob4944be2019-08-15 15:23:07 +080013798target_if_deinit:
13799 target_if_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013800dispatcher_deinit:
13801 dispatcher_deinit();
Abhishek Singhd5cf22d2019-01-08 19:51:09 +053013802mlme_global_deinit:
13803 ucfg_mlme_global_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013804
13805 return status;
Mukul Sharmad75a6672017-06-22 15:40:53 +053013806}
13807
13808/**
Dustin Brownd585cb32018-09-12 17:12:23 -070013809 * hdd_component_deinit() - Deinitialize all components
Mukul Sharmad75a6672017-06-22 15:40:53 +053013810 *
13811 * Return: None
13812 */
Dustin Brownd585cb32018-09-12 17:12:23 -070013813static void hdd_component_deinit(void)
Mukul Sharmad75a6672017-06-22 15:40:53 +053013814{
Dustin Brownd585cb32018-09-12 17:12:23 -070013815 /* deinitialize non-converged components */
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +053013816 ucfg_blm_deinit();
Wu Gao5f793402018-12-08 11:04:00 +080013817 ucfg_tdls_deinit();
Wu Gaod6b5e402018-12-03 22:09:24 +080013818 policy_mgr_deinit();
Paul Zhang37185672019-05-14 11:20:14 +080013819 ucfg_interop_issues_ap_deinit();
Wu Gao637d58a2018-12-08 10:37:34 +080013820 ucfg_p2p_deinit();
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013821 nan_deinit();
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053013822 ucfg_action_oui_deinit();
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +053013823 ipa_deinit();
Zhang Qian47e22ce2018-01-04 15:38:38 +080013824 ucfg_ocb_deinit();
Mukul Sharmad75a6672017-06-22 15:40:53 +053013825 pmo_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013826 disa_deinit();
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013827 ucfg_fwol_deinit();
Vignesh Viswanathana0921c42018-09-04 19:03:35 +053013828 ucfg_mlme_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013829
13830 /* deinitialize converged components */
Wu Gaob4944be2019-08-15 15:23:07 +080013831 target_if_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013832 dispatcher_deinit();
Abhishek Singhd5cf22d2019-01-08 19:51:09 +053013833 ucfg_mlme_global_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013834}
13835
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013836QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc)
13837{
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013838 QDF_STATUS status;
13839
13840 status = ucfg_mlme_psoc_open(psoc);
13841 if (QDF_IS_STATUS_ERROR(status))
13842 return status;
13843
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +053013844 status = ucfg_blm_psoc_open(psoc);
13845 if (QDF_IS_STATUS_ERROR(status))
13846 goto err_blm;
13847
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013848 status = ucfg_fwol_psoc_open(psoc);
13849 if (QDF_IS_STATUS_ERROR(status))
Wu Gao66454f12018-09-26 19:55:41 +080013850 goto err_fwol;
13851
13852 status = ucfg_pmo_psoc_open(psoc);
13853 if (QDF_IS_STATUS_ERROR(status))
13854 goto err_pmo;
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013855
Krunal Sonie9c12f52018-10-04 11:45:42 -070013856 status = ucfg_policy_mgr_psoc_open(psoc);
13857 if (QDF_IS_STATUS_ERROR(status))
13858 goto err_plcy_mgr;
13859
Wu Gao637d58a2018-12-08 10:37:34 +080013860 status = ucfg_p2p_psoc_open(psoc);
13861 if (QDF_IS_STATUS_ERROR(status))
13862 goto err_p2p;
Wu Gao5f793402018-12-08 11:04:00 +080013863
13864 status = ucfg_tdls_psoc_open(psoc);
13865 if (QDF_IS_STATUS_ERROR(status))
13866 goto err_tdls;
13867
Manikandan Mohan4e66c9a2019-07-12 14:55:17 -070013868 status = ucfg_nan_psoc_open(psoc);
13869 if (QDF_IS_STATUS_ERROR(status))
13870 goto err_nan;
13871
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013872 return status;
13873
Manikandan Mohan4e66c9a2019-07-12 14:55:17 -070013874err_nan:
13875 ucfg_nan_psoc_close(psoc);
Wu Gao5f793402018-12-08 11:04:00 +080013876err_tdls:
13877 ucfg_tdls_psoc_close(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013878err_p2p:
13879 ucfg_p2p_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070013880err_plcy_mgr:
13881 ucfg_pmo_psoc_close(psoc);
Wu Gao66454f12018-09-26 19:55:41 +080013882err_pmo:
13883 ucfg_fwol_psoc_close(psoc);
13884err_fwol:
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +053013885 ucfg_blm_psoc_close(psoc);
13886err_blm:
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013887 ucfg_mlme_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070013888
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013889 return status;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013890}
13891
13892void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc)
13893{
Wu Gao5f793402018-12-08 11:04:00 +080013894 ucfg_tdls_psoc_close(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013895 ucfg_p2p_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070013896 ucfg_policy_mgr_psoc_close(psoc);
Wu Gao66454f12018-09-26 19:55:41 +080013897 ucfg_pmo_psoc_close(psoc);
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013898 ucfg_fwol_psoc_close(psoc);
gaurank kathpalia3ebc17b2019-05-29 10:25:09 +053013899 ucfg_blm_psoc_close(psoc);
Vignesh Viswanathana0921c42018-09-04 19:03:35 +053013900 ucfg_mlme_psoc_close(psoc);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013901}
13902
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013903void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc)
13904{
Zhang Qian47e22ce2018-01-04 15:38:38 +080013905 ocb_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013906 disa_psoc_enable(psoc);
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013907 nan_psoc_enable(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013908 p2p_psoc_enable(psoc);
Paul Zhang37185672019-05-14 11:20:14 +080013909 ucfg_interop_issues_ap_psoc_enable(psoc);
Wu Gaod6b5e402018-12-03 22:09:24 +080013910 policy_mgr_psoc_enable(psoc);
Wu Gaoa67c3802018-12-27 12:07:52 +080013911 ucfg_tdls_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013912}
13913
13914void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc)
13915{
Wu Gaoa67c3802018-12-27 12:07:52 +080013916 ucfg_tdls_psoc_disable(psoc);
Wu Gaod6b5e402018-12-03 22:09:24 +080013917 policy_mgr_psoc_disable(psoc);
Paul Zhang37185672019-05-14 11:20:14 +080013918 ucfg_interop_issues_ap_psoc_disable(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013919 p2p_psoc_disable(psoc);
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013920 nan_psoc_disable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013921 disa_psoc_disable(psoc);
Zhang Qian47e22ce2018-01-04 15:38:38 +080013922 ocb_psoc_disable(psoc);
Mukul Sharmad75a6672017-06-22 15:40:53 +053013923}
13924
Sandeep Puligillab7beb472018-08-13 22:54:20 -070013925QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev)
13926{
13927 return ucfg_mlme_pdev_open(pdev);
13928}
13929
13930void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev)
13931{
13932 ucfg_mlme_pdev_close(pdev);
13933}
13934
Dustin Browna2a39dc2018-09-17 15:29:59 -070013935static QDF_STATUS hdd_qdf_print_init(void)
13936{
13937 QDF_STATUS status;
13938 int qdf_print_idx;
13939
13940 status = qdf_print_setup();
13941 if (QDF_IS_STATUS_ERROR(status)) {
13942 pr_err("Failed qdf_print_setup; status:%u\n", status);
13943 return status;
13944 }
13945
13946 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
13947 if (qdf_print_idx < 0) {
13948 pr_err("Failed to register for qdf_print_ctrl\n");
13949 return QDF_STATUS_E_FAILURE;
13950 }
13951
13952 qdf_set_pidx(qdf_print_idx);
13953
13954 return QDF_STATUS_SUCCESS;
13955}
13956
13957static void hdd_qdf_print_deinit(void)
13958{
13959 int qdf_pidx = qdf_get_pidx();
13960
13961 qdf_set_pidx(-1);
13962 qdf_print_ctrl_cleanup(qdf_pidx);
13963
13964 /* currently, no qdf print 'un-setup'*/
13965}
13966
13967static QDF_STATUS hdd_qdf_init(void)
13968{
13969 QDF_STATUS status;
13970
13971 status = hdd_qdf_print_init();
13972 if (QDF_IS_STATUS_ERROR(status))
13973 goto exit;
13974
13975 status = qdf_debugfs_init();
13976 if (QDF_IS_STATUS_ERROR(status)) {
13977 hdd_err("Failed to init debugfs; status:%u", status);
13978 goto print_deinit;
13979 }
13980
13981 qdf_lock_stats_init();
13982 qdf_mem_init();
Dustin Brownc2796312019-03-13 16:43:36 -070013983 qdf_delayed_work_feature_init();
Dustin Brown4a93bb52019-03-13 11:46:34 -070013984 qdf_periodic_work_feature_init();
Dustin Browna2a39dc2018-09-17 15:29:59 -070013985 qdf_mc_timer_manager_init();
13986 qdf_event_list_init();
13987
Dustin Brownd315c452018-11-27 11:28:48 -080013988 status = qdf_talloc_feature_init();
13989 if (QDF_IS_STATUS_ERROR(status)) {
13990 hdd_err("Failed to init talloc; status:%u", status);
13991 goto event_deinit;
13992 }
13993
Dustin Browna2a39dc2018-09-17 15:29:59 -070013994 status = qdf_cpuhp_init();
13995 if (QDF_IS_STATUS_ERROR(status)) {
13996 hdd_err("Failed to init cpuhp; status:%u", status);
Dustin Brownd315c452018-11-27 11:28:48 -080013997 goto talloc_deinit;
Dustin Browna2a39dc2018-09-17 15:29:59 -070013998 }
13999
14000 status = qdf_trace_spin_lock_init();
14001 if (QDF_IS_STATUS_ERROR(status)) {
14002 hdd_err("Failed to init spinlock; status:%u", status);
14003 goto cpuhp_deinit;
14004 }
14005
14006 qdf_trace_init();
14007 qdf_register_debugcb_init();
14008
14009 return QDF_STATUS_SUCCESS;
14010
14011cpuhp_deinit:
14012 qdf_cpuhp_deinit();
Dustin Brownd315c452018-11-27 11:28:48 -080014013talloc_deinit:
14014 qdf_talloc_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070014015event_deinit:
14016 qdf_event_list_destroy();
14017 qdf_mc_timer_manager_exit();
Dustin Brown4a93bb52019-03-13 11:46:34 -070014018 qdf_periodic_work_feature_deinit();
Dustin Brownc2796312019-03-13 16:43:36 -070014019 qdf_delayed_work_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070014020 qdf_mem_exit();
14021 qdf_lock_stats_deinit();
14022 qdf_debugfs_exit();
14023print_deinit:
14024 hdd_qdf_print_deinit();
14025
14026exit:
14027 return status;
14028}
14029
14030static void hdd_qdf_deinit(void)
14031{
14032 /* currently, no debugcb deinit */
14033
14034 qdf_trace_deinit();
14035
14036 /* currently, no trace spinlock deinit */
14037
14038 qdf_cpuhp_deinit();
Dustin Brownd315c452018-11-27 11:28:48 -080014039 qdf_talloc_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070014040 qdf_event_list_destroy();
14041 qdf_mc_timer_manager_exit();
Dustin Brown4a93bb52019-03-13 11:46:34 -070014042 qdf_periodic_work_feature_deinit();
Dustin Brownc2796312019-03-13 16:43:36 -070014043 qdf_delayed_work_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070014044 qdf_mem_exit();
14045 qdf_lock_stats_deinit();
14046 qdf_debugfs_exit();
14047 hdd_qdf_print_deinit();
14048}
Dustin Brownf0f70562018-09-14 10:29:38 -070014049
Dustin Brown26afe8f2019-03-01 12:37:24 -080014050#ifdef FEATURE_MONITOR_MODE_SUPPORT
14051static bool is_monitor_mode_supported(void)
14052{
14053 return true;
14054}
14055#else
14056static bool is_monitor_mode_supported(void)
14057{
14058 pr_err("Monitor mode not supported!");
14059 return false;
14060}
14061#endif
14062
14063#ifdef WLAN_FEATURE_EPPING
14064static bool is_epping_mode_supported(void)
14065{
14066 return true;
14067}
14068#else
14069static bool is_epping_mode_supported(void)
14070{
14071 pr_err("Epping mode not supported!");
14072 return false;
14073}
14074#endif
14075
14076#ifdef QCA_WIFI_FTM
14077static bool is_ftm_mode_supported(void)
14078{
14079 return true;
14080}
14081#else
14082static bool is_ftm_mode_supported(void)
14083{
14084 pr_err("FTM mode not supported!");
14085 return false;
14086}
14087#endif
14088
14089/**
14090 * is_con_mode_valid() check con mode is valid or not
14091 * @mode: global con mode
14092 *
14093 * Return: TRUE on success FALSE on failure
14094 */
14095static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
14096{
14097 switch (mode) {
14098 case QDF_GLOBAL_MONITOR_MODE:
14099 return is_monitor_mode_supported();
14100 case QDF_GLOBAL_EPPING_MODE:
14101 return is_epping_mode_supported();
14102 case QDF_GLOBAL_FTM_MODE:
14103 return is_ftm_mode_supported();
14104 case QDF_GLOBAL_MISSION_MODE:
14105 return true;
14106 default:
14107 return false;
14108 }
14109}
14110
14111static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
14112 enum QDF_GLOBAL_MODE curr_mode)
14113{
14114 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
14115 return;
14116
14117 switch (curr_mode) {
14118 case QDF_GLOBAL_MONITOR_MODE:
14119 hdd_info("Release wakelock for monitor mode!");
14120 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
14121 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
14122 /* fallthrough */
14123 case QDF_GLOBAL_MISSION_MODE:
14124 case QDF_GLOBAL_FTM_MODE:
14125 hdd_abort_mac_scan_all_adapters(hdd_ctx);
14126 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
14127 hdd_stop_all_adapters(hdd_ctx);
14128 hdd_deinit_all_adapters(hdd_ctx, false);
14129
14130 break;
14131 default:
14132 break;
14133 }
14134}
14135
14136static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
14137 enum QDF_GLOBAL_MODE curr_mode)
14138{
14139 int driver_status;
14140
14141 driver_status = hdd_ctx->driver_status;
14142
14143 switch (curr_mode) {
14144 case QDF_GLOBAL_MISSION_MODE:
14145 case QDF_GLOBAL_MONITOR_MODE:
14146 case QDF_GLOBAL_FTM_MODE:
14147 hdd_close_all_adapters(hdd_ctx, false);
14148 break;
14149 case QDF_GLOBAL_EPPING_MODE:
14150 epping_disable();
14151 epping_close();
14152 break;
14153 default:
14154 return;
14155 }
14156}
14157
14158static int
14159hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode)
14160{
14161 QDF_STATUS status;
14162 uint32_t mode;
14163
14164 *out_mode = QDF_GLOBAL_MAX_MODE;
14165
14166 status = qdf_uint32_parse(mode_str, &mode);
14167 if (QDF_IS_STATUS_ERROR(status))
14168 return qdf_status_to_os_return(status);
14169
14170 if (mode >= QDF_GLOBAL_MAX_MODE)
14171 return -ERANGE;
14172
14173 *out_mode = (enum QDF_GLOBAL_MODE)mode;
14174
14175 return 0;
14176}
14177
Rajeev Kumar588a2542019-04-08 10:57:19 -070014178static int hdd_mode_change_psoc_idle_shutdown(struct device *dev)
14179{
14180 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14181
Rajeev Kumar47b77292019-06-19 14:01:59 -070014182 if (!hdd_ctx)
14183 return -EINVAL;
14184
Rajeev Kumar588a2542019-04-08 10:57:19 -070014185 return hdd_wlan_stop_modules(hdd_ctx, true);
14186}
14187
14188static int hdd_mode_change_psoc_idle_restart(struct device *dev)
14189{
14190 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Alan Chene523cd92019-07-15 16:45:09 -070014191 int ret;
Rajeev Kumar588a2542019-04-08 10:57:19 -070014192
Rajeev Kumar47b77292019-06-19 14:01:59 -070014193 if (!hdd_ctx)
14194 return -EINVAL;
Alan Chen0f29e972019-09-04 12:04:22 -070014195 ret = hdd_soc_idle_restart_lock(dev);
14196 if (ret)
14197 return ret;
Alan Chene523cd92019-07-15 16:45:09 -070014198 ret = hdd_wlan_start_modules(hdd_ctx, false);
14199 hdd_soc_idle_restart_unlock();
Rajeev Kumar47b77292019-06-19 14:01:59 -070014200
Alan Chene523cd92019-07-15 16:45:09 -070014201 return ret;
Rajeev Kumar588a2542019-04-08 10:57:19 -070014202}
14203
Dustin Brown26afe8f2019-03-01 12:37:24 -080014204/**
14205 * __hdd_driver_mode_change() - Handles a driver mode change
14206 * @hdd_ctx: Pointer to the global HDD context
14207 * @next_mode: the driver mode to transition to
14208 *
14209 * This function is invoked when user updates con_mode using sys entry,
14210 * to initialize and bring-up driver in that specific mode.
14211 *
14212 * Return: Errno
14213 */
14214static int __hdd_driver_mode_change(struct hdd_context *hdd_ctx,
14215 enum QDF_GLOBAL_MODE next_mode)
14216{
14217 enum QDF_GLOBAL_MODE curr_mode;
14218 int errno;
14219
14220 hdd_info("Driver mode changing to %d", next_mode);
14221
14222 errno = wlan_hdd_validate_context(hdd_ctx);
14223 if (errno)
14224 return errno;
14225
14226 if (!is_con_mode_valid(next_mode)) {
14227 hdd_err_rl("Requested driver mode is invalid");
14228 return -EINVAL;
14229 }
14230
Dustin Brown26afe8f2019-03-01 12:37:24 -080014231 curr_mode = hdd_get_conparam();
14232 if (curr_mode == next_mode) {
14233 hdd_err_rl("Driver is already in the requested mode");
Dustin Browne0a77272019-03-19 16:28:06 -070014234 return 0;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014235 }
14236
Varuneshwar Petlozudbe255c2019-07-18 17:22:22 +053014237 hdd_psoc_idle_timer_stop(hdd_ctx);
14238
Dustin Brown26afe8f2019-03-01 12:37:24 -080014239 /* ensure adapters are stopped */
14240 hdd_stop_present_mode(hdd_ctx, curr_mode);
14241
Varuneshwar Petlozudbe255c2019-07-18 17:22:22 +053014242 if (DRIVER_MODULES_CLOSED != hdd_ctx->driver_status) {
14243 is_mode_change_psoc_idle_shutdown = true;
14244 errno = pld_idle_shutdown(hdd_ctx->parent_dev,
14245 hdd_mode_change_psoc_idle_shutdown);
14246 if (errno) {
14247 is_mode_change_psoc_idle_shutdown = false;
14248 hdd_err("Stop wlan modules failed");
14249 return errno;
14250 }
Dustin Brown26afe8f2019-03-01 12:37:24 -080014251 }
14252
14253 /* Cleanup present mode before switching to new mode */
14254 hdd_cleanup_present_mode(hdd_ctx, curr_mode);
14255
14256 hdd_set_conparam(next_mode);
14257
Rajeev Kumar588a2542019-04-08 10:57:19 -070014258 errno = pld_idle_restart(hdd_ctx->parent_dev,
14259 hdd_mode_change_psoc_idle_restart);
Dustin Brown26afe8f2019-03-01 12:37:24 -080014260 if (errno) {
14261 hdd_err("Start wlan modules failed: %d", errno);
Dustin Browne0a77272019-03-19 16:28:06 -070014262 return errno;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014263 }
14264
14265 errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode);
14266 if (errno) {
14267 hdd_err("Failed to open adapters");
Dustin Browne0a77272019-03-19 16:28:06 -070014268 return errno;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014269 }
14270
14271 if (next_mode == QDF_GLOBAL_MONITOR_MODE) {
14272 struct hdd_adapter *adapter =
14273 hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
14274
14275 QDF_BUG(adapter);
14276 if (!adapter) {
14277 hdd_err("Failed to get monitor adapter");
Dustin Browne0a77272019-03-19 16:28:06 -070014278 return -EINVAL;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014279 }
14280
14281 errno = hdd_start_adapter(adapter);
14282 if (errno) {
14283 hdd_err("Failed to start monitor adapter");
Dustin Browne0a77272019-03-19 16:28:06 -070014284 return errno;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014285 }
14286
14287 hdd_info("Acquire wakelock for monitor mode");
14288 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
14289 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
14290 }
14291
14292 /* con_mode is a global module parameter */
14293 con_mode = next_mode;
14294 hdd_info("Driver mode successfully changed to %d", next_mode);
14295
Dustin Browne0a77272019-03-19 16:28:06 -070014296 return 0;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014297}
14298
14299static int hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode)
14300{
Dustin Brownc1d81af2019-03-01 13:43:43 -080014301 struct osif_driver_sync *driver_sync;
Dustin Brown26afe8f2019-03-01 12:37:24 -080014302 struct hdd_context *hdd_ctx;
14303 QDF_STATUS status;
14304 int errno;
14305
14306 hdd_enter();
14307
Dustin Brownc1d81af2019-03-01 13:43:43 -080014308 status = osif_driver_sync_trans_start_wait(&driver_sync);
Dustin Brown26afe8f2019-03-01 12:37:24 -080014309 if (QDF_IS_STATUS_ERROR(status)) {
14310 hdd_err("Failed to start 'mode change'; status:%u", status);
14311 errno = qdf_status_to_os_return(status);
14312 goto exit;
14313 }
14314
Dustin Brownc1d81af2019-03-01 13:43:43 -080014315 osif_driver_sync_wait_for_ops(driver_sync);
Dustin Brown26afe8f2019-03-01 12:37:24 -080014316
14317 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14318 errno = wlan_hdd_validate_context(hdd_ctx);
14319 if (errno)
14320 goto trans_stop;
14321
Dustin Brown26afe8f2019-03-01 12:37:24 -080014322 errno = __hdd_driver_mode_change(hdd_ctx, mode);
Dustin Brown26afe8f2019-03-01 12:37:24 -080014323
14324trans_stop:
Dustin Brownc1d81af2019-03-01 13:43:43 -080014325 osif_driver_sync_trans_stop(driver_sync);
Dustin Brown26afe8f2019-03-01 12:37:24 -080014326
14327exit:
14328 hdd_exit();
14329
14330 return errno;
14331}
14332
14333static int hdd_set_con_mode(enum QDF_GLOBAL_MODE mode)
14334{
14335 con_mode = mode;
14336
14337 return 0;
14338}
14339
14340static int (*hdd_set_con_mode_cb)(enum QDF_GLOBAL_MODE mode) = hdd_set_con_mode;
14341
14342static void hdd_driver_mode_change_register(void)
14343{
14344 hdd_set_con_mode_cb = hdd_driver_mode_change;
14345}
14346
14347static void hdd_driver_mode_change_unregister(void)
14348{
14349 hdd_set_con_mode_cb = hdd_set_con_mode;
14350}
14351
14352static int con_mode_handler(const char *kmessage, const struct kernel_param *kp)
14353{
14354 enum QDF_GLOBAL_MODE mode;
14355 int errno;
14356
14357 errno = hdd_parse_driver_mode(kmessage, &mode);
14358 if (errno) {
14359 hdd_err_rl("Failed to parse driver mode '%s'", kmessage);
14360 return errno;
14361 }
14362
14363 return hdd_set_con_mode_cb(mode);
14364}
Dustin Brown95ff00b2019-02-28 13:41:13 -080014365
Dustin Brownf0f70562018-09-14 10:29:38 -070014366/**
14367 * hdd_driver_load() - Perform the driver-level load operation
14368 *
14369 * Note: this is used in both static and DLKM driver builds
14370 *
14371 * Return: Errno
14372 */
14373static int hdd_driver_load(void)
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014374{
Dustin Brownc1d81af2019-03-01 13:43:43 -080014375 struct osif_driver_sync *driver_sync;
Dustin Brownd585cb32018-09-12 17:12:23 -070014376 QDF_STATUS status;
Dustin Brownf0f70562018-09-14 10:29:38 -070014377 int errno;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014378
Dustin Brownc1d81af2019-03-01 13:43:43 -080014379 pr_err("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
Rajeev Kumare555e2d2018-09-17 11:52:37 -070014380 g_wlan_driver_version);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014381
Dustin Browna2a39dc2018-09-17 15:29:59 -070014382 status = hdd_qdf_init();
14383 if (QDF_IS_STATUS_ERROR(status)) {
14384 errno = qdf_status_to_os_return(status);
14385 goto exit;
14386 }
14387
Dustin Brownc1d81af2019-03-01 13:43:43 -080014388 osif_sync_init();
Dustin Brown21a1d462018-07-31 15:13:06 -070014389
Dustin Brownc1d81af2019-03-01 13:43:43 -080014390 status = osif_driver_sync_create_and_trans(&driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070014391 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Brownc1d81af2019-03-01 13:43:43 -080014392 hdd_err("Failed to init driver sync; status:%u", status);
Dustin Brown21a1d462018-07-31 15:13:06 -070014393 errno = qdf_status_to_os_return(status);
Dustin Brownc1d81af2019-03-01 13:43:43 -080014394 goto sync_deinit;
Dustin Brown21a1d462018-07-31 15:13:06 -070014395 }
14396
Dustin Brownf0f70562018-09-14 10:29:38 -070014397 errno = hdd_init();
14398 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014399 hdd_err("Failed to init HDD; errno:%d", errno);
Dustin Brown21a1d462018-07-31 15:13:06 -070014400 goto trans_stop;
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053014401 }
14402
Dustin Brownd585cb32018-09-12 17:12:23 -070014403 status = hdd_component_init();
14404 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014405 hdd_err("Failed to init components; status:%u", status);
Dustin Brownf0f70562018-09-14 10:29:38 -070014406 errno = qdf_status_to_os_return(status);
Dustin Brownd585cb32018-09-12 17:12:23 -070014407 goto hdd_deinit;
14408 }
Mukul Sharmad75a6672017-06-22 15:40:53 +053014409
Dustin Brownf0f70562018-09-14 10:29:38 -070014410 status = qdf_wake_lock_create(&wlan_wake_lock, "wlan");
14411 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014412 hdd_err("Failed to create wake lock; status:%u", status);
Dustin Brownf0f70562018-09-14 10:29:38 -070014413 errno = qdf_status_to_os_return(status);
14414 goto comp_deinit;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014415 }
14416
Dustin Brownf0f70562018-09-14 10:29:38 -070014417 hdd_set_conparam(con_mode);
14418
Dustin Brownf0f70562018-09-14 10:29:38 -070014419 errno = wlan_hdd_state_ctrl_param_create();
14420 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014421 hdd_err("Failed to create ctrl param; errno:%d", errno);
Dustin Brown4b9dbe62018-09-14 15:41:11 -070014422 goto wakelock_destroy;
14423 }
14424
Dustin Brown25843ad2018-09-17 14:54:33 -070014425 errno = pld_init();
14426 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014427 hdd_err("Failed to init PLD; errno:%d", errno);
Dustin Brown25843ad2018-09-17 14:54:33 -070014428 goto param_destroy;
14429 }
14430
Dustin Brown95ff00b2019-02-28 13:41:13 -080014431 hdd_driver_mode_change_register();
Dustin Brownc1d81af2019-03-01 13:43:43 -080014432
14433 osif_driver_sync_register(driver_sync);
14434 osif_driver_sync_trans_stop(driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070014435
14436 /* psoc probe can happen in registration; do after 'load' transition */
Dustin Brown4b9dbe62018-09-14 15:41:11 -070014437 errno = wlan_hdd_register_driver();
14438 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014439 hdd_err("Failed to register driver; errno:%d", errno);
Dustin Brown25843ad2018-09-17 14:54:33 -070014440 goto pld_deinit;
Sachin Ahuja16904db2017-12-13 19:56:57 +053014441 }
14442
Dustin Browna2a39dc2018-09-17 15:29:59 -070014443 hdd_debug("%s: driver loaded", WLAN_MODULE_NAME);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014444
14445 return 0;
Dustin Brownd585cb32018-09-12 17:12:23 -070014446
Dustin Brown25843ad2018-09-17 14:54:33 -070014447pld_deinit:
Dustin Brownc1d81af2019-03-01 13:43:43 -080014448 status = osif_driver_sync_trans_start(&driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070014449 QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
14450
Dustin Brownc1d81af2019-03-01 13:43:43 -080014451 osif_driver_sync_unregister();
14452 osif_driver_sync_wait_for_ops(driver_sync);
14453
Dustin Brown95ff00b2019-02-28 13:41:13 -080014454 hdd_driver_mode_change_unregister();
Dustin Brown25843ad2018-09-17 14:54:33 -070014455 pld_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070014456
Alan Chen30181292019-08-20 10:06:43 -070014457 hdd_start_complete(errno);
Dustin Brown4b9dbe62018-09-14 15:41:11 -070014458param_destroy:
14459 wlan_hdd_state_ctrl_param_destroy();
Dustin Brownf0f70562018-09-14 10:29:38 -070014460wakelock_destroy:
Anurag Chouhana37b5b72016-02-21 14:53:42 +053014461 qdf_wake_lock_destroy(&wlan_wake_lock);
Dustin Brownf0f70562018-09-14 10:29:38 -070014462comp_deinit:
Dustin Brownd585cb32018-09-12 17:12:23 -070014463 hdd_component_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070014464hdd_deinit:
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053014465 hdd_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070014466trans_stop:
Dustin Brownc1d81af2019-03-01 13:43:43 -080014467 osif_driver_sync_trans_stop(driver_sync);
14468 osif_driver_sync_destroy(driver_sync);
14469sync_deinit:
14470 osif_sync_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070014471 hdd_qdf_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070014472
Dustin Brown25843ad2018-09-17 14:54:33 -070014473exit:
Dustin Brownf0f70562018-09-14 10:29:38 -070014474 return errno;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014475}
14476
14477/**
Dustin Brownf0f70562018-09-14 10:29:38 -070014478 * hdd_driver_unload() - Performs the driver-level unload operation
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014479 *
Dustin Brownf0f70562018-09-14 10:29:38 -070014480 * Note: this is used in both static and DLKM driver builds
14481 *
14482 * Return: None
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014483 */
Dustin Brownf0f70562018-09-14 10:29:38 -070014484static void hdd_driver_unload(void)
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014485{
Dustin Brownc1d81af2019-03-01 13:43:43 -080014486 struct osif_driver_sync *driver_sync;
Will Huang36049722018-04-13 11:48:51 +080014487 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Dustin Brown21a1d462018-07-31 15:13:06 -070014488 QDF_STATUS status;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +053014489
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014490 pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
14491 QWLAN_VERSIONSTR);
14492
Dustin Brown8c0b5e32019-01-18 13:56:02 -080014493 if (hdd_ctx)
14494 hdd_psoc_idle_timer_stop(hdd_ctx);
14495
14496 /* trigger SoC remove */
14497 wlan_hdd_unregister_driver();
14498
Dustin Brownc1d81af2019-03-01 13:43:43 -080014499 status = osif_driver_sync_trans_start_wait(&driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070014500 QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
14501 if (QDF_IS_STATUS_ERROR(status)) {
14502 hdd_err("Unable to unload wlan; status:%u", status);
Arunk Khandavalli830c9692018-03-22 12:17:40 +053014503 return;
Dustin Brown21a1d462018-07-31 15:13:06 -070014504 }
14505
Dustin Brownc1d81af2019-03-01 13:43:43 -080014506 osif_driver_sync_unregister();
14507 osif_driver_sync_wait_for_ops(driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070014508
Will Huangba035ec2018-07-05 11:13:30 +080014509 cds_set_driver_loaded(false);
14510 cds_set_unload_in_progress(true);
14511
Dustin Brown95ff00b2019-02-28 13:41:13 -080014512 hdd_driver_mode_change_unregister();
Dustin Brown25843ad2018-09-17 14:54:33 -070014513 pld_deinit();
Dustin Brown4b9dbe62018-09-14 15:41:11 -070014514 wlan_hdd_state_ctrl_param_destroy();
Dustin Brownf0f70562018-09-14 10:29:38 -070014515 hdd_set_conparam(0);
Anurag Chouhana37b5b72016-02-21 14:53:42 +053014516 qdf_wake_lock_destroy(&wlan_wake_lock);
Dustin Brownd585cb32018-09-12 17:12:23 -070014517 hdd_component_deinit();
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053014518 hdd_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070014519
Dustin Brownc1d81af2019-03-01 13:43:43 -080014520 osif_driver_sync_trans_stop(driver_sync);
14521 osif_driver_sync_destroy(driver_sync);
Dustin Brown623e7e32018-09-05 14:27:50 -070014522
Dustin Brownc1d81af2019-03-01 13:43:43 -080014523 osif_sync_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070014524
Dustin Browna2a39dc2018-09-17 15:29:59 -070014525 hdd_qdf_deinit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014526}
14527
Arun Khandavallifae92942016-08-01 13:31:08 +053014528#ifndef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014529/**
Arun Khandavallifae92942016-08-01 13:31:08 +053014530 * wlan_boot_cb() - Wlan boot callback
14531 * @kobj: object whose directory we're creating the link in.
14532 * @attr: attribute the user is interacting with
14533 * @buff: the buffer containing the user data
14534 * @count: number of bytes in the buffer
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014535 *
Arun Khandavallifae92942016-08-01 13:31:08 +053014536 * This callback is invoked when the fs is ready to start the
14537 * wlan driver initialization.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014538 *
Arun Khandavallifae92942016-08-01 13:31:08 +053014539 * Return: 'count' on success or a negative error code in case of failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014540 */
Arun Khandavallifae92942016-08-01 13:31:08 +053014541static ssize_t wlan_boot_cb(struct kobject *kobj,
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014542 struct kobj_attribute *attr,
14543 const char *buf,
14544 size_t count)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014545{
Arun Khandavallifae92942016-08-01 13:31:08 +053014546
Arun Khandavallifae92942016-08-01 13:31:08 +053014547 if (wlan_loader->loaded_state) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014548 hdd_err("wlan driver already initialized");
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014549 return -EALREADY;
Arun Khandavallifae92942016-08-01 13:31:08 +053014550 }
14551
Dustin Brownf0f70562018-09-14 10:29:38 -070014552 if (hdd_driver_load())
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014553 return -EIO;
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014554
14555 wlan_loader->loaded_state = MODULE_INITIALIZED;
Arun Khandavallifae92942016-08-01 13:31:08 +053014556
14557 return count;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014558}
Arun Khandavallifae92942016-08-01 13:31:08 +053014559
14560/**
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014561 * hdd_sysfs_cleanup() - cleanup sysfs
14562 *
14563 * Return: None
14564 *
14565 */
14566static void hdd_sysfs_cleanup(void)
14567{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014568 /* remove from group */
14569 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
14570 sysfs_remove_group(wlan_loader->boot_wlan_obj,
14571 wlan_loader->attr_group);
14572
14573 /* unlink the object from parent */
14574 kobject_del(wlan_loader->boot_wlan_obj);
14575
14576 /* free the object */
14577 kobject_put(wlan_loader->boot_wlan_obj);
14578
14579 kfree(wlan_loader->attr_group);
14580 kfree(wlan_loader);
14581
14582 wlan_loader = NULL;
14583}
14584
14585/**
Arun Khandavallifae92942016-08-01 13:31:08 +053014586 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
14587 * ready
14588 *
14589 * This is creates the syfs entry boot_wlan. Which shall be invoked
14590 * when the filesystem is ready.
14591 *
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014592 * QDF API cannot be used here since this function is called even before
14593 * initializing WLAN driver.
14594 *
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070014595 * Return: 0 for success, errno on failure
Arun Khandavallifae92942016-08-01 13:31:08 +053014596 */
14597static int wlan_init_sysfs(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014598{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014599 int ret = -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053014600
14601 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070014602 if (!wlan_loader)
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014603 return -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053014604
14605 wlan_loader->boot_wlan_obj = NULL;
14606 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
14607 GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070014608 if (!wlan_loader->attr_group)
Arun Khandavallifae92942016-08-01 13:31:08 +053014609 goto error_return;
Arun Khandavallifae92942016-08-01 13:31:08 +053014610
14611 wlan_loader->loaded_state = 0;
14612 wlan_loader->attr_group->attrs = attrs;
14613
Qun Zhang4a83a462018-09-11 16:28:51 +080014614 wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME,
Arun Khandavallifae92942016-08-01 13:31:08 +053014615 kernel_kobj);
14616 if (!wlan_loader->boot_wlan_obj) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014617 hdd_err("sysfs create and add failed");
Arun Khandavallifae92942016-08-01 13:31:08 +053014618 goto error_return;
14619 }
14620
14621 ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
14622 wlan_loader->attr_group);
14623 if (ret) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014624 hdd_err("sysfs create group failed; errno:%d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053014625 goto error_return;
14626 }
14627
14628 return 0;
14629
14630error_return:
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014631 hdd_sysfs_cleanup();
Arun Khandavallifae92942016-08-01 13:31:08 +053014632
14633 return ret;
14634}
14635
14636/**
14637 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
14638 *
14639 * Return: 0 on success or errno on failure
14640 */
14641static int wlan_deinit_sysfs(void)
14642{
Arun Khandavallifae92942016-08-01 13:31:08 +053014643 if (!wlan_loader) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070014644 hdd_err("wlan_loader is null");
Arun Khandavallifae92942016-08-01 13:31:08 +053014645 return -EINVAL;
14646 }
14647
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014648 hdd_sysfs_cleanup();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014649 return 0;
14650}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014651
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070014652#endif /* MODULE */
Arun Khandavallifae92942016-08-01 13:31:08 +053014653
14654#ifdef MODULE
14655/**
Dustin Brownf0f70562018-09-14 10:29:38 -070014656 * hdd_module_init() - Module init helper
Arun Khandavallifae92942016-08-01 13:31:08 +053014657 *
14658 * Module init helper function used by both module and static driver.
14659 *
14660 * Return: 0 for success, errno on failure
14661 */
14662static int hdd_module_init(void)
14663{
Dustin Brownf0f70562018-09-14 10:29:38 -070014664 if (hdd_driver_load())
Dustin Brownab482ac2017-06-09 17:00:44 -070014665 return -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053014666
Dustin Brownab482ac2017-06-09 17:00:44 -070014667 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053014668}
14669#else
14670static int __init hdd_module_init(void)
14671{
14672 int ret = -EINVAL;
14673
14674 ret = wlan_init_sysfs();
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070014675 if (ret)
Dustin Browna2a39dc2018-09-17 15:29:59 -070014676 hdd_err("Failed to create sysfs entry");
Arun Khandavallifae92942016-08-01 13:31:08 +053014677
14678 return ret;
14679}
14680#endif
14681
14682
14683#ifdef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014684/**
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014685 * hdd_module_exit() - Exit function
14686 *
14687 * This is the driver exit point (invoked when module is unloaded using rmmod)
14688 *
14689 * Return: None
14690 */
14691static void __exit hdd_module_exit(void)
14692{
Dustin Brownf0f70562018-09-14 10:29:38 -070014693 hdd_driver_unload();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014694}
Arun Khandavallifae92942016-08-01 13:31:08 +053014695#else
14696static void __exit hdd_module_exit(void)
14697{
Dustin Brownf0f70562018-09-14 10:29:38 -070014698 hdd_driver_unload();
Arun Khandavallifae92942016-08-01 13:31:08 +053014699 wlan_deinit_sysfs();
14700}
14701#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014702
Srinivas Girigowda841da292018-02-21 16:33:00 -080014703static int fwpath_changed_handler(const char *kmessage,
14704 const struct kernel_param *kp)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014705{
14706 return param_set_copystring(kmessage, kp);
14707}
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014708
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053014709static int con_mode_handler_ftm(const char *kmessage,
Srinivas Girigowda841da292018-02-21 16:33:00 -080014710 const struct kernel_param *kp)
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053014711{
14712 int ret;
14713
14714 ret = param_set_int(kmessage, kp);
14715
14716 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
14717 pr_err("Only FTM mode supported!");
14718 return -ENOTSUPP;
14719 }
14720
14721 hdd_set_conparam(con_mode_ftm);
14722 con_mode = con_mode_ftm;
14723
14724 return ret;
14725}
14726
Nirav Shah6aeecf92019-02-13 14:05:03 +053014727#ifdef WLAN_FEATURE_EPPING
14728static int con_mode_handler_epping(const char *kmessage,
14729 const struct kernel_param *kp)
14730{
14731 int ret;
14732
14733 ret = param_set_int(kmessage, kp);
14734
14735 if (con_mode_epping != QDF_GLOBAL_EPPING_MODE) {
14736 pr_err("Only EPPING mode supported!");
14737 return -ENOTSUPP;
14738 }
14739
14740 hdd_set_conparam(con_mode_epping);
14741 con_mode = con_mode_epping;
14742
14743 return ret;
14744}
14745#endif
14746
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014747/**
14748 * hdd_get_conparam() - driver exit point
14749 *
14750 * This is the driver exit point (invoked when module is unloaded using rmmod)
14751 *
Jeff Johnson876c1a62017-12-12 10:43:07 -080014752 * Return: enum QDF_GLOBAL_MODE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014753 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080014754enum QDF_GLOBAL_MODE hdd_get_conparam(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014755{
Jeff Johnson876c1a62017-12-12 10:43:07 -080014756 return (enum QDF_GLOBAL_MODE) curr_con_mode;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014757}
14758
Dustin Brownf0f70562018-09-14 10:29:38 -070014759void hdd_set_conparam(int32_t con_param)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014760{
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080014761 curr_con_mode = con_param;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014762}
14763
Komal Seelamc11bb222016-01-27 18:57:10 +053014764/**
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014765 * hdd_clean_up_pre_cac_interface() - Clean up the pre cac interface
14766 * @hdd_ctx: HDD context
14767 *
14768 * Cleans up the pre cac interface, if it exists
14769 *
14770 * Return: None
14771 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014772void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx)
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014773{
Jeff Johnson55d2ab42019-03-06 11:43:49 -080014774 uint8_t vdev_id;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014775 QDF_STATUS status;
Jeff Johnson85b5c112017-08-11 15:15:23 -070014776 struct hdd_adapter *precac_adapter;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014777
Jeff Johnson55d2ab42019-03-06 11:43:49 -080014778 status = wlan_sap_get_pre_cac_vdev_id(hdd_ctx->mac_handle, &vdev_id);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014779 if (QDF_IS_STATUS_ERROR(status)) {
14780 hdd_err("failed to get pre cac vdev id");
14781 return;
14782 }
14783
Jeff Johnson55d2ab42019-03-06 11:43:49 -080014784 precac_adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014785 if (!precac_adapter) {
Jeff Johnsondd2f1fc2018-05-06 11:22:52 -070014786 hdd_err("invalid pre cac adapter");
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014787 return;
14788 }
14789
14790 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
14791 wlan_hdd_sap_pre_cac_failure,
14792 (void *)precac_adapter);
14793 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
14794
14795}
14796
14797/**
Yu Ouyang486fac82019-07-02 14:12:15 +080014798 * hdd_svc_fw_crashed_ind() - API to send FW CRASHED IND to Userspace
14799 *
14800 * Return: void
14801 */
14802static void hdd_svc_fw_crashed_ind(void)
14803{
14804 struct hdd_context *hdd_ctx;
14805
14806 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14807
14808 hdd_ctx ? wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
14809 WLAN_SVC_FW_CRASHED_IND,
14810 NULL, 0) : 0;
14811}
14812
14813/**
Komal Seelamec702b02016-02-24 18:42:16 +053014814 * hdd_update_ol_config - API to update ol configuration parameters
14815 * @hdd_ctx: HDD context
Komal Seelamc11bb222016-01-27 18:57:10 +053014816 *
Komal Seelamc11bb222016-01-27 18:57:10 +053014817 * Return: void
14818 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014819static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
Komal Seelamc11bb222016-01-27 18:57:10 +053014820{
Abhishek Singh98278ce2018-12-27 11:41:03 +053014821 struct ol_config_info cfg = {0};
Anurag Chouhandf2b2682016-02-29 14:15:27 +053014822 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014823 bool self_recovery = false;
14824 QDF_STATUS status;
Komal Seelamc11bb222016-01-27 18:57:10 +053014825
Komal Seelamec702b02016-02-24 18:42:16 +053014826 if (!ol_ctx)
14827 return;
14828
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014829 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
14830 if (QDF_IS_STATUS_ERROR(status))
14831 hdd_err("Failed to get self recovery ini config");
14832
14833 cfg.enable_self_recovery = self_recovery;
Komal Seelamec702b02016-02-24 18:42:16 +053014834 cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
14835 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
14836 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
Jeff Johnsonb8bf9072016-09-23 17:39:27 -070014837 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
Komal Seelamec702b02016-02-24 18:42:16 +053014838
14839 ol_init_ini_config(ol_ctx, &cfg);
Yu Ouyang486fac82019-07-02 14:12:15 +080014840 ol_set_fw_crashed_cb(ol_ctx, hdd_svc_fw_crashed_ind);
Komal Seelamec702b02016-02-24 18:42:16 +053014841}
14842
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014843#ifdef FEATURE_RUNTIME_PM
14844/**
14845 * hdd_populate_runtime_cfg() - populate runtime configuration
14846 * @hdd_ctx: hdd context
14847 * @cfg: pointer to the configuration memory being populated
14848 *
14849 * Return: void
14850 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014851static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014852 struct hif_config_info *cfg)
14853{
14854 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
Wu Gao66454f12018-09-26 19:55:41 +080014855 cfg->runtime_pm_delay =
14856 ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc);
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014857}
14858#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014859static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014860 struct hif_config_info *cfg)
14861{
14862}
14863#endif
14864
Komal Seelamec702b02016-02-24 18:42:16 +053014865/**
14866 * hdd_update_hif_config - API to update HIF configuration parameters
14867 * @hdd_ctx: HDD Context
14868 *
14869 * Return: void
14870 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014871static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053014872{
Anurag Chouhandf2b2682016-02-29 14:15:27 +053014873 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
Abhishek Singh98278ce2018-12-27 11:41:03 +053014874 struct hif_config_info cfg = {0};
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014875 bool prevent_link_down = false;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014876 bool self_recovery = false;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014877 QDF_STATUS status;
Komal Seelamec702b02016-02-24 18:42:16 +053014878
14879 if (!scn)
14880 return;
14881
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014882 status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc,
14883 &prevent_link_down);
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014884 if (QDF_IS_STATUS_ERROR(status))
14885 hdd_err("Failed to get prevent_link_down config");
14886
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014887 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
14888 if (QDF_IS_STATUS_ERROR(status))
14889 hdd_err("Failed to get self recovery ini config");
14890
14891 cfg.enable_self_recovery = self_recovery;
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014892 hdd_populate_runtime_cfg(hdd_ctx, &cfg);
Mohit Khannaa8c9f562019-03-25 22:17:02 -070014893 cfg.rx_softirq_max_yield_duration_ns =
14894 cfg_get(hdd_ctx->psoc,
14895 CFG_DP_RX_SOFTIRQ_MAX_YIELD_TIME_NS);
14896
Komal Seelamec702b02016-02-24 18:42:16 +053014897 hif_init_ini_config(scn, &cfg);
Dustin Brownee3e0592017-09-07 13:50:11 -070014898
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014899 if (prevent_link_down)
Dustin Brownee3e0592017-09-07 13:50:11 -070014900 hif_vote_link_up(scn);
Komal Seelamec702b02016-02-24 18:42:16 +053014901}
14902
Mohit Khannaa8c9f562019-03-25 22:17:02 -070014903#ifdef WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT
14904/**
14905 * hdd_update_dp_config_rx_softirq_limits() - Update DP rx softirq limit config
14906 * datapath
14907 * @hdd_ctx: HDD Context
14908 * @params: pointer to cdp_config_params to be updated
14909 *
14910 * Void
14911 */
14912static
14913void hdd_update_dp_config_rx_softirq_limits(struct hdd_context *hdd_ctx,
14914 struct cdp_config_params *params)
14915{
14916 params->tx_comp_loop_pkt_limit = cfg_get(hdd_ctx->psoc,
14917 CFG_DP_TX_COMP_LOOP_PKT_LIMIT);
14918 params->rx_reap_loop_pkt_limit = cfg_get(hdd_ctx->psoc,
14919 CFG_DP_RX_REAP_LOOP_PKT_LIMIT);
14920 params->rx_hp_oos_update_limit = cfg_get(hdd_ctx->psoc,
14921 CFG_DP_RX_HP_OOS_UPDATE_LIMIT);
14922}
14923#else
14924static
14925void hdd_update_dp_config_rx_softirq_limits(struct hdd_context *hdd_ctx,
14926 struct cdp_config_params *params)
14927{
14928}
14929#endif /* WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT */
14930
hangtianb9c91362019-06-07 10:39:38 +080014931#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL)
14932static void
14933hdd_update_dp_config_queue_threshold(struct hdd_context *hdd_ctx,
14934 struct cdp_config_params *params)
14935{
14936 params->tx_flow_stop_queue_threshold =
14937 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
14938 params->tx_flow_start_queue_offset =
14939 cfg_get(hdd_ctx->psoc,
14940 CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
14941}
14942#else
14943static inline void
14944hdd_update_dp_config_queue_threshold(struct hdd_context *hdd_ctx,
14945 struct cdp_config_params *params)
14946{
14947}
14948#endif
14949
Komal Seelamec702b02016-02-24 18:42:16 +053014950/**
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014951 * hdd_update_dp_config() - Propagate config parameters to Lithium
14952 * datapath
14953 * @hdd_ctx: HDD Context
14954 *
14955 * Return: 0 for success/errno for failure
14956 */
14957static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
14958{
Abhishek Singh98278ce2018-12-27 11:41:03 +053014959 struct cdp_config_params params = {0};
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014960 QDF_STATUS status;
jitiphil377bcc12018-10-05 19:46:08 +053014961 void *soc;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014962
jitiphil377bcc12018-10-05 19:46:08 +053014963 soc = cds_get_context(QDF_MODULE_ID_SOC);
14964 params.tso_enable = cfg_get(hdd_ctx->psoc, CFG_DP_TSO);
14965 params.lro_enable = cfg_get(hdd_ctx->psoc, CFG_DP_LRO);
hangtianb9c91362019-06-07 10:39:38 +080014966 hdd_update_dp_config_queue_threshold(hdd_ctx, &params);
jitiphil377bcc12018-10-05 19:46:08 +053014967 params.flow_steering_enable =
14968 cfg_get(hdd_ctx->psoc, CFG_DP_FLOW_STEERING_ENABLED);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014969 params.napi_enable = hdd_ctx->napi_enable;
14970 params.tcp_udp_checksumoffload =
jitiphil377bcc12018-10-05 19:46:08 +053014971 cfg_get(hdd_ctx->psoc,
14972 CFG_DP_TCP_UDP_CKSUM_OFFLOAD);
Sravan Kumar Kairam0af1ee52018-12-12 20:37:51 +053014973 params.ipa_enable = ucfg_ipa_is_enabled();
Mohit Khanna81418772018-10-30 14:14:46 -070014974 params.gro_enable = cfg_get(hdd_ctx->psoc, CFG_DP_GRO);
Mohit Khannaa8c9f562019-03-25 22:17:02 -070014975 params.tx_comp_loop_pkt_limit = cfg_get(hdd_ctx->psoc,
14976 CFG_DP_TX_COMP_LOOP_PKT_LIMIT);
14977 params.rx_reap_loop_pkt_limit = cfg_get(hdd_ctx->psoc,
14978 CFG_DP_RX_REAP_LOOP_PKT_LIMIT);
14979 params.rx_hp_oos_update_limit = cfg_get(hdd_ctx->psoc,
14980 CFG_DP_RX_HP_OOS_UPDATE_LIMIT);
14981 hdd_update_dp_config_rx_softirq_limits(hdd_ctx, &params);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014982
jitiphil377bcc12018-10-05 19:46:08 +053014983 status = cdp_update_config_parameters(soc, &params);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014984 if (status) {
Dustin Browna2868622018-03-20 11:38:14 -070014985 hdd_err("Failed to attach config parameters");
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014986 return status;
14987 }
14988
14989 return 0;
14990}
14991
14992/**
Komal Seelamec702b02016-02-24 18:42:16 +053014993 * hdd_update_config() - Initialize driver per module ini parameters
14994 * @hdd_ctx: HDD Context
14995 *
14996 * API is used to initialize all driver per module configuration parameters
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014997 * Return: 0 for success, errno for failure
Komal Seelamec702b02016-02-24 18:42:16 +053014998 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014999int hdd_update_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053015000{
Arun Khandavallic811dcc2016-06-26 07:37:21 +053015001 int ret;
15002
Wu Gao66454f12018-09-26 19:55:41 +080015003 if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc))
15004 hdd_ctx->ns_offload_enable = true;
15005
Komal Seelamec702b02016-02-24 18:42:16 +053015006 hdd_update_ol_config(hdd_ctx);
15007 hdd_update_hif_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053015008 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
15009 ret = hdd_update_cds_config_ftm(hdd_ctx);
15010 else
15011 ret = hdd_update_cds_config(hdd_ctx);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080015012 ret = hdd_update_user_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053015013
15014 return ret;
Komal Seelamc11bb222016-01-27 18:57:10 +053015015}
15016
Mukul Sharma9d797a02017-01-05 20:26:03 +053015017/**
15018 * hdd_update_pmo_config - API to update pmo configuration parameters
15019 * @hdd_ctx: HDD context
15020 *
15021 * Return: void
15022 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015023static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053015024{
Abhishek Singh98278ce2018-12-27 11:41:03 +053015025 struct pmo_psoc_cfg psoc_cfg = {0};
Mukul Sharma9d797a02017-01-05 20:26:03 +053015026 QDF_STATUS status;
Wu Gao66454f12018-09-26 19:55:41 +080015027 enum pmo_wow_enable_type wow_enable;
15028
15029 ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg);
Mukul Sharma9d797a02017-01-05 20:26:03 +053015030
15031 /*
15032 * Value of hdd_ctx->wowEnable can be,
15033 * 0 - Disable both magic pattern match and pattern byte match.
15034 * 1 - Enable magic pattern match on all interfaces.
15035 * 2 - Enable pattern byte match on all interfaces.
15036 * 3 - Enable both magic patter and pattern byte match on
15037 * all interfaces.
15038 */
Wu Gao66454f12018-09-26 19:55:41 +080015039 wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc);
15040 psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false;
Mukul Sharma9d797a02017-01-05 20:26:03 +053015041 psoc_cfg.ptrn_match_enable_all_vdev =
Wu Gao66454f12018-09-26 19:55:41 +080015042 (wow_enable & 0x02) ? true : false;
Mukul Sharma9d797a02017-01-05 20:26:03 +053015043 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
Will Huang3cd2b7c2017-11-17 13:16:56 +080015044 psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
Bala Venkatesh46e29032018-11-14 18:24:55 +053015045 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
15046 &psoc_cfg.sta_max_li_mod_dtim);
15047
Mukul Sharma9d797a02017-01-05 20:26:03 +053015048
Mukul Sharma9223f232017-03-08 18:42:27 +053015049 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053015050
Dustin Brown1dbefe62018-09-11 16:32:03 -070015051 status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg);
Dustin Brownb9987af2018-03-01 17:15:11 -080015052 if (QDF_IS_STATUS_ERROR(status))
15053 hdd_err("failed pmo psoc configuration; status:%d", status);
15054
15055 return qdf_status_to_os_return(status);
Mukul Sharma9d797a02017-01-05 20:26:03 +053015056}
15057
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015058void hdd_update_ie_whitelist_attr(struct probe_req_whitelist_attr *ie_whitelist,
Dundi Raviteja85a240a2018-09-10 15:03:07 +053015059 struct hdd_context *hdd_ctx)
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015060{
Dundi Raviteja85a240a2018-09-10 15:03:07 +053015061 struct wlan_fwol_ie_whitelist whitelist = {0};
15062 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Dundi Raviteja85a240a2018-09-10 15:03:07 +053015063 QDF_STATUS status;
15064 bool is_ie_whitelist_enable = false;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015065 uint8_t i = 0;
15066
Dundi Raviteja85a240a2018-09-10 15:03:07 +053015067 status = ucfg_fwol_get_ie_whitelist(psoc, &is_ie_whitelist_enable);
15068 if (QDF_IS_STATUS_ERROR(status)) {
15069 hdd_err("Unable to get IE whitelist param");
15070 return;
15071 }
15072
15073 ie_whitelist->white_list = is_ie_whitelist_enable;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015074 if (!ie_whitelist->white_list)
15075 return;
15076
Dundi Raviteja85a240a2018-09-10 15:03:07 +053015077 status = ucfg_fwol_get_all_whitelist_params(psoc, &whitelist);
15078 if (QDF_IS_STATUS_ERROR(status)) {
15079 hdd_err("Unable to get all whitelist params");
15080 return;
15081 }
15082
15083 ie_whitelist->ie_bitmap[0] = whitelist.ie_bitmap_0;
15084 ie_whitelist->ie_bitmap[1] = whitelist.ie_bitmap_1;
15085 ie_whitelist->ie_bitmap[2] = whitelist.ie_bitmap_2;
15086 ie_whitelist->ie_bitmap[3] = whitelist.ie_bitmap_3;
15087 ie_whitelist->ie_bitmap[4] = whitelist.ie_bitmap_4;
15088 ie_whitelist->ie_bitmap[5] = whitelist.ie_bitmap_5;
15089 ie_whitelist->ie_bitmap[6] = whitelist.ie_bitmap_6;
15090 ie_whitelist->ie_bitmap[7] = whitelist.ie_bitmap_7;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015091
Dundi Raviteja9ab4e7b2018-09-28 14:18:28 +053015092 ie_whitelist->num_vendor_oui = whitelist.no_of_probe_req_ouis;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015093 for (i = 0; i < ie_whitelist->num_vendor_oui; i++)
Dundi Raviteja9ab4e7b2018-09-28 14:18:28 +053015094 ie_whitelist->voui[i] = whitelist.probe_req_voui[i];
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053015095}
15096
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015097uint32_t hdd_limit_max_per_index_score(uint32_t per_index_score)
15098{
15099 uint8_t i, score;
15100
15101 for (i = 0; i < MAX_INDEX_PER_INI; i++) {
15102 score = WLAN_GET_SCORE_PERCENTAGE(per_index_score, i);
15103 if (score > MAX_INDEX_SCORE)
15104 WLAN_SET_SCORE_PERCENTAGE(per_index_score,
15105 MAX_INDEX_SCORE, i);
15106 }
15107
15108 return per_index_score;
15109}
15110
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053015111QDF_STATUS hdd_update_score_config(
15112 struct scoring_config *score_config, struct hdd_context *hdd_ctx)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015113{
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053015114 struct hdd_config *cfg = hdd_ctx->config;
gaurank kathpaliaae52c982018-10-04 01:35:18 +053015115 QDF_STATUS status;
gaurank kathpalia651abcd2018-11-12 22:41:23 +053015116 struct wlan_mlme_nss_chains vdev_ini_cfg;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053015117 bool bval = false;
Wu Gaoed616a12019-01-16 15:19:21 +080015118 uint32_t channel_bonding_mode;
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015119
Abhishek Singh98278ce2018-12-27 11:41:03 +053015120 qdf_mem_zero(&vdev_ini_cfg, sizeof(struct wlan_mlme_nss_chains));
gaurank kathpalia651abcd2018-11-12 22:41:23 +053015121 /* Populate the nss chain params from ini for this vdev type */
15122 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
15123 QDF_STA_MODE,
15124 hdd_ctx->num_rf_chains);
15125
15126 score_config->vdev_nss_24g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ];
gaurank kathpalia19c23542019-06-01 16:57:28 +053015127 score_config->vdev_nss_5g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ];
gaurank kathpalia651abcd2018-11-12 22:41:23 +053015128
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053015129 sme_update_score_config(hdd_ctx->mac_handle, score_config);
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015130
Wu Gaoed616a12019-01-16 15:19:21 +080015131 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
15132 &channel_bonding_mode);
15133 score_config->cb_mode_24G = channel_bonding_mode;
15134 ucfg_mlme_get_channel_bonding_5ghz(hdd_ctx->psoc,
15135 &channel_bonding_mode);
15136 score_config->cb_mode_5G = channel_bonding_mode;
gaurank kathpaliaae52c982018-10-04 01:35:18 +053015137
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015138 if (cfg->dot11Mode == eHDD_DOT11_MODE_AUTO ||
15139 cfg->dot11Mode == eHDD_DOT11_MODE_11ax ||
15140 cfg->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)
15141 score_config->he_cap = 1;
15142
15143 if (score_config->he_cap ||
15144 cfg->dot11Mode == eHDD_DOT11_MODE_11ac ||
15145 cfg->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)
15146 score_config->vht_cap = 1;
15147
15148 if (score_config->vht_cap || cfg->dot11Mode == eHDD_DOT11_MODE_11n ||
15149 cfg->dot11Mode == eHDD_DOT11_MODE_11n_ONLY)
15150 score_config->ht_cap = 1;
15151
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053015152 status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &bval);
15153 if (!QDF_IS_STATUS_SUCCESS(status))
15154 hdd_err("Failed to get vht_for_24ghz");
15155 if (score_config->vht_cap && bval)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015156 score_config->vht_24G_cap = 1;
15157
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053015158 status = ucfg_mlme_get_vht_enable_tx_bf(hdd_ctx->psoc,
15159 &bval);
15160 if (!QDF_IS_STATUS_SUCCESS(status))
15161 hdd_err("unable to get vht_enable_tx_bf");
15162
15163 if (bval)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015164 score_config->beamformee_cap = 1;
15165
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053015166 return QDF_STATUS_SUCCESS;
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053015167}
15168
Abhishek Singh257a9482017-03-06 16:52:39 +053015169/**
bings81fe50a2017-11-27 14:33:26 +080015170 * hdd_update_dfs_config() - API to update dfs configuration parameters.
15171 * @hdd_ctx: HDD context
15172 *
15173 * Return: 0 if success else err
15174 */
15175static int hdd_update_dfs_config(struct hdd_context *hdd_ctx)
15176{
Dustin Brown1dbefe62018-09-11 16:32:03 -070015177 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Abhishek Singh98278ce2018-12-27 11:41:03 +053015178 struct dfs_user_config dfs_cfg = {0};
bings81fe50a2017-11-27 14:33:26 +080015179 QDF_STATUS status;
15180
Arif Hussain224d3812018-11-16 17:58:38 -080015181 ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc,
15182 &dfs_cfg.dfs_is_phyerr_filter_offload);
bings81fe50a2017-11-27 14:33:26 +080015183 status = ucfg_dfs_update_config(psoc, &dfs_cfg);
15184 if (QDF_IS_STATUS_ERROR(status)) {
15185 hdd_err("failed dfs psoc configuration");
15186 return -EINVAL;
15187 }
15188
15189 return 0;
15190}
15191
15192/**
Abhishek Singh257a9482017-03-06 16:52:39 +053015193 * hdd_update_scan_config - API to update scan configuration parameters
15194 * @hdd_ctx: HDD context
15195 *
15196 * Return: 0 if success else err
15197 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015198static int hdd_update_scan_config(struct hdd_context *hdd_ctx)
Abhishek Singh257a9482017-03-06 16:52:39 +053015199{
Dustin Brown1dbefe62018-09-11 16:32:03 -070015200 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Sandeep Puligillad7887022019-02-26 00:48:52 -080015201 struct scan_user_cfg scan_cfg;
Abhishek Singh257a9482017-03-06 16:52:39 +053015202 QDF_STATUS status;
Krunal Sonid2c33e12018-12-06 15:02:37 -080015203 uint32_t mcast_mcc_rest_time = 0;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053015204
Sandeep Puligillad7887022019-02-26 00:48:52 -080015205 qdf_mem_zero(&scan_cfg, sizeof(scan_cfg));
Krunal Sonid2c33e12018-12-06 15:02:37 -080015206 status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc,
15207 &mcast_mcc_rest_time);
15208 if (!QDF_IS_STATUS_SUCCESS(status)) {
15209 hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def");
15210 return -EIO;
15211 }
15212 scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time;
Dundi Raviteja85a240a2018-09-10 15:03:07 +053015213 hdd_update_ie_whitelist_attr(&scan_cfg.ie_whitelist, hdd_ctx);
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053015214
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053015215 status = hdd_update_score_config(&scan_cfg.score_config, hdd_ctx);
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053015216 if (QDF_IS_STATUS_ERROR(status)) {
15217 hdd_err("Failed to update scoring config");
15218 return -EINVAL;
15219 }
Abhishek Singhb20db962017-03-03 21:28:46 +053015220
Abhishek Singh257a9482017-03-06 16:52:39 +053015221 status = ucfg_scan_update_user_config(psoc, &scan_cfg);
15222 if (status != QDF_STATUS_SUCCESS) {
15223 hdd_err("failed pmo psoc configuration");
15224 return -EINVAL;
15225 }
15226
15227 return 0;
15228}
Abhishek Singh257a9482017-03-06 16:52:39 +053015229
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015230int hdd_update_components_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053015231{
15232 int ret;
15233
15234 ret = hdd_update_pmo_config(hdd_ctx);
Abhishek Singh257a9482017-03-06 16:52:39 +053015235 if (ret)
15236 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015237
Abhishek Singh257a9482017-03-06 16:52:39 +053015238 ret = hdd_update_scan_config(hdd_ctx);
Frank Liud4b2fa02017-03-29 11:46:48 +080015239 if (ret)
15240 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015241
Frank Liud4b2fa02017-03-29 11:46:48 +080015242 ret = hdd_update_tdls_config(hdd_ctx);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070015243 if (ret)
15244 return ret;
15245
15246 ret = hdd_update_dp_config(hdd_ctx);
bings81fe50a2017-11-27 14:33:26 +080015247 if (ret)
15248 return ret;
15249
15250 ret = hdd_update_dfs_config(hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053015251
15252 return ret;
15253}
15254
Agrawal Ashish65634612016-08-18 13:24:32 +053015255/**
15256 * wlan_hdd_get_dfs_mode() - get ACS DFS mode
15257 * @mode : cfg80211 DFS mode
15258 *
15259 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
15260 */
15261enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
15262{
15263 switch (mode) {
15264 case DFS_MODE_ENABLE:
15265 return ACS_DFS_MODE_ENABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053015266 case DFS_MODE_DISABLE:
15267 return ACS_DFS_MODE_DISABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053015268 case DFS_MODE_DEPRIORITIZE:
15269 return ACS_DFS_MODE_DEPRIORITIZE;
Agrawal Ashish65634612016-08-18 13:24:32 +053015270 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080015271 hdd_debug("ACS dfs mode is NONE");
15272 return ACS_DFS_MODE_NONE;
Agrawal Ashish65634612016-08-18 13:24:32 +053015273 }
15274}
15275
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053015276/**
15277 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
15278 * @hddctx: pointer to hdd context
15279 * @set_value: enable/disable
15280 *
15281 * When Host sends vendor command enable, FW will send *ONE* CA ind to
15282 * Host(even though it is duplicate). When Host send vendor command
15283 * disable,FW doesn't perform any action. Whenever any change in
15284 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
15285 *
15286 * return - 0 on success, appropriate error values on failure.
15287 */
Jeff Johnson16528362018-06-14 12:34:16 -070015288int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value)
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053015289{
15290 QDF_STATUS status;
15291
Jeff Johnson16528362018-06-14 12:34:16 -070015292 if (0 != wlan_hdd_validate_context(hdd_ctx))
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053015293 return -EAGAIN;
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053015294
Jeff Johnson16528362018-06-14 12:34:16 -070015295 status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle,
15296 set_value);
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053015297 if (!QDF_IS_STATUS_SUCCESS(status)) {
15298 hdd_err("Failed to send chan avoid command to SME");
15299 return -EINVAL;
15300 }
15301 return 0;
15302}
Agrawal Ashish65634612016-08-18 13:24:32 +053015303
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015304/**
15305 * hdd_set_roaming_in_progress() - to set the roaming in progress flag
15306 * @value: value to set
15307 *
15308 * This function will set the passed value to roaming in progress flag.
15309 *
15310 * Return: None
15311 */
15312void hdd_set_roaming_in_progress(bool value)
15313{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015314 struct hdd_context *hdd_ctx;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015315
15316 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15317 if (!hdd_ctx) {
15318 hdd_err("HDD context is NULL");
15319 return;
15320 }
15321
15322 hdd_ctx->roaming_in_progress = value;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080015323 hdd_debug("Roaming in Progress set to %d", value);
Abhinav Kumar2b431b62019-03-18 20:23:58 +053015324 if (!hdd_ctx->roaming_in_progress) {
15325 /* Reset scan reject params on successful roam complete */
15326 hdd_debug("Reset scan reject params");
15327 hdd_init_scan_reject_params(hdd_ctx);
15328 }
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015329}
15330
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053015331bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx)
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015332{
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015333 if (!hdd_ctx) {
15334 hdd_err("HDD context is NULL");
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053015335 return false;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015336 }
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080015337
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053015338 hdd_debug("roaming_in_progress = %d", hdd_ctx->roaming_in_progress);
15339
15340 return hdd_ctx->roaming_in_progress;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080015341}
15342
Jeff Johnsona2ac4e72019-03-06 08:35:29 -080015343bool hdd_is_connection_in_progress(uint8_t *out_vdev_id,
15344 enum scan_reject_states *out_reason)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015345{
Jeff Johnson40dae4e2017-08-29 14:00:25 -070015346 struct hdd_station_ctx *hdd_sta_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -070015347 struct hdd_adapter *adapter = NULL;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015348 uint8_t sta_id = 0;
15349 uint8_t *sta_mac = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015350 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -070015351 mac_handle_t mac_handle;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015352
15353 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15354 if (!hdd_ctx) {
15355 hdd_err("HDD context is NULL");
15356 return false;
15357 }
15358
Jeff Johnson16528362018-06-14 12:34:16 -070015359 mac_handle = hdd_ctx->mac_handle;
15360
Dustin Brown920397d2017-12-13 16:27:50 -080015361 hdd_for_each_adapter(hdd_ctx, adapter) {
Tushnim Bhattacharyya929afa42018-06-01 15:04:44 -070015362 hdd_debug("Adapter with device mode %s(%d) exists",
Dustin Brown458027c2018-10-19 12:26:27 -070015363 qdf_opmode_str(adapter->device_mode),
15364 adapter->device_mode);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015365 if (((QDF_STA_MODE == adapter->device_mode)
15366 || (QDF_P2P_CLIENT_MODE == adapter->device_mode)
15367 || (QDF_P2P_DEVICE_MODE == adapter->device_mode))
15368 && (eConnectionState_Connecting ==
15369 (WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
Jeff Johnsone7951512019-02-27 10:02:51 -080015370 conn_info.conn_state)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053015371 hdd_debug("%pK(%d) Connection is in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015372 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015373 adapter->vdev_id);
Jeff Johnsona2ac4e72019-03-06 08:35:29 -080015374 if (out_vdev_id && out_reason) {
15375 *out_vdev_id = adapter->vdev_id;
15376 *out_reason = CONNECTION_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015377 }
15378 return true;
15379 }
Archana Ramachandran62886ce2017-03-24 14:46:32 -070015380 /*
15381 * sme_neighbor_middle_of_roaming is for LFR2
15382 * hdd_is_roaming_in_progress is for LFR3
15383 */
15384 if (((QDF_STA_MODE == adapter->device_mode) &&
15385 sme_neighbor_middle_of_roaming(
Jeff Johnson16528362018-06-14 12:34:16 -070015386 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015387 adapter->vdev_id)) ||
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053015388 hdd_is_roaming_in_progress(hdd_ctx)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053015389 hdd_debug("%pK(%d) Reassociation in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015390 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015391 adapter->vdev_id);
Jeff Johnsona2ac4e72019-03-06 08:35:29 -080015392 if (out_vdev_id && out_reason) {
15393 *out_vdev_id = adapter->vdev_id;
15394 *out_reason = REASSOC_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015395 }
15396 return true;
15397 }
15398 if ((QDF_STA_MODE == adapter->device_mode) ||
15399 (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
15400 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
15401 hdd_sta_ctx =
15402 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
15403 if ((eConnectionState_Associated ==
Jeff Johnsone7951512019-02-27 10:02:51 -080015404 hdd_sta_ctx->conn_info.conn_state)
Vignesh Viswanathan0a569292018-02-14 15:34:47 +053015405 && sme_is_sta_key_exchange_in_progress(
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015406 mac_handle, adapter->vdev_id)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015407 sta_mac = (uint8_t *)
Jeff Johnson1e851a12017-10-28 14:36:12 -070015408 &(adapter->mac_addr.bytes[0]);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070015409 hdd_debug("client " QDF_MAC_ADDR_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015410 " is in middle of WPS/EAPOL exchange.",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070015411 QDF_MAC_ADDR_ARRAY(sta_mac));
Jeff Johnsona2ac4e72019-03-06 08:35:29 -080015412 if (out_vdev_id && out_reason) {
15413 *out_vdev_id = adapter->vdev_id;
15414 *out_reason = EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015415 }
15416 return true;
15417 }
15418 } else if ((QDF_SAP_MODE == adapter->device_mode) ||
15419 (QDF_P2P_GO_MODE == adapter->device_mode)) {
15420 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
15421 sta_id++) {
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070015422 if (!((adapter->sta_info[sta_id].in_use)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015423 && (OL_TXRX_PEER_STATE_CONN ==
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070015424 adapter->sta_info[sta_id].peer_state)))
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015425 continue;
15426
15427 sta_mac = (uint8_t *)
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070015428 &(adapter->sta_info[sta_id].
Jeff Johnsonf2356512017-10-21 16:04:12 -070015429 sta_mac.bytes[0]);
Srinivas Girigowdacb7b8b82019-04-10 14:27:47 -070015430 hdd_debug("client " QDF_MAC_ADDR_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015431 " of SAP/GO is in middle of WPS/EAPOL exchange",
Srinivas Girigowda34fbba02019-04-08 12:07:44 -070015432 QDF_MAC_ADDR_ARRAY(sta_mac));
Jeff Johnsona2ac4e72019-03-06 08:35:29 -080015433 if (out_vdev_id && out_reason) {
15434 *out_vdev_id = adapter->vdev_id;
15435 *out_reason = SAP_EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015436 }
15437 return true;
15438 }
15439 if (hdd_ctx->connection_in_progress) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053015440 hdd_debug("AP/GO: connection is in progress");
Bala Venkatesh25b852b2019-09-20 11:41:35 +053015441 if (out_vdev_id && out_reason) {
15442 *out_reason =
15443 SAP_CONNECTION_IN_PROGRESS;
15444 *out_vdev_id = adapter->vdev_id;
15445 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015446 return true;
15447 }
15448 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015449 }
Dustin Brown920397d2017-12-13 16:27:50 -080015450
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015451 return false;
15452}
15453
15454/**
15455 * hdd_restart_sap() - to restart SAP in driver internally
Jeff Johnson9d295242017-08-29 14:39:48 -070015456 * @ap_adapter: Pointer to SAP struct hdd_adapter structure
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015457 *
15458 * Return: None
15459 */
Jeff Johnson9d295242017-08-29 14:39:48 -070015460void hdd_restart_sap(struct hdd_adapter *ap_adapter)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015461{
Jeff Johnson87251032017-08-29 13:31:11 -070015462 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070015463 struct hdd_hostapd_state *hostapd_state;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015464 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015465 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Jeff Johnson8f8ceb92019-03-24 08:16:55 -070015466 struct sap_config *sap_config;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015467 void *sap_ctx;
15468
15469 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
Jeff Johnson91df29d2017-10-27 19:29:50 -070015470 sap_config = &hdd_ap_ctx->sap_config;
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070015471 sap_ctx = hdd_ap_ctx->sap_context;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015472
15473 mutex_lock(&hdd_ctx->sap_lock);
15474 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
15475 wlan_hdd_del_station(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015476 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
15477 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
15478 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
15479 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053015480 qdf_wait_for_event_completion(&hostapd_state->
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015481 qdf_stop_bss_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053015482 SME_CMD_STOP_BSS_TIMEOUT);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015483
15484 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015485 hdd_err("SAP Stop Failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015486 goto end;
15487 }
15488 }
15489 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -070015490 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015491 ap_adapter->device_mode, ap_adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070015492 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053015493 false);
Jeff Johnson6867ec32017-09-29 20:30:20 -070015494 hdd_err("SAP Stop Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015495
15496 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015497 hdd_err("SAP Not able to set AP IEs");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015498 wlansap_reset_sap_config_add_ie(sap_config,
15499 eUPDATE_IE_ALL);
15500 goto end;
15501 }
15502
15503 qdf_event_reset(&hostapd_state->qdf_event);
15504 if (wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
15505 sap_config,
15506 ap_adapter->dev) != QDF_STATUS_SUCCESS) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015507 hdd_err("SAP Start Bss fail");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015508 wlansap_reset_sap_config_add_ie(sap_config,
15509 eUPDATE_IE_ALL);
15510 goto end;
15511 }
15512
Jeff Johnson6867ec32017-09-29 20:30:20 -070015513 hdd_info("Waiting for SAP to start");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015514 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053015515 qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053015516 SME_CMD_START_BSS_TIMEOUT);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015517 wlansap_reset_sap_config_add_ie(sap_config,
15518 eUPDATE_IE_ALL);
15519 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015520 hdd_err("SAP Start failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015521 goto end;
15522 }
Jeff Johnson6867ec32017-09-29 20:30:20 -070015523 hdd_err("SAP Start Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015524 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053015525 if (hostapd_state->bss_state == BSS_START) {
Dustin Brown1dbefe62018-09-11 16:32:03 -070015526 policy_mgr_incr_active_session(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080015527 ap_adapter->device_mode,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015528 ap_adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070015529 hdd_green_ap_start_state_mc(hdd_ctx,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053015530 ap_adapter->device_mode,
15531 true);
15532 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015533 }
15534end:
15535 mutex_unlock(&hdd_ctx->sap_lock);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015536}
15537
15538/**
15539 * hdd_check_and_restart_sap_with_non_dfs_acs() - Restart SAP
15540 * with non dfs acs
15541 *
15542 * Restarts SAP in non-DFS ACS mode when STA-AP mode DFS is not supported
15543 *
15544 * Return: None
15545 */
15546void hdd_check_and_restart_sap_with_non_dfs_acs(void)
15547{
Jeff Johnson9d295242017-08-29 14:39:48 -070015548 struct hdd_adapter *ap_adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015549 struct hdd_context *hdd_ctx;
Jeff Johnson2b6982c2018-05-29 14:56:11 -070015550 struct cds_context *cds_ctx;
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053015551 uint8_t restart_chan;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015552
15553 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15554 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015555 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015556 return;
15557 }
15558
15559 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
15560 if (!cds_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015561 hdd_err("Invalid CDS Context");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015562 return;
15563 }
15564
Dustin Brown1dbefe62018-09-11 16:32:03 -070015565 if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc)
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080015566 != (QDF_STA_MASK | QDF_SAP_MASK)) {
Dustin Brown7e761c72018-07-31 13:50:17 -070015567 hdd_debug("Concurrency mode is not SAP");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015568 return;
15569 }
15570
15571 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
Dustin Brown07901ec2018-09-07 11:02:41 -070015572 if (ap_adapter &&
15573 test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags) &&
15574 wlan_reg_is_dfs_ch(hdd_ctx->pdev,
15575 ap_adapter->session.ap.operating_channel)) {
Liangwei Dong444cd262019-05-08 23:22:56 -040015576 if (policy_mgr_get_dfs_master_dynamic_enabled(
15577 hdd_ctx->psoc, ap_adapter->vdev_id))
15578 return;
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053015579 hdd_warn("STA-AP Mode DFS not supported, Switch SAP channel to Non DFS");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015580
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053015581 restart_chan =
bings6c4672b2019-03-19 16:00:19 +080015582 wlansap_get_safe_channel_from_pcl_and_acs_range(
15583 WLAN_HDD_GET_SAP_CTX_PTR(ap_adapter));
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053015584 if (!restart_chan ||
Dustin Brown07901ec2018-09-07 11:02:41 -070015585 wlan_reg_is_dfs_ch(hdd_ctx->pdev, restart_chan))
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053015586 restart_chan = SAP_DEFAULT_5GHZ_CHANNEL;
Bala Venkatesh8b9bbde2019-07-03 16:25:16 +053015587 wlan_hdd_set_sap_csa_reason(hdd_ctx->psoc, ap_adapter->vdev_id,
15588 CSA_REASON_STA_CONNECT_DFS_TO_NON_DFS);
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053015589 hdd_switch_sap_channel(ap_adapter, restart_chan, true);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015590 }
15591}
15592
15593/**
15594 * hdd_set_connection_in_progress() - to set the connection in
15595 * progress flag
15596 * @value: value to set
15597 *
15598 * This function will set the passed value to connection in progress flag.
15599 * If value is previously being set to true then no need to set it again.
15600 *
15601 * Return: true if value is being set correctly and false otherwise.
15602 */
15603bool hdd_set_connection_in_progress(bool value)
15604{
15605 bool status = true;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015606 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015607
15608 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15609 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070015610 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080015611 return false;
15612 }
15613
15614 qdf_spin_lock(&hdd_ctx->connection_status_lock);
15615 /*
15616 * if the value is set to true previously and if someone is
15617 * trying to make it true again then it could be some race
15618 * condition being triggered. Avoid this situation by returning
15619 * false
15620 */
15621 if (hdd_ctx->connection_in_progress && value)
15622 status = false;
15623 else
15624 hdd_ctx->connection_in_progress = value;
15625 qdf_spin_unlock(&hdd_ctx->connection_status_lock);
15626 return status;
15627}
15628
Jeff Johnson9d295242017-08-29 14:39:48 -070015629int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070015630{
15631 if (!adapter) {
15632 hdd_err("Invalid adapter");
15633 return -EINVAL;
15634 }
15635 hdd_info("Send MCC P2P QUOTA to WMA: %d", set_value);
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015636 sme_cli_set_command(adapter->vdev_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070015637 WMA_VDEV_MCC_SET_TIME_QUOTA,
15638 set_value, VDEV_CMD);
15639 return 0;
15640
15641}
15642
Jeff Johnson9d295242017-08-29 14:39:48 -070015643int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070015644{
15645 if (!adapter) {
15646 hdd_err("Invalid adapter");
15647 return -EINVAL;
15648 }
15649
15650 hdd_info("Send MCC latency WMA: %d", set_value);
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015651 sme_cli_set_command(adapter->vdev_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070015652 WMA_VDEV_MCC_SET_TIME_LATENCY,
15653 set_value, VDEV_CMD);
15654 return 0;
15655}
15656
Jeff Johnson9d295242017-08-29 14:39:48 -070015657struct hdd_adapter *wlan_hdd_get_adapter_from_vdev(struct wlan_objmgr_psoc
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070015658 *psoc, uint8_t vdev_id)
15659{
Jeff Johnson9d295242017-08-29 14:39:48 -070015660 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070015661 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070015662
15663 /*
15664 * Currently PSOC is not being used. But this logic will
15665 * change once we have the converged implementation of
15666 * HDD context per PSOC in place. This would break if
15667 * multiple vdev objects reuse the vdev id.
15668 */
15669 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
15670 if (!adapter)
15671 hdd_err("Get adapter by vdev id failed");
15672
15673 return adapter;
15674}
15675
Jeff Johnson9d295242017-08-29 14:39:48 -070015676int hdd_get_rssi_snr_by_bssid(struct hdd_adapter *adapter, const uint8_t *bssid,
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053015677 int8_t *rssi, int8_t *snr)
15678{
15679 QDF_STATUS status;
Jeff Johnson16528362018-06-14 12:34:16 -070015680 mac_handle_t mac_handle;
Jeff Johnson025618c2018-03-18 14:41:00 -070015681 struct csr_roam_profile *roam_profile;
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053015682
Jeff Johnson025618c2018-03-18 14:41:00 -070015683 roam_profile = hdd_roam_profile(adapter);
Jeff Johnson16528362018-06-14 12:34:16 -070015684 mac_handle = hdd_adapter_get_mac_handle(adapter);
15685 status = sme_get_rssi_snr_by_bssid(mac_handle,
Jeff Johnson025618c2018-03-18 14:41:00 -070015686 roam_profile, bssid, rssi, snr);
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053015687 if (QDF_STATUS_SUCCESS != status) {
15688 hdd_warn("sme_get_rssi_snr_by_bssid failed");
15689 return -EINVAL;
15690 }
15691
15692 return 0;
15693}
15694
Ganesh Kondabattini35739572017-06-21 16:26:39 +053015695/**
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015696 * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
15697 * @adapter - HDD adapter
15698 *
15699 * Return: 0 on success and non zero value on failure
15700 */
15701int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
15702{
15703 struct hdd_context *hdd_ctx;
15704 int ret;
15705 QDF_STATUS status;
Krunal Sonie71838d2018-09-27 10:45:05 -070015706 uint8_t sys_pref = 0;
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015707
15708 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
15709 ret = wlan_hdd_validate_context(hdd_ctx);
15710 if (ret < 0)
15711 return ret;
15712
Krunal Sonie71838d2018-09-27 10:45:05 -070015713 ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc,
15714 &sys_pref);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015715 /* set the system preferece to default */
Krunal Sonie71838d2018-09-27 10:45:05 -070015716 policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015717
15718 /* clear the bitmap */
15719 adapter->active_ac = 0;
15720
15721 hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015722 adapter->vdev_id, adapter->active_ac);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015723
Jeff Johnson16528362018-06-14 12:34:16 -070015724 status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080015725 adapter->vdev_id,
Jeff Johnson16528362018-06-14 12:34:16 -070015726 false, 0, 0, false);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015727 if (!QDF_IS_STATUS_SUCCESS(status)) {
15728 hdd_err("failed to reset limit off chan params");
15729 ret = -EINVAL;
15730 }
Ganesh Kondabattini35739572017-06-21 16:26:39 +053015731
15732 return ret;
15733}
15734
Yun Parkff6a16a2017-09-26 16:38:18 -070015735void hdd_set_rx_mode_rps(bool enable)
15736{
15737 struct cds_config_info *cds_cfg = cds_get_ini_config();
Ryan Hsu0e878fa2018-05-04 15:22:09 -070015738 struct hdd_context *hdd_ctx;
15739 struct hdd_adapter *adapter;
Yun Parkff6a16a2017-09-26 16:38:18 -070015740
Ryan Hsu0e878fa2018-05-04 15:22:09 -070015741 if (!cds_cfg)
15742 return;
15743
15744 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15745 if (!hdd_ctx)
15746 return;
15747
15748 adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
15749 if (!adapter)
15750 return;
15751
15752 if (!hdd_ctx->rps && cds_cfg->uc_offload_enabled) {
Yun Parkff6a16a2017-09-26 16:38:18 -070015753 if (enable && !cds_cfg->rps_enabled)
15754 hdd_send_rps_ind(adapter);
15755 else if (!enable && cds_cfg->rps_enabled)
15756 hdd_send_rps_disable_ind(adapter);
15757 }
15758}
15759
Abhinav Kumar338e57d2019-02-04 17:30:10 +053015760void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id)
15761{
15762 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
15763 struct hdd_adapter *adapter;
15764
15765 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
15766
15767 if (!adapter) {
15768 hdd_err("Adapter is null");
15769 return;
15770 }
15771 /* enable roaming on all adapters once hdd get hidden ssid rsp */
Abhinav Kumar523ca372019-08-30 16:28:19 +053015772 wlan_hdd_enable_roaming(adapter, RSO_START_BSS);
Abhinav Kumar338e57d2019-02-04 17:30:10 +053015773}
15774
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015775/* Register the module init/exit functions */
15776module_init(hdd_module_init);
15777module_exit(hdd_module_exit);
15778
15779MODULE_LICENSE("Dual BSD/GPL");
15780MODULE_AUTHOR("Qualcomm Atheros, Inc.");
15781MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
15782
Srinivas Girigowda841da292018-02-21 16:33:00 -080015783static const struct kernel_param_ops con_mode_ops = {
15784 .set = con_mode_handler,
15785 .get = param_get_int,
15786};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015787
Srinivas Girigowda841da292018-02-21 16:33:00 -080015788static const struct kernel_param_ops con_mode_ftm_ops = {
15789 .set = con_mode_handler_ftm,
15790 .get = param_get_int,
15791};
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053015792
Nirav Shah6aeecf92019-02-13 14:05:03 +053015793#ifdef WLAN_FEATURE_EPPING
15794static const struct kernel_param_ops con_mode_epping_ops = {
15795 .set = con_mode_handler_epping,
15796 .get = param_get_int,
15797};
15798#endif
15799
Srinivas Girigowda841da292018-02-21 16:33:00 -080015800static const struct kernel_param_ops fwpath_ops = {
15801 .set = fwpath_changed_handler,
15802 .get = param_get_string,
15803};
15804
15805module_param_cb(con_mode, &con_mode_ops, &con_mode,
15806 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
15807
15808module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm,
15809 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
15810
Nirav Shah6aeecf92019-02-13 14:05:03 +053015811#ifdef WLAN_FEATURE_EPPING
15812module_param_cb(con_mode_epping, &con_mode_epping_ops,
15813 &con_mode_epping, 0644);
15814#endif
15815
Srinivas Girigowda841da292018-02-21 16:33:00 -080015816module_param_cb(fwpath, &fwpath_ops, &fwpath,
15817 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015818
15819module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
15820
15821module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
15822
15823module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);
Dustin Brown4bbd5462019-03-22 11:18:13 -070015824
15825static int timer_multiplier_get_handler(char *buffer,
15826 const struct kernel_param *kp)
15827{
15828 return scnprintf(buffer, PAGE_SIZE, "%u", qdf_timer_get_multiplier());
15829}
15830
15831static int timer_multiplier_set_handler(const char *kmessage,
15832 const struct kernel_param *kp)
15833{
15834 QDF_STATUS status;
15835 uint32_t scalar;
15836
15837 status = qdf_uint32_parse(kmessage, &scalar);
15838 if (QDF_IS_STATUS_ERROR(status))
15839 return qdf_status_to_os_return(status);
15840
15841 if (!cfg_in_range(CFG_TIMER_MULTIPLIER, scalar))
15842 return -ERANGE;
15843
15844 qdf_timer_set_multiplier(scalar);
15845
15846 return 0;
15847}
15848
15849static const struct kernel_param_ops timer_multiplier_ops = {
15850 .get = timer_multiplier_get_handler,
15851 .set = timer_multiplier_set_handler,
15852};
15853
15854module_param_cb(timer_multiplier, &timer_multiplier_ops, NULL, 0644);
15855