blob: 7d6000eb4bc0bd0ac151f6bbc1a8372b97f023b6 [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"
Naveen Rawate02f8f52018-04-05 11:58:04 -070053#include <wlan_osif_request_manager.h>
Dustin Brown26b3d042017-12-21 11:13:27 -080054#ifdef CONFIG_LEAK_DETECTION
Dustin Brown4bc0a622017-12-06 15:56:50 -080055#include "qdf_debug_domain.h"
Dustin Brown26b3d042017-12-21 11:13:27 -080056#endif
Dustin Brown8d8ab302019-03-05 16:19:36 -080057#include "qdf_delayed_work.h"
Dustin Brown4a93bb52019-03-13 11:46:34 -070058#include "qdf_periodic_work.h"
Dustin Brownd4241942018-02-26 12:51:37 -080059#include "qdf_str.h"
Dustin Brownd315c452018-11-27 11:28:48 -080060#include "qdf_talloc.h"
Dustin Brownd4241942018-02-26 12:51:37 -080061#include "qdf_trace.h"
62#include "qdf_types.h"
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070063#include <cdp_txrx_peer_ops.h>
Dhanashri Atrea8f82f22017-01-23 12:58:24 -080064#include <cdp_txrx_misc.h>
Mohit Khannaca4173b2017-09-12 21:52:19 -070065#include <cdp_txrx_stats.h>
bings0e03a982018-05-09 08:40:59 +080066#include "cdp_txrx_flow_ctrl_legacy.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080067
68#include <net/addrconf.h>
69#include <linux/wireless.h>
70#include <net/cfg80211.h>
71#include <linux/inetdevice.h>
72#include <net/addrconf.h>
73#include "wlan_hdd_cfg80211.h"
74#include "wlan_hdd_ext_scan.h"
75#include "wlan_hdd_p2p.h"
76#include <linux/rtnetlink.h>
77#include "sap_api.h"
78#include <linux/semaphore.h>
79#include <linux/ctype.h>
80#include <linux/compat.h>
Arunk Khandavalli830c9692018-03-22 12:17:40 +053081#include <linux/reboot.h>
Subrat Dash5f36fbe2019-02-12 16:28:14 +053082#include <linux/ethtool.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080083#ifdef MSM_PLATFORM
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080084#include <soc/qcom/subsystem_restart.h>
85#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080086#include <wlan_hdd_hostapd.h>
87#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson8bb61112018-03-31 13:33:54 -070088#include <wlan_hdd_green_ap.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080089#include "qwlan_version.h"
90#include "wma_types.h"
91#include "wlan_hdd_tdls.h"
92#ifdef FEATURE_WLAN_CH_AVOID
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +053093#include "cds_regdomain.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080094#endif /* FEATURE_WLAN_CH_AVOID */
Dustin Brownce46d1d2017-08-15 13:34:24 -070095#include "cdp_txrx_flow_ctrl_v2.h"
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070096#include "pld_common.h"
Tushnim Bhattacharyya15596cf2016-02-12 11:57:02 -080097#include "wlan_hdd_ocb.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080098#include "wlan_hdd_nan.h"
99#include "wlan_hdd_debugfs.h"
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +0530100#include "wlan_hdd_debugfs_csr.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800101#include "wlan_hdd_driver_ops.h"
102#include "epping_main.h"
Poddar, Siddarth34872782017-08-10 14:08:51 +0530103#include "wlan_hdd_data_stall_detection.h"
stonezc9936cb2019-03-11 16:41:22 +0800104#include "wlan_hdd_mpta_helper.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800105
106#include <wlan_hdd_ipa.h>
107#include "hif.h"
108#include "wma.h"
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -0800109#include "wlan_policy_mgr_api.h"
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700110#include "wlan_hdd_tsf.h"
Komal Seelamec702b02016-02-24 18:42:16 +0530111#include "bmi.h"
Amar Singhale4f28ee2015-10-21 14:36:56 -0700112#include <wlan_hdd_regulatory.h>
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700113#include "wlan_hdd_lpass.h"
Nachiket Kukade63bb63d2018-11-21 14:42:14 +0530114#include "wlan_nan_api.h"
Orhan K AKYILDIZ1481aff2016-05-16 12:40:13 -0700115#include <wlan_hdd_napi.h>
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +0530116#include "wlan_hdd_disa.h"
Rajeev Kumar97767a02016-11-30 11:20:40 -0800117#include <dispatcher_init_deinit.h>
Rajeev Kumar699debf2017-01-06 14:17:00 -0800118#include "wlan_hdd_object_manager.h"
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +0530119#include "cds_utils.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800120#include <cdp_txrx_handle.h>
Sandeep Puligillafdd201e2017-02-02 18:43:46 -0800121#include <qca_vendor.h>
Mukul Sharma9d797a02017-01-05 20:26:03 +0530122#include "wlan_pmo_ucfg_api.h"
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +0530123#include "sir_api.h"
Naveen Rawat910726a2017-03-06 11:42:51 -0800124#include "os_if_wifi_pos.h"
125#include "wifi_pos_api.h"
126#include "wlan_hdd_oemdata.h"
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800127#include "wlan_hdd_he.h"
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700128#include "os_if_nan.h"
129#include "nan_public_structs.h"
Nachiket Kukade85aa3782018-11-02 20:12:34 +0530130#include "nan_ucfg_api.h"
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -0700131#include "wlan_reg_ucfg_api.h"
bings81fe50a2017-11-27 14:33:26 +0800132#include "wlan_dfs_ucfg_api.h"
Ravi Joshi4f095952017-06-29 15:39:19 -0700133#include "wlan_hdd_rx_monitor.h"
Mukul Sharmad16c2022017-07-25 18:56:12 +0530134#include "sme_power_save_api.h"
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +0530135#include "enet.h"
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700136#include <cdp_txrx_cmn_struct.h>
Mohit Khanna70322002018-05-15 19:21:32 -0700137#include <dp_txrx.h>
Amar Singhal0928b192017-12-01 10:50:54 -0800138#include "wlan_hdd_sysfs.h"
Nachiket Kukade98f562a2017-12-15 12:18:07 +0530139#include "wlan_disa_ucfg_api.h"
Wu Gao52084c12018-05-17 20:47:11 +0800140#include "wlan_disa_obj_mgmt_api.h"
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +0530141#include "wlan_action_oui_ucfg_api.h"
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +0530142#include "wlan_ipa_ucfg_api.h"
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530143#include <target_if.h>
Alok Kumarb64650c2018-03-23 17:05:11 +0530144#include "wlan_hdd_nud_tracking.h"
Nachiket Kukaded0dd62e2018-05-21 18:39:22 +0530145#include "wlan_hdd_apf.h"
Varun Reddy Yeturue93d2462018-05-22 13:54:52 -0700146#include "wlan_hdd_twt.h"
Rachit Kankane0dc3e852018-05-07 17:33:42 +0530147#include "qc_sap_ioctl.h"
Sandeep Puligillac5609d52018-05-17 19:23:41 -0700148#include "wlan_mlme_main.h"
Wu Gaoe5689792018-07-05 19:20:13 +0800149#include "wlan_p2p_cfg_api.h"
Wu Gao637d58a2018-12-08 10:37:34 +0800150#include "wlan_cfg80211_p2p.h"
Wu Gaobdb7f272018-07-05 19:33:26 +0800151#include "wlan_tdls_cfg_api.h"
Qiwei Caie689a262018-07-26 15:50:22 +0800152#include <wlan_hdd_rssi_monitor.h>
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +0530153#include "wlan_mlme_ucfg_api.h"
Sourav Mohapatra113685f2018-08-29 14:21:55 +0530154#include "wlan_fwol_ucfg_api.h"
Krunal Sonie71838d2018-09-27 10:45:05 -0700155#include "wlan_policy_mgr_ucfg.h"
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +0530156#ifdef CNSS_GENL
157#include <net/cnss_nl.h>
158#endif
Amar Singhal5cccafe2017-02-15 12:42:58 -0800159#include "wlan_reg_ucfg_api.h"
Zhang Qian47e22ce2018-01-04 15:38:38 +0800160#include "wlan_ocb_ucfg_api.h"
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -0800161#include <wlan_hdd_spectralscan.h>
gaurank kathpalia4a205fc2018-09-15 00:59:15 +0530162#include "wlan_green_ap_ucfg_api.h"
Liangwei Dong3abfe8f2018-09-20 02:25:44 -0400163#include <wlan_p2p_ucfg_api.h>
Mohit Khanna81418772018-10-30 14:14:46 -0700164#include <target_type.h>
Arun Kumar Khandavallideda5a82019-03-11 15:32:19 +0530165#include <wlan_hdd_debugfs_coex.h>
Liangwei Dong3abfe8f2018-09-20 02:25:44 -0400166
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800167#ifdef MODULE
168#define WLAN_MODULE_NAME module_name(THIS_MODULE)
169#else
170#define WLAN_MODULE_NAME "wlan"
171#endif
172
173#ifdef TIMER_MANAGER
174#define TIMER_MANAGER_STR " +TIMER_MANAGER"
175#else
176#define TIMER_MANAGER_STR ""
177#endif
178
179#ifdef MEMORY_DEBUG
180#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
181#else
182#define MEMORY_DEBUG_STR ""
183#endif
184
Dustin Brownc1034df2018-02-07 14:51:32 -0800185#ifdef PANIC_ON_BUG
186#define PANIC_ON_BUG_STR " +PANIC_ON_BUG"
187#else
188#define PANIC_ON_BUG_STR ""
189#endif
190
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530191bool g_is_system_reboot_triggered;
Sachin Ahujadddd2632017-03-07 19:07:24 +0530192int wlan_start_ret_val;
193static DECLARE_COMPLETION(wlan_start_comp);
194static unsigned int dev_num = 1;
195static struct cdev wlan_hdd_state_cdev;
196static struct class *class;
197static dev_t device;
Arun Khandavallifae92942016-08-01 13:31:08 +0530198#ifndef MODULE
199static struct gwlan_loader *wlan_loader;
200static ssize_t wlan_boot_cb(struct kobject *kobj,
201 struct kobj_attribute *attr,
202 const char *buf, size_t count);
203struct gwlan_loader {
204 bool loaded_state;
205 struct kobject *boot_wlan_obj;
206 struct attribute_group *attr_group;
207};
208
209static struct kobj_attribute wlan_boot_attribute =
210 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
211
212static struct attribute *attrs[] = {
213 &wlan_boot_attribute.attr,
214 NULL,
215};
216
217#define MODULE_INITIALIZED 1
Qun Zhang4a83a462018-09-11 16:28:51 +0800218
219#ifdef MULTI_IF_NAME
220#define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME
221#else
222#define WLAN_LOADER_NAME "boot_wlan"
223#endif
Arun Khandavallifae92942016-08-01 13:31:08 +0530224#endif
225
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800226/* the Android framework expects this param even though we don't use it */
227#define BUF_LEN 20
228static char fwpath_buffer[BUF_LEN];
229static struct kparam_string fwpath = {
230 .string = fwpath_buffer,
231 .maxlen = BUF_LEN,
232};
233
234static char *country_code;
235static int enable_11d = -1;
236static int enable_dfs_chan_scan = -1;
237
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800238#define WLAN_NLINK_CESIUM 30
239
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530240static qdf_wake_lock_t wlan_wake_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800241
242#define WOW_MAX_FILTER_LISTS 1
243#define WOW_MAX_FILTERS_PER_LIST 4
244#define WOW_MIN_PATTERN_SIZE 6
245#define WOW_MAX_PATTERN_SIZE 64
246
Bala Venkatesh110b03e2018-07-10 16:02:08 +0530247/* max peer can be tdls peers + self peer + bss peer */
248#define HDD_MAX_VDEV_PEER_COUNT (HDD_MAX_NUM_TDLS_STA + 2)
Sourav Mohapatra808e3d42018-07-04 09:34:23 +0530249#define IS_IDLE_STOP (!cds_is_driver_unloading() && \
250 !cds_is_driver_recovering() && !cds_is_driver_loading())
Bala Venkatesh110b03e2018-07-10 16:02:08 +0530251
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800252#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
253static const struct wiphy_wowlan_support wowlan_support_reg_init = {
254 .flags = WIPHY_WOWLAN_ANY |
255 WIPHY_WOWLAN_MAGIC_PKT |
256 WIPHY_WOWLAN_DISCONNECT |
257 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
258 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
259 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
260 WIPHY_WOWLAN_4WAY_HANDSHAKE |
261 WIPHY_WOWLAN_RFKILL_RELEASE,
262 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
263 .pattern_min_len = WOW_MIN_PATTERN_SIZE,
264 .pattern_max_len = WOW_MAX_PATTERN_SIZE,
265};
266#endif
267
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700268static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
269 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL},
270 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL},
271 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL},
272 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL},
273 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL},
274 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL},
275 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL},
276 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL},
277 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL},
278 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL},
279 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL},
280 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
281 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
282 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL},
283 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL},
284 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL},
285 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL},
286 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL},
287 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL},
288 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL},
289 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL},
290 [QDF_MODULE_ID_DP] = {QDF_TRACE_LEVEL_ALL},
291 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL},
292 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL},
293 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL},
294 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL},
295 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL},
296 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL},
297 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL},
298 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL},
299 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL},
300 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL},
301 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL},
302 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL},
Arif Hussainfde76e72017-09-05 16:58:23 -0700303 [QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumarca8ef9d2017-10-06 10:43:21 -0700304 [QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL},
Deepak Dhamdheref918d422017-07-06 12:56:29 -0700305 [QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL},
Himanshu Agarwalb229a142017-12-21 10:16:45 +0530306 [QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL},
Zhang Qian47e22ce2018-01-04 15:38:38 +0800307 [QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL},
Sravan Kumar Kairam1309e7e2018-03-13 09:29:52 +0530308 [QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +0530309 [QDF_MODULE_ID_ACTION_OUI] = {QDF_TRACE_LEVEL_ALL},
Dustin Brown84f46ea2018-02-15 11:57:36 -0800310 [QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL},
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +0530311 [QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL},
Ashish Kumar Dhanotiya8d039c82018-07-11 20:41:14 +0530312 [QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL},
Kiran Kumar Lokere4ce40482018-08-30 16:31:00 -0700313 [QDF_MODULE_ID_CRYPTO] = {QDF_TRACE_LEVEL_ALL},
Sourav Mohapatra113685f2018-08-29 14:21:55 +0530314 [QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL},
Abhishek Singh0b0105f2018-09-25 10:44:16 +0530315 [QDF_MODULE_ID_SM_ENGINE] = {QDF_TRACE_LEVEL_ALL},
316 [QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL},
Nachiket Kukade089b9832018-12-12 16:38:17 +0530317 [QDF_MODULE_ID_NAN] = {QDF_TRACE_LEVEL_ALL},
Ashish Kumar Dhanotiya6ed44342019-02-07 21:11:00 +0530318 [QDF_MODULE_ID_CP_STATS] = {QDF_TRACE_LEVEL_ALL},
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700319};
320
Ashish Kumar Dhanotiyacf11bae2017-04-04 03:29:47 +0530321struct notifier_block hdd_netdev_notifier;
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530322struct notifier_block system_reboot_notifier;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800323
324struct sock *cesium_nl_srv_sock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800325#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700326static void wlan_hdd_auto_shutdown_cb(void);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800327#endif
328
Sachin Ahujadddd2632017-03-07 19:07:24 +0530329void hdd_start_complete(int ret)
330{
331 wlan_start_ret_val = ret;
332
333 complete(&wlan_start_comp);
334}
335
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800336/**
Nirav Shahbd36b062016-07-18 11:12:59 +0530337 * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700338 * @hdd_ctx: pointer to struct hdd_context
Nirav Shahbd36b062016-07-18 11:12:59 +0530339 *
340 * Return: none
341 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700342static void hdd_set_rps_cpu_mask(struct hdd_context *hdd_ctx)
Nirav Shahbd36b062016-07-18 11:12:59 +0530343{
Jeff Johnson9d295242017-08-29 14:39:48 -0700344 struct hdd_adapter *adapter;
Nirav Shahbd36b062016-07-18 11:12:59 +0530345
Dustin Brown920397d2017-12-13 16:27:50 -0800346 hdd_for_each_adapter(hdd_ctx, adapter)
347 hdd_send_rps_ind(adapter);
Nirav Shahbd36b062016-07-18 11:12:59 +0530348}
349
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530350#ifdef QCA_HL_NETDEV_FLOW_CONTROL
351void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter,
352 enum netif_action_type action)
353{
354 if (!adapter->tx_flow_timer_initialized)
355 return;
356
357 if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) {
358 qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
Ajit Pal Singhe6da1de2018-12-27 16:20:45 +0530359 adapter->hdd_stats.tx_rx_stats.is_txflow_paused = false;
360 adapter->hdd_stats.tx_rx_stats.txflow_unpause_cnt++;
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530361 } else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) {
362 QDF_STATUS status =
363 qdf_mc_timer_start(&adapter->tx_flow_control_timer,
364 WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
365
366 if (!QDF_IS_STATUS_SUCCESS(status))
367 hdd_err("Failed to start tx_flow_control_timer");
368 else
369 adapter->
370 hdd_stats.tx_rx_stats.txflow_timer_cnt++;
371
372 adapter->hdd_stats.tx_rx_stats.txflow_pause_cnt++;
373 adapter->hdd_stats.tx_rx_stats.is_txflow_paused = true;
374 }
375}
376#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
377
Alok Kumar2fad6442018-11-08 19:19:28 +0530378#ifdef MSM_PLATFORM
379void wlan_hdd_update_tcp_rx_param(struct hdd_context *hdd_ctx, void *data)
380{
381 if (!hdd_ctx) {
382 hdd_err("HDD context is null");
383 return;
384 }
385
386 if (!data) {
387 hdd_err("Data is null");
388 return;
389 }
390 if (hdd_ctx->config->enable_tcp_param_update)
391 wlan_hdd_send_tcp_param_update_event(hdd_ctx, data, 1);
392 else
393 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
394 WLAN_SVC_WLAN_TP_IND,
395 data,
396 sizeof(struct wlan_rx_tp_data));
397}
398
399void wlan_hdd_update_tcp_tx_param(struct hdd_context *hdd_ctx, void *data)
400{
401 enum wlan_tp_level next_tx_level;
402 struct wlan_tx_tp_data *tx_tp_data;
403
404 if (!hdd_ctx) {
405 hdd_err("HDD context is null");
406 return;
407 }
408
409 if (!data) {
410 hdd_err("Data is null");
411 return;
412 }
413
414 tx_tp_data = (struct wlan_tx_tp_data *)data;
415 next_tx_level = tx_tp_data->level;
416
417 if (hdd_ctx->config->enable_tcp_param_update)
418 wlan_hdd_send_tcp_param_update_event(hdd_ctx, data, 0);
419 else
420 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
421 WLAN_SVC_WLAN_TP_TX_IND,
422 &next_tx_level,
423 sizeof(next_tx_level));
424}
425
426/**
427 * wlan_hdd_send_tcp_param_update_event() - Send vendor event to update
428 * TCP parameter through Wi-Fi HAL
429 * @hdd_ctx: Pointer to HDD context
430 * @data: Parameters to update
431 * @dir: Direction(tx/rx) to update
432 *
433 * Return: None
434 */
435void wlan_hdd_send_tcp_param_update_event(struct hdd_context *hdd_ctx,
436 void *data,
437 uint8_t dir)
438{
439 struct sk_buff *vendor_event;
440 uint32_t event_len;
441 bool tcp_limit_output = false;
442 bool tcp_del_ack_ind_enabled = false;
443 bool tcp_adv_win_scl_enabled = false;
444 enum wlan_tp_level next_tp_level = WLAN_SVC_TP_NONE;
445
446 event_len = sizeof(uint8_t) + sizeof(uint8_t) + NLMSG_HDRLEN;
447
448 if (dir == 0) /*TX Flow */ {
449 struct wlan_tx_tp_data *tx_tp_data =
450 (struct wlan_tx_tp_data *)data;
451
452 next_tp_level = tx_tp_data->level;
453
454 if (tx_tp_data->tcp_limit_output) {
455 /* TCP_LIMIT_OUTPUT_BYTES */
456 event_len += sizeof(uint32_t);
457 tcp_limit_output = true;
458 }
459 } else if (dir == 1) /* RX Flow */ {
460 struct wlan_rx_tp_data *rx_tp_data =
461 (struct wlan_rx_tp_data *)data;
462
463 next_tp_level = rx_tp_data->level;
464
465 if (rx_tp_data->rx_tp_flags & TCP_DEL_ACK_IND_MASK) {
466 event_len += sizeof(uint32_t); /* TCP_DELACK_SEG */
467 tcp_del_ack_ind_enabled = true;
468 }
469 if (rx_tp_data->rx_tp_flags & TCP_ADV_WIN_SCL_MASK) {
470 event_len += sizeof(uint32_t); /* TCP_ADV_WIN_SCALE */
471 tcp_adv_win_scl_enabled = true;
472 }
473 } else {
474 hdd_err("Invalid Direction [%d]", dir);
475 return;
476 }
477
478 vendor_event =
479 cfg80211_vendor_event_alloc(
480 hdd_ctx->wiphy,
481 NULL, event_len,
482 QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT_INDEX,
483 GFP_KERNEL);
484
485 if (!vendor_event) {
486 hdd_err("cfg80211_vendor_event_alloc failed");
487 return;
488 }
489
490 if (nla_put_u8(
491 vendor_event,
492 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION,
493 dir))
494 goto tcp_param_change_nla_failed;
495
496 if (nla_put_u8(
497 vendor_event,
498 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL,
499 (next_tp_level == WLAN_SVC_TP_LOW ?
500 QCA_WLAN_THROUGHPUT_LEVEL_LOW :
501 QCA_WLAN_THROUGHPUT_LEVEL_HIGH)))
502 goto tcp_param_change_nla_failed;
503
504 if (tcp_limit_output &&
505 nla_put_u32(
506 vendor_event,
507 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES,
508 (next_tp_level == WLAN_SVC_TP_LOW ?
509 TCP_LIMIT_OUTPUT_BYTES_LOW :
510 TCP_LIMIT_OUTPUT_BYTES_HI)))
511 goto tcp_param_change_nla_failed;
512
513 if (tcp_del_ack_ind_enabled &&
514 (nla_put_u32(
515 vendor_event,
516 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG,
517 (next_tp_level == WLAN_SVC_TP_LOW ?
518 TCP_DEL_ACK_LOW : TCP_DEL_ACK_HI))))
519 goto tcp_param_change_nla_failed;
520
521 if (tcp_adv_win_scl_enabled &&
522 (nla_put_u32(
523 vendor_event,
524 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE,
525 (next_tp_level == WLAN_SVC_TP_LOW ?
526 WIN_SCALE_LOW : WIN_SCALE_HI))))
527 goto tcp_param_change_nla_failed;
528
529 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
530 return;
531
532tcp_param_change_nla_failed:
533 hdd_err("nla_put api failed");
534 kfree_skb(vendor_event);
535}
536#endif /* MSM_PLATFORM */
537
Nirav Shahbd36b062016-07-18 11:12:59 +0530538/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800539 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
540 * @vdev_id: vdev_id
541 * @action: action type
542 * @reason: reason type
543 *
544 * Return: none
545 */
546void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
547 enum netif_action_type action, enum netif_reason_type reason)
548{
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700549 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson9d295242017-08-29 14:39:48 -0700550 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800551
552 if (!hdd_ctx) {
553 hdd_err("hdd ctx is NULL");
554 return;
555 }
556 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530557 wlan_hdd_mod_fc_timer(adapter, action);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800558 wlan_hdd_netif_queue_control(adapter, action, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800559}
560
561/*
Dustin Brownab482ac2017-06-09 17:00:44 -0700562 * Store WLAN driver version and timestamp info in global variables such that
563 * crash debugger can extract them from driver debug symbol and crashdump for
564 * post processing
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800565 */
Dustin Brown96cd9632017-11-13 12:45:04 -0800566#ifdef BUILD_TAG
Rajeev Kumare555e2d2018-09-17 11:52:37 -0700567uint8_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 -0800568#else
Rajeev Kumare555e2d2018-09-17 11:52:37 -0700569uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR;
Naveen Rawat93836252017-06-20 16:30:59 -0700570#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800571
572/**
Liangwei Dong17bf2662018-01-05 02:02:05 -0500573 * hdd_get_valid_chan() - return current chan list from regulatory.
574 * @hdd_ctx: HDD context
575 * @chan_list: buf hold returned chan list
576 * @chan_num: input buf size and output returned chan num
577 *
578 * This function helps get current available chan list from regulatory
579 * module. It excludes the "disabled" and "invalid" channels.
580 *
581 * Return: 0 for success.
582 */
583static int hdd_get_valid_chan(struct hdd_context *hdd_ctx,
584 uint8_t *chan_list,
585 uint32_t *chan_num)
586{
587 int i = 0, j = 0;
588 struct regulatory_channel *cur_chan_list;
589 struct wlan_objmgr_pdev *pdev;
590
Dustin Brown07901ec2018-09-07 11:02:41 -0700591 if (!hdd_ctx || !hdd_ctx->pdev || !chan_list || !chan_num)
Liangwei Dong17bf2662018-01-05 02:02:05 -0500592 return -EINVAL;
593
Dustin Brown07901ec2018-09-07 11:02:41 -0700594 pdev = hdd_ctx->pdev;
Liangwei Dong17bf2662018-01-05 02:02:05 -0500595 cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
596 sizeof(struct regulatory_channel));
597 if (!cur_chan_list)
598 return -ENOMEM;
599
600 if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) !=
601 QDF_STATUS_SUCCESS) {
602 qdf_mem_free(cur_chan_list);
603 return -EINVAL;
604 }
605
606 for (i = 0; i < NUM_CHANNELS; i++) {
607 uint32_t ch = cur_chan_list[i].chan_num;
608 enum channel_state state = wlan_reg_get_channel_state(pdev,
609 ch);
610
611 if (state != CHANNEL_STATE_DISABLE &&
612 state != CHANNEL_STATE_INVALID &&
613 j < *chan_num) {
614 chan_list[j] = (uint8_t)ch;
615 j++;
616 }
617 }
618 *chan_num = j;
619 qdf_mem_free(cur_chan_list);
620 return 0;
621}
622
623/**
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530624 * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo
625 * @adapter: HDD adapter
626 * @chan_number: Channel number
627 * @chan_bw: Bandwidth
628 *
629 * Checks if the given bandwidth is valid for the given channel number.
630 *
631 * Return: 0 for success, non-zero for failure
632 */
Jeff Johnson9d295242017-08-29 14:39:48 -0700633int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530634 uint32_t chan_number,
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800635 enum phy_ch_width chan_bw)
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530636{
Liangwei Dong17bf2662018-01-05 02:02:05 -0500637 uint8_t chan[NUM_CHANNELS];
638 uint32_t len = NUM_CHANNELS, i;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530639 bool found = false;
Jeff Johnson16528362018-06-14 12:34:16 -0700640 mac_handle_t mac_handle;
Liangwei Dong17bf2662018-01-05 02:02:05 -0500641 int ret;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530642
Jeff Johnson16528362018-06-14 12:34:16 -0700643 mac_handle = hdd_adapter_get_mac_handle(adapter);
644 if (!mac_handle) {
645 hdd_err("Invalid MAC handle");
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530646 return -EINVAL;
647 }
648
Liangwei Dong17bf2662018-01-05 02:02:05 -0500649 ret = hdd_get_valid_chan(adapter->hdd_ctx, chan,
650 &len);
651 if (ret) {
652 hdd_err("error %d in getting valid channel list", ret);
653 return ret;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530654 }
655
656 for (i = 0; i < len; i++) {
657 if (chan[i] == chan_number) {
658 found = true;
659 break;
660 }
661 }
662
663 if (found == false) {
664 hdd_err("Channel not in driver's valid channel list");
665 return -EOPNOTSUPP;
666 }
667
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700668 if ((!WLAN_REG_IS_24GHZ_CH(chan_number)) &&
669 (!WLAN_REG_IS_5GHZ_CH(chan_number))) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530670 hdd_err("CH %d is not in 2.4GHz or 5GHz", chan_number);
671 return -EINVAL;
672 }
673
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700674 if (WLAN_REG_IS_24GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530675 if (chan_bw == CH_WIDTH_80MHZ) {
676 hdd_err("BW80 not possible in 2.4GHz band");
677 return -EINVAL;
678 }
679 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 14) &&
680 (chan_bw != CH_WIDTH_MAX)) {
681 hdd_err("Only BW20 possible on channel 14");
682 return -EINVAL;
683 }
684 }
685
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700686 if (WLAN_REG_IS_5GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530687 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 165) &&
688 (chan_bw != CH_WIDTH_MAX)) {
689 hdd_err("Only BW20 possible on channel 165");
690 return -EINVAL;
691 }
692 }
693
694 return 0;
695}
696
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800697#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
Dustin Brown98f7c822019-03-06 12:25:49 -0800698static inline struct net_device *hdd_net_dev_from_notifier(void *context)
699{
700 struct netdev_notifier_info *info = context;
701
702 return info->dev;
703}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800704#else
Dustin Brown98f7c822019-03-06 12:25:49 -0800705static inline struct net_device *hdd_net_dev_from_notifier(void *context)
706{
707 return context;
708}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800709#endif
Dustin Brown98f7c822019-03-06 12:25:49 -0800710
711static int __hdd_netdev_notifier_call(struct net_device *net_dev,
712 unsigned long state)
713{
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530714 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700715 struct hdd_context *hdd_ctx;
Min Liu8c5d99e2018-09-10 17:18:44 +0800716 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800717
Dustin Brown98f7c822019-03-06 12:25:49 -0800718 hdd_enter_dev(net_dev);
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800719
Dustin Brown98f7c822019-03-06 12:25:49 -0800720 if (!net_dev->ieee80211_ptr) {
Dustin Brownaeb55642018-07-30 17:20:32 -0700721 hdd_debug("ieee80211_ptr is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800722 return NOTIFY_DONE;
723 }
724
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530725 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
726 if (!hdd_ctx) {
727 hdd_err("HDD Context is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800728 return NOTIFY_DONE;
729 }
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800730
731 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -0700732 hdd_debug("%s: Driver module is closed", __func__);
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800733 return NOTIFY_DONE;
734 }
735
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530736 /* Make sure that this callback corresponds to our device. */
Dustin Brown98f7c822019-03-06 12:25:49 -0800737 adapter = hdd_get_adapter_by_iface_name(hdd_ctx, net_dev->name);
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530738 if (!adapter) {
Dustin Brown98f7c822019-03-06 12:25:49 -0800739 hdd_debug("failed to look up adapter for '%s'", net_dev->name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800740 return NOTIFY_DONE;
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530741 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800742
Dustin Brown98f7c822019-03-06 12:25:49 -0800743 if (adapter != WLAN_HDD_GET_PRIV_PTR(net_dev)) {
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530744 hdd_err("HDD adapter mismatch!");
745 return NOTIFY_DONE;
746 }
747
Dustin Brownaeb55642018-07-30 17:20:32 -0700748 if (cds_is_driver_recovering()) {
749 hdd_debug("Driver is recovering");
750 return NOTIFY_DONE;
751 }
752
753 if (cds_is_driver_in_bad_state()) {
754 hdd_debug("Driver is in failed recovery state");
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530755 return NOTIFY_DONE;
756 }
757
Dustin Brown98f7c822019-03-06 12:25:49 -0800758 hdd_debug("%s New Net Device State = %lu", net_dev->name, state);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800759
760 switch (state) {
761 case NETDEV_REGISTER:
762 break;
763
764 case NETDEV_UNREGISTER:
765 break;
766
767 case NETDEV_UP:
Jeff Johnson16528362018-06-14 12:34:16 -0700768 sme_ch_avoid_update_req(hdd_ctx->mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769 break;
770
771 case NETDEV_DOWN:
772 break;
773
774 case NETDEV_CHANGE:
Jeff Johnsonc72c5732017-10-28 12:49:37 -0700775 if (adapter->is_link_up_service_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800776 complete(&adapter->linkup_event_var);
777 break;
778
779 case NETDEV_GOING_DOWN:
Min Liu8c5d99e2018-09-10 17:18:44 +0800780 vdev = hdd_objmgr_get_vdev(adapter);
781 if (!vdev)
782 break;
783 if (ucfg_scan_get_vdev_status(vdev) !=
Sandeep Puligilla5f86d992017-10-29 14:58:53 -0700784 SCAN_NOT_IN_PROGRESS) {
Dustin Brown07901ec2018-09-07 11:02:41 -0700785 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
Jeff Johnson5a6fc962019-02-04 14:20:25 -0800786 adapter->vdev_id, INVALID_SCAN_ID,
Dustin Brown07901ec2018-09-07 11:02:41 -0700787 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800788 }
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +0530789 hdd_objmgr_put_vdev(vdev);
Min Liu9be5d4a2018-05-17 11:51:53 +0800790 cds_flush_work(&adapter->scan_block_work);
791 /* Need to clean up blocked scan request */
Dustin Brown96b98dd2019-03-06 12:39:37 -0800792 wlan_hdd_cfg80211_scan_block(adapter);
Min Liu9be5d4a2018-05-17 11:51:53 +0800793 hdd_debug("Scan is not Pending from user");
Arunk Khandavallif0c0d762017-12-07 10:18:50 +0530794 /*
795 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
796 * of return status of hdd_stop call, kernel resets the IFF_UP
797 * flag after which driver does not send the cfg80211_scan_done.
798 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN
799 */
Dustin Brown98f7c822019-03-06 12:25:49 -0800800 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, net_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800801 break;
802
803 default:
804 break;
805 }
806
807 return NOTIFY_DONE;
808}
809
810/**
811 * hdd_netdev_notifier_call() - netdev notifier callback function
812 * @nb: pointer to notifier block
813 * @state: state
Dustin Brown98f7c822019-03-06 12:25:49 -0800814 * @context: notifier callback context pointer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800815 *
816 * Return: 0 on success, error number otherwise.
817 */
818static int hdd_netdev_notifier_call(struct notifier_block *nb,
819 unsigned long state,
Dustin Brown98f7c822019-03-06 12:25:49 -0800820 void *context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800821{
Dustin Brown98f7c822019-03-06 12:25:49 -0800822 struct net_device *net_dev = hdd_net_dev_from_notifier(context);
823 struct osif_vdev_sync *vdev_sync;
824 int errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800825
Dustin Brown98f7c822019-03-06 12:25:49 -0800826 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
827 if (errno)
828 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800829
Dustin Brown98f7c822019-03-06 12:25:49 -0800830 errno = __hdd_netdev_notifier_call(net_dev, state);
831
832 osif_vdev_sync_op_stop(vdev_sync);
833
834 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800835}
836
837struct notifier_block hdd_netdev_notifier = {
838 .notifier_call = hdd_netdev_notifier_call,
839};
840
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530841static int system_reboot_notifier_call(struct notifier_block *nb,
842 unsigned long msg_type, void *_unused)
843{
844 switch (msg_type) {
845 case SYS_DOWN:
846 case SYS_HALT:
847 case SYS_POWER_OFF:
848 g_is_system_reboot_triggered = true;
849 hdd_info("reboot, reason: %ld", msg_type);
850 break;
851 default:
852 break;
853 }
854
855 return NOTIFY_OK;
856}
857
858struct notifier_block system_reboot_notifier = {
859 .notifier_call = system_reboot_notifier_call,
860};
861
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800862/* variable to hold the insmod parameters */
863static int con_mode;
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800864
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530865static int con_mode_ftm;
Nirav Shah6aeecf92019-02-13 14:05:03 +0530866int con_mode_epping;
Ravi Joshia307f632017-07-17 23:41:41 -0700867int con_mode_monitor;
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530868
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800869/* Variable to hold connection mode including module parameter con_mode */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800870static int curr_con_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800871
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530872/**
873 * hdd_map_nl_chan_width() - Map NL channel width to internal representation
874 * @ch_width: NL channel width
875 *
876 * Converts the NL channel width to the driver's internal representation
877 *
878 * Return: Converted channel width. In case of non matching NL channel width,
879 * CH_WIDTH_MAX will be returned.
880 */
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800881enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530882{
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800883 uint8_t fw_ch_bw;
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700884
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800885 fw_ch_bw = wma_get_vht_ch_width();
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530886 switch (ch_width) {
887 case NL80211_CHAN_WIDTH_20_NOHT:
888 case NL80211_CHAN_WIDTH_20:
889 return CH_WIDTH_20MHZ;
890 case NL80211_CHAN_WIDTH_40:
891 return CH_WIDTH_40MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530892 case NL80211_CHAN_WIDTH_80:
893 return CH_WIDTH_80MHZ;
894 case NL80211_CHAN_WIDTH_80P80:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800895 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
896 return CH_WIDTH_80P80MHZ;
897 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
898 return CH_WIDTH_160MHZ;
899 else
900 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530901 case NL80211_CHAN_WIDTH_160:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800902 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
903 return CH_WIDTH_160MHZ;
904 else
905 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530906 case NL80211_CHAN_WIDTH_5:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800907 return CH_WIDTH_5MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530908 case NL80211_CHAN_WIDTH_10:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800909 return CH_WIDTH_10MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530910 default:
911 hdd_err("Invalid channel width %d, setting to default",
912 ch_width);
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800913 return CH_WIDTH_INVALID;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530914 }
915}
916
Dustin Brown56377e12018-10-10 17:04:04 -0700917QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type,
918 enum QDF_OPMODE *out_qdf_type)
919{
920 switch (nl_type) {
921 case NL80211_IFTYPE_ADHOC:
922 *out_qdf_type = QDF_IBSS_MODE;
923 break;
924 case NL80211_IFTYPE_AP:
925 *out_qdf_type = QDF_SAP_MODE;
926 break;
927 case NL80211_IFTYPE_MONITOR:
928 *out_qdf_type = QDF_MONITOR_MODE;
929 break;
930 case NL80211_IFTYPE_OCB:
931 *out_qdf_type = QDF_OCB_MODE;
932 break;
933 case NL80211_IFTYPE_P2P_CLIENT:
934 *out_qdf_type = QDF_P2P_CLIENT_MODE;
935 break;
936 case NL80211_IFTYPE_P2P_DEVICE:
937 *out_qdf_type = QDF_P2P_DEVICE_MODE;
938 break;
939 case NL80211_IFTYPE_P2P_GO:
940 *out_qdf_type = QDF_P2P_GO_MODE;
941 break;
942 case NL80211_IFTYPE_STATION:
943 *out_qdf_type = QDF_STA_MODE;
944 break;
945 case NL80211_IFTYPE_WDS:
946 *out_qdf_type = QDF_WDS_MODE;
947 break;
948 default:
949 hdd_err("Invalid nl80211 interface type %d", nl_type);
950 return QDF_STATUS_E_INVAL;
951 }
952
953 return QDF_STATUS_SUCCESS;
954}
955
Jeff Johnson16528362018-06-14 12:34:16 -0700956uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel,
957 uint8_t bw_offset)
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +0530958{
959 uint8_t opclass = 0;
960
Jeff Johnson16528362018-06-14 12:34:16 -0700961 sme_get_opclass(mac_handle, channel, bw_offset, &opclass);
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +0530962 return opclass;
963}
964
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800965/**
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530966 * hdd_qdf_trace_enable() - configure initial QDF Trace enable
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530967 * @module_id: Module whose trace level is being configured
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800968 * @bitmask: Bitmask of log levels to be enabled
969 *
970 * Called immediately after the cfg.ini is read in order to configure
971 * the desired trace levels.
972 *
973 * Return: None
974 */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530975int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800976{
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530977 QDF_TRACE_LEVEL level;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530978 int qdf_print_idx = -1;
979 int status = -1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800980 /*
981 * if the bitmask is the default value, then a bitmask was not
982 * specified in cfg.ini, so leave the logging level alone (it
983 * will remain at the "compiled in" default value)
984 */
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700985 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530986 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800987
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530988 qdf_print_idx = qdf_get_pidx();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800989
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530990 /* a mask was specified. start by disabling all logging */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530991 status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +0530992 QDF_TRACE_LEVEL_NONE, 0);
993
994 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530995 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800996 /* now cycle through the bitmask until all "set" bits are serviced */
Ashish Kumar Dhanotiya83f286b2017-09-15 19:52:58 +0530997 level = QDF_TRACE_LEVEL_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800998 while (0 != bitmask) {
999 if (bitmask & 1) {
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301000 status = qdf_print_set_category_verbose(qdf_print_idx,
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301001 module_id, level, 1);
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301002 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301003 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001004 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001005
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001006 level++;
1007 bitmask >>= 1;
1008 }
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301009 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001010}
1011
Dustin Brownda351e32018-07-23 15:48:22 -07001012int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func)
Chris Guo1751acf2017-07-03 14:09:01 +08001013{
Dustin Brownda351e32018-07-23 15:48:22 -07001014 if (!hdd_ctx) {
1015 hdd_err("HDD context is null (via %s)", func);
1016 return -ENODEV;
1017 }
1018
1019 if (!hdd_ctx->config) {
1020 hdd_err("HDD config is null (via %s)", func);
Chris Guo1751acf2017-07-03 14:09:01 +08001021 return -ENODEV;
1022 }
1023
1024 if (cds_is_driver_recovering()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001025 hdd_debug("Recovery in progress (via %s); state:0x%x",
1026 func, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001027 return -EAGAIN;
1028 }
1029
Yue Ma9f275d92017-09-14 16:58:41 -07001030 if (cds_is_load_or_unload_in_progress()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001031 hdd_debug("Load/unload in progress (via %s); state:0x%x",
1032 func, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001033 return -EAGAIN;
Yue Ma9f275d92017-09-14 16:58:41 -07001034 }
Arun Khandavallia172c3e2016-08-26 17:33:13 +05301035
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301036 if (cds_is_driver_in_bad_state()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001037 hdd_debug("Driver in bad state (via %s); state:0x%x",
1038 func, cds_get_driver_state());
Sourav Mohapatra21b3c982018-04-03 17:33:03 +05301039 return -EAGAIN;
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301040 }
1041
Arunk Khandavalli2859fa12018-02-14 10:46:26 +05301042 if (cds_is_fw_down()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001043 hdd_debug("FW is down (via %s); state:0x%x",
1044 func, cds_get_driver_state());
Sourav Mohapatra21b3c982018-04-03 17:33:03 +05301045 return -EAGAIN;
Arunk Khandavalli2859fa12018-02-14 10:46:26 +05301046 }
1047
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001048 return 0;
1049}
1050
Dustin Browna8700cc2018-08-07 12:04:47 -07001051int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func)
Dustin Brownf13b8c32017-05-19 17:23:08 -07001052{
1053 if (!adapter) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001054 hdd_err("adapter is null (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001055 return -EINVAL;
1056 }
1057
1058 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001059 hdd_err("bad adapter magic (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001060 return -EINVAL;
1061 }
1062
1063 if (!adapter->dev) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001064 hdd_err("adapter net_device is null (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001065 return -EINVAL;
1066 }
1067
1068 if (!(adapter->dev->flags & IFF_UP)) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001069 hdd_debug_rl("adapter '%s' is not up (via %s)",
1070 adapter->dev->name, func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001071 return -EAGAIN;
1072 }
1073
Jeff Johnson7eb6e842019-02-23 14:33:34 -08001074 return __wlan_hdd_validate_vdev_id(adapter->vdev_id, func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001075}
1076
Jeff Johnson7eb6e842019-02-23 14:33:34 -08001077int __wlan_hdd_validate_vdev_id(uint8_t vdev_id, const char *func)
Dustin Brown63500612018-08-07 11:36:09 -07001078{
Srinivas Girigowdad8697d42019-03-08 15:34:39 -08001079 if (vdev_id == WLAN_UMAC_VDEV_ID_MAX) {
Dustin Brown63500612018-08-07 11:36:09 -07001080 hdd_debug_rl("adapter is not up (via %s)", func);
1081 return -EINVAL;
1082 }
1083
Jeff Johnson7eb6e842019-02-23 14:33:34 -08001084 if (vdev_id >= WLAN_MAX_VDEVS) {
1085 hdd_err("bad vdev Id:%u (via %s)", vdev_id, func);
Dustin Brown63500612018-08-07 11:36:09 -07001086 return -EINVAL;
1087 }
1088
1089 return 0;
1090}
1091
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05301092QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr,
1093 const char *func)
1094{
1095 if (!mac_addr) {
1096 hdd_err("Received NULL mac address (via %s)", func);
1097 return QDF_STATUS_E_INVAL;
1098 }
1099
1100 if (qdf_is_macaddr_zero(mac_addr)) {
1101 hdd_err("MAC is all zero (via %s)", func);
1102 return QDF_STATUS_E_INVAL;
1103 }
1104
1105 if (qdf_is_macaddr_broadcast(mac_addr)) {
1106 hdd_err("MAC is Broadcast (via %s)", func);
1107 return QDF_STATUS_E_INVAL;
1108 }
1109
1110 if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) {
1111 hdd_err("MAC is Multicast (via %s)", func);
1112 return QDF_STATUS_E_INVAL;
1113 }
1114
1115 return QDF_STATUS_SUCCESS;
1116}
1117
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001118/**
Arun Khandavallica892f62017-05-26 14:25:50 +05301119 * wlan_hdd_validate_modules_state() - Check modules status
1120 * @hdd_ctx: HDD context pointer
1121 *
1122 * Check's the driver module's state and returns true if the
1123 * modules are enabled returns false if modules are closed.
1124 *
1125 * Return: True if modules are enabled or false.
1126 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001127bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx)
Arun Khandavallica892f62017-05-26 14:25:50 +05301128{
Arun Khandavallica892f62017-05-26 14:25:50 +05301129 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07001130 hdd_info("Modules not enabled, Present status: %d",
1131 hdd_ctx->driver_status);
Arun Khandavallica892f62017-05-26 14:25:50 +05301132 return false;
1133 }
Dustin Brownf688ea12019-03-19 17:02:32 -07001134
Arun Khandavallica892f62017-05-26 14:25:50 +05301135 return true;
1136}
1137
1138/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001139 * hdd_set_ibss_power_save_params() - update IBSS Power Save params to WMA.
Jeff Johnson9d295242017-08-29 14:39:48 -07001140 * @struct hdd_adapter Hdd adapter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001141 *
1142 * This function sets the IBSS power save config parameters to WMA
1143 * which will send it to firmware if FW supports IBSS power save
1144 * before vdev start.
1145 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301146 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001147 * on failure.
1148 */
Jeff Johnson9d295242017-08-29 14:39:48 -07001149QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001150{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001151 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001152
Jeff Johnsond36fa332019-03-18 13:42:25 -07001153 if (!hdd_ctx) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001154 hdd_err("HDD context is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301155 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001156 }
1157
Manikandan Mohan2bd09772018-11-28 18:27:32 -08001158 return ucfg_mlme_ibss_power_save_setup(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08001159 adapter->vdev_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001160}
1161
Yue Macd359b72017-10-03 15:21:00 -07001162#ifdef FEATURE_RUNTIME_PM
1163/**
1164 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
1165 * @hdd_ctx: HDD context
1166 *
1167 * Return: None
1168 */
1169static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
1170{
1171 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1172
Yue Macd359b72017-10-03 15:21:00 -07001173 qdf_runtime_lock_init(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001174 qdf_runtime_lock_init(&ctx->connect);
Yue Macd359b72017-10-03 15:21:00 -07001175
Dustin Brown07901ec2018-09-07 11:02:41 -07001176 wlan_scan_runtime_pm_init(hdd_ctx->pdev);
Yue Macd359b72017-10-03 15:21:00 -07001177}
1178
1179/**
1180 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
1181 * @hdd_ctx: HDD Context
1182 *
1183 * Return: None
1184 */
1185static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
1186{
1187 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1188
Yue Macd359b72017-10-03 15:21:00 -07001189 qdf_runtime_lock_deinit(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001190 qdf_runtime_lock_deinit(&ctx->connect);
Yue Macd359b72017-10-03 15:21:00 -07001191
Dustin Brown07901ec2018-09-07 11:02:41 -07001192 wlan_scan_runtime_pm_deinit(hdd_ctx->pdev);
Yue Macd359b72017-10-03 15:21:00 -07001193}
1194
Yue Macd359b72017-10-03 15:21:00 -07001195#else /* FEATURE_RUNTIME_PM */
1196static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {}
1197static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {}
Yue Macd359b72017-10-03 15:21:00 -07001198#endif /* FEATURE_RUNTIME_PM */
1199
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001200#define INTF_MACADDR_MASK 0x7
1201
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301202void hdd_update_macaddr(struct hdd_context *hdd_ctx,
1203 struct qdf_mac_addr hw_macaddr, bool generate_mac_auto)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001204{
1205 int8_t i;
1206 uint8_t macaddr_b3, tmp_br3;
1207
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301208 /*
1209 * If "generate_mac_auto" is true, it indicates that all the
1210 * addresses are derived addresses, else the first addresses
1211 * is not derived address (It is provided by fw).
1212 */
1213 if (!generate_mac_auto) {
1214 qdf_mem_copy(hdd_ctx->provisioned_mac_addr[0].bytes,
1215 hw_macaddr.bytes, QDF_MAC_ADDR_SIZE);
1216 hdd_ctx->num_provisioned_addr++;
1217 hdd_info("hdd_ctx->provisioned_mac_addr[0]: "
1218 MAC_ADDRESS_STR,
1219 MAC_ADDR_ARRAY(hdd_ctx->
1220 provisioned_mac_addr[0].bytes));
1221 } else {
1222 qdf_mem_copy(hdd_ctx->derived_mac_addr[0].bytes,
1223 hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301224 QDF_MAC_ADDR_SIZE);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301225 hdd_ctx->num_derived_addr++;
1226 hdd_info("hdd_ctx->derived_mac_addr[0]: "
1227 MAC_ADDRESS_STR,
1228 MAC_ADDR_ARRAY(hdd_ctx->derived_mac_addr[0].bytes));
1229 }
1230 for (i = hdd_ctx->num_derived_addr; i < (QDF_MAX_CONCURRENCY_PERSONA -
1231 hdd_ctx->num_provisioned_addr);
1232 i++) {
1233 qdf_mem_copy(hdd_ctx->derived_mac_addr[i].bytes,
1234 hw_macaddr.bytes,
1235 QDF_MAC_ADDR_SIZE);
1236 macaddr_b3 = hdd_ctx->derived_mac_addr[i].bytes[3];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001237 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
1238 INTF_MACADDR_MASK;
1239 macaddr_b3 += tmp_br3;
1240
1241 /* XOR-ing bit-24 of the mac address. This will give enough
1242 * mac address range before collision
1243 */
1244 macaddr_b3 ^= (1 << 7);
1245
1246 /* Set locally administered bit */
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301247 hdd_ctx->derived_mac_addr[i].bytes[0] |= 0x02;
1248 hdd_ctx->derived_mac_addr[i].bytes[3] = macaddr_b3;
1249 hdd_info("hdd_ctx->derived_mac_addr[%d]: "
1250 MAC_ADDRESS_STR, i,
1251 MAC_ADDR_ARRAY(hdd_ctx->derived_mac_addr[i].bytes));
1252 hdd_ctx->num_derived_addr++;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001253 }
1254}
1255
Jeff Johnson2de58792019-02-08 07:49:17 -08001256#ifdef FEATURE_WLAN_TDLS
Kabilan Kannan44a58372017-12-06 18:16:11 -08001257static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1258{
Dustin Brown1dbefe62018-09-11 16:32:03 -07001259 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001260 struct tdls_start_params tdls_cfg;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001261 QDF_STATUS status;
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301262 struct wlan_mlme_nss_chains vdev_ini_cfg;
1263
1264 /* Populate the nss chain params from ini for this vdev type */
1265 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
1266 QDF_TDLS_MODE,
1267 hdd_ctx->num_rf_chains);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001268
Dustin Brown1dbefe62018-09-11 16:32:03 -07001269 cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301270 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]);
Dustin Brown1dbefe62018-09-11 16:32:03 -07001271 cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301272 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]);
jiad7b8a5e02018-11-26 16:37:57 +08001273 hdd_init_tdls_config(&tdls_cfg);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001274 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
1275 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
1276 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
1277 tdls_cfg.tdls_evt_cb_data = psoc;
Jeff Johnson1d40f5b2018-03-02 08:35:53 -08001278 tdls_cfg.tdls_peer_context = hdd_ctx;
1279 tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer;
1280 tdls_cfg.tdls_dereg_peer = hdd_tdls_deregister_peer;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001281 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
1282 tdls_cfg.tdls_wmm_cb_data = psoc;
1283 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
1284 tdls_cfg.tdls_rx_cb_data = psoc;
1285 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
1286
1287 status = ucfg_tdls_update_config(psoc, &tdls_cfg);
1288 if (status != QDF_STATUS_SUCCESS) {
1289 hdd_err("failed pmo psoc configuration");
1290 return -EINVAL;
1291 }
1292
1293 hdd_ctx->tdls_umac_comp_active = true;
1294 /* enable napier specific tdls data path */
1295 hdd_ctx->tdls_nap_active = true;
1296
1297 return 0;
1298}
Jeff Johnson74c6bb22019-02-15 10:15:07 -08001299#else
1300static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1301{
1302 return 0;
1303}
1304#endif
Kabilan Kannan44a58372017-12-06 18:16:11 -08001305
Wu Gaoca416ff2018-09-17 11:05:07 +08001306#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1307static void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1308 struct wma_tgt_services *cfg)
1309{
1310 bool roam_offload_enable;
1311
Dustin Brown1dbefe62018-09-11 16:32:03 -07001312 ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable);
1313 ucfg_mlme_set_roaming_offload(hdd_ctx->psoc,
Wu Gaoca416ff2018-09-17 11:05:07 +08001314 roam_offload_enable &
1315 cfg->en_roam_offload);
1316}
1317#else
1318static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1319 struct wma_tgt_services *cfg)
1320{
1321}
1322#endif
1323
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001324static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325 struct wma_tgt_services *cfg)
1326{
1327 struct hdd_config *config = hdd_ctx->config;
Wu Gao66454f12018-09-26 19:55:41 +08001328 bool arp_offload_enable;
Wu Gao1ab05582018-11-08 16:22:49 +08001329 bool mawc_enabled;
Wu Gaobdb7f272018-07-05 19:33:26 +08001330#ifdef FEATURE_WLAN_TDLS
1331 bool tdls_support;
1332 bool tdls_off_channel;
1333 bool tdls_buffer_sta;
1334 uint32_t tdls_uapsd_mask;
1335#endif
jiad7b8a5e02018-11-26 16:37:57 +08001336 bool value;
1337
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001338 /* Set up UAPSD */
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05301339 ucfg_mlme_set_sap_uapsd_flag(hdd_ctx->psoc, cfg->uapsd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08001341 /* 11AX mode support */
1342 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
1343 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
1344 config->dot11Mode = eHDD_DOT11_MODE_11ac;
1345
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001346 /* 11AC mode support */
1347 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
1348 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
1349 config->dot11Mode = eHDD_DOT11_MODE_AUTO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001350
1351 /* ARP offload: override user setting if invalid */
Wu Gao66454f12018-09-26 19:55:41 +08001352 arp_offload_enable =
1353 ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc);
1354 ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc,
1355 arp_offload_enable & cfg->arp_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001356#ifdef FEATURE_WLAN_SCAN_PNO
1357 /* PNO offload */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001358 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001359 if (cfg->pno_offload)
Pragaspathi Thilagaraj24789d32018-12-10 22:28:03 +05301360 ucfg_scan_set_pno_offload(hdd_ctx->psoc, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001361#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001362#ifdef FEATURE_WLAN_TDLS
Dustin Brown1dbefe62018-09-11 16:32:03 -07001363 cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support);
1364 cfg_tdls_set_support_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001365 tdls_support & cfg->en_tdls);
1366
Dustin Brown1dbefe62018-09-11 16:32:03 -07001367 cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel);
1368 cfg_tdls_set_off_channel_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001369 tdls_off_channel &&
1370 cfg->en_tdls_offchan);
1371
Dustin Brown1dbefe62018-09-11 16:32:03 -07001372 cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta);
1373 cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001374 tdls_buffer_sta &&
1375 cfg->en_tdls_uapsd_buf_sta);
1376
Dustin Brown1dbefe62018-09-11 16:32:03 -07001377 cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask);
Wu Gaobdb7f272018-07-05 19:33:26 +08001378 if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta)
Dustin Brown1dbefe62018-09-11 16:32:03 -07001379 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001380 else
Dustin Brown1dbefe62018-09-11 16:32:03 -07001381 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001382#endif
Wu Gaoca416ff2018-09-17 11:05:07 +08001383 hdd_update_roam_offload(hdd_ctx, cfg);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05301384
Dustin Brown05d81302018-09-11 16:49:22 -07001385 if (ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value) ==
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05301386 QDF_STATUS_SUCCESS)
1387 value &= cfg->get_peer_info_enabled;
1388
Wu Gao1ab05582018-11-08 16:22:49 +08001389 ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled);
1390 ucfg_mlme_set_mawc_enabled(hdd_ctx->psoc,
1391 mawc_enabled & cfg->is_fw_mawc_capable);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001392 hdd_update_tdls_config(hdd_ctx);
Jeff Johnson16528362018-06-14 12:34:16 -07001393 sme_update_tgt_services(hdd_ctx->mac_handle, cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001394}
1395
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001396/**
1397 * hdd_update_vdev_nss() - sets the vdev nss
1398 * @hdd_ctx: HDD context
1399 *
1400 * Sets the Nss per vdev type based on INI
1401 *
1402 * Return: None
1403 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001404static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx)
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001405{
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001406 uint8_t max_supp_nss = 1;
Jeff Johnson16528362018-06-14 12:34:16 -07001407 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301408 QDF_STATUS status;
1409 bool bval;
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001410
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301411 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
1412 if (!QDF_IS_STATUS_SUCCESS(status))
1413 hdd_err("unable to get vht_enable2x2");
1414
1415 if (bval && !cds_is_sub_20_mhz_enabled())
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001416 max_supp_nss = 2;
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301417
1418 hdd_debug("max nss %d", max_supp_nss);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001419
Jeff Johnson16528362018-06-14 12:34:16 -07001420 mac_handle = hdd_ctx->mac_handle;
1421 sme_update_vdev_type_nss(mac_handle, max_supp_nss,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301422 NSS_CHAINS_BAND_2GHZ);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001423
Jeff Johnson16528362018-06-14 12:34:16 -07001424 sme_update_vdev_type_nss(mac_handle, max_supp_nss,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301425 NSS_CHAINS_BAND_5GHZ);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001426}
1427
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301428/**
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301429 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
1430 * @hdd_ctx: HDD context
1431 *
1432 * Updates wiphy vhtcap fields
1433 *
1434 * Return: None
1435 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001436static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx)
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301437{
1438 struct ieee80211_supported_band *band_5g =
1439 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301440 QDF_STATUS status;
1441 uint8_t value = 0, value1 = 0;
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301442
1443 if (!band_5g) {
1444 hdd_debug("5GHz band disabled, skipping capability population");
1445 return;
1446 }
1447
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301448 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
1449 &value);
1450 if (!QDF_IS_STATUS_SUCCESS(status))
1451 hdd_err("unable to get tx_bfee_ant_supp");
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301452
Abhinav Kumare057b412018-10-09 17:28:16 +05301453 band_5g->vht_cap.cap |=
1454 (value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301455
1456 value1 = NUM_OF_SOUNDING_DIMENSIONS;
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301457 band_5g->vht_cap.cap |=
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301458 (value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301459
Dustin Brown7e761c72018-07-31 13:50:17 -07001460 hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301461 band_5g->vht_cap.cap, value, value1);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301462}
1463
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001464static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001465 struct wma_tgt_ht_cap *cfg)
1466{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301467 QDF_STATUS status;
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301468 qdf_size_t value_len;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301469 uint32_t value;
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301470 uint8_t mpdu_density;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301471 struct mlme_ht_capabilities_info ht_cap_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001472 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301473 bool b_enable1x1;
Jeff Johnson16528362018-06-14 12:34:16 -07001474
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001475 /* get the MPDU density */
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301476 status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density);
1477 if (QDF_IS_STATUS_ERROR(status)) {
1478 hdd_err("could not get HT MPDU Density");
1479 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001480 }
1481
1482 /*
1483 * MPDU density:
1484 * override user's setting if value is larger
1485 * than the one supported by target
1486 */
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301487 if (mpdu_density > cfg->mpdu_density) {
1488 status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc,
1489 cfg->mpdu_density);
1490 if (QDF_IS_STATUS_ERROR(status))
1491 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001492 }
1493
1494 /* get the HT capability info */
Dustin Brown1dbefe62018-09-11 16:32:03 -07001495 status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301496 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001497 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001498 return;
1499 }
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301500
1501 /* check and update RX STBC */
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301502 if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc)
1503 ht_cap_info.rx_stbc = cfg->ht_rx_stbc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001504
1505 /* Set the LDPC capability */
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301506 ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001507
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301508 if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20)
1509 ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001510
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301511 if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40)
1512 ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001513
1514 hdd_ctx->num_rf_chains = cfg->num_rf_chains;
1515 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
1516
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301517 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1);
1518 if (!QDF_IS_STATUS_SUCCESS(status))
1519 hdd_err("unable to get vht_enable2x2");
1520
1521 b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2);
1522
1523 status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1);
1524 if (!QDF_IS_STATUS_SUCCESS(status))
1525 hdd_err("unable to set vht_enable2x2");
1526
Abhinav Kumare057b412018-10-09 17:28:16 +05301527 if (!b_enable1x1) {
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301528 ht_cap_info.tx_stbc = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001529
1530 /* 1x1 */
1531 /* Update Rx Highest Long GI data Rate */
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301532 status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(
1533 hdd_ctx->psoc,
1534 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1);
1535 if (!QDF_IS_STATUS_SUCCESS(status))
1536 hdd_err("Failed to set rx_supp_data_rate");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001537 /* Update Tx Highest Long GI data Rate */
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301538 status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(
1539 hdd_ctx->psoc,
1540 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1);
1541 if (!QDF_IS_STATUS_SUCCESS(status))
1542 hdd_err("Failed to set tx_supp_data_rate");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001543 }
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301544 if (!(cfg->ht_tx_stbc && b_enable1x1))
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301545 ht_cap_info.tx_stbc = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001546
Dustin Brown1dbefe62018-09-11 16:32:03 -07001547 status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301548 if (status != QDF_STATUS_SUCCESS)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001549 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001550#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301551 value_len = SIZE_OF_SUPPORTED_MCS_SET;
1552 if (ucfg_mlme_get_supported_mcs_set(
1553 hdd_ctx->psoc, mcs_set,
1554 &value_len) == QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001555 hdd_debug("Read MCS rate set");
gaurank kathpalia18b49362018-04-15 23:12:03 +05301556 if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET)
1557 cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301558
1559 if (b_enable1x1) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001560 for (value = 0; value < cfg->num_rf_chains; value++)
1561 mcs_set[value] =
1562 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
1563
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301564 status = ucfg_mlme_set_supported_mcs_set(
1565 hdd_ctx->psoc,
1566 mcs_set,
1567 (qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET);
1568 if (QDF_IS_STATUS_ERROR(status))
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001569 hdd_err("could not set MCS SET to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001570 }
1571 }
1572#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
1573}
1574
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001575static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001576 struct wma_tgt_vht_cap *cfg)
1577{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301578 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001579 struct wiphy *wiphy = hdd_ctx->wiphy;
1580 struct ieee80211_supported_band *band_5g =
Srinivas Girigowda11c28e02017-06-27 20:06:21 -07001581 wiphy->bands[HDD_NL80211_BAND_5GHZ];
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001582 uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ;
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001583 struct wma_caps_per_phy caps_per_phy;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301584 uint8_t val = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001585
Dustin Brown5e06bd32016-10-04 12:49:10 -07001586 if (!band_5g) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001587 hdd_debug("5GHz band disabled, skipping capability population");
Dustin Brown5e06bd32016-10-04 12:49:10 -07001588 return;
1589 }
1590
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301591 status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg);
1592 if (QDF_IS_STATUS_ERROR(status))
1593 hdd_err("could not update vht capabilities");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001594
1595 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
1596 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1597 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
1598 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1599 else
1600 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1601
1602
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001603 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
Abhinav Kumare057b412018-10-09 17:28:16 +05301604 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc,
1605 VHT_CAP_160_AND_80P80_SUPP);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301606 if (QDF_IS_STATUS_ERROR(status))
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001607 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001608 band_5g->vht_cap.cap |=
1609 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001610 ch_width = eHT_CHANNEL_WIDTH_80P80MHZ;
1611 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
Abhinav Kumare057b412018-10-09 17:28:16 +05301612 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc,
1613 VHT_CAP_160_SUPP);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301614 if (QDF_IS_STATUS_ERROR(status))
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001615 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001616 band_5g->vht_cap.cap |=
1617 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001618 ch_width = eHT_CHANNEL_WIDTH_160MHZ;
1619 }
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001620
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301621 status =
1622 ucfg_mlme_cfg_get_vht_chan_width(hdd_ctx->psoc, &val);
1623 if (QDF_IS_STATUS_ERROR(status))
1624 hdd_err("could not get channel_width");
1625
1626 val = QDF_MIN(val, ch_width);
Abhinav Kumare057b412018-10-09 17:28:16 +05301627 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, val);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301628 if (QDF_IS_STATUS_ERROR(status))
1629 hdd_err("could not set the channel width");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001630
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001631 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001632 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001633 hdd_debug("VHT RxLDPC capability is set");
1634 } else {
1635 /*
1636 * Get the RX LDPC capability for the NON DBS
1637 * hardware mode for 5G band
1638 */
1639 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
1640 HW_MODE_DBS_NONE, CDS_BAND_5GHZ);
1641 if ((QDF_IS_STATUS_SUCCESS(status)) &&
1642 (caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) {
1643 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
1644 hdd_debug("VHT RX LDPC capability is set");
1645 }
1646 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001647
1648 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
1649 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1650 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
1651 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1652
1653 if (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)
1654 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
1655
1656 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
1657 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1658 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)
1659 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
1660 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
1661 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
1662
1663 band_5g->vht_cap.cap |=
1664 (cfg->vht_max_ampdu_len_exp <<
1665 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
1666
1667 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
1668 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1669 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
1670 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1671 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
1672 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1673 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
1674 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1675
1676 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
1677 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1678
1679}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001681/**
1682 * hdd_generate_macaddr_auto() - Auto-generate mac address
1683 * @hdd_ctx: Pointer to the HDD context
1684 *
1685 * Auto-generate mac address using device serial number.
1686 * Keep the first 3 bytes of OUI as before and replace
1687 * the last 3 bytes with the lower 3 bytes of serial number.
1688 *
1689 * Return: 0 for success
1690 * Non zero failure code for errors
1691 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001692static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx)
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001693{
1694 unsigned int serialno = 0;
1695 struct qdf_mac_addr mac_addr = {
1696 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
1697 };
1698
Yuanyuan Liuf97e8222016-09-21 10:31:38 -07001699 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001700 if (serialno == 0)
1701 return -EINVAL;
1702
1703 serialno &= 0x00ffffff;
1704
1705 mac_addr.bytes[3] = (serialno >> 16) & 0xff;
1706 mac_addr.bytes[4] = (serialno >> 8) & 0xff;
1707 mac_addr.bytes[5] = serialno & 0xff;
1708
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301709 hdd_update_macaddr(hdd_ctx, mac_addr, true);
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001710 return 0;
1711}
1712
Jeff Johnsonf9176382018-07-17 19:15:58 -07001713static void hdd_sar_target_config(struct hdd_context *hdd_ctx,
1714 struct wma_tgt_cfg *cfg)
1715{
1716 hdd_ctx->sar_version = cfg->sar_version;
1717}
1718
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001719static void hdd_update_vhtcap_2g(struct hdd_context *hdd_ctx)
1720{
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001721 uint32_t chip_mode = 0;
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001722 QDF_STATUS status;
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001723 bool b2g_vht_cfg = false;
1724 bool b2g_vht_target = false;
1725 struct wma_caps_per_phy caps_per_phy;
1726 struct wmi_unified *wmi_handle;
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001727
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001728 wmi_handle = get_wmi_unified_hdl_from_psoc(hdd_ctx->psoc);
1729 if (!wmi_handle) {
1730 hdd_err("wmi handle is NULL");
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001731 return;
1732 }
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001733
1734 status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &b2g_vht_cfg);
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001735 if (QDF_IS_STATUS_ERROR(status)) {
1736 hdd_err("Failed to get 2g vht mode");
1737 return;
1738 }
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001739 if (wmi_service_enabled(wmi_handle, wmi_service_ext_msg)) {
1740 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
1741 HW_MODE_DBS_NONE,
1742 CDS_BAND_ALL);
1743 if (QDF_IS_STATUS_ERROR(status)) {
1744 hdd_err("Failed to get phy caps");
1745 return;
1746 }
1747 if (caps_per_phy.vht_2g)
1748 b2g_vht_target = true;
1749 } else {
1750 status = wlan_reg_get_chip_mode(hdd_ctx->pdev, &chip_mode);
1751 if (QDF_IS_STATUS_ERROR(status)) {
1752 hdd_err("Failed to get chip mode");
1753 return;
1754 }
1755 b2g_vht_target =
1756 (chip_mode & WMI_HOST_REGDMN_MODE_11AC_VHT20_2G) ?
1757 true : false;
1758 }
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001759
Jianmin Zhu2f9e7532019-01-21 15:39:50 +08001760 b2g_vht_cfg = b2g_vht_cfg && b2g_vht_target;
1761 hdd_debug("vht 2g target: %d, cfg: %d", b2g_vht_target, b2g_vht_cfg);
1762 status = ucfg_mlme_set_vht_for_24ghz(hdd_ctx->psoc, b2g_vht_cfg);
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001763 if (QDF_IS_STATUS_ERROR(status)) {
1764 hdd_err("Failed to update 2g vht mode");
1765 return;
1766 }
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08001767}
1768
Jeff Johnson8abc5932018-06-02 22:51:37 -07001769void hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001770{
Rajeev Kumarf49dfdb2017-01-13 15:40:35 -08001771 int ret;
Jeff Johnsonea70b942018-07-02 09:42:31 -07001772 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301773 uint8_t temp_band_cap, band_capability;
Naveen Rawat64e477e2016-05-20 10:34:56 -07001774 struct cds_config_info *cds_cfg = cds_get_ini_config();
Nitesh Shahe50711f2017-04-26 16:30:45 +05301775 uint8_t antenna_mode;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301776 uint8_t sub_20_chan_width;
Arif Hussainee10f902017-12-27 16:30:17 -08001777 QDF_STATUS status;
Jeff Johnson16528362018-06-14 12:34:16 -07001778 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301779 bool bval = false;
1780 uint8_t value = 0;
Arif Hussainbd5194c2018-11-27 19:01:15 -08001781 uint32_t fine_time_meas_cap = 0;
gaurank kathpaliafa7ad0a2019-03-12 19:17:56 +05301782 enum nss_chains_band_info band;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301783
gaurank kathpalia843f7c32018-07-02 18:04:14 +05301784 if (!hdd_ctx) {
1785 hdd_err("HDD context is NULL");
1786 return;
1787 }
Dustin Brownbd68fe12017-11-21 15:28:52 -08001788 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
1789 if (ret) {
Dustin Brown64204d22018-08-15 16:35:19 -07001790 QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret);
1791 return;
1792 }
1793
1794 hdd_debug("New pdev has been created with pdev_id = %u",
Dustin Brown07901ec2018-09-07 11:02:41 -07001795 hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id);
Dustin Brown64204d22018-08-15 16:35:19 -07001796
Dustin Brown07901ec2018-09-07 11:02:41 -07001797 status = dispatcher_pdev_open(hdd_ctx->pdev);
Dustin Brown64204d22018-08-15 16:35:19 -07001798 if (QDF_IS_STATUS_ERROR(status)) {
1799 QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d",
1800 status);
1801 return;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301802 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001803
Sandeep Puligillab7beb472018-08-13 22:54:20 -07001804 status = hdd_component_pdev_open(hdd_ctx->pdev);
1805 if (QDF_IS_STATUS_ERROR(status)) {
1806 QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d",
1807 status);
1808 return;
1809 }
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05301810 cdp_pdev_set_ctrl_pdev(cds_get_context(QDF_MODULE_ID_SOC),
1811 cds_get_context(QDF_MODULE_ID_TXRX),
Dustin Brown07901ec2018-09-07 11:02:41 -07001812 (struct cdp_ctrl_objmgr_pdev *)hdd_ctx->pdev);
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05301813
Dustin Brown07901ec2018-09-07 11:02:41 -07001814 wlan_pdev_set_dp_handle(hdd_ctx->pdev,
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05301815 cds_get_context(QDF_MODULE_ID_TXRX));
1816
Will Huang07244172018-05-14 14:23:30 +08001817 hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count);
1818
Dustin Brown1dbefe62018-09-11 16:32:03 -07001819 ucfg_ipa_set_dp_handle(hdd_ctx->psoc,
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05301820 cds_get_context(QDF_MODULE_ID_SOC));
Dustin Brown1dbefe62018-09-11 16:32:03 -07001821 ucfg_ipa_set_txrx_handle(hdd_ctx->psoc,
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05301822 cds_get_context(QDF_MODULE_ID_TXRX));
Dustin Brown07901ec2018-09-07 11:02:41 -07001823 ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev,
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05301824 hdd_softap_hard_start_xmit);
Dustin Brown07901ec2018-09-07 11:02:41 -07001825 ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev,
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05301826 hdd_ipa_send_skb_to_network);
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05301827
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301828 status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
1829 &sub_20_chan_width);
1830 if (QDF_IS_STATUS_ERROR(status)) {
1831 hdd_err("Failed to get sub_20_chan_width config");
1832 return;
1833 }
1834
Naveen Rawat64e477e2016-05-20 10:34:56 -07001835 if (cds_cfg) {
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301836 if (sub_20_chan_width !=
1837 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
Naveen Rawat64e477e2016-05-20 10:34:56 -07001838 hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
1839 cds_cfg->sub_20_channel_width =
1840 WLAN_SUB_20_CH_WIDTH_NONE;
1841 } else {
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301842 cds_cfg->sub_20_channel_width = sub_20_chan_width;
Naveen Rawat64e477e2016-05-20 10:34:56 -07001843 }
1844 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001845
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301846 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
1847 if (QDF_IS_STATUS_ERROR(status)) {
1848 hdd_err("Failed to get MLME band capability");
1849 return;
1850 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001851
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301852 /* first store the INI band capability */
1853 temp_band_cap = band_capability;
1854
1855 band_capability = cfg->band_cap;
Vignesh Viswanathan731186f2017-09-18 13:47:37 +05301856 hdd_ctx->is_fils_roaming_supported =
1857 cfg->services.is_fils_roaming_supported;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001858
Vignesh Viswanathan694e28e2018-01-18 20:53:57 +05301859 hdd_ctx->config->is_11k_offload_supported =
1860 cfg->services.is_11k_offload_supported;
1861
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08001862 /*
1863 * now overwrite the target band capability with INI
1864 * setting if INI setting is a subset
1865 */
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301866 if ((band_capability == BAND_ALL) &&
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001867 (temp_band_cap != BAND_ALL))
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301868 band_capability = temp_band_cap;
1869 else if ((band_capability != BAND_ALL) &&
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001870 (temp_band_cap != BAND_ALL) &&
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301871 (band_capability != temp_band_cap)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001872 hdd_warn("ini BandCapability not supported by the target");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001873 }
1874
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301875 status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability);
1876 if (QDF_IS_STATUS_ERROR(status)) {
1877 hdd_err("Failed to set MLME Band Capability");
1878 return;
1879 }
1880
1881 hdd_ctx->curr_band = band_capability;
Amar Singhal58b45ef2017-08-01 13:43:54 -07001882
Qun Zhang043635a2019-02-27 15:19:29 +08001883 status = wlan_hdd_update_wiphy_supported_band(hdd_ctx);
1884 if (QDF_IS_STATUS_ERROR(status)) {
1885 hdd_err("Failed to update wiphy band info");
1886 return;
1887 }
1888
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301889 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001890 hdd_ctx->reg.reg_domain = cfg->reg_domain;
1891 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
1892 }
1893
1894 /* This can be extended to other configurations like ht, vht cap... */
1895
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05301896 if (!qdf_is_macaddr_zero(&cfg->hw_macaddr))
1897 qdf_mem_copy(&hdd_ctx->hw_macaddr, &cfg->hw_macaddr,
1898 QDF_MAC_ADDR_SIZE);
1899 else
1900 hdd_info("hw_mac is zero");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001901
1902 hdd_ctx->target_fw_version = cfg->target_fw_version;
Sandeep Puligilla3d6a8e22016-10-11 18:57:14 -07001903 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001904
Ryan Hsuc6918552018-05-16 13:29:59 -07001905 hdd_ctx->hw_bd_id = cfg->hw_bd_id;
1906 qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info,
1907 sizeof(cfg->hw_bd_info));
1908
Dustin Brownad06be62019-02-04 14:52:56 -08001909 if (cfg->max_intf_count > WLAN_MAX_VDEVS) {
Dustin Brownbee82832018-07-23 10:10:51 -07001910 hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u",
Dustin Brownad06be62019-02-04 14:52:56 -08001911 cfg->max_intf_count, WLAN_MAX_VDEVS, WLAN_MAX_VDEVS);
1912 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS;
Dustin Brownbee82832018-07-23 10:10:51 -07001913 } else {
1914 hdd_ctx->max_intf_count = cfg->max_intf_count;
1915 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001916
Jeff Johnsonf9176382018-07-17 19:15:58 -07001917 hdd_sar_target_config(hdd_ctx, cfg);
Jeff Johnsonc875e242016-09-23 18:12:34 -07001918 hdd_lpass_target_config(hdd_ctx, cfg);
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08001919
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001920 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
1921 hdd_update_tgt_services(hdd_ctx, &cfg->services);
1922
1923 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
1924
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001925 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
Krishna Kumaar Natarajaned1efd92016-09-24 18:05:47 -07001926 if (cfg->services.en_11ax) {
1927 hdd_info("11AX: 11ax is enabled - update HDD config");
1928 hdd_update_tgt_he_cap(hdd_ctx, cfg);
1929 }
Varun Reddy Yeturue93d2462018-05-22 13:54:52 -07001930 hdd_update_tgt_twt_cap(hdd_ctx, cfg);
Tushnim Bhattacharyyaf44a9d82016-07-05 10:52:06 -07001931
gaurank kathpaliafa7ad0a2019-03-12 19:17:56 +05301932 for (band = NSS_CHAINS_BAND_2GHZ; band < NSS_CHAINS_BAND_MAX; band++) {
1933 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
1934 QDF_STA_MODE, band);
1935 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
1936 QDF_SAP_MODE, band);
1937 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
1938 QDF_TDLS_MODE, band);
1939 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
1940 QDF_P2P_DEVICE_MODE,
1941 band);
1942 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
1943 QDF_OCB_MODE, band);
1944 sme_modify_nss_chains_tgt_cfg(hdd_ctx->mac_handle,
1945 QDF_TDLS_MODE, band);
1946 }
1947
Tushnim Bhattacharyyaf44a9d82016-07-05 10:52:06 -07001948 hdd_update_vdev_nss(hdd_ctx);
1949
gaurank kathpalia5fcefa92018-10-24 15:03:15 +05301950 hdd_ctx->dynamic_nss_chains_support =
1951 cfg->dynamic_nss_chains_support;
Arif Hussainbd5194c2018-11-27 19:01:15 -08001952 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap);
1953 fine_time_meas_cap &= cfg->fine_time_measurement_cap;
1954 status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc,
1955 fine_time_meas_cap);
1956 if (QDF_IS_STATUS_ERROR(status)) {
1957 hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x",
1958 fine_time_meas_cap, cfg->fine_time_measurement_cap);
1959 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
1960 &fine_time_meas_cap);
1961 }
1962
Krunal Sonie3531942016-04-12 17:43:53 -07001963 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
Arif Hussainbd5194c2018-11-27 19:01:15 -08001964 hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap);
Archana Ramachandran393f3792015-11-13 17:13:21 -08001965
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301966 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
1967 if (!QDF_IS_STATUS_SUCCESS(status))
1968 hdd_err("unable to get vht_enable2x2");
1969
1970 antenna_mode = (bval == 0x01) ?
Nitesh Shahe50711f2017-04-26 16:30:45 +05301971 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
1972 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001973 hdd_debug("Init current antenna mode: %d",
Arif Hussainee10f902017-12-27 16:30:17 -08001974 hdd_ctx->current_antenna_mode);
Archana Ramachandran393f3792015-11-13 17:13:21 -08001975
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05301976 hdd_ctx->rcpi_enabled = cfg->rcpi_enabled;
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05301977
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301978 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
Abhinav Kumare057b412018-10-09 17:28:16 +05301979 &value);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301980 if (QDF_IS_STATUS_ERROR(status)) {
1981 status = false;
1982 hdd_err("set tx_bfee_ant_supp failed");
1983 }
1984
1985 if ((value >
Arif Hussainee10f902017-12-27 16:30:17 -08001986 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301987 !cfg->tx_bfee_8ss_enabled) {
1988 status =
1989 ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
1990 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF);
1991 if (QDF_IS_STATUS_ERROR(status)) {
1992 status = false;
1993 hdd_err("set tx_bfee_ant_supp failed");
1994 }
1995 }
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05301996
Jeff Johnson16528362018-06-14 12:34:16 -07001997 mac_handle = hdd_ctx->mac_handle;
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05301998
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301999 hdd_debug("txBFCsnValue %d", value);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05302000
2001 /*
2002 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
2003 */
2004 hdd_update_wiphy_vhtcap(hdd_ctx);
Manjeet Singh70d3d932016-12-20 20:41:10 +05302005
Jianmin Zhuc8bfffb2019-01-15 12:40:03 +08002006 hdd_update_vhtcap_2g(hdd_ctx);
2007
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05302008 hdd_ctx->wmi_max_len = cfg->wmi_max_len;
2009
Ashish Kumar Dhanotiya908925d2019-03-01 17:35:30 +05302010 wlan_config_sched_scan_plans_to_wiphy(hdd_ctx->wiphy, hdd_ctx->psoc);
Yue Macd359b72017-10-03 15:21:00 -07002011 /*
2012 * This needs to be done after HDD pdev is created and stored since
2013 * it will access the HDD pdev object lock.
2014 */
2015 hdd_runtime_suspend_context_init(hdd_ctx);
2016
Deepak Dhamdhere13230d32016-05-26 00:46:53 -07002017 /* Configure NAN datapath features */
2018 hdd_nan_datapath_target_config(hdd_ctx, cfg);
Nachiket Kukade85aa3782018-11-02 20:12:34 +05302019 ucfg_nan_set_tgt_caps(hdd_ctx->psoc, &cfg->nan_caps);
Arif Hussain759a0232017-03-20 13:17:18 -07002020 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08002021 hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share;
Liangwei Dong0da14262018-07-03 03:30:23 -04002022 hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload;
Wu Gao5f764082019-01-04 15:54:38 +08002023 status = ucfg_mlme_set_obss_detection_offload_enabled(
2024 hdd_ctx->psoc, cfg->obss_detection_offloaded);
Arif Hussainee10f902017-12-27 16:30:17 -08002025 if (QDF_IS_STATUS_ERROR(status))
2026 hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG");
Arif Hussain05fb4872018-01-03 16:02:55 -08002027
Wu Gao5f764082019-01-04 15:54:38 +08002028 status = ucfg_mlme_set_obss_color_collision_offload_enabled(
2029 hdd_ctx->psoc, cfg->obss_color_collision_offloaded);
Arif Hussain05fb4872018-01-03 16:02:55 -08002030 if (QDF_IS_STATUS_ERROR(status))
2031 hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD");
Arif Hussain50689082019-03-26 12:07:58 -07002032
2033 ucfg_mlme_get_bcast_twt(hdd_ctx->psoc, &bval);
2034 if (bval)
2035 ucfg_mlme_set_bcast_twt(hdd_ctx->psoc, cfg->bcast_twt_support);
2036 else
2037 hdd_debug("bcast twt is disable in ini, fw cap %d",
2038 cfg->bcast_twt_support);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002039}
2040
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002041bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002042{
Jeff Johnson9d295242017-08-29 14:39:48 -07002043 struct hdd_adapter *adapter;
Jeff Johnson87251032017-08-29 13:31:11 -07002044 struct hdd_ap_ctx *ap_ctx;
Arif Hussain224d3812018-11-16 17:58:38 -08002045 bool dfs_disable_channel_switch = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002046
Jiachao Wuf610d912018-01-23 17:47:32 +08002047 if (!hdd_ctx) {
2048 hdd_info("Couldn't get hdd_ctx");
2049 return true;
2050 }
2051
Arif Hussain224d3812018-11-16 17:58:38 -08002052 ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc,
2053 &dfs_disable_channel_switch);
2054 if (dfs_disable_channel_switch) {
Jeff Johnson36e74c42017-09-18 08:15:42 -07002055 hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d",
Arif Hussain224d3812018-11-16 17:58:38 -08002056 hdd_ctx, dfs_disable_channel_switch);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302057 return true;
Arif Hussaincd151632017-02-11 16:57:19 -08002058 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002059
Dustin Brown920397d2017-12-13 16:27:50 -08002060 hdd_for_each_adapter(hdd_ctx, adapter) {
Arif Hussaincd151632017-02-11 16:57:19 -08002061 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
2062
2063 if ((QDF_SAP_MODE == adapter->device_mode ||
2064 QDF_P2P_GO_MODE == adapter->device_mode) &&
Dustin Brown07901ec2018-09-07 11:02:41 -07002065 (wlan_reg_is_passive_or_disable_ch(hdd_ctx->pdev,
Jeff Johnson01206862017-10-27 20:55:59 -07002066 ap_ctx->operating_channel))) {
Arif Hussaincd151632017-02-11 16:57:19 -08002067 WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx =
2068 true;
Jeff Johnson7eb6e842019-02-23 14:33:34 -08002069 hdd_info("tx blocked for vdev: %d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -08002070 adapter->vdev_id);
bings6fb9bf62018-07-05 14:01:53 +08002071 if (adapter->txrx_vdev)
2072 cdp_fc_vdev_flush(
2073 cds_get_context(QDF_MODULE_ID_SOC),
bings0e03a982018-05-09 08:40:59 +08002074 adapter->txrx_vdev);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302075 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002076 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302077
2078 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002079}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002080
Jeff Johnson030cd902018-11-11 10:19:40 -08002081bool hdd_is_valid_mac_address(const uint8_t *mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002082{
2083 int xdigit = 0;
2084 int separator = 0;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002085
Jeff Johnson030cd902018-11-11 10:19:40 -08002086 while (*mac_addr) {
2087 if (isxdigit(*mac_addr)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002088 xdigit++;
Jeff Johnson030cd902018-11-11 10:19:40 -08002089 } else if (':' == *mac_addr) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002090 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
2091 break;
2092
2093 ++separator;
2094 } else {
2095 /* Invalid MAC found */
Jeff Johnson030cd902018-11-11 10:19:40 -08002096 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002097 }
Jeff Johnson030cd902018-11-11 10:19:40 -08002098 ++mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002099 }
2100 return xdigit == 12 && (separator == 5 || separator == 0);
2101}
2102
2103/**
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302104 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
2105 * @dev: Handle to struct net_device to be updated.
2106 *
2107 * Return: None
2108 */
2109static void hdd_mon_mode_ether_setup(struct net_device *dev)
2110{
2111 dev->header_ops = NULL;
2112 dev->type = ARPHRD_IEEE80211_RADIOTAP;
2113 dev->hard_header_len = ETH_HLEN;
2114 dev->mtu = ETH_DATA_LEN;
2115 dev->addr_len = ETH_ALEN;
2116 dev->tx_queue_len = 1000; /* Ethernet wants good queues */
2117 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
2118 dev->priv_flags |= IFF_TX_SKB_SHARING;
2119
2120 memset(dev->broadcast, 0xFF, ETH_ALEN);
2121}
2122
Nirav Shah73713f72018-05-17 14:50:41 +05302123#ifdef FEATURE_MONITOR_MODE_SUPPORT
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302124/**
chenguo71303962018-10-24 19:44:34 +08002125 * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device.
2126 * @hdd_ctx: Pointer to HDD context.
2127 *
2128 * Return: None
2129 */
2130static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx)
2131{
2132 ucfg_pmo_set_power_save_mode(hdd_ctx->psoc, PS_NOT_SUPPORTED);
2133 ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH);
2134}
2135
2136/**
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002137 * __hdd__mon_open() - HDD Open function
2138 * @dev: Pointer to net_device structure
2139 *
2140 * This is called in response to ifconfig up
2141 *
2142 * Return: 0 for success; non-zero for failure
2143 */
2144static int __hdd_mon_open(struct net_device *dev)
2145{
2146 int ret;
Ravi Joshia307f632017-07-17 23:41:41 -07002147 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2148 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002149
Dustin Brownfdf17c12018-03-14 12:55:34 -07002150 hdd_enter_dev(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002151
2152 ret = wlan_hdd_validate_context(hdd_ctx);
2153 if (ret)
2154 return ret;
2155
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302156 hdd_mon_mode_ether_setup(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002157
2158 if (con_mode == QDF_GLOBAL_MONITOR_MODE) {
Dustin Brown3ecc8782018-09-19 16:37:13 -07002159 ret = hdd_psoc_idle_restart(hdd_ctx);
Ravi Joshia307f632017-07-17 23:41:41 -07002160 if (ret) {
2161 hdd_err("Failed to start WLAN modules return");
2162 return ret;
2163 }
2164 hdd_err("hdd_wlan_start_modules() successful !");
2165
2166 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
2167 ret = hdd_start_adapter(adapter);
2168 if (ret) {
2169 hdd_err("Failed to start adapter :%d",
2170 adapter->device_mode);
2171 return ret;
2172 }
2173 hdd_err("hdd_start_adapters() successful !");
2174 }
chenguo71303962018-10-24 19:44:34 +08002175 hdd_mon_turn_off_ps_and_wow(hdd_ctx);
Ravi Joshia307f632017-07-17 23:41:41 -07002176 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
2177 }
2178
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002179 ret = hdd_set_mon_rx_cb(dev);
Ravi Joshi4f095952017-06-29 15:39:19 -07002180
2181 if (!ret)
2182 ret = hdd_enable_monitor_mode(dev);
2183
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002184 return ret;
2185}
2186
2187/**
2188 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
2189 * @dev: Pointer to net_device structure
2190 *
2191 * This is called in response to ifconfig up
2192 *
2193 * Return: 0 for success; non-zero for failure
2194 */
Dustin Brown0e1e1622019-01-17 11:00:22 -08002195static int hdd_mon_open(struct net_device *net_dev)
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002196{
Dustin Brown0e1e1622019-01-17 11:00:22 -08002197 int errno;
2198 struct osif_vdev_sync *vdev_sync;
2199
2200 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
2201 if (errno)
2202 return errno;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002203
Dustin Brown0e1e1622019-01-17 11:00:22 -08002204 errno = __hdd_mon_open(net_dev);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002205
Dustin Brown0e1e1622019-01-17 11:00:22 -08002206 osif_vdev_sync_trans_stop(vdev_sync);
2207
2208 return errno;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002209}
Nirav Shah73713f72018-05-17 14:50:41 +05302210#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002211
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002212static QDF_STATUS
2213wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
2214{
2215 struct policy_mgr_dual_mac_config cfg = {0};
2216 QDF_STATUS status;
Krunal Sonie64b17e2018-12-13 16:00:02 -08002217 uint32_t chnl_sel_logic_conc = 0;
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002218 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Krunal Sonidf29bc42018-11-15 13:26:29 -08002219 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002220
2221 if (!hdd_ctx) {
2222 hdd_err("HDD context is NULL");
2223 return QDF_STATUS_E_FAILURE;
2224 }
2225
Krunal Sonie64b17e2018-12-13 16:00:02 -08002226 /*
2227 * ROME platform doesn't support any DBS related commands in FW,
2228 * so if driver sends wmi command with dual_mac_config with all set to
2229 * 0 then FW wouldn't respond back and driver would timeout on waiting
2230 * for response. Check if FW supports DBS to eliminate ROME vs
2231 * NON-ROME platform.
2232 */
2233 if (!policy_mgr_find_if_fw_supports_dbs(hdd_ctx->psoc))
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002234 return QDF_STATUS_SUCCESS;
2235
2236 cfg.scan_config = 0;
2237 cfg.fw_mode_config = 0;
2238 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
Krunal Sonie64b17e2018-12-13 16:00:02 -08002239 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) {
2240 status =
2241 ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc,
2242 &chnl_sel_logic_conc);
2243 if (status != QDF_STATUS_SUCCESS) {
2244 hdd_err("can't get chnl sel policy, use def");
2245 return status;
2246 }
Krunal Sonidf29bc42018-11-15 13:26:29 -08002247 }
2248 status =
2249 ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
2250 &dual_mac_feature);
2251 if (status != QDF_STATUS_SUCCESS) {
2252 hdd_err("ucfg_policy_mgr_get_dual_mac_feature failed, use def");
2253 return status;
2254 }
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002255
Krunal Sonidf29bc42018-11-15 13:26:29 -08002256 if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) {
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002257 status = policy_mgr_get_updated_scan_and_fw_mode_config(
Dustin Brown1dbefe62018-09-11 16:32:03 -07002258 hdd_ctx->psoc, &cfg.scan_config,
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002259 &cfg.fw_mode_config,
Krunal Sonidf29bc42018-11-15 13:26:29 -08002260 dual_mac_feature,
Krunal Sonie64b17e2018-12-13 16:00:02 -08002261 chnl_sel_logic_conc);
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002262
2263 if (status != QDF_STATUS_SUCCESS) {
2264 hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",
2265 status);
2266 return status;
2267 }
2268 }
2269
2270 hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw",
2271 cfg.scan_config, cfg.fw_mode_config);
2272
2273 status = sme_soc_set_dual_mac_config(cfg);
2274 if (status != QDF_STATUS_SUCCESS) {
2275 hdd_err("sme_soc_set_dual_mac_config failed %d", status);
2276 return status;
2277 }
2278
2279 return QDF_STATUS_SUCCESS;
2280}
2281
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002282/**
Arun Khandavallifae92942016-08-01 13:31:08 +05302283 * hdd_start_adapter() - Wrapper function for device specific adapter
2284 * @adapter: pointer to HDD adapter
2285 *
2286 * This function is called to start the device specific adapter for
2287 * the mode passed in the adapter's device_mode.
2288 *
2289 * Return: 0 for success; non-zero for failure
2290 */
Jeff Johnson9d295242017-08-29 14:39:48 -07002291int hdd_start_adapter(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05302292{
2293
2294 int ret;
Jeff Johnsonc1e62782017-11-09 09:50:17 -08002295 enum QDF_OPMODE device_mode = adapter->device_mode;
Arun Khandavallifae92942016-08-01 13:31:08 +05302296
Dustin Brownfdf17c12018-03-14 12:55:34 -07002297 hdd_enter_dev(adapter->dev);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002298 hdd_debug("Start_adapter for mode : %d", adapter->device_mode);
Arun Khandavallifae92942016-08-01 13:31:08 +05302299
2300 switch (device_mode) {
2301 case QDF_P2P_CLIENT_MODE:
2302 case QDF_P2P_DEVICE_MODE:
2303 case QDF_OCB_MODE:
2304 case QDF_STA_MODE:
2305 case QDF_MONITOR_MODE:
2306 ret = hdd_start_station_adapter(adapter);
2307 if (ret)
2308 goto err_start_adapter;
Alok Kumar81e1d732018-09-04 11:10:36 +05302309
2310 hdd_nud_ignore_tracking(adapter, false);
Arun Khandavallifae92942016-08-01 13:31:08 +05302311 break;
2312 case QDF_P2P_GO_MODE:
2313 case QDF_SAP_MODE:
2314 ret = hdd_start_ap_adapter(adapter);
2315 if (ret)
2316 goto err_start_adapter;
2317 break;
Arun Khandavallib2f6c262016-08-18 19:07:19 +05302318 case QDF_IBSS_MODE:
2319 /*
2320 * For IBSS interface is initialized as part of
2321 * hdd_init_station_mode()
2322 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08002323 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302324 case QDF_FTM_MODE:
Dustin Browndb2a8be2017-12-20 11:49:56 -08002325 /* vdevs are dynamically managed by firmware in FTM */
2326 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302327 default:
2328 hdd_err("Invalid session type %d", device_mode);
2329 QDF_ASSERT(0);
2330 goto err_start_adapter;
2331 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08002332
Arun Khandavallifae92942016-08-01 13:31:08 +05302333 if (hdd_set_fw_params(adapter))
2334 hdd_err("Failed to set the FW params for the adapter!");
2335
Jeff Johnson912b1bb2019-03-06 10:12:36 -08002336 if (adapter->vdev_id != WLAN_UMAC_VDEV_ID_MAX) {
Dustin Browne7e71d32018-05-11 16:00:08 -07002337 ret = wlan_hdd_cfg80211_register_frames(adapter);
2338 if (ret < 0) {
2339 hdd_err("Failed to register frames - ret %d", ret);
2340 goto err_start_adapter;
2341 }
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302342 }
Dustin Browne7e71d32018-05-11 16:00:08 -07002343
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002344 wlan_hdd_update_dbs_scan_and_fw_mode_config();
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302345
Dustin Browndb2a8be2017-12-20 11:49:56 -08002346exit_with_success:
Dustin Browne74003f2018-03-14 12:51:58 -07002347 hdd_exit();
Dustin Browndb2a8be2017-12-20 11:49:56 -08002348
Arun Khandavallifae92942016-08-01 13:31:08 +05302349 return 0;
Dustin Browndb2a8be2017-12-20 11:49:56 -08002350
Arun Khandavallifae92942016-08-01 13:31:08 +05302351err_start_adapter:
2352 return -EINVAL;
2353}
2354
2355/**
Komal Seelamf2136bb2016-09-28 18:30:44 +05302356 * hdd_enable_power_management() - API to Enable Power Management
2357 *
2358 * API invokes Bus Interface Layer power management functionality
2359 *
2360 * Return: None
2361 */
2362static void hdd_enable_power_management(void)
2363{
2364 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2365
2366 if (!hif_ctx) {
2367 hdd_err("Bus Interface Context is Invalid");
2368 return;
2369 }
2370
2371 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
2372}
2373
2374/**
2375 * hdd_disable_power_management() - API to disable Power Management
2376 *
2377 * API disable Bus Interface Layer Power management functionality
2378 *
2379 * Return: None
2380 */
2381static void hdd_disable_power_management(void)
2382{
2383 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2384
2385 if (!hif_ctx) {
2386 hdd_err("Bus Interface Context is Invalid");
2387 return;
2388 }
2389
2390 hif_disable_power_management(hif_ctx);
2391}
2392
Ryan Hsuaadba072018-04-20 13:01:53 -07002393void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx)
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302394{
2395 void *hif_sc;
Dustin Brown6f17a022017-07-19 13:40:55 -07002396 size_t target_hw_name_len;
2397 const char *target_hw_name;
Ryan Hsuaadba072018-04-20 13:01:53 -07002398 uint8_t *buf;
2399 uint32_t buf_len;
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302400
2401 hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
2402 if (!hif_sc) {
2403 hdd_err("HIF context is NULL");
2404 return;
2405 }
2406
Ryan Hsuaadba072018-04-20 13:01:53 -07002407 hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302408 &hdd_ctx->target_hw_revision,
Dustin Brown6f17a022017-07-19 13:40:55 -07002409 &target_hw_name);
2410
2411 if (hdd_ctx->target_hw_name)
2412 qdf_mem_free(hdd_ctx->target_hw_name);
2413
2414 target_hw_name_len = strlen(target_hw_name) + 1;
2415 hdd_ctx->target_hw_name = qdf_mem_malloc(target_hw_name_len);
2416 if (hdd_ctx->target_hw_name)
2417 qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name,
2418 target_hw_name_len);
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302419
Ryan Hsuaadba072018-04-20 13:01:53 -07002420 buf = qdf_mem_malloc(WE_MAX_STR_LEN);
2421 if (buf) {
2422 buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf);
2423 hdd_info("%s", buf);
2424 qdf_mem_free(buf);
2425 }
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302426}
2427
2428/**
gbian62edd7e2017-03-07 13:12:13 +08002429 * hdd_update_cds_ac_specs_params() - update cds ac_specs params
2430 * @hdd_ctx: Pointer to hdd context
2431 *
2432 * Return: none
2433 */
2434static void
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002435hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx)
gbian62edd7e2017-03-07 13:12:13 +08002436{
jitiphil8e15ea62018-11-16 18:05:34 +05302437 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM] = {0};
2438 qdf_size_t out_size = 0;
gbian62edd7e2017-03-07 13:12:13 +08002439 int i;
Jeff Johnson2b6982c2018-05-29 14:56:11 -07002440 struct cds_context *cds_ctx;
gbian62edd7e2017-03-07 13:12:13 +08002441
Jeff Johnsond36fa332019-03-18 13:42:25 -07002442 if (!hdd_ctx)
gbian62edd7e2017-03-07 13:12:13 +08002443 return;
2444
Jeff Johnsond36fa332019-03-18 13:42:25 -07002445 if (!hdd_ctx->config) {
gbian62edd7e2017-03-07 13:12:13 +08002446 /* Do nothing if hdd_ctx is invalid */
2447 hdd_err("%s: Warning: hdd_ctx->cfg_ini is NULL", __func__);
2448 return;
2449 }
2450
2451 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2452
2453 if (!cds_ctx) {
2454 hdd_err("Invalid CDS Context");
2455 return;
2456 }
2457
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002458 for (i = 0; i < QCA_WLAN_AC_ALL; i++) {
gbian62edd7e2017-03-07 13:12:13 +08002459 switch (i) {
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002460 case QCA_WLAN_AC_BE:
jitiphil8e15ea62018-11-16 18:05:34 +05302461 qdf_uint8_array_parse(
2462 cfg_get(hdd_ctx->psoc,
2463 CFG_DP_ENABLE_TX_SCHED_WRR_BE),
2464 tx_sched_wrr_param,
2465 sizeof(tx_sched_wrr_param),
2466 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002467 break;
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002468 case QCA_WLAN_AC_BK:
jitiphil8e15ea62018-11-16 18:05:34 +05302469 qdf_uint8_array_parse(
2470 cfg_get(hdd_ctx->psoc,
2471 CFG_DP_ENABLE_TX_SCHED_WRR_BK),
2472 tx_sched_wrr_param,
2473 sizeof(tx_sched_wrr_param),
2474 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002475 break;
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002476 case QCA_WLAN_AC_VI:
jitiphil8e15ea62018-11-16 18:05:34 +05302477 qdf_uint8_array_parse(
2478 cfg_get(hdd_ctx->psoc,
2479 CFG_DP_ENABLE_TX_SCHED_WRR_VI),
2480 tx_sched_wrr_param,
2481 sizeof(tx_sched_wrr_param),
2482 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002483 break;
Srinivas Girigowdad462f3b2019-03-25 14:05:33 -07002484 case QCA_WLAN_AC_VO:
jitiphil8e15ea62018-11-16 18:05:34 +05302485 qdf_uint8_array_parse(
2486 cfg_get(hdd_ctx->psoc,
2487 CFG_DP_ENABLE_TX_SCHED_WRR_VO),
2488 tx_sched_wrr_param,
2489 sizeof(tx_sched_wrr_param),
2490 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002491 break;
2492 default:
gbian62edd7e2017-03-07 13:12:13 +08002493 break;
2494 }
2495
jitiphil8e15ea62018-11-16 18:05:34 +05302496 if (out_size == TX_SCHED_WRR_PARAMS_NUM) {
gbian62edd7e2017-03-07 13:12:13 +08002497 cds_ctx->ac_specs[i].wrr_skip_weight =
2498 tx_sched_wrr_param[0];
2499 cds_ctx->ac_specs[i].credit_threshold =
2500 tx_sched_wrr_param[1];
2501 cds_ctx->ac_specs[i].send_limit =
2502 tx_sched_wrr_param[2];
2503 cds_ctx->ac_specs[i].credit_reserve =
2504 tx_sched_wrr_param[3];
2505 cds_ctx->ac_specs[i].discard_weight =
2506 tx_sched_wrr_param[4];
2507 }
2508
jitiphil8e15ea62018-11-16 18:05:34 +05302509 out_size = 0;
gbian62edd7e2017-03-07 13:12:13 +08002510 }
2511}
2512
Ryan Hsuaadba072018-04-20 13:01:53 -07002513uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx,
2514 const size_t version_len, uint8_t *version)
2515{
2516 uint32_t size;
2517 uint32_t msp_id = 0, mspid = 0, siid = 0, crmid = 0, sub_id = 0;
2518
2519 if (!hdd_ctx) {
2520 hdd_err("Invalid context, HDD context is null");
2521 return 0;
2522 }
2523
Ashish Kumar Dhanotiya7353f882018-05-15 12:50:19 +05302524 if (!version || version_len == 0) {
Ryan Hsuaadba072018-04-20 13:01:53 -07002525 hdd_err("Invalid buffer pointr or buffer len\n");
2526 return 0;
2527 }
2528
2529 msp_id = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
2530 mspid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
2531 siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
2532 crmid = hdd_ctx->target_fw_version & 0x7fff;
2533 sub_id = (hdd_ctx->target_fw_vers_ext & 0xf0000000) >> 28;
2534
2535 size = scnprintf(version, version_len,
Ryan Hsuc6918552018-05-16 13:29:59 -07002536 "Host SW:%s, FW:%d.%d.%d.%d.%d, HW:%s, Board ver: %x Ref design id: %x, Customer id: %x, Project id: %x, Board Data Rev: %x",
Ryan Hsuaadba072018-04-20 13:01:53 -07002537 QWLAN_VERSIONSTR,
2538 msp_id, mspid, siid, crmid, sub_id,
Ryan Hsuc6918552018-05-16 13:29:59 -07002539 hdd_ctx->target_hw_name,
2540 hdd_ctx->hw_bd_info.bdf_version,
2541 hdd_ctx->hw_bd_info.ref_design_id,
2542 hdd_ctx->hw_bd_info.customer_id,
2543 hdd_ctx->hw_bd_info.project_id,
2544 hdd_ctx->hw_bd_info.board_data_rev);
Ryan Hsuaadba072018-04-20 13:01:53 -07002545
2546 return size;
2547}
2548
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302549int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value,
2550 struct sap_config *sap_config)
2551{
2552 uint8_t preamble = 0, nss = 0, rix = 0;
2553 int ret;
2554 mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
2555
2556 if (!sap_config) {
2557 if (!sme_is_feature_supported_by_fw(DOT11AX)) {
2558 hdd_err("Target does not support 11ax");
2559 return -EIO;
2560 }
2561 } else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax &&
2562 sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) {
2563 hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch = %d",
2564 sap_config->SapHw_mode, sap_config->channel);
2565 return -EIO;
2566 }
2567
2568 if (set_value != 0xff) {
2569 rix = RC_2_RATE_IDX_11AX(set_value);
2570 preamble = WMI_RATE_PREAMBLE_HE;
2571 nss = HT_RC_2_STREAMS_11AX(set_value);
2572
2573 set_value = hdd_assemble_rate_code(preamble, nss, rix);
2574 } else {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08002575 ret = sme_set_auto_rate_he_ltf(mac_handle, adapter->vdev_id,
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302576 QCA_WLAN_HE_LTF_AUTO);
2577 }
2578
2579 hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d",
2580 set_value, rix, preamble, nss);
2581
Jeff Johnson5a6fc962019-02-04 14:20:25 -08002582 ret = wma_cli_set_command(adapter->vdev_id,
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302583 WMI_VDEV_PARAM_FIXED_RATE,
2584 set_value, VDEV_CMD);
2585
2586 return ret;
2587}
2588
2589int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate)
2590{
2591 int set_value;
2592
2593 if (sme_is_feature_supported_by_fw(DOT11AX))
2594 set_value = WMI_ASSEMBLE_RATECODE_V1(rate, nss, preamble);
2595 else
2596 set_value = (preamble << 6) | (nss << 4) | rate;
2597
2598 return set_value;
2599}
2600
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002601#ifdef FEATURE_WLAN_WAPI
2602/**
2603 * hdd_wapi_security_sta_exist() - return wapi security sta exist or not
2604 *
2605 * This API returns the wapi security station exist or not
2606 *
2607 * Return: true - wapi security station exist
2608 */
2609static bool hdd_wapi_security_sta_exist(void)
2610{
2611 struct hdd_adapter *adapter = NULL;
2612 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2613
2614 hdd_for_each_adapter(hdd_ctx, adapter) {
2615 if ((adapter->device_mode == QDF_STA_MODE) &&
2616 adapter->wapi_info.wapi_mode &&
2617 (adapter->wapi_info.wapi_auth_mode != WAPI_AUTH_MODE_OPEN))
2618 return true;
2619 }
2620 return false;
2621}
2622#else
2623static bool hdd_wapi_security_sta_exist(void)
2624{
2625 return false;
2626}
2627#endif
2628
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002629#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002630static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
2631 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
2632{
Jeff Johnson9d295242017-08-29 14:39:48 -07002633 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002634 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002635
2636 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2637 if (!adapter) {
2638 hdd_err("Adapter is NULL");
2639 return PM_MAX_NUM_OF_MODE;
2640 }
2641
2642 return policy_mgr_convert_device_mode_to_qdf_type(
2643 adapter->device_mode);
2644}
2645
Abhishek Singh3bbf6cb2019-03-28 14:05:43 +05302646/**
2647 * hdd_is_chan_switch_in_progress() - Check if any adapter has channel switch in
2648 * progress
2649 *
2650 * Return: true, if any adapter has channel switch in
2651 * progress else false
2652 */
2653static bool hdd_is_chan_switch_in_progress(void)
2654{
2655 struct hdd_adapter *adapter = NULL;
2656 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2657
2658 hdd_for_each_adapter(hdd_ctx, adapter) {
2659 if ((adapter->device_mode == QDF_SAP_MODE ||
2660 adapter->device_mode == QDF_P2P_GO_MODE) &&
2661 qdf_atomic_read(&adapter->ch_switch_in_progress)) {
2662 hdd_debug("channel switch progress for vdev_id %d",
2663 adapter->vdev_id);
2664 return true;
2665 }
2666 }
2667
2668 return false;
2669}
2670
2671
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002672static void hdd_register_policy_manager_callback(
2673 struct wlan_objmgr_psoc *psoc)
2674{
2675 struct policy_mgr_hdd_cbacks hdd_cbacks;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07002676
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002677 qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks));
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002678 hdd_cbacks.sap_restart_chan_switch_cb =
Jeff Johnson23812942017-10-06 11:33:55 -07002679 hdd_sap_restart_chan_switch_cb;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002680 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
2681 wlan_hdd_get_channel_for_sap_restart;
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002682 hdd_cbacks.get_mode_for_non_connected_vdev =
2683 wlan_hdd_get_mode_for_non_connected_vdev;
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05302684 hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode;
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002685 hdd_cbacks.hdd_wapi_security_sta_exist =
2686 hdd_wapi_security_sta_exist;
Abhishek Singh3bbf6cb2019-03-28 14:05:43 +05302687 hdd_cbacks.hdd_is_chan_switch_in_progress =
2688 hdd_is_chan_switch_in_progress;
2689
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002690 if (QDF_STATUS_SUCCESS !=
2691 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
2692 hdd_err("HDD callback registration with policy manager failed");
2693 }
2694}
2695#else
2696static void hdd_register_policy_manager_callback(
2697 struct wlan_objmgr_psoc *psoc)
2698{
2699}
2700#endif
2701
Nachiket Kukade2fb1fdb2019-01-08 15:35:27 +05302702#ifdef WLAN_FEATURE_NAN
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002703static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002704{
2705 struct nan_callbacks cb_obj = {0};
2706
2707 cb_obj.ndi_open = hdd_ndi_open;
2708 cb_obj.ndi_close = hdd_ndi_close;
2709 cb_obj.ndi_start = hdd_ndi_start;
2710 cb_obj.ndi_delete = hdd_ndi_delete;
2711 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
2712 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
2713
Naveen Rawat37f62c82017-03-26 22:24:43 -07002714 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002715 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
Naveen Rawat37f62c82017-03-26 22:24:43 -07002716
Dustin Brown1dbefe62018-09-11 16:32:03 -07002717 os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002718}
jiadff1ac132018-11-26 16:27:48 +08002719#else
2720static inline void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
2721{
2722}
2723#endif
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002724
Dustin Brown26b3d042017-12-21 11:13:27 -08002725#ifdef CONFIG_LEAK_DETECTION
Dustin Brown4c5b9902017-12-19 11:17:19 -08002726/**
2727 * hdd_check_for_leaks() - Perform runtime memory leak checks
Dustin Browna6246dd2018-05-24 14:35:58 -07002728 * @hdd_ctx: the global HDD context
Dustin Brown29533f22018-07-24 13:11:56 -07002729 * @is_ssr: true if SSR is in progress
Dustin Brown4c5b9902017-12-19 11:17:19 -08002730 *
2731 * This API triggers runtime memory leak detection. This feature enforces the
2732 * policy that any memory allocated at runtime must also be released at runtime.
2733 *
2734 * Allocating memory at runtime and releasing it at unload is effectively a
2735 * memory leak for configurations which never unload (e.g. LONU, statically
2736 * compiled driver). Such memory leaks are NOT false positives, and must be
2737 * fixed.
2738 *
2739 * Return: None
2740 */
Dustin Brown29533f22018-07-24 13:11:56 -07002741static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
Dustin Brown4bc0a622017-12-06 15:56:50 -08002742{
Dustin Brown4c5b9902017-12-19 11:17:19 -08002743 /* DO NOT REMOVE these checks; for false positives, read above first */
2744
Dustin Brown1dbefe62018-09-11 16:32:03 -07002745 wlan_objmgr_psoc_check_for_peer_leaks(hdd_ctx->psoc);
2746 wlan_objmgr_psoc_check_for_vdev_leaks(hdd_ctx->psoc);
2747 wlan_objmgr_psoc_check_for_pdev_leaks(hdd_ctx->psoc);
Dustin Brown29533f22018-07-24 13:11:56 -07002748
2749 /* many adapter resources are not freed by design during SSR */
2750 if (is_ssr)
2751 return;
2752
Dustin Brownc2796312019-03-13 16:43:36 -07002753 qdf_delayed_work_check_for_leaks();
Dustin Brown677e0862017-10-10 16:30:09 -07002754 qdf_mc_timer_check_for_leaks();
Dustin Brown8e711502017-12-07 16:49:11 -08002755 qdf_nbuf_map_check_for_leaks();
Dustin Brown4a93bb52019-03-13 11:46:34 -07002756 qdf_periodic_work_check_for_leaks();
Dustin Browne6b9d5a2017-12-14 15:18:49 -08002757 qdf_mem_check_for_leaks();
Dustin Brown4bc0a622017-12-06 15:56:50 -08002758}
2759
Dustin Brown26b3d042017-12-21 11:13:27 -08002760#define hdd_debug_domain_set(domain) qdf_debug_domain_set(domain)
2761#else
Dustin Brown29533f22018-07-24 13:11:56 -07002762static inline void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
2763{ }
Dustin Brown26b3d042017-12-21 11:13:27 -08002764
2765#define hdd_debug_domain_set(domain)
2766#endif /* CONFIG_LEAK_DETECTION */
2767
gbian62edd7e2017-03-07 13:12:13 +08002768/**
Paul Zhange03cf4c2018-01-19 18:33:22 +08002769 * hdd_update_country_code - Update country code
2770 * @hdd_ctx: HDD context
2771 *
2772 * Update country code based on module parameter country_code
2773 *
2774 * Return: 0 on success and errno on failure
2775 */
2776static int hdd_update_country_code(struct hdd_context *hdd_ctx)
2777{
2778 if (!country_code)
2779 return 0;
2780
2781 return hdd_reg_set_country(hdd_ctx, country_code);
2782}
2783
Dustin Browne7e71d32018-05-11 16:00:08 -07002784int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
Arun Khandavallifae92942016-08-01 13:31:08 +05302785{
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07002786 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05302787 qdf_device_t qdf_dev;
2788 QDF_STATUS status;
Arun Khandavallifae92942016-08-01 13:31:08 +05302789 bool unint = false;
2790 void *hif_ctx;
Jingxiang Ge95912f82018-04-19 12:01:26 +08002791 struct target_psoc_info *tgt_hdl;
Arun Khandavallifae92942016-08-01 13:31:08 +05302792
Arun Khandavallifae92942016-08-01 13:31:08 +05302793 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
2794 if (!qdf_dev) {
2795 hdd_err("QDF Device Context is Invalid return");
2796 return -EINVAL;
2797 }
2798
Dustin Brown4c663222018-10-23 14:19:36 -07002799 hdd_psoc_idle_timer_stop(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05302800
Arun Khandavalli5a62a822017-11-14 19:43:00 +05302801 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07002802 hdd_debug("Driver modules already Enabled");
Dustin Browne74003f2018-03-14 12:51:58 -07002803 hdd_exit();
Arun Khandavalli5a62a822017-11-14 19:43:00 +05302804 return 0;
2805 }
2806
Arun Khandavallifae92942016-08-01 13:31:08 +05302807 switch (hdd_ctx->driver_status) {
2808 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown550f6d22017-12-14 15:44:01 -08002809 hdd_info("Wlan transitioning (UNINITIALIZED -> CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +05302810 unint = true;
2811 /* Fall through dont add break here */
2812 case DRIVER_MODULES_CLOSED:
Dustin Brown1a20b082018-08-03 17:27:15 -07002813 hdd_info("Wlan transitioning (CLOSED -> ENABLED)");
Dustin Brown550f6d22017-12-14 15:44:01 -08002814
Dustin Brown26b3d042017-12-21 11:13:27 -08002815 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
Dustin Brown4bc0a622017-12-06 15:56:50 -08002816
Arun Khandavallifae92942016-08-01 13:31:08 +05302817 if (!reinit && !unint) {
2818 ret = pld_power_on(qdf_dev->dev);
2819 if (ret) {
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07002820 hdd_err("Failed to power up device; errno:%d",
Dustin Browndca39692017-11-09 15:30:25 -08002821 ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05302822 goto release_lock;
2823 }
2824 }
Yuanyuan Liuf8fe4bc2017-06-07 16:55:58 -07002825
2826 pld_set_fw_log_mode(hdd_ctx->parent_dev,
2827 hdd_ctx->config->enable_fw_log);
Arun Khandavallifae92942016-08-01 13:31:08 +05302828 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
2829 qdf_dev->bus_type,
2830 (reinit == true) ? HIF_ENABLE_TYPE_REINIT :
2831 HIF_ENABLE_TYPE_PROBE);
2832 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002833 hdd_err("Failed to open hif; errno: %d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05302834 goto power_down;
2835 }
2836
2837 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
Arun Khandavalli1318b992016-08-09 11:04:57 +05302838 if (!hif_ctx) {
2839 hdd_err("hif context is null!!");
Dustin Browndca39692017-11-09 15:30:25 -08002840 ret = -EINVAL;
Arun Khandavalli1318b992016-08-09 11:04:57 +05302841 goto power_down;
2842 }
2843
Arun Khandavallifae92942016-08-01 13:31:08 +05302844 status = ol_cds_init(qdf_dev, hif_ctx);
2845 if (status != QDF_STATUS_SUCCESS) {
Dustin Browndca39692017-11-09 15:30:25 -08002846 hdd_err("No Memory to Create BMI Context; status: %d",
2847 status);
2848 ret = qdf_status_to_os_return(status);
Arun Khandavallifae92942016-08-01 13:31:08 +05302849 goto hif_close;
2850 }
2851
Nirav Shah6aeecf92019-02-13 14:05:03 +05302852 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) {
2853 status = epping_open();
2854 if (status) {
2855 hdd_err("Failed to open in epping mode: %d",
2856 status);
2857 ret = -EINVAL;
2858 goto cds_free;
2859 }
2860
2861 status = epping_enable(qdf_dev->dev, false);
2862 if (status) {
2863 hdd_err("Failed to enable in epping mode : %d",
2864 status);
2865 epping_close();
2866 goto cds_free;
2867 }
2868
2869 hdd_info("epping mode enabled");
2870 break;
2871 }
2872
jitiphil4c256a32018-09-07 08:51:52 +05302873 ucfg_ipa_component_config_update(hdd_ctx->psoc);
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05302874
gbian62edd7e2017-03-07 13:12:13 +08002875 hdd_update_cds_ac_specs_params(hdd_ctx);
2876
Dustin Brown1dbefe62018-09-11 16:32:03 -07002877 status = hdd_component_psoc_open(hdd_ctx->psoc);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05302878 if (QDF_IS_STATUS_ERROR(status)) {
2879 hdd_err("Failed to Open legacy components; status: %d",
2880 status);
2881 ret = qdf_status_to_os_return(status);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05302882 goto cds_free;
2883 }
2884
2885 ret = hdd_update_config(hdd_ctx);
2886 if (ret) {
2887 hdd_err("Failed to update configuration; errno: %d",
2888 ret);
2889 goto cds_free;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05302890 }
2891
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +05302892 status = wbuff_module_init();
2893 if (QDF_IS_STATUS_ERROR(status))
2894 hdd_err("WBUFF init unsuccessful; status: %d", status);
2895
Dustin Brown1dbefe62018-09-11 16:32:03 -07002896 status = cds_open(hdd_ctx->psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07002897 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002898 hdd_err("Failed to Open CDS; status: %d", status);
Dustin Brown28b17892017-10-10 13:29:38 -07002899 ret = qdf_status_to_os_return(status);
Krunal Sonie71838d2018-09-27 10:45:05 -07002900 goto psoc_close;
Arun Khandavallifae92942016-08-01 13:31:08 +05302901 }
2902
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +05302903 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
2904
Manjunathappa Prakashb6b4ff12018-06-04 12:32:33 -07002905 if (hdd_ctx->config->rx_thread_affinity_mask)
2906 cds_set_rx_thread_cpu_mask(
2907 hdd_ctx->config->rx_thread_affinity_mask);
2908
2909 /* initialize components configurations after psoc open */
Mukul Sharma9d797a02017-01-05 20:26:03 +05302910 ret = hdd_update_components_config(hdd_ctx);
2911 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002912 hdd_err("Failed to update component configs; errno: %d",
Mukul Sharma9d797a02017-01-05 20:26:03 +05302913 ret);
2914 goto close;
2915 }
Sourav Mohapatra674925f2018-04-16 11:16:58 +05302916
Dustin Brown1dbefe62018-09-11 16:32:03 -07002917 status = cds_dp_open(hdd_ctx->psoc);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002918 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002919 hdd_err("Failed to Open cds post open; status: %d",
2920 status);
2921 ret = qdf_status_to_os_return(status);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002922 goto close;
2923 }
Mukul Sharma9d797a02017-01-05 20:26:03 +05302924
Sourav Mohapatra674925f2018-04-16 11:16:58 +05302925 ret = hdd_register_cb(hdd_ctx);
2926 if (ret) {
2927 hdd_err("Failed to register HDD callbacks!");
2928 goto cds_txrx_free;
2929 }
2930
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002931 /*
2932 * NAN compoenet requires certian operations like, open adapter,
2933 * close adapter, etc. to be initiated by HDD, for those
2934 * register HDD callbacks with UMAC's NAN componenet.
2935 */
2936 hdd_nan_register_callbacks(hdd_ctx);
2937
Jeff Johnson3a280122017-09-13 07:42:00 -07002938 status = cds_pre_enable();
Arun Khandavallifae92942016-08-01 13:31:08 +05302939 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002940 hdd_err("Failed to pre-enable CDS; status: %d", status);
2941 ret = qdf_status_to_os_return(status);
Sourav Mohapatra674925f2018-04-16 11:16:58 +05302942 goto deregister_cb;
Arun Khandavallifae92942016-08-01 13:31:08 +05302943 }
2944
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002945 hdd_register_policy_manager_callback(
Dustin Brown1dbefe62018-09-11 16:32:03 -07002946 hdd_ctx->psoc);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002947
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05302948 hdd_sysfs_create_driver_root_obj();
Dustin Brown1dbefe62018-09-11 16:32:03 -07002949 hdd_sysfs_create_version_interface(hdd_ctx->psoc);
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05302950 hdd_sysfs_create_powerstats_interface();
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302951 hdd_update_hw_sw_info(hdd_ctx);
Dustin Brown550f6d22017-12-14 15:44:01 -08002952
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05302953 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
2954 hdd_err("in ftm mode, no need to configure cds modules");
Dustin Browndca39692017-11-09 15:30:25 -08002955 ret = -EINVAL;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05302956 break;
2957 }
Dustin Browndca39692017-11-09 15:30:25 -08002958
Dustin Browne7e71d32018-05-11 16:00:08 -07002959 ret = hdd_configure_cds(hdd_ctx);
Dustin Browndca39692017-11-09 15:30:25 -08002960 if (ret) {
2961 hdd_err("Failed to Enable cds modules; errno: %d", ret);
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05302962 goto destroy_driver_sysfs;
Arun Khandavallifae92942016-08-01 13:31:08 +05302963 }
Dustin Browndca39692017-11-09 15:30:25 -08002964
Komal Seelamf2136bb2016-09-28 18:30:44 +05302965 hdd_enable_power_management();
Dustin Brown550f6d22017-12-14 15:44:01 -08002966
Arun Khandavallifae92942016-08-01 13:31:08 +05302967 break;
Dustin Brown550f6d22017-12-14 15:44:01 -08002968
Arun Khandavallifae92942016-08-01 13:31:08 +05302969 default:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07002970 QDF_DEBUG_PANIC("Unknown driver state:%d",
Arun Khandavallifae92942016-08-01 13:31:08 +05302971 hdd_ctx->driver_status);
Dustin Browndca39692017-11-09 15:30:25 -08002972 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05302973 goto release_lock;
2974 }
Dustin Brown550f6d22017-12-14 15:44:01 -08002975
Dustin Brown1a20b082018-08-03 17:27:15 -07002976 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
2977 hdd_info("Wlan transitioned (now ENABLED)");
2978
Dustin Browne74003f2018-03-14 12:51:58 -07002979 hdd_exit();
Dustin Brown550f6d22017-12-14 15:44:01 -08002980
Arun Khandavallifae92942016-08-01 13:31:08 +05302981 return 0;
2982
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05302983destroy_driver_sysfs:
2984 hdd_sysfs_destroy_powerstats_interface();
2985 hdd_sysfs_destroy_version_interface();
2986 hdd_sysfs_destroy_driver_root_obj();
Rajeev Kumarbe021242017-02-16 16:12:23 -08002987 cds_post_disable();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08002988
Sourav Mohapatra674925f2018-04-16 11:16:58 +05302989deregister_cb:
2990 hdd_deregister_cb(hdd_ctx);
2991
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002992cds_txrx_free:
Dustin Brown1dbefe62018-09-11 16:32:03 -07002993 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
Jingxiang Ge95912f82018-04-19 12:01:26 +08002994
2995 if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl)) {
2996 hdd_runtime_suspend_context_deinit(hdd_ctx);
Dustin Brown07901ec2018-09-07 11:02:41 -07002997 dispatcher_pdev_close(hdd_ctx->pdev);
Jingxiang Ge95912f82018-04-19 12:01:26 +08002998 hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
2999 }
3000
Dustin Brown1dbefe62018-09-11 16:32:03 -07003001 cds_dp_close(hdd_ctx->psoc);
Dustin Brown550f6d22017-12-14 15:44:01 -08003002
Arun Khandavallifae92942016-08-01 13:31:08 +05303003close:
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003004 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -08003005 hdd_info("Wlan transition aborted (now CLOSED)");
3006
Dustin Brown1dbefe62018-09-11 16:32:03 -07003007 cds_close(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +05303008
Krunal Sonie71838d2018-09-27 10:45:05 -07003009psoc_close:
Dustin Brown1dbefe62018-09-11 16:32:03 -07003010 hdd_component_psoc_close(hdd_ctx->psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07003011 cds_deinit_ini_config();
3012
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003013cds_free:
Arun Khandavallifae92942016-08-01 13:31:08 +05303014 ol_cds_free();
3015
3016hif_close:
Jeff Johnson60dc2b12017-09-28 14:56:02 -07003017 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
3018 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303019power_down:
3020 if (!reinit && !unint)
3021 pld_power_off(qdf_dev->dev);
3022release_lock:
Abhinav Kumar7ae9b7b2017-12-19 15:11:54 +05303023 if (hdd_ctx->target_hw_name) {
3024 qdf_mem_free(hdd_ctx->target_hw_name);
3025 hdd_ctx->target_hw_name = NULL;
3026 }
Dustin Brown29533f22018-07-24 13:11:56 -07003027
3028 hdd_check_for_leaks(hdd_ctx, reinit);
Dustin Brown26b3d042017-12-21 11:13:27 -08003029 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -08003030
Dustin Browne74003f2018-03-14 12:51:58 -07003031 hdd_exit();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003032
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07003033 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05303034}
3035
Naveen Rawat910726a2017-03-06 11:42:51 -08003036#ifdef WIFI_POS_CONVERGED
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003037static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003038{
3039 int ret = os_if_wifi_pos_register_nl();
3040
3041 if (ret)
3042 hdd_err("os_if_wifi_pos_register_nl failed");
3043
3044 return ret;
3045}
3046
3047static int hdd_deactivate_wifi_pos(void)
3048{
3049 int ret = os_if_wifi_pos_deregister_nl();
3050
3051 if (ret)
3052 hdd_err("os_if_wifi_pos_deregister_nl failed");
3053
3054 return ret;
3055}
3056
3057/**
3058 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
3059 * @hdd_ctx: hdd context
3060 *
3061 * Return: status of operation
3062 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003063static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003064{
Dustin Brown1dbefe62018-09-11 16:32:03 -07003065 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Wu Gao1ab05582018-11-08 16:22:49 +08003066 uint16_t neighbor_scan_max_chan_time;
3067 uint16_t neighbor_scan_min_chan_time;
Naveen Rawat910726a2017-03-06 11:42:51 -08003068
3069 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
3070 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
3071 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
3072 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
3073 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
3074 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
Wu Gao1ab05582018-11-08 16:22:49 +08003075 ucfg_mlme_get_neighbor_scan_max_chan_time(psoc,
3076 &neighbor_scan_max_chan_time);
3077 ucfg_mlme_get_neighbor_scan_min_chan_time(psoc,
3078 &neighbor_scan_min_chan_time);
3079 wifi_pos_set_dwell_time_min(psoc, neighbor_scan_min_chan_time);
3080 wifi_pos_set_dwell_time_max(psoc, neighbor_scan_max_chan_time);
Naveen Rawat910726a2017-03-06 11:42:51 -08003081}
3082#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003083static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003084{
3085 return oem_activate_service(hdd_ctx);
3086}
3087
3088static int hdd_deactivate_wifi_pos(void)
3089{
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05303090 return oem_deactivate_service();
Naveen Rawat910726a2017-03-06 11:42:51 -08003091}
3092
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003093static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003094{
3095}
3096#endif
3097
Arun Khandavallifae92942016-08-01 13:31:08 +05303098/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003099 * __hdd_open() - HDD Open function
3100 * @dev: Pointer to net_device structure
3101 *
3102 * This is called in response to ifconfig up
3103 *
3104 * Return: 0 for success; non-zero for failure
3105 */
3106static int __hdd_open(struct net_device *dev)
3107{
Jeff Johnson9d295242017-08-29 14:39:48 -07003108 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003109 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003110 int ret;
3111
Dustin Brownfdf17c12018-03-14 12:55:34 -07003112 hdd_enter_dev(dev);
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +05303113
3114 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
3115 TRACE_CODE_HDD_OPEN_REQUEST,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08003116 adapter->vdev_id, adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003117
Ashish Kumar Dhanotiya15a7db52017-08-03 10:27:34 +05303118 /* Nothing to be done if device is unloading */
3119 if (cds_is_driver_unloading()) {
3120 hdd_err("Driver is unloading can not open the hdd");
3121 return -EBUSY;
3122 }
3123
Dustin Brown01847752017-10-25 13:56:27 -07003124 if (cds_is_driver_recovering()) {
3125 hdd_err("WLAN is currently recovering; Please try again.");
3126 return -EBUSY;
3127 }
3128
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303129 /*
3130 * This scenario can be hit in cases where in the wlan driver after
3131 * registering the netdevices and there is a failure in driver
3132 * initialization. So return error gracefully because the netdevices
3133 * will be de-registered as part of the load failure.
3134 */
3135
3136 if (!cds_is_driver_loaded()) {
3137 hdd_err("Failed to start the wlan driver!!");
Dustin Brown3da3a832019-03-19 15:51:54 -07003138 return -EIO;
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303139 }
Abhishek Singh23edd1c2016-05-05 11:56:06 +05303140
Dustin Brown3ecc8782018-09-19 16:37:13 -07003141 ret = hdd_psoc_idle_restart(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303142 if (ret) {
3143 hdd_err("Failed to start WLAN modules return");
Dustin Brown3da3a832019-03-19 15:51:54 -07003144 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05303145 }
3146
Arun Khandavallifae92942016-08-01 13:31:08 +05303147 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
3148 ret = hdd_start_adapter(adapter);
3149 if (ret) {
3150 hdd_err("Failed to start adapter :%d",
3151 adapter->device_mode);
Dustin Brown3da3a832019-03-19 15:51:54 -07003152 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05303153 }
3154 }
3155
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003156 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3157 if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003158 hdd_debug("Enabling Tx Queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003159 /* Enable TX queues only when we are connected */
3160 wlan_hdd_netif_queue_control(adapter,
Arun Khandavallifae92942016-08-01 13:31:08 +05303161 WLAN_START_ALL_NETIF_QUEUE,
3162 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003163 }
3164
Naveen Rawat286def52016-09-23 15:38:02 -07003165 /* Enable carrier and transmit queues for NDI */
3166 if (WLAN_HDD_IS_NDI(adapter)) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003167 hdd_debug("Enabling Tx Queues");
Naveen Rawat286def52016-09-23 15:38:02 -07003168 wlan_hdd_netif_queue_control(adapter,
3169 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
3170 WLAN_CONTROL_PATH);
3171 }
3172
Naveen Rawat910726a2017-03-06 11:42:51 -08003173 hdd_populate_wifi_pos_cfg(hdd_ctx);
Arunk Khandavalli40943af2017-05-15 19:25:34 +05303174 hdd_lpass_notify_start(hdd_ctx, adapter);
Naveen Rawat910726a2017-03-06 11:42:51 -08003175
Dustin Brown3da3a832019-03-19 15:51:54 -07003176 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003177}
3178
3179/**
3180 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
Dustin Brown98f7c822019-03-06 12:25:49 -08003181 * @net_dev: Pointer to net_device structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003182 *
3183 * This is called in response to ifconfig up
3184 *
3185 * Return: 0 for success; non-zero for failure
3186 */
Dustin Brown0e1e1622019-01-17 11:00:22 -08003187static int hdd_open(struct net_device *net_dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003188{
Dustin Brown0e1e1622019-01-17 11:00:22 -08003189 int errno;
3190 struct osif_vdev_sync *vdev_sync;
3191
3192 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
3193 if (errno)
3194 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003195
Dustin Brown0e1e1622019-01-17 11:00:22 -08003196 errno = __hdd_open(net_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003197
Dustin Brown0e1e1622019-01-17 11:00:22 -08003198 osif_vdev_sync_trans_stop(vdev_sync);
3199
3200 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003201}
3202
3203/**
3204 * __hdd_stop() - HDD stop function
3205 * @dev: Pointer to net_device structure
3206 *
3207 * This is called in response to ifconfig down
3208 *
3209 * Return: 0 for success; non-zero for failure
3210 */
3211static int __hdd_stop(struct net_device *dev)
3212{
Jeff Johnson9d295242017-08-29 14:39:48 -07003213 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003214 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003215 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -07003216 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003217
Dustin Brownfdf17c12018-03-14 12:55:34 -07003218 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003219
Ashish Kumar Dhanotiyaf10aa5f2018-12-28 21:29:56 +05303220 qdf_mtrace(QDF_MODULE_ID_HDD, QDF_MODULE_ID_HDD,
3221 TRACE_CODE_HDD_STOP_REQUEST,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08003222 adapter->vdev_id, adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003223
3224 ret = wlan_hdd_validate_context(hdd_ctx);
Arunk Khandavalli987c8d52018-06-21 17:40:31 +05303225 if (ret) {
3226 set_bit(DOWN_DURING_SSR, &adapter->event_flags);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003227 return ret;
Arunk Khandavalli987c8d52018-06-21 17:40:31 +05303228 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003229
3230 /* Nothing to be done if the interface is not opened */
3231 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003232 hdd_err("NETDEV Interface is not OPENED");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003233 return -ENODEV;
3234 }
3235
3236 /* Make sure the interface is marked as closed */
3237 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303238
Jeff Johnson16528362018-06-14 12:34:16 -07003239 mac_handle = hdd_ctx->mac_handle;
3240
Mukul Sharmad16c2022017-07-25 18:56:12 +05303241 hdd_debug("Disabling Auto Power save timer");
3242 sme_ps_disable_auto_ps_timer(
Jeff Johnson16528362018-06-14 12:34:16 -07003243 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08003244 adapter->vdev_id);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303245
3246 /*
3247 * Disable TX on the interface, after this hard_start_xmit() will not
3248 * be called on that interface
3249 */
Dustin Browna7bb6ae2018-08-16 16:51:50 -07003250 hdd_debug("Disabling queues, adapter device mode: %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07003251 qdf_opmode_str(adapter->device_mode), adapter->device_mode);
Kabilan Kannan8dac3502017-10-30 12:40:27 -07003252
Himanshu Agarwal865201d2017-04-12 15:45:31 +05303253 wlan_hdd_netif_queue_control(adapter,
3254 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
3255 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003256
Arunk Khandavalli40943af2017-05-15 19:25:34 +05303257 if (adapter->device_mode == QDF_STA_MODE)
3258 hdd_lpass_notify_stop(hdd_ctx);
3259
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003260 /*
Naveen Rawat286def52016-09-23 15:38:02 -07003261 * NAN data interface is different in some sense. The traffic on NDI is
3262 * bursty in nature and depends on the need to transfer. The service
3263 * layer may down the interface after the usage and up again when
3264 * required. In some sense, the NDI is expected to be available
3265 * (like SAP) iface until NDI delete request is issued by the service
3266 * layer. Skip BSS termination and adapter deletion for NAN Data
3267 * interface (NDI).
3268 */
3269 if (WLAN_HDD_IS_NDI(adapter))
3270 return 0;
3271
3272 /*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003273 * The interface is marked as down for outside world (aka kernel)
3274 * But the driver is pretty much alive inside. The driver needs to
3275 * tear down the existing connection on the netdev (session)
3276 * cleanup the data pipes and wait until the control plane is stabilized
3277 * for this interface. The call also needs to wait until the above
3278 * mentioned actions are completed before returning to the caller.
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003279 * Notice that hdd_stop_adapter is requested not to close the session
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003280 * That is intentional to be able to scan if it is a STA/P2P interface
3281 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08003282 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003283
3284 /* DeInit the adapter. This ensures datapath cleanup as well */
3285 hdd_deinit_adapter(hdd_ctx, adapter, true);
3286
Dustin Brown4c663222018-10-23 14:19:36 -07003287 if (!hdd_is_any_interface_open(hdd_ctx))
3288 hdd_psoc_idle_timer_start(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303289
Dustin Browne74003f2018-03-14 12:51:58 -07003290 hdd_exit();
Dustin Brown4c663222018-10-23 14:19:36 -07003291
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003292 return 0;
3293}
3294
3295/**
3296 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
3297 * @dev: pointer to net_device structure
3298 *
3299 * This is called in response to ifconfig down
3300 *
3301 * Return: 0 for success and error number for failure
3302 */
Dustin Brown0e1e1622019-01-17 11:00:22 -08003303static int hdd_stop(struct net_device *net_dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003304{
Dustin Brown0e1e1622019-01-17 11:00:22 -08003305 int errno;
3306 struct osif_vdev_sync *vdev_sync;
3307
3308 errno = osif_vdev_sync_trans_start(net_dev, &vdev_sync);
3309 if (errno)
3310 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003311
Dustin Brown0e1e1622019-01-17 11:00:22 -08003312 errno = __hdd_stop(net_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003313
Dustin Brown0e1e1622019-01-17 11:00:22 -08003314 osif_vdev_sync_trans_stop(vdev_sync);
3315
3316 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003317}
3318
3319/**
Dustin Brown96b98dd2019-03-06 12:39:37 -08003320 * hdd_uninit() - HDD uninit function
3321 * @dev: Pointer to net_device structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003322 *
3323 * This is called during the netdev unregister to uninitialize all data
3324 * associated with the device
3325 *
Dustin Brown96b98dd2019-03-06 12:39:37 -08003326 * This function must be protected by a transition
3327 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003328 * Return: None
3329 */
Dustin Brown96b98dd2019-03-06 12:39:37 -08003330static void hdd_uninit(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003331{
Jeff Johnson9d295242017-08-29 14:39:48 -07003332 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson399c6272017-08-30 10:51:00 -07003333 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003334
Dustin Brownfdf17c12018-03-14 12:55:34 -07003335 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003336
Dustin Brown96b98dd2019-03-06 12:39:37 -08003337 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
3338 hdd_err("Invalid magic");
3339 goto exit;
3340 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003341
Dustin Brown96b98dd2019-03-06 12:39:37 -08003342 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3343 if (!hdd_ctx) {
3344 hdd_err("NULL hdd_ctx");
3345 goto exit;
3346 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003347
Dustin Brown96b98dd2019-03-06 12:39:37 -08003348 if (dev != adapter->dev)
3349 hdd_err("Invalid device reference");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003350
Dustin Brown96b98dd2019-03-06 12:39:37 -08003351 hdd_deinit_adapter(hdd_ctx, adapter, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003352
Dustin Brown96b98dd2019-03-06 12:39:37 -08003353 /* after uninit our adapter structure will no longer be valid */
3354 adapter->dev = NULL;
3355 adapter->magic = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003356
Dustin Brown96b98dd2019-03-06 12:39:37 -08003357exit:
Dustin Browne74003f2018-03-14 12:51:58 -07003358 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003359}
3360
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003361static int hdd_open_cesium_nl_sock(void)
3362{
3363#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3364 struct netlink_kernel_cfg cfg = {
3365 .groups = WLAN_NLINK_MCAST_GRP_ID,
3366 .input = NULL
3367 };
3368#endif
3369 int ret = 0;
3370
3371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3372 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3373#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
3374 THIS_MODULE,
3375#endif
3376 &cfg);
3377#else
3378 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3379 WLAN_NLINK_MCAST_GRP_ID,
3380 NULL, NULL, THIS_MODULE);
3381#endif
3382
Jeff Johnsond36fa332019-03-18 13:42:25 -07003383 if (!cesium_nl_srv_sock) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003384 hdd_err("NLINK: cesium netlink_kernel_create failed");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003385 ret = -ECONNREFUSED;
3386 }
3387
3388 return ret;
3389}
3390
3391static void hdd_close_cesium_nl_sock(void)
3392{
Jeff Johnsond36fa332019-03-18 13:42:25 -07003393 if (cesium_nl_srv_sock) {
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003394 netlink_kernel_release(cesium_nl_srv_sock);
3395 cesium_nl_srv_sock = NULL;
3396 }
3397}
3398
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303399void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx,
3400 struct qdf_mac_addr *curr_mac_addr,
3401 struct qdf_mac_addr *new_mac_addr)
3402{
3403 uint8_t i;
3404
3405 hdd_enter();
3406
3407 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303408 if (!qdf_mem_cmp(
3409 curr_mac_addr->bytes,
3410 &hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes[0],
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303411 sizeof(struct qdf_mac_addr))) {
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303412 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].dynamic_mac,
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303413 new_mac_addr->bytes,
3414 sizeof(struct qdf_mac_addr));
3415 break;
3416 }
3417 }
3418
3419 hdd_exit();
3420}
3421
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003422/**
3423 * __hdd_set_mac_address() - set the user specified mac address
3424 * @dev: Pointer to the net device.
3425 * @addr: Pointer to the sockaddr.
3426 *
3427 * This function sets the user specified mac address using
Jeff Johnson06095fb2018-05-06 16:16:42 -07003428 * the command ifconfig wlanX hw ether <mac address>.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003429 *
3430 * Return: 0 for success, non zero for failure
3431 */
3432static int __hdd_set_mac_address(struct net_device *dev, void *addr)
3433{
Jeff Johnson9d295242017-08-29 14:39:48 -07003434 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +05303435 struct hdd_adapter *adapter_temp;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003436 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003437 struct sockaddr *psta_mac_addr = addr;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303438 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003439 int ret;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303440 struct qdf_mac_addr mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003441
Dustin Brownfdf17c12018-03-14 12:55:34 -07003442 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003443
Hanumanth Reddy Pothula5c7a7812018-03-09 12:55:32 +05303444 if (netif_running(dev)) {
3445 hdd_err("On iface up, set mac address change isn't supported");
3446 return -EBUSY;
3447 }
3448
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003449 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3450 ret = wlan_hdd_validate_context(hdd_ctx);
3451 if (0 != ret)
3452 return ret;
3453
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303454 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +05303455 adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
3456 if (adapter_temp) {
3457 if (!qdf_str_cmp(adapter_temp->dev->name, dev->name))
3458 return 0;
3459 hdd_err("%s adapter exist with same address " MAC_ADDRESS_STR,
3460 adapter_temp->dev->name,
Ashish Kumar Dhanotiyaf974f332018-04-19 16:03:15 +05303461 MAC_ADDR_ARRAY(mac_addr.bytes));
3462 return -EINVAL;
3463 }
3464
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05303465 qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr);
3466 if (QDF_IS_STATUS_ERROR(qdf_ret_status))
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303467 return -EINVAL;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303468
Ashish Kumar Dhanotiya8bfef122018-04-18 16:48:27 +05303469 hdd_info("Changing MAC to " MAC_ADDRESS_STR " of the interface %s ",
3470 MAC_ADDR_ARRAY(mac_addr.bytes), dev->name);
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303471
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303472 hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr);
Jeff Johnson1e851a12017-10-28 14:36:12 -07003473 memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003474 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
3475
Dustin Browne74003f2018-03-14 12:51:58 -07003476 hdd_exit();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303477 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003478}
3479
3480/**
3481 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
Dustin Brown98f7c822019-03-06 12:25:49 -08003482 * function from SSR
3483 * @net_dev: pointer to net_device structure
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003484 * @addr: Pointer to the sockaddr
3485 *
3486 * This function sets the user specified mac address using
Jeff Johnson06095fb2018-05-06 16:16:42 -07003487 * the command ifconfig wlanX hw ether <mac address>.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003488 *
3489 * Return: 0 for success.
3490 */
Dustin Brown98f7c822019-03-06 12:25:49 -08003491static int hdd_set_mac_address(struct net_device *net_dev, void *addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003492{
Dustin Brown98f7c822019-03-06 12:25:49 -08003493 struct osif_vdev_sync *vdev_sync;
3494 int errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003495
Dustin Brown98f7c822019-03-06 12:25:49 -08003496 errno = osif_vdev_sync_op_start(net_dev, &vdev_sync);
3497 if (errno)
3498 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003499
Dustin Brown98f7c822019-03-06 12:25:49 -08003500 errno = __hdd_set_mac_address(net_dev, addr);
3501
3502 osif_vdev_sync_op_stop(vdev_sync);
3503
3504 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003505}
3506
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303507static uint8_t *wlan_hdd_get_derived_intf_addr(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003508{
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303509 int i, j;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003510
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303511 i = qdf_ffz(hdd_ctx->derived_intf_addr_mask);
3512 if (i < 0 || i >= hdd_ctx->num_derived_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003513 return NULL;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303514 qdf_atomic_set_bit(i, &hdd_ctx->derived_intf_addr_mask);
3515 hdd_info("Assigning MAC from derived list" MAC_ADDRESS_STR,
3516 MAC_ADDR_ARRAY(hdd_ctx->derived_mac_addr[i].bytes));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003517
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303518 /* Copy the mac in dynamic mac list at first free position */
3519 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) {
3520 if (qdf_is_macaddr_zero(&hdd_ctx->
3521 dynamic_mac_list[j].dynamic_mac))
3522 break;
3523 }
3524 if (j == QDF_MAX_CONCURRENCY_PERSONA) {
3525 hdd_err("Max interfaces are up");
3526 return NULL;
3527 }
Dustin Brown61cc3932018-10-18 16:12:13 -07003528
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303529 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes,
3530 &hdd_ctx->derived_mac_addr[i].bytes,
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303531 sizeof(struct qdf_mac_addr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303532 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = false;
3533 hdd_ctx->dynamic_mac_list[j].bit_position = i;
3534
3535 return hdd_ctx->derived_mac_addr[i].bytes;
3536}
3537
3538static uint8_t *wlan_hdd_get_provisioned_intf_addr(struct hdd_context *hdd_ctx)
3539{
3540 int i, j;
3541
3542 i = qdf_ffz(hdd_ctx->provisioned_intf_addr_mask);
3543 if (i < 0 || i >= hdd_ctx->num_provisioned_addr)
3544 return NULL;
3545 qdf_atomic_set_bit(i, &hdd_ctx->provisioned_intf_addr_mask);
3546 hdd_info("Assigning MAC from provisioned list" MAC_ADDRESS_STR,
3547 MAC_ADDR_ARRAY(hdd_ctx->provisioned_mac_addr[i].bytes));
3548
3549 /* Copy the mac in dynamic mac list at first free position */
3550 for (j = 0; j < QDF_MAX_CONCURRENCY_PERSONA; j++) {
3551 if (qdf_is_macaddr_zero(&hdd_ctx->
3552 dynamic_mac_list[j].dynamic_mac))
3553 break;
3554 }
3555 if (j == QDF_MAX_CONCURRENCY_PERSONA) {
3556 hdd_err("Max interfaces are up");
3557 return NULL;
3558 }
3559
3560 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[j].dynamic_mac.bytes,
3561 &hdd_ctx->provisioned_mac_addr[i].bytes,
3562 sizeof(struct qdf_mac_addr));
3563 hdd_ctx->dynamic_mac_list[j].is_provisioned_mac = true;
3564 hdd_ctx->dynamic_mac_list[j].bit_position = i;
3565 return hdd_ctx->provisioned_mac_addr[i].bytes;
3566}
3567
3568uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx,
3569 enum QDF_OPMODE interface_type)
3570{
3571 uint8_t *mac_addr = NULL;
3572
3573 if (qdf_atomic_test_bit(interface_type,
3574 (unsigned long *)
3575 (&hdd_ctx->config->provisioned_intf_pool)))
3576 mac_addr = wlan_hdd_get_provisioned_intf_addr(hdd_ctx);
3577
3578 if ((!mac_addr) &&
3579 (qdf_atomic_test_bit(interface_type,
3580 (unsigned long *)
3581 (&hdd_ctx->config->derived_intf_pool))))
3582 mac_addr = wlan_hdd_get_derived_intf_addr(hdd_ctx);
3583
3584 if (!mac_addr)
3585 hdd_err("MAC is not available in both the lists");
3586 return mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003587}
3588
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07003589void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
3590 uint8_t *releaseAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003591{
3592 int i;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303593 int mac_pos_in_mask;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003594
Anurag Chouhan6d760662016-02-20 16:05:43 +05303595 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003596 if (!memcmp(releaseAddr,
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303597 hdd_ctx->dynamic_mac_list[i].dynamic_mac.bytes,
3598 QDF_MAC_ADDR_SIZE)) {
3599 mac_pos_in_mask =
3600 hdd_ctx->dynamic_mac_list[i].bit_position;
3601 if (hdd_ctx->dynamic_mac_list[i].is_provisioned_mac) {
3602 qdf_atomic_clear_bit(
3603 mac_pos_in_mask,
3604 &hdd_ctx->
3605 provisioned_intf_addr_mask);
3606 hdd_info("Releasing MAC from provisioned list");
3607 hdd_info(
3608 MAC_ADDRESS_STR,
3609 MAC_ADDR_ARRAY(releaseAddr));
3610 } else {
3611 qdf_atomic_clear_bit(
3612 mac_pos_in_mask, &hdd_ctx->
3613 derived_intf_addr_mask);
3614 hdd_info("Releasing MAC from derived list");
3615 hdd_info(MAC_ADDRESS_STR,
3616 MAC_ADDR_ARRAY(releaseAddr));
3617 }
3618 qdf_zero_macaddr(&hdd_ctx->
3619 dynamic_mac_list[i].dynamic_mac);
3620 hdd_ctx->dynamic_mac_list[i].is_provisioned_mac =
3621 false;
3622 hdd_ctx->dynamic_mac_list[i].bit_position = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003623 break;
3624 }
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303625
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003626 }
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05303627 if (i == QDF_MAX_CONCURRENCY_PERSONA)
3628 hdd_err("Releasing non existing MAC" MAC_ADDRESS_STR,
3629 MAC_ADDR_ARRAY(releaseAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003630}
3631
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003632/**
3633 * __hdd_set_multicast_list() - set the multicast address list
3634 * @dev: Pointer to the WLAN device.
3635 * @skb: Pointer to OS packet (sk_buff).
3636 *
3637 * This funciton sets the multicast address list.
3638 *
3639 * Return: None
3640 */
3641static void __hdd_set_multicast_list(struct net_device *dev)
3642{
Jeff Johnson9d295242017-08-29 14:39:48 -07003643 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Dustin Brown0f874482018-06-13 14:39:22 -07003644 int i = 0, errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003645 struct netdev_hw_addr *ha;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003646 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303647 struct pmo_mc_addr_list_params *mc_list_request = NULL;
Dustin Brown1dbefe62018-09-11 16:32:03 -07003648 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303649 int mc_count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003650
Dustin Brownfdf17c12018-03-14 12:55:34 -07003651 hdd_enter_dev(dev);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303652 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303653 goto out;
Mukul Sharma51c44942015-10-30 19:30:19 +05303654
Dustin Brown0f874482018-06-13 14:39:22 -07003655 errno = wlan_hdd_validate_context(hdd_ctx);
3656 if (errno)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303657 goto out;
3658
Dustin Brown0f874482018-06-13 14:39:22 -07003659 errno = hdd_validate_adapter(adapter);
3660 if (errno)
Dustin Brownc788acb2017-08-01 17:43:51 -07003661 goto out;
3662
Arunk Khandavalli6a227882017-12-12 19:31:08 +05303663 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
3664 hdd_err("%s: Driver module is closed", __func__);
Dustin Brown0f874482018-06-13 14:39:22 -07003665 goto out;
Arunk Khandavalli6a227882017-12-12 19:31:08 +05303666 }
3667
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303668 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
Min Liu74a1a502018-10-10 19:59:07 +08003669 if (!mc_list_request)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303670 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003671
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05303672 /* Delete already configured multicast address list */
3673 if (adapter->mc_addr_list.mc_cnt > 0) {
Dustin Brown0f874482018-06-13 14:39:22 -07003674 hdd_debug("clear previously configured MC address list");
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05303675 hdd_disable_and_flush_mc_addr_list(adapter,
3676 pmo_mc_list_change_notify);
3677 }
3678
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003679 if (dev->flags & IFF_ALLMULTI) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003680 hdd_debug("allow all multicast frames");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303681 hdd_disable_and_flush_mc_addr_list(adapter,
3682 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003683 } else {
3684 mc_count = netdev_mc_count(dev);
Wu Gaod7dd6e42018-10-16 17:22:56 +08003685 if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003686 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
Wu Gaod7dd6e42018-10-16 17:22:56 +08003687 ucfg_pmo_max_mc_addr_supported(psoc));
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303688 hdd_disable_and_flush_mc_addr_list(adapter,
3689 pmo_mc_list_change_notify);
stonezdf2bdfd2018-11-20 14:45:06 +08003690 adapter->mc_addr_list.mc_cnt = 0;
Dustin Brown0f874482018-06-13 14:39:22 -07003691 goto free_req;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003692 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003693 netdev_for_each_mc_addr(ha, dev) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003694 hdd_debug("ha_addr[%d] "MAC_ADDRESS_STR,
Sachin Ahujaa69c72a2016-09-03 15:59:33 +05303695 i, MAC_ADDR_ARRAY(ha->addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003696 if (i == mc_count)
3697 break;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303698 memset(&(mc_list_request->mc_addr[i].bytes),
3699 0, ETH_ALEN);
3700 memcpy(&(mc_list_request->mc_addr[i].bytes),
3701 ha->addr, ETH_ALEN);
Dustin Brown0f874482018-06-13 14:39:22 -07003702 hdd_debug("mlist[%d] = %pM", i,
3703 mc_list_request->mc_addr[i].bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003704 i++;
3705 }
3706 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303707
stonezdf2bdfd2018-11-20 14:45:06 +08003708 adapter->mc_addr_list.mc_cnt = mc_count;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303709 mc_list_request->psoc = psoc;
Jeff Johnson5a6fc962019-02-04 14:20:25 -08003710 mc_list_request->vdev_id = adapter->vdev_id;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303711 mc_list_request->count = mc_count;
Dustin Brown0f874482018-06-13 14:39:22 -07003712
3713 errno = hdd_cache_mc_addr_list(mc_list_request);
3714 if (errno) {
3715 hdd_err("Failed to cache MC address list for vdev %u; errno:%d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -08003716 adapter->vdev_id, errno);
Dustin Brown0f874482018-06-13 14:39:22 -07003717 goto free_req;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003718 }
Dustin Brown0f874482018-06-13 14:39:22 -07003719
3720 hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify);
3721
3722free_req:
3723 qdf_mem_free(mc_list_request);
3724
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303725out:
Dustin Browne74003f2018-03-14 12:51:58 -07003726 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003727}
3728
3729/**
3730 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
Dustin Brown98f7c822019-03-06 12:25:49 -08003731 * @net_dev: pointer to net_device
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003732 *
3733 * Return: none
3734 */
Dustin Brown98f7c822019-03-06 12:25:49 -08003735static void hdd_set_multicast_list(struct net_device *net_dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003736{
Dustin Brown98f7c822019-03-06 12:25:49 -08003737 struct osif_vdev_sync *vdev_sync;
3738
3739 if (osif_vdev_sync_op_start(net_dev, &vdev_sync))
3740 return;
3741
3742 __hdd_set_multicast_list(net_dev);
3743
3744 osif_vdev_sync_op_stop(vdev_sync);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003745}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003746
Subrat Dash5f36fbe2019-02-12 16:28:14 +05303747#ifdef WLAN_FEATURE_TSF_PTP
3748static const struct ethtool_ops wlan_ethtool_ops = {
3749 .get_ts_info = wlan_get_ts_info,
3750};
3751#endif
3752
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003753static const struct net_device_ops wlan_drv_ops = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003754 .ndo_open = hdd_open,
3755 .ndo_stop = hdd_stop,
3756 .ndo_uninit = hdd_uninit,
3757 .ndo_start_xmit = hdd_hard_start_xmit,
3758 .ndo_tx_timeout = hdd_tx_timeout,
3759 .ndo_get_stats = hdd_get_stats,
3760 .ndo_do_ioctl = hdd_ioctl,
3761 .ndo_set_mac_address = hdd_set_mac_address,
3762 .ndo_select_queue = hdd_select_queue,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003763 .ndo_set_rx_mode = hdd_set_multicast_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003764};
3765
Nirav Shah73713f72018-05-17 14:50:41 +05303766#ifdef FEATURE_MONITOR_MODE_SUPPORT
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003767/* Monitor mode net_device_ops, doesnot Tx and most of operations. */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003768static const struct net_device_ops wlan_mon_drv_ops = {
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003769 .ndo_open = hdd_mon_open,
3770 .ndo_stop = hdd_stop,
3771 .ndo_get_stats = hdd_get_stats,
3772};
3773
Subrat Dash5f36fbe2019-02-12 16:28:14 +05303774#ifdef WLAN_FEATURE_TSF_PTP
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003775/**
3776 * hdd_set_station_ops() - update net_device ops for monitor mode
Jeff Johnson5505db82017-11-02 21:19:23 -07003777 * @dev: Handle to struct net_device to be updated.
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003778 * Return: None
3779 */
Jeff Johnson5505db82017-11-02 21:19:23 -07003780void hdd_set_station_ops(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003781{
Subrat Dash5f36fbe2019-02-12 16:28:14 +05303782 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE) {
3783 dev->netdev_ops = &wlan_mon_drv_ops;
3784 } else {
3785 dev->netdev_ops = &wlan_drv_ops;
3786 dev->ethtool_ops = &wlan_ethtool_ops;
3787 }
3788}
3789#else
3790void hdd_set_station_ops(struct net_device *dev)
3791{
3792 if (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE)
Jeff Johnson5505db82017-11-02 21:19:23 -07003793 dev->netdev_ops = &wlan_mon_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003794 else
Jeff Johnson5505db82017-11-02 21:19:23 -07003795 dev->netdev_ops = &wlan_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003796}
Subrat Dash5f36fbe2019-02-12 16:28:14 +05303797
3798#endif
3799#else
3800#ifdef WLAN_FEATURE_TSF_PTP
3801void hdd_set_station_ops(struct net_device *dev)
3802{
3803 dev->netdev_ops = &wlan_drv_ops;
3804 dev->ethtool_ops = &wlan_ethtool_ops;
3805}
Nirav Shah73713f72018-05-17 14:50:41 +05303806#else
3807void hdd_set_station_ops(struct net_device *dev)
3808{
3809 dev->netdev_ops = &wlan_drv_ops;
3810}
3811#endif
Subrat Dash5f36fbe2019-02-12 16:28:14 +05303812#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003813
3814/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08003815 * hdd_alloc_station_adapter() - allocate the station hdd adapter
3816 * @hdd_ctx: global hdd context
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003817 * @mac_addr: mac address to assign to the interface
Ryan Hsu07495ea2016-01-21 15:25:39 -08003818 * @name: User-visible name of the interface
3819 *
3820 * hdd adapter pointer would point to the netdev->priv space, this function
Jeff Johnson62018292018-05-06 16:18:35 -07003821 * would retrieve the pointer, and setup the hdd adapter configuration.
Ryan Hsu07495ea2016-01-21 15:25:39 -08003822 *
3823 * Return: the pointer to hdd adapter, otherwise NULL
3824 */
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003825static struct hdd_adapter *
3826hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr,
3827 unsigned char name_assign_type, const char *name)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003828{
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003829 struct net_device *dev;
3830 struct hdd_adapter *adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07003831 struct hdd_station_ctx *sta_ctx;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303832 QDF_STATUS qdf_status;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003833
3834 /* cfg80211 initialization and registration */
3835 dev = alloc_netdev_mq(sizeof(*adapter), name,
Ryan Hsu07495ea2016-01-21 15:25:39 -08003836#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003837 name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003838#endif
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003839 (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE ?
3840 hdd_mon_mode_ether_setup : ether_setup),
3841 NUM_TX_QUEUES);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003842
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003843 if (!dev) {
3844 hdd_err("Failed to allocate new net_device '%s'", name);
3845 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003846 }
3847
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003848 adapter = netdev_priv(dev);
3849
3850 qdf_mem_zero(adapter, sizeof(*adapter));
3851 sta_ctx = &adapter->session.station;
Jeff Johnson0a082d92019-03-04 12:25:49 -08003852 qdf_mem_set(sta_ctx->conn_info.sta_id,
3853 sizeof(sta_ctx->conn_info.sta_id),
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003854 HDD_WLAN_INVALID_STA_ID);
3855 adapter->dev = dev;
3856 adapter->hdd_ctx = hdd_ctx;
3857 adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
Jeff Johnson912b1bb2019-03-06 10:12:36 -08003858 adapter->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003859
3860 qdf_status = qdf_event_create(&adapter->qdf_session_open_event);
3861 if (QDF_IS_STATUS_ERROR(qdf_status))
3862 goto free_net_dev;
3863
3864 qdf_status = qdf_event_create(&adapter->qdf_session_close_event);
3865 if (QDF_IS_STATUS_ERROR(qdf_status))
3866 goto free_net_dev;
3867
3868 adapter->offloads_configured = false;
3869 adapter->is_link_up_service_needed = false;
3870 adapter->disconnection_in_progress = false;
3871 adapter->send_mode_change = true;
3872
3873 /* Init the net_device structure */
3874 strlcpy(dev->name, name, IFNAMSIZ);
3875
3876 qdf_mem_copy(dev->dev_addr, mac_addr, sizeof(tSirMacAddr));
3877 qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr));
3878 dev->watchdog_timeo = HDD_TX_TIMEOUT;
3879
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003880 hdd_set_station_ops(adapter->dev);
3881
3882 hdd_dev_setup_destructor(dev);
3883 dev->ieee80211_ptr = &adapter->wdev;
3884 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
3885 adapter->wdev.wiphy = hdd_ctx->wiphy;
3886 adapter->wdev.netdev = dev;
3887
3888 /* set dev's parent to underlying device */
3889 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
3890 hdd_wmm_init(adapter);
3891 spin_lock_init(&adapter->pause_map_lock);
3892 adapter->start_time = qdf_system_ticks();
3893 adapter->last_time = adapter->start_time;
3894
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003895 return adapter;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003896
3897free_net_dev:
3898 free_netdev(adapter->dev);
3899
3900 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003901}
3902
Jeff Johnson9d295242017-08-29 14:39:48 -07003903static QDF_STATUS hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003904{
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003905 struct net_device *dev = adapter->dev;
3906 int ret;
3907
Dustin Brown491d54b2018-03-14 12:39:11 -07003908 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003909
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08003910 if (rtnl_held) {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003911 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
3912
3913 ret = dev_alloc_name(dev, dev->name);
3914 if (ret < 0) {
3915 hdd_err(
3916 "unable to get dev name: %s, err = 0x%x",
3917 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303918 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003919 }
3920 }
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003921
3922 ret = register_netdevice(dev);
3923 if (ret) {
3924 hdd_err("register_netdevice(%s) failed, err = 0x%x",
3925 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303926 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003927 }
3928 } else {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003929 ret = register_netdev(dev);
3930 if (ret) {
3931 hdd_err("register_netdev(%s) failed, err = 0x%x",
3932 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303933 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003934 }
3935 }
3936 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
3937
Dustin Browne74003f2018-03-14 12:51:58 -07003938 hdd_exit();
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003939
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303940 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003941}
3942
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003943QDF_STATUS hdd_sme_open_session_callback(uint8_t vdev_id,
Pragaspathi Thilagaraj3551caa2018-09-26 15:52:56 +05303944 QDF_STATUS qdf_status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003945{
Krunal Sonib51eec72017-11-20 21:53:01 -08003946 struct hdd_adapter *adapter;
3947 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003948
Krunal Sonib51eec72017-11-20 21:53:01 -08003949 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3950 if (!hdd_ctx) {
3951 hdd_err("Invalid HDD_CTX");
3952 return QDF_STATUS_E_FAILURE;
3953 }
3954
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003955 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnsond36fa332019-03-18 13:42:25 -07003956 if (!adapter) {
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003957 hdd_err("NULL adapter for %d", vdev_id);
Krunal Sonib51eec72017-11-20 21:53:01 -08003958 return QDF_STATUS_E_INVAL;
3959 }
Pragaspathi Thilagaraj3551caa2018-09-26 15:52:56 +05303960
3961 if (qdf_status == QDF_STATUS_SUCCESS)
3962 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
3963
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303964 qdf_event_set(&adapter->qdf_session_open_event);
Jeff Johnson5a6fc962019-02-04 14:20:25 -08003965 hdd_debug("session %d opened", adapter->vdev_id);
Krunal Sonib51eec72017-11-20 21:53:01 -08003966
3967 return QDF_STATUS_SUCCESS;
3968}
3969
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003970QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id)
Krunal Sonib51eec72017-11-20 21:53:01 -08003971{
3972 struct hdd_adapter *adapter;
3973 struct hdd_context *hdd_ctx;
3974
3975 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3976 if (!hdd_ctx) {
3977 hdd_err("Invalid HDD_CTX");
3978 return QDF_STATUS_E_FAILURE;
3979 }
3980
Jeff Johnson55d2ab42019-03-06 11:43:49 -08003981 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Jeff Johnsond36fa332019-03-18 13:42:25 -07003982 if (!adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003983 hdd_err("NULL adapter");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303984 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003985 }
3986
3987 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003988 hdd_err("Invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303989 return QDF_STATUS_NOT_INITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003990 }
3991
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003992 /*
3993 * For NAN Data interface, the close session results in the final
3994 * indication to the userspace
3995 */
Rakesh Sunki3480f962016-08-29 17:29:53 -07003996 if (adapter->device_mode == QDF_NDI_MODE)
3997 hdd_ndp_session_end_handler(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003998
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003999 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
4000
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004001 /*
4002 * We can be blocked while waiting for scheduled work to be
4003 * flushed, and the adapter structure can potentially be freed, in
4004 * which case the magic will have been reset. So make sure the
4005 * magic is still good, and hence the adapter structure is still
4006 * valid, before signaling completion
4007 */
4008 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304009 qdf_event_set(&adapter->qdf_session_close_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004010
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304011 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004012}
4013
Jeff Johnson9d295242017-08-29 14:39:48 -07004014int hdd_vdev_ready(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004015{
Min Liu8c5d99e2018-09-10 17:18:44 +08004016 struct wlan_objmgr_vdev *vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004017 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004018
Min Liu8c5d99e2018-09-10 17:18:44 +08004019 vdev = hdd_objmgr_get_vdev(adapter);
4020 if (!vdev)
4021 return -EINVAL;
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004022
Min Liu8c5d99e2018-09-10 17:18:44 +08004023 status = pmo_vdev_ready(vdev);
4024 if (QDF_IS_STATUS_ERROR(status)) {
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304025 hdd_objmgr_put_vdev(vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004026 return qdf_status_to_os_return(status);
Min Liu8c5d99e2018-09-10 17:18:44 +08004027 }
4028
4029 status = ucfg_reg_11d_vdev_created_update(vdev);
4030 if (QDF_IS_STATUS_ERROR(status)) {
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304031 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08004032 return qdf_status_to_os_return(status);
4033 }
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004034
4035 if (wma_capability_enhanced_mcast_filter())
Min Liu8c5d99e2018-09-10 17:18:44 +08004036 status = ucfg_pmo_enhanced_mc_filter_enable(vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004037 else
Min Liu8c5d99e2018-09-10 17:18:44 +08004038 status = ucfg_pmo_enhanced_mc_filter_disable(vdev);
4039
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304040 hdd_objmgr_put_vdev(vdev);
Dustin Brownd28772b2017-03-17 14:16:07 -07004041
4042 return qdf_status_to_os_return(status);
4043}
4044
Jeff Johnson9d295242017-08-29 14:39:48 -07004045int hdd_vdev_destroy(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07004046{
4047 QDF_STATUS status;
Dustin Brown2da29eb2018-07-13 14:23:12 -07004048 int errno;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004049 struct hdd_context *hdd_ctx;
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004050 uint8_t vdev_id;
Min Liu8c5d99e2018-09-10 17:18:44 +08004051 struct wlan_objmgr_vdev *vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004052
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004053 vdev_id = adapter->vdev_id;
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004054 hdd_info("destroying vdev %d", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004055
4056 /* vdev created sanity check */
4057 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
Dustin Brown2da29eb2018-07-13 14:23:12 -07004058 hdd_err("vdev %u does not exist", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004059 return -EINVAL;
4060 }
Dustin Brown2da29eb2018-07-13 14:23:12 -07004061
Abhishek Singh628bb6f2019-03-26 14:52:40 +05304062 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4063
4064 /*
4065 * if this is the last active connection check & stop the
4066 * opportunistic timer first
4067 */
4068 if ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 1 &&
4069 policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
4070 policy_mgr_convert_device_mode_to_qdf_type(
4071 adapter->device_mode), NULL) == 1) ||
4072 !policy_mgr_get_connection_count(hdd_ctx->psoc))
4073 policy_mgr_check_and_stop_opportunistic_timer(hdd_ctx->psoc,
4074 adapter->vdev_id);
4075
Min Liu8c5d99e2018-09-10 17:18:44 +08004076 vdev = hdd_objmgr_get_vdev(adapter);
4077 if (!vdev)
4078 return -EINVAL;
Ashish Kumar Dhanotiya68ee2e42018-11-19 21:15:14 +05304079
4080 ucfg_pmo_del_wow_pattern(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08004081 status = ucfg_reg_11d_vdev_delete_update(vdev);
Abhishek Singh935e4772018-11-21 14:14:10 +05304082 ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304083 hdd_objmgr_put_vdev(vdev);
Yue Maf9782842017-05-08 12:49:49 -07004084
Dustin Brownd28772b2017-03-17 14:16:07 -07004085 /* close sme session (destroy vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304086 qdf_event_reset(&adapter->qdf_session_close_event);
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004087 status = sme_close_session(hdd_ctx->mac_handle, adapter->vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004088 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Brown2da29eb2018-07-13 14:23:12 -07004089 hdd_err("failed to close sme session; status:%d", status);
Jiachao Wu2c42c222018-01-15 18:13:19 +08004090 goto release_vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004091 }
4092
4093 /* block on a completion variable until sme session is closed */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304094 status = qdf_wait_for_event_completion(
4095 &adapter->qdf_session_close_event,
Abhishek Singh13bf0ce2018-10-24 14:26:14 +05304096 SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
Dustin Brown2da29eb2018-07-13 14:23:12 -07004097
4098 if (QDF_IS_STATUS_ERROR(status)) {
4099 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
4100
Dustin Brownd28772b2017-03-17 14:16:07 -07004101 if (adapter->device_mode == QDF_NDI_MODE)
4102 hdd_ndp_session_end_handler(adapter);
Dustin Brown2da29eb2018-07-13 14:23:12 -07004103
4104 if (status == QDF_STATUS_E_TIMEOUT)
4105 hdd_err("timed out waiting for sme close session");
4106 else if (adapter->qdf_session_close_event.force_set)
4107 hdd_info("SSR occurred during sme close session");
4108 else
4109 hdd_err("failed to wait for sme close session; status:%u",
4110 status);
Dustin Brownd28772b2017-03-17 14:16:07 -07004111 }
Jiachao Wu2c42c222018-01-15 18:13:19 +08004112
Yue Maf9782842017-05-08 12:49:49 -07004113release_vdev:
Jiachao Wu2c42c222018-01-15 18:13:19 +08004114
Sandeep Puligillaef415362017-08-30 16:37:13 -07004115 /* do vdev logical destroy via objmgr */
Dustin Brownb277dd62018-01-26 15:17:33 -08004116 errno = hdd_objmgr_release_and_destroy_vdev(adapter);
Sandeep Puligillaef415362017-08-30 16:37:13 -07004117 if (errno) {
Dustin Brownb277dd62018-01-26 15:17:33 -08004118 hdd_err("failed to destroy objmgr vdev; errno:%d", errno);
Sandeep Puligillaef415362017-08-30 16:37:13 -07004119 return errno;
4120 }
4121
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004122 hdd_info("vdev %d destroyed successfully", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004123
4124 return 0;
4125}
4126
Krunal Sonib51eec72017-11-20 21:53:01 -08004127static int hdd_set_sme_session_param(struct hdd_adapter *adapter,
4128 struct sme_session_params *session_param,
Jeff Johnson6a18c962018-07-01 09:09:37 -07004129 csr_roam_complete_cb callback,
Krunal Sonib51eec72017-11-20 21:53:01 -08004130 void *callback_ctx)
Dustin Brownd28772b2017-03-17 14:16:07 -07004131{
Dustin Brownd28772b2017-03-17 14:16:07 -07004132 uint32_t type;
4133 uint32_t sub_type;
Krunal Sonib51eec72017-11-20 21:53:01 -08004134 QDF_STATUS status;
Dustin Brownd28772b2017-03-17 14:16:07 -07004135
4136 /* determine vdev (sub)type */
4137 status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304138 if (QDF_STATUS_SUCCESS != status) {
Dustin Brownd28772b2017-03-17 14:16:07 -07004139 hdd_err("failed to get vdev type: %d", status);
4140 return qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004141 }
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004142 session_param->sme_session_id = adapter->vdev_id;
Krunal Sonib51eec72017-11-20 21:53:01 -08004143 session_param->self_mac_addr = (uint8_t *)&adapter->mac_addr;
4144 session_param->type_of_persona = type;
4145 session_param->subtype_of_persona = sub_type;
4146 session_param->session_open_cb = hdd_sme_open_session_callback;
4147 session_param->session_close_cb = hdd_sme_close_session_callback;
4148 session_param->callback = callback;
4149 session_param->callback_ctx = callback_ctx;
4150
4151 return 0;
4152}
4153
gaurank kathpalia6c4b50c2019-02-28 14:07:48 +05304154void
gaurank kathpalia78af1932018-10-27 20:33:10 +05304155hdd_store_nss_chains_cfg_in_vdev(struct hdd_adapter *adapter)
4156{
4157 struct wlan_mlme_nss_chains vdev_ini_cfg;
4158 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4159
gaurank kathpaliab414bce2018-11-09 18:44:46 +05304160 /* Populate the nss chain params from ini for this vdev type */
gaurank kathpalia78af1932018-10-27 20:33:10 +05304161 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
4162 adapter->device_mode,
4163 hdd_ctx->num_rf_chains);
gaurank kathpaliab414bce2018-11-09 18:44:46 +05304164
4165 /* Store the nss chain config into the vdev */
4166 sme_store_nss_chains_cfg_in_vdev(adapter->vdev, &vdev_ini_cfg);
gaurank kathpalia78af1932018-10-27 20:33:10 +05304167}
gaurank kathpalia6982d472018-10-31 21:54:15 +05304168
4169bool hdd_is_vdev_in_conn_state(struct hdd_adapter *adapter)
4170{
4171 switch (adapter->device_mode) {
4172 case QDF_STA_MODE:
4173 case QDF_P2P_CLIENT_MODE:
4174 case QDF_P2P_DEVICE_MODE:
4175 return hdd_conn_is_connected(
4176 WLAN_HDD_GET_STATION_CTX_PTR(adapter));
4177 case QDF_SAP_MODE:
4178 case QDF_P2P_GO_MODE:
4179 return (test_bit(SOFTAP_BSS_STARTED,
4180 &adapter->event_flags));
4181 default:
4182 hdd_err("Device mode %d invalid", adapter->device_mode);
4183 return 0;
4184 }
4185
4186 return 0;
4187}
4188
Krunal Sonib51eec72017-11-20 21:53:01 -08004189int hdd_vdev_create(struct hdd_adapter *adapter,
Jeff Johnson6a18c962018-07-01 09:09:37 -07004190 csr_roam_complete_cb callback, void *ctx)
Krunal Sonib51eec72017-11-20 21:53:01 -08004191{
4192 QDF_STATUS status;
4193 int errno;
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304194 bool bval;
Krunal Sonib51eec72017-11-20 21:53:01 -08004195 struct hdd_context *hdd_ctx;
4196 struct sme_session_params sme_session_params = {0};
Min Liu8c5d99e2018-09-10 17:18:44 +08004197 struct wlan_objmgr_vdev *vdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08004198
4199 hdd_info("creating new vdev");
Dustin Brownd28772b2017-03-17 14:16:07 -07004200
4201 /* do vdev create via objmgr */
4202 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Dustin Brown07901ec2018-09-07 11:02:41 -07004203 errno = hdd_objmgr_create_and_store_vdev(hdd_ctx->pdev, adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -07004204 if (errno) {
4205 hdd_err("failed to create objmgr vdev: %d", errno);
4206 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004207 }
Dustin Brownd28772b2017-03-17 14:16:07 -07004208
4209 /* Open a SME session (prepare vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304210 status = qdf_event_reset(&adapter->qdf_session_open_event);
4211 if (QDF_STATUS_SUCCESS != status) {
4212 hdd_err("failed to reinit session open event");
4213 return -EINVAL;
4214 }
Krunal Sonib51eec72017-11-20 21:53:01 -08004215 errno = hdd_set_sme_session_param(adapter, &sme_session_params,
4216 callback, ctx);
4217 if (errno) {
4218 hdd_err("failed to populating SME params");
4219 goto objmgr_vdev_destroy_procedure;
4220 }
Jeff Johnson16528362018-06-14 12:34:16 -07004221 status = sme_open_session(hdd_ctx->mac_handle, &sme_session_params);
Dustin Brownd28772b2017-03-17 14:16:07 -07004222 if (QDF_IS_STATUS_ERROR(status)) {
4223 hdd_err("failed to open sme session: %d", status);
4224 errno = qdf_status_to_os_return(status);
Krunal Soni4a020c72017-10-30 20:58:40 -07004225 goto objmgr_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004226 }
4227
4228 /* block on a completion variable until sme session is opened */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304229 status = qdf_wait_for_event_completion(&adapter->qdf_session_open_event,
Abhishek Singh13bf0ce2018-10-24 14:26:14 +05304230 SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304231 if (QDF_STATUS_SUCCESS != status) {
4232 if (adapter->qdf_session_open_event.force_set) {
4233 /*
4234 * SSR/PDR has caused shutdown, which has forcefully
4235 * set the event. Return without the closing session.
4236 */
Jeff Johnson912b1bb2019-03-06 10:12:36 -08004237 adapter->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304238 hdd_err("Session open event forcefully set");
4239 return -EINVAL;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304240 }
Jeff Johnsonc66d3102018-02-28 11:58:26 -08004241
4242 if (QDF_STATUS_E_TIMEOUT == status)
4243 hdd_err("Session failed to open within timeout period");
4244 else
4245 hdd_err("Failed to wait for session open event(status-%d)",
4246 status);
4247 errno = -ETIMEDOUT;
4248 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
4249 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004250 }
4251
Pragaspathi Thilagaraj3551caa2018-09-26 15:52:56 +05304252 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
4253 hdd_err("Session failed to open due to vdev create failure");
4254 errno = -EINVAL;
4255 goto objmgr_vdev_destroy_procedure;
4256 }
4257
Dustin Brownd28772b2017-03-17 14:16:07 -07004258 /* firmware ready for component communication, raise vdev_ready event */
4259 errno = hdd_vdev_ready(adapter);
4260 if (errno) {
4261 hdd_err("failed to dispatch vdev ready event: %d", errno);
Krunal Soni4a020c72017-10-30 20:58:40 -07004262 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004263 }
4264
Naveen Rawat2b430892018-03-13 13:58:18 -07004265 if (adapter->device_mode == QDF_STA_MODE) {
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304266 bval = false;
4267 status = ucfg_mlme_get_rtt_mac_randomization(hdd_ctx->psoc,
4268 &bval);
4269 if (QDF_IS_STATUS_ERROR(status))
4270 hdd_err("unable to get RTT MAC randomization value");
4271
4272 hdd_debug("setting RTT mac randomization param: %d", bval);
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004273 errno = sme_cli_set_command(adapter->vdev_id,
Naveen Rawat2b430892018-03-13 13:58:18 -07004274 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC,
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304275 bval,
Naveen Rawat2b430892018-03-13 13:58:18 -07004276 VDEV_CMD);
4277 if (0 != errno)
4278 hdd_err("RTT mac randomization param set failed %d",
4279 errno);
4280 }
4281
Bala Venkatesh110b03e2018-07-10 16:02:08 +05304282 if (adapter->device_mode == QDF_STA_MODE ||
Min Liu8c5d99e2018-09-10 17:18:44 +08004283 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
4284 vdev = hdd_objmgr_get_vdev(adapter);
4285 if (!vdev)
4286 goto hdd_vdev_destroy_procedure;
4287 wlan_vdev_set_max_peer_count(vdev, HDD_MAX_VDEV_PEER_COUNT);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05304288 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08004289 }
Bala Venkatesh110b03e2018-07-10 16:02:08 +05304290
gaurank kathpalia78af1932018-10-27 20:33:10 +05304291 hdd_store_nss_chains_cfg_in_vdev(adapter);
4292
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004293 hdd_info("vdev %d created successfully", adapter->vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004294
4295 return 0;
4296
4297 /*
4298 * Due to legacy constraints, we need to destroy in the same order as
4299 * create. So, split error handling into 2 cases to accommodate.
4300 */
4301
Krunal Soni4a020c72017-10-30 20:58:40 -07004302objmgr_vdev_destroy_procedure:
Dustin Brown7d043f62017-03-27 12:07:36 -07004303 QDF_BUG(!hdd_objmgr_release_and_destroy_vdev(adapter));
Dustin Brownd28772b2017-03-17 14:16:07 -07004304
4305 return errno;
4306
Krunal Soni4a020c72017-10-30 20:58:40 -07004307hdd_vdev_destroy_procedure:
Dustin Brownd28772b2017-03-17 14:16:07 -07004308 QDF_BUG(!hdd_vdev_destroy(adapter));
4309
4310 return errno;
4311}
4312
Jeff Johnson9d295242017-08-29 14:39:48 -07004313QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07004314{
Jeff Johnsonb9424862017-10-30 08:49:35 -07004315 struct hdd_station_ctx *sta_ctx = &adapter->session.station;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004316 struct hdd_context *hdd_ctx;
Dustin Brownd28772b2017-03-17 14:16:07 -07004317 QDF_STATUS status;
4318 int ret_val;
Jeff Johnson16528362018-06-14 12:34:16 -07004319 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304320 bool bval = false;
Dustin Brownd28772b2017-03-17 14:16:07 -07004321
Dustin Brownd28772b2017-03-17 14:16:07 -07004322 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson16528362018-06-14 12:34:16 -07004323 mac_handle = hdd_ctx->mac_handle;
4324 sme_set_curr_device_mode(mac_handle, adapter->device_mode);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304325 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
4326 if (!QDF_IS_STATUS_SUCCESS(status))
4327 hdd_err("unable to get vht_enable2x2");
4328 sme_set_pdev_ht_vht_ies(mac_handle, bval);
4329
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004330 sme_set_vdev_ies_per_band(mac_handle, adapter->vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004331
Jeff Johnson7f2c5912018-03-23 11:42:28 -07004332 hdd_roam_profile_init(adapter);
4333 hdd_register_wext(adapter->dev);
4334
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -07004335 hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004336
Jeff Johnson0a082d92019-03-04 12:25:49 -08004337 qdf_mem_set(sta_ctx->conn_info.sta_id,
4338 sizeof(sta_ctx->conn_info.sta_id),
4339 HDD_WLAN_INVALID_STA_ID);
Hanumanth Reddy Pothulab2d729c2017-05-30 11:49:53 +05304340
Deepak Dhamdherea2785822016-11-17 01:17:45 -08004341 /* set fast roaming capability in sme session */
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004342 status = sme_config_fast_roaming(mac_handle, adapter->vdev_id,
Abhishek Singh1f217ec2017-12-22 11:48:27 +05304343 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004344 /* Set the default operation channel */
Jeff Johnson8626e932019-02-27 18:35:22 -08004345 sta_ctx->conn_info.channel =
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +05304346 hdd_ctx->config->operating_channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004347
4348 /* Make the default Auth Type as OPEN */
Jeff Johnson96e33512019-02-27 15:10:21 -08004349 sta_ctx->conn_info.auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004350
4351 status = hdd_init_tx_rx(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304352 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004353 hdd_err("hdd_init_tx_rx() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004354 status, status);
4355 goto error_init_txrx;
4356 }
4357
4358 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4359
4360 status = hdd_wmm_adapter_init(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304361 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004362 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004363 status, status);
4364 goto error_wmm_init;
4365 }
4366
4367 set_bit(WMM_INIT_DONE, &adapter->event_flags);
4368
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004369 ret_val = sme_cli_set_command(adapter->vdev_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004370 WMI_PDEV_PARAM_BURST_ENABLE,
Dundi Raviteja3aa01be2018-05-21 18:58:59 +05304371 HDD_ENABLE_SIFS_BURST_DEFAULT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004372 PDEV_CMD);
Dustin Brownd28772b2017-03-17 14:16:07 -07004373 if (ret_val)
4374 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004375
Poddar, Siddarth4b3f7312017-11-02 17:00:20 +05304376 /*
4377 * In case of USB tethering, LRO is disabled. If SSR happened
4378 * during that time, then as part of SSR init, do not enable
4379 * the LRO again. Keep the LRO state same as before SSR.
4380 */
jitiphil377bcc12018-10-05 19:46:08 +05304381 if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
4382 cfg_dp_lro_enable) &&
4383 !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -07004384 adapter->dev->features |= NETIF_F_LRO;
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05304385
Rakshith Suresh Patkar9f5c5862019-02-04 16:23:02 +05304386 if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
4387 cfg_dp_enable_ip_tcp_udp_checksum_offload))
4388 adapter->dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
4389 adapter->dev->features |= NETIF_F_RXCSUM;
4390
4391 hdd_set_tso_flags(hdd_ctx, adapter->dev);
4392
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05304393 /* rcpi info initialization */
4394 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
4395
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304396 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004397
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004398error_wmm_init:
4399 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4400 hdd_deinit_tx_rx(adapter);
4401error_init_txrx:
Dustin Brownd28772b2017-03-17 14:16:07 -07004402 hdd_unregister_wext(adapter->dev);
Dustin Brownd28772b2017-03-17 14:16:07 -07004403 QDF_BUG(!hdd_vdev_destroy(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004404
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004405 return status;
4406}
4407
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304408/**
Krunal Soni4a020c72017-10-30 20:58:40 -07004409 * hdd_deinit_station_mode() - De-initialize the station adapter
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304410 * @hdd_ctx: global hdd context
4411 * @adapter: HDD adapter
Jeff Johnson590e2012016-10-05 16:16:24 -07004412 * @rtnl_held: Used to indicate whether or not the caller is holding
4413 * the kernel rtnl_mutex
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304414 *
4415 * This function De-initializes the STA/P2P/OCB adapter.
4416 *
4417 * Return: None.
4418 */
Krunal Soni4a020c72017-10-30 20:58:40 -07004419static void hdd_deinit_station_mode(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004420 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004421 bool rtnl_held)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304422{
Dustin Brownfdf17c12018-03-14 12:55:34 -07004423 hdd_enter_dev(adapter->dev);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304424
Hanumanth Reddy Pothula7a657402016-09-07 20:59:18 +05304425 if (adapter->dev) {
4426 if (rtnl_held)
4427 adapter->dev->wireless_handlers = NULL;
4428 else {
4429 rtnl_lock();
4430 adapter->dev->wireless_handlers = NULL;
4431 rtnl_unlock();
4432 }
4433 }
4434
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304435 if (test_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags)) {
4436 hdd_deinit_tx_rx(adapter);
4437 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4438 }
4439
4440 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
4441 hdd_wmm_adapter_close(adapter);
4442 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
4443 }
4444
Krunal Sonib51eec72017-11-20 21:53:01 -08004445
Dustin Browne74003f2018-03-14 12:51:58 -07004446 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304447}
4448
Krunal Sonib51eec72017-11-20 21:53:01 -08004449void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
4450 struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004451 bool rtnl_held)
4452{
Dustin Brown491d54b2018-03-14 12:39:11 -07004453 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304454
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004455 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004456 case QDF_STA_MODE:
4457 case QDF_P2P_CLIENT_MODE:
4458 case QDF_P2P_DEVICE_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08004459 case QDF_IBSS_MODE:
4460 case QDF_NDI_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004461 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004462 hdd_deinit_station_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004463 break;
4464 }
4465
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004466 case QDF_SAP_MODE:
4467 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004468 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004469 hdd_deinit_ap_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004470 break;
4471 }
4472
4473 default:
4474 break;
4475 }
4476
Dustin Browne74003f2018-03-14 12:51:58 -07004477 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004478}
4479
Min Liu8c5d99e2018-09-10 17:18:44 +08004480static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
4481 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004482 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004483{
Jeff Johnson5505db82017-11-02 21:19:23 -07004484 struct net_device *dev = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004485
4486 if (adapter)
Jeff Johnson5505db82017-11-02 21:19:23 -07004487 dev = adapter->dev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004488 else {
Jeff Johnson5880d792016-08-15 13:32:30 -07004489 hdd_err("adapter is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004490 return;
4491 }
4492
Alok Kumarb64650c2018-03-23 17:05:11 +05304493 hdd_nud_deinit_tracking(adapter);
4494 qdf_mutex_destroy(&adapter->disconnection_status_lock);
Nachiket Kukade5f0ce4f2018-06-15 19:47:37 +05304495 hdd_apf_context_destroy(adapter);
Min Liu8c5d99e2018-09-10 17:18:44 +08004496 qdf_spinlock_destroy(&adapter->vdev_lock);
Alok Kumarb64650c2018-03-23 17:05:11 +05304497
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05304498 wlan_hdd_debugfs_csr_deinit(adapter);
Arunk Khandavallica56d4b2018-11-29 15:46:00 +05304499 if (adapter->device_mode == QDF_STA_MODE)
4500 hdd_sysfs_destroy_adapter_root_obj(adapter);
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05304501
Rajeev Kumardca5f812016-02-04 17:28:06 -08004502 hdd_debugfs_exit(adapter);
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05304503
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004504 /*
4505 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
4506 * the driver is almost closed and cannot handle either control
4507 * messages or data. However, unregister_netdevice() call above will
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004508 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
4509 * to close the active connections(basically excites control path) which
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004510 * is not right. Setting this flag helps hdd_stop() to recognize that
4511 * the interface is closed and restricts any operations on that
4512 */
4513 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
4514
4515 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004516 if (rtnl_held)
Jeff Johnson5505db82017-11-02 21:19:23 -07004517 unregister_netdevice(dev);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004518 else
Jeff Johnson5505db82017-11-02 21:19:23 -07004519 unregister_netdev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004520 /*
4521 * Note that the adapter is no longer valid at this point
4522 * since the memory has been reclaimed
4523 */
4524 }
4525}
4526
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004527static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07004528 tSirMacAddr mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004529{
Jeff Johnson9d295242017-08-29 14:39:48 -07004530 struct hdd_adapter *adapter;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004531
Dustin Brown920397d2017-12-13 16:27:50 -08004532 hdd_for_each_adapter(hdd_ctx, adapter) {
4533 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07004534 mac_addr, sizeof(tSirMacAddr))) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304535 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004536 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004537 }
Dustin Brown920397d2017-12-13 16:27:50 -08004538
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304539 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004540}
Ryan Hsu07495ea2016-01-21 15:25:39 -08004541
Arun Khandavalli2358d522016-05-16 18:05:37 +05304542#ifdef CONFIG_FW_LOGS_BASED_ON_INI
4543/**
4544 * hdd_set_fw_log_params() - Set log parameters to FW
4545 * @hdd_ctx: HDD Context
4546 * @adapter: HDD Adapter
4547 *
4548 * This function set the FW Debug log level based on the INI.
4549 *
4550 * Return: None
4551 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004552static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004553 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304554{
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304555 QDF_STATUS status;
4556 uint16_t enable_fw_log_level, enable_fw_log_type;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304557 int ret;
4558
Arun Khandavallifae92942016-08-01 13:31:08 +05304559 if (QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
4560 (!hdd_ctx->config->enable_fw_log)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004561 hdd_debug("enable_fw_log not enabled in INI or in FTM mode return");
Arun Khandavalli2358d522016-05-16 18:05:37 +05304562 return;
4563 }
4564
Arun Khandavallifae92942016-08-01 13:31:08 +05304565 /* Enable FW logs based on INI configuration */
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304566 status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc,
4567 &enable_fw_log_type);
4568 if (QDF_IS_STATUS_ERROR(status))
4569 return;
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004570 ret = sme_cli_set_command(adapter->vdev_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304571 WMI_DBGLOG_TYPE,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304572 enable_fw_log_type,
Arun Khandavallifae92942016-08-01 13:31:08 +05304573 DBG_CMD);
4574 if (ret != 0)
4575 hdd_err("Failed to enable FW log type ret %d",
4576 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304577
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304578 status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc,
4579 &enable_fw_log_level);
4580 if (QDF_IS_STATUS_ERROR(status))
4581 return;
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004582 ret = sme_cli_set_command(adapter->vdev_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304583 WMI_DBGLOG_LOG_LEVEL,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304584 enable_fw_log_level,
Arun Khandavallifae92942016-08-01 13:31:08 +05304585 DBG_CMD);
4586 if (ret != 0)
4587 hdd_err("Failed to enable FW log level ret %d",
4588 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304589
lifengfaa83cb2018-11-24 01:53:56 +08004590 sme_enable_fw_module_log_level(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004591 adapter->vdev_id);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304592}
4593#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004594static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004595 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304596{
4597}
4598
4599#endif
4600
4601/**
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004602 * hdd_configure_chain_mask() - programs chain mask to firmware
4603 * @adapter: HDD adapter
4604 *
4605 * Return: 0 on success or errno on failure
4606 */
4607static int hdd_configure_chain_mask(struct hdd_adapter *adapter)
4608{
Naveen Rawat98322472018-03-06 10:29:42 -08004609 QDF_STATUS status;
4610 struct wma_caps_per_phy non_dbs_phy_cap;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004611 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304612 bool enable2x2 = false, enable_bt_chain_sep = false;
Krunal Sonidf29bc42018-11-15 13:26:29 -08004613 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
4614
4615 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
4616 &dual_mac_feature);
4617 if (!QDF_IS_STATUS_SUCCESS(status))
4618 hdd_err("unable to get dual mac feature");
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304619
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304620 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &enable2x2);
4621 if (QDF_IS_STATUS_ERROR(status))
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304622 hdd_err("unable to get vht_enable2x2");
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004623
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304624 status = ucfg_mlme_get_bt_chain_separation_flag(hdd_ctx->psoc,
4625 &enable_bt_chain_sep);
4626 if (QDF_IS_STATUS_ERROR(status))
4627 hdd_debug("unable to get BT chain separation. using default");
4628
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304629 hdd_debug("enable2x2: %d, lte_coex: %d, disable_DBS: %d",
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304630 enable2x2, hdd_ctx->lte_coex_ant_share,
Krunal Sonidf29bc42018-11-15 13:26:29 -08004631 dual_mac_feature);
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304632 hdd_debug("enable_bt_chain_separation %d", enable_bt_chain_sep);
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004633
Naveen Rawat98322472018-03-06 10:29:42 -08004634 status = wma_get_caps_for_phyidx_hwmode(&non_dbs_phy_cap,
4635 HW_MODE_DBS_NONE,
4636 CDS_BAND_ALL);
4637 if (QDF_IS_STATUS_ERROR(status)) {
4638 hdd_err("couldn't get phy caps. skip chain mask programming");
4639 return qdf_status_to_os_return(status);
4640 }
4641
4642 if (non_dbs_phy_cap.tx_chain_mask_2G < 3 ||
4643 non_dbs_phy_cap.rx_chain_mask_2G < 3 ||
4644 non_dbs_phy_cap.tx_chain_mask_5G < 3 ||
4645 non_dbs_phy_cap.rx_chain_mask_5G < 3) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07004646 hdd_debug("firmware not capable. skip chain mask programming");
Naveen Rawat98322472018-03-06 10:29:42 -08004647 return 0;
4648 }
4649
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304650 if (enable2x2 && !enable_bt_chain_sep) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07004651 hdd_debug("2x2 enabled. skip chain mask programming");
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004652 return 0;
4653 }
4654
Krunal Sonidf29bc42018-11-15 13:26:29 -08004655 if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07004656 hdd_debug("DBS enabled(%d). skip chain mask programming",
Krunal Sonidf29bc42018-11-15 13:26:29 -08004657 dual_mac_feature);
Naveen Rawatb54c72b2018-02-05 10:39:06 -08004658 return 0;
4659 }
4660
Naveen Rawatdacb5032018-02-08 15:23:24 -08004661 if (hdd_ctx->lte_coex_ant_share) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07004662 hdd_debug("lte ant sharing enabled. skip chainmask programming");
Naveen Rawatdacb5032018-02-08 15:23:24 -08004663 return 0;
4664 }
4665
Dustin Brown1dbefe62018-09-11 16:32:03 -07004666 status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004667 adapter->vdev_id);
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304668 if (status != QDF_STATUS_SUCCESS)
4669 goto error;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004670
4671 return 0;
4672
4673error:
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304674 hdd_err("WMI PDEV set param failed");
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004675 return -EINVAL;
4676}
4677
4678/**
Dundi Raviteja3b637092018-09-12 13:42:50 +05304679 * hdd_send_coex_config_params() - Send coex config params to FW
4680 * @hdd_ctx: HDD context
4681 * @adapter: Primary adapter context
4682 *
4683 * This function is used to send all coex config related params to FW
4684 *
4685 * Return: 0 on success and -EINVAL on failure
4686 */
4687static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx,
4688 struct hdd_adapter *adapter)
4689{
4690 struct coex_config_params coex_cfg_params = {0};
4691 struct wlan_fwol_coex_config config = {0};
Dustin Brown05d81302018-09-11 16:49:22 -07004692 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Dundi Raviteja3b637092018-09-12 13:42:50 +05304693 QDF_STATUS status;
4694
4695 if (!hdd_ctx) {
4696 hdd_err("hdd_ctx is invalid");
4697 goto err;
4698 }
4699
4700 if (!adapter) {
4701 hdd_err("adapter is invalid");
4702 goto err;
4703 }
4704
4705 if (!psoc) {
4706 hdd_err("HDD psoc is invalid");
4707 goto err;
4708 }
4709
4710 status = ucfg_fwol_get_coex_config_params(psoc, &config);
4711 if (QDF_IS_STATUS_ERROR(status)) {
4712 hdd_err("Unable to get coex config params");
4713 goto err;
4714 }
4715
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004716 coex_cfg_params.vdev_id = adapter->vdev_id;
Dundi Raviteja3b637092018-09-12 13:42:50 +05304717 coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER;
4718 coex_cfg_params.config_arg1 = config.max_tx_power_for_btc;
4719
4720 status = sme_send_coex_config_cmd(&coex_cfg_params);
4721 if (QDF_IS_STATUS_ERROR(status)) {
4722 hdd_err("Failed to send coex Tx power");
4723 goto err;
4724 }
4725
4726 coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI;
4727 coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold;
4728
4729 status = sme_send_coex_config_cmd(&coex_cfg_params);
4730 if (QDF_IS_STATUS_ERROR(status)) {
4731 hdd_err("Failed to send coex handover RSSI");
4732 goto err;
4733 }
4734
4735 coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE;
4736 coex_cfg_params.config_arg1 = config.btc_mode;
4737
4738 status = sme_send_coex_config_cmd(&coex_cfg_params);
4739 if (QDF_IS_STATUS_ERROR(status)) {
4740 hdd_err("Failed to send coex BTC mode");
4741 goto err;
4742 }
4743
4744 coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION;
4745 coex_cfg_params.config_arg1 = config.antenna_isolation;
4746
4747 status = sme_send_coex_config_cmd(&coex_cfg_params);
4748 if (QDF_IS_STATUS_ERROR(status)) {
4749 hdd_err("Failed to send coex antenna isolation");
4750 goto err;
4751 }
4752
4753 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD;
4754 coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold;
4755
4756 status = sme_send_coex_config_cmd(&coex_cfg_params);
4757 if (QDF_IS_STATUS_ERROR(status)) {
4758 hdd_err("Failed to send coex BT low RSSI threshold");
4759 goto err;
4760 }
4761
4762 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL;
4763 coex_cfg_params.config_arg1 = config.bt_interference_low_ll;
4764 coex_cfg_params.config_arg2 = config.bt_interference_low_ul;
4765 coex_cfg_params.config_arg3 = config.bt_interference_medium_ll;
4766 coex_cfg_params.config_arg4 = config.bt_interference_medium_ul;
4767 coex_cfg_params.config_arg5 = config.bt_interference_high_ll;
4768 coex_cfg_params.config_arg6 = config.bt_interference_high_ul;
4769
4770 status = sme_send_coex_config_cmd(&coex_cfg_params);
4771 if (QDF_IS_STATUS_ERROR(status)) {
4772 hdd_err("Failed to send coex BT interference level");
4773 goto err;
4774 }
stonezc9936cb2019-03-11 16:41:22 +08004775
4776 if (wlan_hdd_mpta_helper_enable(&coex_cfg_params, &config))
4777 goto err;
4778
Dundi Raviteja3b637092018-09-12 13:42:50 +05304779 return 0;
4780err:
4781 return -EINVAL;
4782}
4783
4784/**
Arun Khandavalli2358d522016-05-16 18:05:37 +05304785 * hdd_set_fw_params() - Set parameters to firmware
4786 * @adapter: HDD adapter
4787 *
4788 * This function Sets various parameters to fw once the
4789 * adapter is started.
4790 *
4791 * Return: 0 on success or errno on failure
4792 */
Jeff Johnson9d295242017-08-29 14:39:48 -07004793int hdd_set_fw_params(struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304794{
4795 int ret;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304796 uint16_t upper_brssi_thresh, lower_brssi_thresh, rts_profile;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304797 bool enable_dtim_1chrx;
4798 QDF_STATUS status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004799 struct hdd_context *hdd_ctx;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304800 bool bval = false;
Manikandan Mohand350c192018-11-29 14:01:12 -08004801 uint8_t max_amsdu_len, enable_tx_sch_delay;
4802 uint32_t dtim_sel_diversity, enable_secondary_rate;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304803
Dustin Brownfdf17c12018-03-14 12:55:34 -07004804 hdd_enter_dev(adapter->dev);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304805
4806 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4807 if (!hdd_ctx)
4808 return -EINVAL;
4809
Dustin Brown732ab9c2017-06-15 13:24:09 -07004810 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
4811 hdd_debug("FTM Mode is active; nothing to do");
4812 return 0;
4813 }
4814
Manikandan Mohand350c192018-11-29 14:01:12 -08004815 ret = -1;
4816 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_lprx_enable(hdd_ctx->psoc,
4817 &bval))) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004818 ret = sme_cli_set_command(adapter->vdev_id,
Manikandan Mohand350c192018-11-29 14:01:12 -08004819 WMI_PDEV_PARAM_DTIM_SYNTH,
4820 bval, PDEV_CMD);
4821 }
Ashish Kumar Dhanotiyab8630ab2017-07-21 14:18:14 +05304822 if (ret) {
4823 hdd_err("Failed to set LPRx");
4824 goto error;
4825 }
4826
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +05304827 ucfg_mlme_get_dtim_selection_diversity(hdd_ctx->psoc,
4828 &dtim_sel_diversity);
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05304829
4830 ret = sme_cli_set_command(
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004831 adapter->vdev_id,
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05304832 WMI_PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION,
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +05304833 dtim_sel_diversity, PDEV_CMD);
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05304834 if (ret) {
4835 hdd_err("Failed to set DTIM_OPTIMIZED_CHAIN_SELECTION");
4836 goto error;
4837 }
4838
Manikandan Mohand350c192018-11-29 14:01:12 -08004839 ret = -1;
4840 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_tx_sch_delay(
4841 hdd_ctx->psoc, &enable_tx_sch_delay))) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004842 ret = sme_cli_set_command(adapter->vdev_id,
Manikandan Mohand350c192018-11-29 14:01:12 -08004843 WMI_PDEV_PARAM_TX_SCH_DELAY,
4844 enable_tx_sch_delay, PDEV_CMD);
4845 }
Ashish Kumar Dhanotiya48dac7d2018-03-28 14:59:50 +05304846 if (ret) {
4847 hdd_err("Failed to set WMI_PDEV_PARAM_TX_SCH_DELAY");
4848 goto error;
4849 }
4850
Manikandan Mohand350c192018-11-29 14:01:12 -08004851 ret = -1;
4852 if (QDF_IS_STATUS_SUCCESS(ucfg_fwol_get_enable_secondary_rate(
4853 hdd_ctx->psoc, &enable_secondary_rate))) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004854 ret = sme_cli_set_command(adapter->vdev_id,
Manikandan Mohand350c192018-11-29 14:01:12 -08004855 WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE,
4856 enable_secondary_rate, PDEV_CMD);
4857 }
Ashish Kumar Dhanotiya959b38c2018-04-06 21:07:57 +05304858 if (ret) {
4859 hdd_err("Failed to set WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE");
4860 goto error;
4861 }
4862
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304863 if (adapter->device_mode == QDF_STA_MODE) {
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304864 status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc,
4865 &upper_brssi_thresh);
4866 if (QDF_IS_STATUS_ERROR(status))
4867 return -EINVAL;
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304868
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004869 sme_set_smps_cfg(adapter->vdev_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304870 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH,
4871 upper_brssi_thresh);
4872
4873 status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc,
4874 &lower_brssi_thresh);
4875 if (QDF_IS_STATUS_ERROR(status))
4876 return -EINVAL;
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304877
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004878 sme_set_smps_cfg(adapter->vdev_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304879 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH,
4880 lower_brssi_thresh);
4881
4882 status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc,
4883 &enable_dtim_1chrx);
4884 if (QDF_IS_STATUS_ERROR(status))
4885 return -EINVAL;
4886
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004887 sme_set_smps_cfg(adapter->vdev_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304888 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE,
4889 enable_dtim_1chrx);
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304890 }
4891
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304892 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
4893 if (!QDF_IS_STATUS_SUCCESS(status))
4894 hdd_err("unable to get vht_enable2x2");
4895
4896 if (bval) {
Dustin Brown732ab9c2017-06-15 13:24:09 -07004897 hdd_debug("configuring 2x2 mode fw params");
4898
Vignesh Viswanathana851d752018-10-03 19:44:38 +05304899 ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004900 adapter->vdev_id);
Dustin Brown732ab9c2017-06-15 13:24:09 -07004901 if (ret) {
4902 hdd_err("WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE set failed %d",
4903 ret);
4904 goto error;
4905 }
Liangwei Dong22810e82018-03-15 03:42:12 -04004906
4907 if (hdd_configure_chain_mask(adapter))
4908 goto error;
Dustin Brown732ab9c2017-06-15 13:24:09 -07004909 } else {
Arun Khandavalli2358d522016-05-16 18:05:37 +05304910#define HDD_DTIM_1CHAIN_RX_ID 0x5
4911#define HDD_SMPS_PARAM_VALUE_S 29
Dustin Brown732ab9c2017-06-15 13:24:09 -07004912 hdd_debug("configuring 1x1 mode fw params");
4913
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004914 /*
4915 * Disable DTIM 1 chain Rx when in 1x1,
4916 * we are passing two value
4917 * as param_id << 29 | param_value.
4918 * Below param_value = 0(disable)
4919 */
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004920 ret = sme_cli_set_command(adapter->vdev_id,
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004921 WMI_STA_SMPS_PARAM_CMDID,
4922 HDD_DTIM_1CHAIN_RX_ID <<
4923 HDD_SMPS_PARAM_VALUE_S,
4924 VDEV_CMD);
4925 if (ret) {
4926 hdd_err("DTIM 1 chain set failed %d", ret);
4927 goto error;
4928 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05304929
Arun Khandavalli2358d522016-05-16 18:05:37 +05304930#undef HDD_DTIM_1CHAIN_RX_ID
4931#undef HDD_SMPS_PARAM_VALUE_S
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004932
4933 if (hdd_configure_chain_mask(adapter))
4934 goto error;
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004935 }
4936
Vignesh Viswanathana851d752018-10-03 19:44:38 +05304937 ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004938 adapter->vdev_id);
Dustin Brown732ab9c2017-06-15 13:24:09 -07004939 if (ret) {
4940 hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d", ret);
4941 goto error;
4942 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05304943
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304944 status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile);
4945 if (QDF_IS_STATUS_ERROR(status))
4946 return -EINVAL;
4947
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004948 ret = sme_cli_set_command(adapter->vdev_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004949 WMI_VDEV_PARAM_ENABLE_RTSCTS,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304950 rts_profile,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004951 VDEV_CMD);
4952 if (ret) {
4953 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
4954 goto error;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304955 }
4956
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05304957 status = ucfg_mlme_get_max_amsdu_num(hdd_ctx->psoc, &max_amsdu_len);
4958 if (QDF_IS_STATUS_ERROR(status)) {
4959 hdd_err("Failed to get Max AMSDU Num");
4960 goto error;
4961 }
4962
4963 hdd_debug("SET AMSDU num %d", max_amsdu_len);
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004964
Jeff Johnson5a6fc962019-02-04 14:20:25 -08004965 ret = wma_cli_set_command(adapter->vdev_id,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004966 GEN_VDEV_PARAM_AMSDU,
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05304967 max_amsdu_len,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004968 GEN_CMD);
4969 if (ret != 0) {
4970 hdd_err("GEN_VDEV_PARAM_AMSDU set failed %d", ret);
4971 goto error;
4972 }
4973
Arun Khandavalli2358d522016-05-16 18:05:37 +05304974 hdd_set_fw_log_params(hdd_ctx, adapter);
Dundi Raviteja3b637092018-09-12 13:42:50 +05304975
4976 ret = hdd_send_coex_config_params(hdd_ctx, adapter);
4977 if (ret) {
4978 hdd_warn("Error initializing coex config params");
4979 goto error;
4980 }
4981
Dustin Browne74003f2018-03-14 12:51:58 -07004982 hdd_exit();
Dustin Brown732ab9c2017-06-15 13:24:09 -07004983
Arun Khandavalli2358d522016-05-16 18:05:37 +05304984 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05304985
Arun Khandavalli2358d522016-05-16 18:05:37 +05304986error:
4987 return -EINVAL;
4988}
4989
Ryan Hsu07495ea2016-01-21 15:25:39 -08004990/**
Abhinav Kumarcc959f12018-08-09 13:58:30 +05304991 * hdd_init_completion() - Initialize Completion Variables
4992 * @adapter: HDD adapter
4993 *
4994 * This function Initialize the completion variables for
4995 * a particular adapter
4996 *
4997 * Return: None
4998 */
4999static void hdd_init_completion(struct hdd_adapter *adapter)
5000{
5001 init_completion(&adapter->disconnect_comp_var);
5002 init_completion(&adapter->roaming_comp_var);
5003 init_completion(&adapter->linkup_event_var);
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305004 init_completion(&adapter->sta_authorized_event);
5005 init_completion(&adapter->offchannel_tx_event);
5006 init_completion(&adapter->tx_action_cnf_event);
5007 init_completion(&adapter->ibss_peer_info_comp);
5008 init_completion(&adapter->lfr_fw_status.disable_lfr_event);
5009}
5010
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305011static void hdd_reset_locally_admin_bit(struct hdd_context *hdd_ctx,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005012 tSirMacAddr mac_addr)
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305013{
5014 int i;
5015 /*
5016 * Reset locally administered bit for dynamic_mac_list
5017 * also as while releasing the MAC address for any
5018 * interface mac will be compared with dynamic mac list
5019 */
5020 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
5021 if (!qdf_mem_cmp(
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005022 mac_addr,
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305023 &hdd_ctx->
5024 dynamic_mac_list[i].dynamic_mac.bytes[0],
5025 sizeof(struct qdf_mac_addr))) {
5026 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(
5027 hdd_ctx->
5028 dynamic_mac_list[i].dynamic_mac.bytes);
5029 break;
5030 }
5031 }
5032 /*
5033 * Reset locally administered bit if the device mode is
5034 * STA
5035 */
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005036 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(mac_addr);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305037 hdd_debug("locally administered bit reset in sta mode: "
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005038 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(mac_addr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05305039}
5040
Dustin Brown96b98dd2019-03-06 12:39:37 -08005041static void wlan_hdd_cfg80211_scan_block_cb(struct work_struct *work)
5042{
5043 struct hdd_adapter *adapter =
5044 container_of(work, struct hdd_adapter, scan_block_work);
5045 struct osif_vdev_sync *vdev_sync;
5046
5047 if (osif_vdev_sync_op_start(adapter->dev, &vdev_sync))
5048 return;
5049
5050 wlan_hdd_cfg80211_scan_block(adapter);
5051
5052 osif_vdev_sync_op_stop(vdev_sync);
5053}
5054
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305055/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08005056 * hdd_open_adapter() - open and setup the hdd adatper
5057 * @hdd_ctx: global hdd context
5058 * @session_type: type of the interface to be created
5059 * @iface_name: User-visible name of the interface
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005060 * @mac_addr: MAC address to assign to the interface
Ryan Hsu07495ea2016-01-21 15:25:39 -08005061 * @name_assign_type: the name of assign type of the netdev
5062 * @rtnl_held: the rtnl lock hold flag
5063 *
5064 * This function open and setup the hdd adpater according to the device
5065 * type request, assign the name, the mac address assigned, and then prepared
5066 * the hdd related parameters, queue, lock and ready to start.
5067 *
5068 * Return: the pointer of hdd adapter, otherwise NULL.
5069 */
Jeff Johnson9d295242017-08-29 14:39:48 -07005070struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t session_type,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005071 const char *iface_name, tSirMacAddr mac_addr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08005072 unsigned char name_assign_type,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08005073 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005074{
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305075 struct net_device *ndev = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07005076 struct hdd_adapter *adapter = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305077 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005078
5079 if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
5080 /*
5081 * Max limit reached on the number of vdevs configured by the
5082 * host. Return error
5083 */
Arun Khandavallifae92942016-08-01 13:31:08 +05305084 hdd_err("Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
5085 hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005086 return NULL;
5087 }
5088
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005089 status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)mac_addr);
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05305090 if (QDF_IS_STATUS_ERROR(status)) {
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005091 /* Not received valid mac_addr */
Arun Khandavallifae92942016-08-01 13:31:08 +05305092 hdd_err("Unable to add virtual intf: Not able to get valid mac address");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005093 return NULL;
5094 }
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05305095
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005096 status = hdd_check_for_existing_macaddr(hdd_ctx, mac_addr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305097 if (QDF_STATUS_E_FAILURE == status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05305098 hdd_err("Duplicate MAC addr: " MAC_ADDRESS_STR
5099 " already exists",
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005100 MAC_ADDR_ARRAY(mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005101 return NULL;
5102 }
5103
5104 switch (session_type) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005105 case QDF_STA_MODE:
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305106 if (!hdd_ctx->config->mac_provision) {
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005107 hdd_reset_locally_admin_bit(hdd_ctx, mac_addr);
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305108 /*
5109 * After resetting locally administered bit
5110 * again check if the new mac address is already
5111 * exists.
5112 */
5113 status = hdd_check_for_existing_macaddr(hdd_ctx,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005114 mac_addr);
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305115 if (QDF_STATUS_E_FAILURE == status) {
5116 hdd_err("Duplicate MAC addr: " MAC_ADDRESS_STR
5117 " already exists",
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005118 MAC_ADDR_ARRAY(mac_addr));
Ashish Kumar Dhanotiya01485192018-12-24 12:44:06 +05305119 return NULL;
5120 }
5121 }
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05305122
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005123 /* fall through */
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005124 case QDF_P2P_CLIENT_MODE:
5125 case QDF_P2P_DEVICE_MODE:
5126 case QDF_OCB_MODE:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07005127 case QDF_NDI_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305128 case QDF_MONITOR_MODE:
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005129 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08005130 name_assign_type,
5131 iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005132
Jeff Johnsond36fa332019-03-18 13:42:25 -07005133 if (!adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05305134 hdd_err("failed to allocate adapter for session %d",
5135 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005136 return NULL;
5137 }
5138
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305139 ndev = adapter->dev;
5140
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005141 if (QDF_P2P_CLIENT_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005142 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005143 else if (QDF_P2P_DEVICE_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005144 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305145 else if (QDF_MONITOR_MODE == session_type)
5146 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005147 else
5148 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
5149
5150 adapter->device_mode = session_type;
5151
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005152
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005153 /*
5154 * Workqueue which gets scheduled in IPv4 notification
5155 * callback
5156 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005157 INIT_WORK(&adapter->ipv4_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005158 hdd_ipv4_notifier_work_queue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005159
5160#ifdef WLAN_NS_OFFLOAD
5161 /*
5162 * Workqueue which gets scheduled in IPv6
5163 * notification callback.
5164 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005165 INIT_WORK(&adapter->ipv6_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005166 hdd_ipv6_notifier_work_queue);
5167#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005168 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005169 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08005170 goto err_free_netdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005171
5172 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005173 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005174 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305175 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5176 WLAN_CONTROL_PATH);
Arun Khandavallifae92942016-08-01 13:31:08 +05305177
Alok Kumarb64650c2018-03-23 17:05:11 +05305178 hdd_nud_init_tracking(adapter);
Arunk Khandavallica56d4b2018-11-29 15:46:00 +05305179 if (adapter->device_mode == QDF_STA_MODE ||
5180 adapter->device_mode == QDF_P2P_DEVICE_MODE)
5181 hdd_sysfs_create_adapter_root_obj(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305182 qdf_mutex_create(&adapter->disconnection_status_lock);
5183
Ravi Joshi1a292562017-05-18 16:28:54 -07005184 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005185
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005186 case QDF_P2P_GO_MODE:
5187 case QDF_SAP_MODE:
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005188 adapter = hdd_wlan_create_ap_dev(hdd_ctx, mac_addr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08005189 name_assign_type,
5190 (uint8_t *) iface_name);
Jeff Johnsond36fa332019-03-18 13:42:25 -07005191 if (!adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005192 hdd_err("failed to allocate adapter for session %d",
Arun Khandavallifae92942016-08-01 13:31:08 +05305193 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005194 return NULL;
5195 }
5196
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305197 ndev = adapter->dev;
5198
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005199 adapter->wdev.iftype =
5200 (session_type ==
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005201 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005202 NL80211_IFTYPE_P2P_GO;
5203 adapter->device_mode = session_type;
5204
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07005205 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005206 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005207 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08005208
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005209 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005210 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305211 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5212 WLAN_CONTROL_PATH);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305213
5214 /*
5215 * Workqueue which gets scheduled in IPv4 notification
5216 * callback
5217 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005218 INIT_WORK(&adapter->ipv4_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305219 hdd_ipv4_notifier_work_queue);
5220
5221#ifdef WLAN_NS_OFFLOAD
5222 /*
5223 * Workqueue which gets scheduled in IPv6
5224 * notification callback.
5225 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005226 INIT_WORK(&adapter->ipv6_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305227 hdd_ipv6_notifier_work_queue);
5228#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005229 break;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305230 case QDF_FTM_MODE:
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07005231 adapter = hdd_alloc_station_adapter(hdd_ctx, mac_addr,
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305232 name_assign_type,
Lin Bai1c678482017-12-18 18:29:11 +08005233 iface_name);
Jeff Johnsond36fa332019-03-18 13:42:25 -07005234 if (!adapter) {
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305235 hdd_err("Failed to allocate adapter for FTM mode");
5236 return NULL;
5237 }
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305238
5239 ndev = adapter->dev;
5240
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305241 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
5242 adapter->device_mode = session_type;
5243 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005244 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08005245 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08005246
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305247 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005248 hdd_debug("Disabling queues");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305249 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305250 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5251 WLAN_CONTROL_PATH);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305252 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005253 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005254 hdd_err("Invalid session type %d", session_type);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305255 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005256 return NULL;
5257 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005258
Min Liu8c5d99e2018-09-10 17:18:44 +08005259 qdf_spinlock_create(&adapter->vdev_lock);
5260
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305261 hdd_init_completion(adapter);
hqueaa33ee2017-05-04 17:56:35 +08005262 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
Min Liu9be5d4a2018-05-17 11:51:53 +08005263 qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT);
5264 qdf_mutex_create(&adapter->blocked_scan_request_q_lock);
hqueaa33ee2017-05-04 17:56:35 +08005265
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305266 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005267 /* Add it to the hdd's session list. */
Dustin Brown920397d2017-12-13 16:27:50 -08005268 status = hdd_add_adapter_back(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005269 }
5270
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305271 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsond36fa332019-03-18 13:42:25 -07005272 if (adapter) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005273 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
5274 adapter = NULL;
5275 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005276
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005277 return NULL;
5278 }
Nachiket Kukade5f0ce4f2018-06-15 19:47:37 +05305279 hdd_apf_context_init(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005280
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305281 if (QDF_STATUS_SUCCESS == status) {
Dustin Brown1dbefe62018-09-11 16:32:03 -07005282 policy_mgr_set_concurrency_mode(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005283 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005284
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005285 /* Adapter successfully added. Increment the vdev count */
5286 hdd_ctx->current_intf_count++;
5287
Jeff Johnson5880d792016-08-15 13:32:30 -07005288 hdd_debug("current_intf_count=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005289 hdd_ctx->current_intf_count);
5290
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08005291 hdd_check_and_restart_sap_with_non_dfs_acs();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005292 }
5293
Rajeev Kumardca5f812016-02-04 17:28:06 -08005294 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
Mahesh Kumar Kalikot Veetil80dda9a2017-07-17 11:38:03 -07005295 hdd_err("Interface %s wow debug_fs init failed",
5296 netdev_name(adapter->dev));
5297
5298 hdd_info("%s interface created. iftype: %d", netdev_name(adapter->dev),
5299 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005300
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05305301 if (adapter->device_mode == QDF_STA_MODE)
5302 wlan_hdd_debugfs_csr_init(adapter);
5303
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005304 return adapter;
5305
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005306err_free_netdev:
Jeff Johnson1e851a12017-10-28 14:36:12 -07005307 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
Madhvapathi Sriram8b056652019-03-27 17:38:12 +05305308
5309 if (ndev)
5310 free_netdev(ndev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005311
5312 return NULL;
5313}
5314
Dustin Brown728d65a2018-10-02 16:27:52 -07005315static void __hdd_close_adapter(struct hdd_context *hdd_ctx,
5316 struct hdd_adapter *adapter,
5317 bool rtnl_held)
5318{
5319 qdf_list_destroy(&adapter->blocked_scan_request_q);
5320 qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock);
5321 policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
5322
5323 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
5324
5325 if (hdd_ctx->current_intf_count != 0)
5326 hdd_ctx->current_intf_count--;
5327}
5328
5329void hdd_close_adapter(struct hdd_context *hdd_ctx,
5330 struct hdd_adapter *adapter,
5331 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005332{
Dustin Brown920397d2017-12-13 16:27:50 -08005333 /*
Dustin Brown728d65a2018-10-02 16:27:52 -07005334 * Stop the global bus bandwidth timer while touching the adapter list
5335 * to avoid bad memory access by the timer handler.
Dustin Brown920397d2017-12-13 16:27:50 -08005336 */
Dustin Brown920397d2017-12-13 16:27:50 -08005337 hdd_bus_bw_compute_timer_stop(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005338
Dustin Brown920397d2017-12-13 16:27:50 -08005339 hdd_remove_adapter(hdd_ctx, adapter);
Dustin Brown728d65a2018-10-02 16:27:52 -07005340 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005341
Dustin Brown920397d2017-12-13 16:27:50 -08005342 /* conditionally restart the bw timer */
5343 hdd_bus_bw_compute_timer_try_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005344}
5345
Dustin Brown728d65a2018-10-02 16:27:52 -07005346void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005347{
Dustin Brown920397d2017-12-13 16:27:50 -08005348 struct hdd_adapter *adapter;
Dustin Brown2c5e0482019-02-05 16:14:43 -08005349 struct osif_vdev_sync *vdev_sync;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005350
Dustin Brown491d54b2018-03-14 12:39:11 -07005351 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005352
Dustin Brown728d65a2018-10-02 16:27:52 -07005353 while (QDF_IS_STATUS_SUCCESS(hdd_remove_front_adapter(hdd_ctx,
5354 &adapter))) {
Dustin Brown2c5e0482019-02-05 16:14:43 -08005355 vdev_sync = osif_vdev_sync_unregister(adapter->dev);
Dustin Brown693b5352019-01-17 10:00:31 -08005356 if (vdev_sync)
Dustin Brown2c5e0482019-02-05 16:14:43 -08005357 osif_vdev_sync_wait_for_ops(vdev_sync);
Dustin Brown693b5352019-01-17 10:00:31 -08005358
Dustin Brown728d65a2018-10-02 16:27:52 -07005359 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
5360 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
Dustin Brown693b5352019-01-17 10:00:31 -08005361
5362 if (vdev_sync)
Dustin Brown2c5e0482019-02-05 16:14:43 -08005363 osif_vdev_sync_destroy(vdev_sync);
Dustin Brown728d65a2018-10-02 16:27:52 -07005364 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005365
Dustin Browne74003f2018-03-14 12:51:58 -07005366 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005367}
5368
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005369void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005370{
Anurag Chouhan6d760662016-02-20 16:05:43 +05305371 struct qdf_mac_addr *bssid = NULL;
Jeff Johnsonc565af12019-03-10 21:09:47 -07005372 tSirUpdateIE update_ie;
Jeff Johnson16528362018-06-14 12:34:16 -07005373 mac_handle_t mac_handle;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005374
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005375 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005376 case QDF_STA_MODE:
5377 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005378 {
Jeff Johnsond377dce2017-10-04 10:32:42 -07005379 struct hdd_station_ctx *sta_ctx =
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005380 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnsone04b6992019-02-27 14:06:55 -08005381 bssid = &sta_ctx->conn_info.bssid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005382 break;
5383 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005384 case QDF_SAP_MODE:
5385 case QDF_P2P_GO_MODE:
5386 case QDF_IBSS_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005387 {
Jeff Johnson1e851a12017-10-28 14:36:12 -07005388 bssid = &adapter->mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005389 break;
5390 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005391 case QDF_FTM_MODE:
5392 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005393 default:
5394 /*
5395 * wlan_hdd_reset_prob_rspies should not have been called
5396 * for these kind of devices
5397 */
Jeff Johnson5880d792016-08-15 13:32:30 -07005398 hdd_err("Unexpected request for the current device type %d",
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005399 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005400 return;
5401 }
5402
Jeff Johnsonc565af12019-03-10 21:09:47 -07005403 qdf_copy_macaddr(&update_ie.bssid, bssid);
5404 update_ie.smeSessionId = adapter->vdev_id;
5405 update_ie.ieBufferlength = 0;
5406 update_ie.pAdditionIEBuffer = NULL;
5407 update_ie.append = true;
5408 update_ie.notify = false;
Jeff Johnson16528362018-06-14 12:34:16 -07005409 mac_handle = hdd_adapter_get_mac_handle(adapter);
5410 if (sme_update_add_ie(mac_handle,
Jeff Johnsonc565af12019-03-10 21:09:47 -07005411 &update_ie,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305412 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005413 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005414 }
5415}
5416
Dustin Browndb2a8be2017-12-20 11:49:56 -08005417QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
5418 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005419{
Dustin Brownd747ecd2018-10-26 16:32:22 -07005420 QDF_STATUS status = QDF_STATUS_SUCCESS;
5421 struct hdd_station_ctx *sta_ctx;
Dustin Brownb4260d52019-01-24 11:53:08 -08005422 struct sap_context *sap_ctx;
Jeff Johnson025618c2018-03-18 14:41:00 -07005423 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005424 union iwreq_data wrqu;
Jeff Johnsonc565af12019-03-10 21:09:47 -07005425 tSirUpdateIE update_ie;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005426 unsigned long rc;
Jeff Johnson8f8ceb92019-03-24 08:16:55 -07005427 struct sap_config *sap_config;
Jeff Johnson16528362018-06-14 12:34:16 -07005428 mac_handle_t mac_handle;
Min Liu8c5d99e2018-09-10 17:18:44 +08005429 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005430
Dustin Brown491d54b2018-03-14 12:39:11 -07005431 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005432
Jeff Johnson912b1bb2019-03-06 10:12:36 -08005433 if (adapter->vdev_id != WLAN_UMAC_VDEV_ID_MAX)
Dustin Browne7e71d32018-05-11 16:00:08 -07005434 wlan_hdd_cfg80211_deregister_frames(adapter);
5435
Alok Kumarb64650c2018-03-23 17:05:11 +05305436 hdd_nud_ignore_tracking(adapter, true);
5437 hdd_nud_reset_tracking(adapter);
Alok Kumar016a1ac2018-09-16 09:55:50 +05305438 hdd_nud_flush_work(adapter);
hangtian9c47aaf2018-11-26 17:59:39 +08005439 hdd_stop_tsf_sync(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305440
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005441 hdd_debug("Disabling queues");
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305442 wlan_hdd_netif_queue_control(adapter,
5443 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5444 WLAN_CONTROL_PATH);
Jeff Johnson16528362018-06-14 12:34:16 -07005445
5446 mac_handle = hdd_ctx->mac_handle;
5447
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005448 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005449 case QDF_STA_MODE:
5450 case QDF_P2P_CLIENT_MODE:
5451 case QDF_IBSS_MODE:
5452 case QDF_P2P_DEVICE_MODE:
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005453 case QDF_NDI_MODE:
Dustin Brownd747ecd2018-10-26 16:32:22 -07005454 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5455
5456 if (adapter->device_mode == QDF_NDI_MODE ||
5457 hdd_conn_is_connected(sta_ctx) ||
5458 hdd_is_connecting(sta_ctx)) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005459 INIT_COMPLETION(adapter->disconnect_comp_var);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005460
Jeff Johnson025618c2018-03-18 14:41:00 -07005461 roam_profile = hdd_roam_profile(adapter);
5462 /* For NDI do not use roam_profile */
Dustin Brownd747ecd2018-10-26 16:32:22 -07005463 if (adapter->device_mode == QDF_NDI_MODE)
5464 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005465 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005466 adapter->vdev_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005467 eCSR_DISCONNECT_REASON_NDI_DELETE);
Jeff Johnson025618c2018-03-18 14:41:00 -07005468 else if (roam_profile->BSSType ==
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005469 eCSR_BSS_TYPE_START_IBSS)
Dustin Brownd747ecd2018-10-26 16:32:22 -07005470 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005471 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005472 adapter->vdev_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005473 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Abhinav Kumar19a7a402018-07-12 17:36:57 +05305474 else if (adapter->device_mode == QDF_STA_MODE)
5475 wlan_hdd_disconnect(adapter,
5476 eCSR_DISCONNECT_REASON_DEAUTH);
5477 else
Dustin Brownd747ecd2018-10-26 16:32:22 -07005478 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005479 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005480 adapter->vdev_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005481 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005482 /* success implies disconnect is queued */
5483 if (QDF_IS_STATUS_SUCCESS(status) &&
5484 adapter->device_mode != QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005485 rc = wait_for_completion_timeout(
5486 &adapter->disconnect_comp_var,
5487 msecs_to_jiffies
Abhishek Singhd1f21c72019-01-21 15:16:34 +05305488 (SME_DISCONNECT_TIMEOUT));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005489 if (!rc)
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005490 hdd_warn("disconn_comp_var wait fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005491 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005492 if (QDF_IS_STATUS_ERROR(status))
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005493 hdd_warn("failed to post disconnect");
Dustin Brownd747ecd2018-10-26 16:32:22 -07005494
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005495 memset(&wrqu, '\0', sizeof(wrqu));
5496 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
5497 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
5498 wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu,
5499 NULL);
Sachin Ahuja988fd102016-09-15 17:16:25 +05305500 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005501
Dustin Brownd747ecd2018-10-26 16:32:22 -07005502 wlan_hdd_scan_abort(adapter);
Wu Gao4a1ec8c2018-07-23 19:18:40 +08005503 wlan_hdd_cleanup_actionframe(adapter);
Abhishek Singh1e94d7a2015-11-30 17:26:54 +05305504 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05305505 hdd_clear_fils_connection_info(adapter);
Ashish Kumar Dhanotiya36510832019-02-20 22:13:25 +05305506
Liangwei Donga44d55b2019-03-20 03:22:08 -04005507 status = wlan_hdd_flush_pmksa_cache(adapter);
Ashish Kumar Dhanotiya36510832019-02-20 22:13:25 +05305508 if (QDF_IS_STATUS_ERROR(status))
5509 hdd_err("Cannot flush PMKIDCache");
5510
Visweswara Tanukub5a61242019-03-26 12:24:13 +05305511 hdd_deregister_hl_netdev_fc_timer(adapter);
5512
Dustin Brownd747ecd2018-10-26 16:32:22 -07005513 hdd_deregister_tx_flow_control(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005514
5515#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005516 cancel_work_sync(&adapter->ipv4_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005517#ifdef WLAN_NS_OFFLOAD
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005518 cancel_work_sync(&adapter->ipv6_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005519#endif
5520#endif
5521
Min Liu8c5d99e2018-09-10 17:18:44 +08005522 if (adapter->device_mode == QDF_STA_MODE) {
5523 struct wlan_objmgr_vdev *vdev;
5524
5525 vdev = hdd_objmgr_get_vdev(adapter);
5526 if (vdev) {
5527 wlan_cfg80211_sched_scan_stop(vdev);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05305528 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08005529 }
5530 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08005531
Pragaspathi Thilagaraje6f37e02019-01-04 12:24:33 +05305532 /*
5533 * During vdev destroy, if any STA is in connecting state the
5534 * roam command will be in active queue and thus vdev destroy is
5535 * queued in pending queue. In case STA tries to connect to
5536 * multiple BSSID and fails to connect, due to auth/assoc
5537 * timeouts it may take more than vdev destroy time to get
5538 * completed. On vdev destroy timeout vdev is moved to logically
5539 * deleted state. Once connection is completed, vdev destroy is
5540 * activated and to release the self-peer ref count it try to
5541 * get the ref of the vdev, which fails as vdev is logically
5542 * deleted and this leads to peer ref leak. So before vdev
5543 * destroy is queued abort any STA ongoing connection to avoid
5544 * vdev destroy timeout.
5545 */
5546 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags))
5547 hdd_abort_ongoing_sta_connection(hdd_ctx);
Dustin Browndb2a8be2017-12-20 11:49:56 -08005548
Himanshu Agarwalb229a142017-12-21 10:16:45 +05305549 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005550 break;
5551
Rajeev Kumar3b906202018-02-01 10:55:14 -08005552 case QDF_MONITOR_MODE:
5553 wlan_hdd_scan_abort(adapter);
Visweswara Tanukub5a61242019-03-26 12:24:13 +05305554 hdd_deregister_hl_netdev_fc_timer(adapter);
Rajeev Kumar3b906202018-02-01 10:55:14 -08005555 hdd_deregister_tx_flow_control(adapter);
5556 hdd_vdev_destroy(adapter);
5557 break;
5558
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005559 case QDF_SAP_MODE:
Will Huang7049bae2018-08-13 17:25:02 +08005560 if (test_bit(ACS_PENDING, &adapter->event_flags)) {
5561 cds_flush_delayed_work(&adapter->acs_pending_work);
5562 clear_bit(ACS_PENDING, &adapter->event_flags);
5563 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005564
wadesongf9b15ed2017-12-14 14:12:32 +08005565 wlan_hdd_scan_abort(adapter);
gaurank kathpaliab7a9f702019-02-15 18:09:58 +05305566 /* Diassociate with all the peers before stop ap post */
5567 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags))
5568 wlan_hdd_del_station(adapter);
Arunk Khandavalli96c122f2017-10-17 11:49:36 +05305569 sap_config = &adapter->session.ap.sap_config;
Dustin Brownd747ecd2018-10-26 16:32:22 -07005570 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
5571
Dustin Brown07901ec2018-09-07 11:02:41 -07005572 ucfg_ipa_flush(hdd_ctx->pdev);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005573
Dustin Brownb4260d52019-01-24 11:53:08 -08005574 /* don't flush pre-cac destroy if we are destroying pre-cac */
5575 sap_ctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter);
5576 if (!wlan_sap_is_pre_cac_context(sap_ctx))
Liangwei Dongad89c762018-06-01 01:56:23 -04005577 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
Dustin Brownb4260d52019-01-24 11:53:08 -08005578
Jeff Johnson46807cd2018-04-29 21:32:22 -07005579 /* fallthrough */
Dustin Browna5cf8e02017-10-19 16:04:19 -07005580
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005581 case QDF_P2P_GO_MODE:
Krunal Soni22208392017-09-29 18:10:34 -07005582 cds_flush_work(&adapter->sap_stop_bss_work);
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05305583 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Dustin Browna5cf8e02017-10-19 16:04:19 -07005584 wlan_hdd_undo_acs(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005585
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005586 if (adapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005587 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5588
Visweswara Tanukub5a61242019-03-26 12:24:13 +05305589 hdd_deregister_hl_netdev_fc_timer(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005590 hdd_deregister_tx_flow_control(adapter);
Kapil Guptac1224bf2017-06-22 21:22:40 +05305591 hdd_destroy_acs_timer(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005592
Pragaspathi Thilagaraje6f37e02019-01-04 12:24:33 +05305593 /**
5594 * During vdev destroy, If any STA is in connecting state the
5595 * roam command will be in active queue and thus vdev destroy is
5596 * queued in pending queue. In case STA is tries to connected to
5597 * multiple BSSID and fails to connect, due to auth/assoc
5598 * timeouts it may take more than vdev destroy time to get
5599 * completes. If vdev destroy timeout vdev is moved to logically
5600 * deleted state. Once connection is completed, vdev destroy is
5601 * activated and to release the self-peer ref count it try to
5602 * get the ref of the vdev, which fails as vdev is logically
5603 * deleted and this leads to peer ref leak. So before vdev
5604 * destroy is queued abort any STA ongoing connection to avoid
5605 * vdev destroy timeout.
5606 */
5607 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags))
5608 hdd_abort_ongoing_sta_connection(hdd_ctx);
5609
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005610 mutex_lock(&hdd_ctx->sap_lock);
5611 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005612 status = wlansap_stop_bss(
5613 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005614
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305615 if (QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonca2530c2017-09-30 18:25:40 -07005616 struct hdd_hostapd_state *hostapd_state =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005617 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +05305618 qdf_event_reset(&hostapd_state->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305619 qdf_stop_bss_event);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005620 status = qdf_wait_for_event_completion(
Nachiket Kukade0396b732017-11-14 16:35:16 +05305621 &hostapd_state->qdf_stop_bss_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +05305622 SME_CMD_STOP_BSS_TIMEOUT);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005623 if (QDF_IS_STATUS_ERROR(status))
Jeff Johnson5880d792016-08-15 13:32:30 -07005624 hdd_err("failure waiting for wlansap_stop_bss %d",
Dustin Brownd747ecd2018-10-26 16:32:22 -07005625 status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005626 } else {
Jeff Johnson5880d792016-08-15 13:32:30 -07005627 hdd_err("failure in wlansap_stop_bss");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005628 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005629
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005630 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -07005631 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005632 adapter->device_mode,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005633 adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07005634 hdd_green_ap_start_state_mc(hdd_ctx,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305635 adapter->device_mode,
5636 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005637
Jeff Johnsonc565af12019-03-10 21:09:47 -07005638 qdf_copy_macaddr(&update_ie.bssid,
Jeff Johnson1e851a12017-10-28 14:36:12 -07005639 &adapter->mac_addr);
Jeff Johnsonc565af12019-03-10 21:09:47 -07005640 update_ie.smeSessionId = adapter->vdev_id;
5641 update_ie.ieBufferlength = 0;
5642 update_ie.pAdditionIEBuffer = NULL;
5643 update_ie.append = false;
5644 update_ie.notify = false;
Dustin Brownd747ecd2018-10-26 16:32:22 -07005645
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005646 /* Probe bcn reset */
Jeff Johnsonc565af12019-03-10 21:09:47 -07005647 status = sme_update_add_ie(mac_handle, &update_ie,
Dustin Brownd747ecd2018-10-26 16:32:22 -07005648 eUPDATE_IE_PROBE_BCN);
5649 if (status == QDF_STATUS_E_FAILURE)
5650 hdd_err("Could not pass PROBE_RSP_BCN to PE");
5651
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005652 /* Assoc resp reset */
Jeff Johnsonc565af12019-03-10 21:09:47 -07005653 status = sme_update_add_ie(mac_handle, &update_ie,
Dustin Brownd747ecd2018-10-26 16:32:22 -07005654 eUPDATE_IE_ASSOC_RESP);
5655 if (status == QDF_STATUS_E_FAILURE)
5656 hdd_err("Could not pass ASSOC_RSP to PE");
5657
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005658 /* Reset WNI_CFG_PROBE_RSP Flags */
5659 wlan_hdd_reset_prob_rspies(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005660 }
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08005661 clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
Jeff Johnsonb9424862017-10-30 08:49:35 -07005662 qdf_mem_free(adapter->session.ap.beacon);
5663 adapter->session.ap.beacon = NULL;
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08005664
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305665 /*
5666 * If Do_Not_Break_Stream was enabled clear avoid channel list.
5667 */
Min Liu8c5d99e2018-09-10 17:18:44 +08005668 vdev = hdd_objmgr_get_vdev(adapter);
5669 if (vdev) {
5670 if (policy_mgr_is_dnsc_set(vdev))
5671 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05305672 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08005673 }
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305674
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305675#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005676 cancel_work_sync(&adapter->ipv4_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305677#ifdef WLAN_NS_OFFLOAD
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005678 cancel_work_sync(&adapter->ipv6_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305679#endif
5680#endif
Dustin Browndb2a8be2017-12-20 11:49:56 -08005681
5682 hdd_vdev_destroy(adapter);
5683
Krunal Sonib51eec72017-11-20 21:53:01 -08005684 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005685 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005686 case QDF_OCB_MODE:
Dustin Brownd747ecd2018-10-26 16:32:22 -07005687 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Krishna Kumaar Natarajane58b4092017-01-25 15:47:35 -08005688 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
Dustin Brownd747ecd2018-10-26 16:32:22 -07005689 cds_get_context(QDF_MODULE_ID_TXRX),
Jeff Johnson0a082d92019-03-04 12:25:49 -08005690 sta_ctx->conn_info.sta_id[0]);
Visweswara Tanukub5a61242019-03-26 12:24:13 +05305691 hdd_deregister_hl_netdev_fc_timer(adapter);
Zhang Qian79d0d132018-02-05 13:40:16 +08005692 hdd_deregister_tx_flow_control(adapter);
5693 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005694 break;
5695 default:
5696 break;
5697 }
5698
Dustin Brown04348372017-12-14 16:13:39 -08005699 if (adapter->scan_info.default_scan_ies) {
5700 qdf_mem_free(adapter->scan_info.default_scan_ies);
5701 adapter->scan_info.default_scan_ies = NULL;
5702 }
5703
Dustin Browne74003f2018-03-14 12:51:58 -07005704 hdd_exit();
Dustin Brownd747ecd2018-10-26 16:32:22 -07005705
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305706 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005707}
5708
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305709/**
5710 * hdd_deinit_all_adapters - deinit all adapters
5711 * @hdd_ctx: HDD context
5712 * @rtnl_held: True if RTNL lock held
5713 *
5714 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005715void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305716{
Jeff Johnson9d295242017-08-29 14:39:48 -07005717 struct hdd_adapter *adapter;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305718
Dustin Brown491d54b2018-03-14 12:39:11 -07005719 hdd_enter();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305720
Dustin Brown920397d2017-12-13 16:27:50 -08005721 hdd_for_each_adapter(hdd_ctx, adapter)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305722 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305723
Dustin Browne74003f2018-03-14 12:51:58 -07005724 hdd_exit();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305725}
5726
Dustin Browndb2a8be2017-12-20 11:49:56 -08005727QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005728{
Jeff Johnson9d295242017-08-29 14:39:48 -07005729 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005730
Dustin Brown491d54b2018-03-14 12:39:11 -07005731 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005732
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05305733 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
5734
Dustin Brown920397d2017-12-13 16:27:50 -08005735 hdd_for_each_adapter(hdd_ctx, adapter)
Dustin Browndb2a8be2017-12-20 11:49:56 -08005736 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005737
Dustin Browne74003f2018-03-14 12:51:58 -07005738 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005739
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305740 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005741}
5742
Paul Zhang84fa9382017-11-10 21:18:21 +08005743static void hdd_reset_scan_operation(struct hdd_context *hdd_ctx,
5744 struct hdd_adapter *adapter)
5745{
5746 switch (adapter->device_mode) {
5747 case QDF_STA_MODE:
5748 case QDF_P2P_CLIENT_MODE:
5749 case QDF_IBSS_MODE:
5750 case QDF_P2P_DEVICE_MODE:
5751 case QDF_NDI_MODE:
5752 wlan_hdd_scan_abort(adapter);
5753 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Min Liu8c5d99e2018-09-10 17:18:44 +08005754 if (adapter->device_mode == QDF_STA_MODE) {
5755 struct wlan_objmgr_vdev *vdev;
5756
5757 vdev = hdd_objmgr_get_vdev(adapter);
5758 if (vdev) {
5759 wlan_cfg80211_sched_scan_stop(vdev);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05305760 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08005761 }
5762 }
Paul Zhang84fa9382017-11-10 21:18:21 +08005763 break;
5764 case QDF_P2P_GO_MODE:
5765 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5766 break;
5767 case QDF_SAP_MODE:
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05305768 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Paul Zhang84fa9382017-11-10 21:18:21 +08005769 wlan_hdd_undo_acs(adapter);
5770 break;
5771 default:
5772 break;
5773 }
5774}
5775
Ke Huangc067b8d2018-05-21 15:50:13 +08005776#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
5777/**
5778 * hdd_adapter_abort_tx_flow() - Abort the tx flow control
5779 * @pAdapter: pointer to hdd_adapter_t
5780 *
5781 * Resume tx and stop the tx flow control timer if the tx is paused
5782 * and the flow control timer is running. This function is called by
5783 * SSR to avoid the inconsistency of tx status before and after SSR.
5784 *
5785 * Return: void
5786 */
5787static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
5788{
5789 if (adapter->hdd_stats.tx_rx_stats.is_txflow_paused &&
5790 QDF_TIMER_STATE_RUNNING ==
5791 qdf_mc_timer_get_current_state(
5792 &adapter->tx_flow_control_timer)) {
5793 hdd_tx_resume_timer_expired_handler(adapter);
5794 qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
5795 }
5796}
5797#endif
5798
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005799QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005800{
Jeff Johnson9d295242017-08-29 14:39:48 -07005801 struct hdd_adapter *adapter;
Jeff Johnsond377dce2017-10-04 10:32:42 -07005802 struct hdd_station_ctx *sta_ctx;
Jeff Johnson2d044612019-02-26 20:08:43 -08005803 struct qdf_mac_addr peer_macaddr;
Yue Ma42654682018-01-11 16:55:24 -08005804 int sta_id;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05305805 bool value;
Min Liu8c5d99e2018-09-10 17:18:44 +08005806 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005807
Dustin Brown491d54b2018-03-14 12:39:11 -07005808 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005809
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05305810 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
5811
Dustin Brown920397d2017-12-13 16:27:50 -08005812 hdd_for_each_adapter(hdd_ctx, adapter) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07005813 hdd_info("[SSR] reset adapter with device mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07005814 qdf_opmode_str(adapter->device_mode),
Dustin Brown5e89ef82018-03-14 11:50:23 -07005815 adapter->device_mode);
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305816
Ke Huangc067b8d2018-05-21 15:50:13 +08005817#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
5818 hdd_adapter_abort_tx_flow(adapter);
5819#endif
5820
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305821 if ((adapter->device_mode == QDF_STA_MODE) ||
Paul Zhang679025e2018-03-08 22:39:44 +08005822 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305823 /* Stop tdls timers */
Min Liu8c5d99e2018-09-10 17:18:44 +08005824 vdev = hdd_objmgr_get_vdev(adapter);
5825 if (vdev) {
5826 hdd_notify_tdls_reset_adapter(vdev);
Rajeev Kumar Sirasanagandla25bdfad2019-02-15 19:15:49 +05305827 hdd_objmgr_put_vdev(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08005828 }
Paul Zhang679025e2018-03-08 22:39:44 +08005829 adapter->session.station.hdd_reassoc_scenario = false;
5830 }
Dustin Brown05d81302018-09-11 16:49:22 -07005831 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05305832 if (value &&
Arun Khandavallicc544b32017-01-30 19:52:16 +05305833 adapter->device_mode == QDF_SAP_MODE) {
5834 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305835 WLAN_STOP_ALL_NETIF_QUEUE,
Arun Khandavallicc544b32017-01-30 19:52:16 +05305836 WLAN_CONTROL_PATH);
Ashish Kumar Dhanotiyadc3900f2019-01-11 20:42:04 +05305837 if (test_bit(ACS_PENDING, &adapter->event_flags)) {
5838 cds_flush_delayed_work(
5839 &adapter->acs_pending_work);
5840 clear_bit(ACS_PENDING, &adapter->event_flags);
5841 }
5842
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005843 if (test_bit(SOFTAP_BSS_STARTED,
Ashish Kumar Dhanotiyadc3900f2019-01-11 20:42:04 +05305844 &adapter->event_flags)) {
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005845 hdd_sap_indicate_disconnect_for_sta(adapter);
Ashish Kumar Dhanotiyadc3900f2019-01-11 20:42:04 +05305846 clear_bit(SOFTAP_BSS_STARTED,
5847 &adapter->event_flags);
5848 }
5849
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005850 } else {
Arun Khandavallicc544b32017-01-30 19:52:16 +05305851 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305852 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005853 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005854 }
Nijun Gong104ccc72018-08-07 10:43:56 +08005855 /*
5856 * Clear fc flag if it was set before SSR to avoid TX queues
5857 * permanently stopped after SSR.
5858 * Here WLAN_START_ALL_NETIF_QUEUE will actually not start any
5859 * queue since it's blocked by reason WLAN_CONTROL_PATH.
5860 */
5861 if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL))
5862 wlan_hdd_netif_queue_control(adapter,
5863 WLAN_START_ALL_NETIF_QUEUE,
5864 WLAN_DATA_FLOW_CONTROL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005865
Paul Zhang84fa9382017-11-10 21:18:21 +08005866 hdd_reset_scan_operation(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005867
5868 hdd_deinit_tx_rx(adapter);
Dustin Brown1dbefe62018-09-11 16:32:03 -07005869 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08005870 adapter->device_mode, adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07005871 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305872 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005873 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
5874 hdd_wmm_adapter_close(adapter);
5875 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
5876 }
5877
Vignesh Viswanathan2eb18742017-09-08 11:18:59 +05305878 if (adapter->device_mode == QDF_STA_MODE)
5879 hdd_clear_fils_connection_info(adapter);
5880
Wu Gao3545e642017-07-14 19:24:41 +08005881 if (adapter->device_mode == QDF_SAP_MODE) {
Jingxiang Geec113592018-08-09 15:40:39 +08005882 wlansap_cleanup_cac_timer(
5883 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Wu Gao3545e642017-07-14 19:24:41 +08005884 /*
5885 * If adapter is SAP, set session ID to invalid
5886 * since SAP session will be cleanup during SSR.
5887 */
Wu Gao36717432016-11-21 15:09:48 +08005888 wlansap_set_invalid_session(
5889 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Wu Gao3545e642017-07-14 19:24:41 +08005890 }
5891
Abhishek Singh8f4aa182019-03-06 10:29:24 +05305892 /* Release vdev ref count to avoid vdev object leak */
5893 if (adapter->device_mode == QDF_P2P_GO_MODE ||
5894 adapter->device_mode == QDF_SAP_MODE)
5895 wlansap_release_vdev_ref(
5896 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
5897
Yue Ma42654682018-01-11 16:55:24 -08005898 /* Delete connection peers if any to avoid peer object leaks */
Yue Mad5b4b9f2017-05-26 16:23:40 -07005899 if (adapter->device_mode == QDF_STA_MODE ||
5900 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
Jeff Johnsond377dce2017-10-04 10:32:42 -07005901 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnson2d044612019-02-26 20:08:43 -08005902 qdf_copy_macaddr(&peer_macaddr,
Jeff Johnsone04b6992019-02-27 14:06:55 -08005903 &sta_ctx->conn_info.bssid);
Yue Mad5b4b9f2017-05-26 16:23:40 -07005904
Yue Ma42654682018-01-11 16:55:24 -08005905 } else if (adapter->device_mode == QDF_P2P_GO_MODE) {
Wu Gao6b81fc52018-05-24 19:27:27 +08005906 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Yue Ma42654682018-01-11 16:55:24 -08005907 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
5908 if (adapter->sta_info[sta_id].in_use) {
5909 hdd_debug("[SSR] deregister STA with ID %d",
5910 sta_id);
5911 hdd_softap_deregister_sta(adapter,
5912 sta_id);
5913 adapter->sta_info[sta_id].in_use = 0;
5914 }
5915 }
Yue Mad5b4b9f2017-05-26 16:23:40 -07005916 }
5917
Alok Kumarb64650c2018-03-23 17:05:11 +05305918 hdd_nud_ignore_tracking(adapter, true);
Alok Kumar016a1ac2018-09-16 09:55:50 +05305919 hdd_nud_reset_tracking(adapter);
5920 hdd_nud_flush_work(adapter);
Ashish Kumar Dhanotiyadc3900f2019-01-11 20:42:04 +05305921
5922 if (adapter->device_mode != QDF_SAP_MODE &&
5923 adapter->device_mode != QDF_P2P_GO_MODE &&
5924 adapter->device_mode != QDF_FTM_MODE)
5925 hdd_set_disconnect_status(adapter, false);
5926
hangtian9c47aaf2018-11-26 17:59:39 +08005927 hdd_stop_tsf_sync(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305928
Tiger Yu94a5a5c2018-03-09 21:22:26 +08005929 hdd_softap_deinit_tx_rx(adapter);
Visweswara Tanukub5a61242019-03-26 12:24:13 +05305930 hdd_deregister_hl_netdev_fc_timer(adapter);
Tiger Yu8c387702018-07-06 16:56:42 +08005931 hdd_deregister_tx_flow_control(adapter);
Tiger Yu94a5a5c2018-03-09 21:22:26 +08005932
Yue Maf9782842017-05-08 12:49:49 -07005933 /* Destroy vdev which will be recreated during reinit. */
5934 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005935 }
5936
Dustin Browne74003f2018-03-14 12:51:58 -07005937 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005938
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305939 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005940}
5941
Dustin Brown4c663222018-10-23 14:19:36 -07005942bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305943{
Dustin Brown920397d2017-12-13 16:27:50 -08005944 struct hdd_adapter *adapter;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305945
Dustin Brown4c663222018-10-23 14:19:36 -07005946 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
Arun Khandavalliba479c42017-07-26 21:29:40 +05305947 hdd_info("FTM mode, don't close the module");
Dustin Brown4c663222018-10-23 14:19:36 -07005948 return true;
Arun Khandavalliba479c42017-07-26 21:29:40 +05305949 }
5950
Dustin Brown920397d2017-12-13 16:27:50 -08005951 hdd_for_each_adapter(hdd_ctx, adapter) {
5952 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
Dustin Brown4c663222018-10-23 14:19:36 -07005953 test_bit(SME_SESSION_OPENED, &adapter->event_flags))
5954 return true;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305955 }
5956
Dustin Brown4c663222018-10-23 14:19:36 -07005957 return false;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305958}
5959
yeshwanth sriram guntukaea63f632017-08-30 19:31:56 +05305960bool hdd_is_interface_up(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05305961{
5962 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
5963 return true;
5964 else
5965 return false;
5966}
5967
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305968#if defined CFG80211_CONNECT_BSS || \
5969 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305970#if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305971 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305972/**
5973 * hdd_convert_timeout_reason() - Convert to kernel specific enum
5974 * @timeout_reason: reason for connect timeout
5975 *
5976 * This function is used to convert host timeout
5977 * reason enum to kernel specific enum.
5978 *
5979 * Return: nl timeout enum
5980 */
5981static enum nl80211_timeout_reason hdd_convert_timeout_reason(
5982 tSirResultCodes timeout_reason)
5983{
5984 switch (timeout_reason) {
5985 case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
5986 return NL80211_TIMEOUT_SCAN;
5987 case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
5988 return NL80211_TIMEOUT_AUTH;
5989 case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
5990 return NL80211_TIMEOUT_ASSOC;
5991 default:
5992 return NL80211_TIMEOUT_UNSPECIFIED;
5993 }
5994}
5995
5996/**
5997 * hdd_cfg80211_connect_timeout() - API to send connection timeout reason
5998 * @dev: network device
5999 * @bssid: bssid to which we want to associate
6000 * @timeout_reason: reason for connect timeout
6001 *
6002 * This API is used to send connection timeout reason to supplicant
6003 *
6004 * Return: void
6005 */
6006static void hdd_cfg80211_connect_timeout(struct net_device *dev,
6007 const u8 *bssid,
6008 tSirResultCodes timeout_reason)
6009{
6010 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006011
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306012 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
6013
6014 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL,
6015 nl_timeout_reason);
6016}
6017
6018/**
6019 * __hdd_connect_bss() - API to send connection status to supplicant
6020 * @dev: network device
6021 * @bssid: bssid to which we want to associate
6022 * @req_ie: Request Information Element
6023 * @req_ie_len: len of the req IE
6024 * @resp_ie: Response IE
6025 * @resp_ie_len: len of ht response IE
6026 * @status: status
6027 * @gfp: Kernel Flag
6028 * @timeout_reason: reason for connect timeout
6029 *
6030 * Return: void
6031 */
6032static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6033 struct cfg80211_bss *bss, const u8 *req_ie,
6034 size_t req_ie_len, const u8 *resp_ie,
6035 size_t resp_ie_len, int status, gfp_t gfp,
6036 tSirResultCodes timeout_reason)
6037{
6038 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006039
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306040 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
6041
6042 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
6043 resp_ie, resp_ie_len, status, gfp,
6044 nl_timeout_reason);
6045}
6046#else
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306047#if defined CFG80211_CONNECT_TIMEOUT || \
6048 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306049static void hdd_cfg80211_connect_timeout(struct net_device *dev,
6050 const u8 *bssid,
6051 tSirResultCodes timeout_reason)
6052{
6053 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL);
6054}
6055#endif
6056
6057static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6058 struct cfg80211_bss *bss, const u8 *req_ie,
6059 size_t req_ie_len, const u8 *resp_ie,
6060 size_t resp_ie_len, int status, gfp_t gfp,
6061 tSirResultCodes timeout_reason)
6062{
6063 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
6064 resp_ie, resp_ie_len, status, gfp);
6065}
6066#endif
6067
Abhishek Singha84d3952016-09-13 13:45:05 +05306068/**
6069 * hdd_connect_bss() - API to send connection status to supplicant
6070 * @dev: network device
6071 * @bssid: bssid to which we want to associate
6072 * @req_ie: Request Information Element
6073 * @req_ie_len: len of the req IE
6074 * @resp_ie: Response IE
6075 * @resp_ie_len: len of ht response IE
6076 * @status: status
6077 * @gfp: Kernel Flag
6078 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306079 * @timeout_reason: reason for connect timeout
Abhishek Singha84d3952016-09-13 13:45:05 +05306080 *
6081 * The API is a wrapper to send connection status to supplicant
6082 *
6083 * Return: Void
6084 */
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306085#if defined CFG80211_CONNECT_TIMEOUT || \
6086 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
Abhishek Singha84d3952016-09-13 13:45:05 +05306087static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6088 struct cfg80211_bss *bss, const u8 *req_ie,
6089 size_t req_ie_len, const u8 *resp_ie,
6090 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306091 bool connect_timeout,
6092 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05306093{
6094 if (connect_timeout)
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306095 hdd_cfg80211_connect_timeout(dev, bssid, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05306096 else
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306097 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
6098 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05306099}
6100#else
6101static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6102 struct cfg80211_bss *bss, const u8 *req_ie,
6103 size_t req_ie_len, const u8 *resp_ie,
6104 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306105 bool connect_timeout,
6106 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05306107{
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306108 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
6109 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05306110}
6111#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05306112
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306113#if defined(WLAN_FEATURE_FILS_SK)
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306114#if (defined(CFG80211_CONNECT_DONE) || \
6115 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))) && \
6116 (LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0))
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306117#if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
6118 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306119/**
6120 * hdd_populate_fils_params() - Populate FILS keys to connect response
6121 * @fils_params: connect response to supplicant
6122 * @fils_kek: FILS kek
6123 * @fils_kek_len: FILS kek length
6124 * @pmk: FILS PMK
6125 * @pmk_len: FILS PMK length
6126 * @pmkid: PMKID
6127 * @fils_seq_num: FILS Seq number
6128 *
6129 * Return: None
6130 */
6131static void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6132 *fils_params, const uint8_t *fils_kek,
6133 size_t fils_kek_len, const uint8_t *pmk,
6134 size_t pmk_len, const uint8_t *pmkid,
6135 uint16_t fils_seq_num)
6136{
6137 /* Increament seq number to be used for next FILS */
6138 fils_params->fils_erp_next_seq_num = fils_seq_num + 1;
6139 fils_params->update_erp_next_seq_num = true;
6140 fils_params->fils_kek = fils_kek;
6141 fils_params->fils_kek_len = fils_kek_len;
6142 fils_params->pmk = pmk;
6143 fils_params->pmk_len = pmk_len;
6144 fils_params->pmkid = pmkid;
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306145 hdd_debug("FILS erp_next_seq_num:%d",
6146 fils_params->fils_erp_next_seq_num);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306147}
6148#else
6149static inline void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6150 *fils_params, const uint8_t
6151 *fils_kek, size_t fils_kek_len,
6152 const uint8_t *pmk, size_t pmk_len,
6153 const uint8_t *pmkid,
6154 uint16_t fils_seq_num)
6155{ }
6156#endif
6157
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306158#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0))
6159/**
6160 * hdd_populate_fils_params() - Populate FILS keys to connect response
6161 * @fils_params: connect response to supplicant
6162 * @fils_kek: FILS kek
6163 * @fils_kek_len: FILS kek length
6164 * @pmk: FILS PMK
6165 * @pmk_len: FILS PMK length
6166 * @pmkid: PMKID
6167 * @fils_seq_num: FILS Seq number
6168 *
6169 * Return: None
6170 */
6171static void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6172 *fils_params, const uint8_t *fils_kek,
6173 size_t fils_kek_len, const uint8_t *pmk,
6174 size_t pmk_len, const uint8_t *pmkid,
6175 uint16_t fils_seq_num)
6176{
6177 /* Increament seq number to be used for next FILS */
6178 fils_params->fils.erp_next_seq_num = fils_seq_num + 1;
6179 fils_params->fils.update_erp_next_seq_num = true;
6180 fils_params->fils.kek = fils_kek;
6181 fils_params->fils.kek_len = fils_kek_len;
6182 fils_params->fils.pmk = pmk;
6183 fils_params->fils.pmk_len = pmk_len;
6184 fils_params->fils.pmkid = pmkid;
6185 hdd_debug("FILS erp_next_seq_num:%d",
6186 fils_params->fils.erp_next_seq_num);
6187}
6188#endif /* CFG80211_CONNECT_DONE */
6189
6190#if defined(CFG80211_CONNECT_DONE) || \
6191 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
6192
Jeff Johnson172237b2017-11-07 15:32:59 -08006193void hdd_update_hlp_info(struct net_device *dev,
6194 struct csr_roam_info *roam_info)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306195{
6196 struct sk_buff *skb;
6197 uint16_t skb_len;
6198 struct llc_snap_hdr_t *llc_hdr;
6199 QDF_STATUS status;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306200 uint8_t *hlp_data;
6201 uint16_t hlp_data_len;
6202 struct fils_join_rsp_params *roam_fils_params
6203 = roam_info->fils_join_rsp;
Jeff Johnsona1382382019-03-31 11:08:27 -07006204 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306205
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306206 if (!roam_fils_params) {
6207 hdd_err("FILS Roam Param NULL");
6208 return;
6209 }
6210
Srinivas Girigowda3cc8e912017-11-28 18:11:57 -08006211 if (!roam_fils_params->hlp_data_len) {
Jianmin Zhucc6b3d02019-03-07 14:19:34 +08006212 hdd_debug("FILS HLP Data NULL, len %d",
6213 roam_fils_params->hlp_data_len);
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306214 return;
6215 }
6216
6217 hlp_data = roam_fils_params->hlp_data;
6218 hlp_data_len = roam_fils_params->hlp_data_len;
6219
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306220 /* Calculate skb length */
6221 skb_len = (2 * ETH_ALEN) + hlp_data_len;
6222 skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false);
Jeff Johnsond36fa332019-03-18 13:42:25 -07006223 if (!skb) {
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306224 hdd_err("HLP packet nbuf alloc fails");
6225 return;
6226 }
6227
6228 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->dst_mac.bytes,
6229 QDF_MAC_ADDR_SIZE);
6230 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->src_mac.bytes,
6231 QDF_MAC_ADDR_SIZE);
6232
6233 llc_hdr = (struct llc_snap_hdr_t *) hlp_data;
6234 if (IS_SNAP(llc_hdr)) {
6235 hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
6236 hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
6237 }
6238
6239 qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len);
6240
6241 /*
6242 * This HLP packet is formed from HLP info encapsulated
6243 * in assoc response frame which is AEAD encrypted.
6244 * Hence, this checksum validation can be set unnecessary.
6245 * i.e. network layer need not worry about checksum.
6246 */
6247 skb->ip_summed = CHECKSUM_UNNECESSARY;
6248
Jeff Johnsona1382382019-03-31 11:08:27 -07006249 status = hdd_rx_packet_cbk(adapter, skb);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306250 if (QDF_IS_STATUS_ERROR(status)) {
6251 hdd_err("Sending HLP packet fails");
6252 return;
6253 }
6254 hdd_debug("send HLP packet to netif successfully");
6255}
6256
6257/**
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306258 * hdd_connect_done() - Wrapper API to call cfg80211_connect_done
6259 * @dev: network device
6260 * @bssid: bssid to which we want to associate
6261 * @bss: cfg80211 bss info
6262 * @roam_info: information about connected bss
6263 * @req_ie: Request Information Element
6264 * @req_ie_len: len of the req IE
6265 * @resp_ie: Response IE
6266 * @resp_ie_len: len of ht response IE
6267 * @status: status
6268 * @gfp: allocation flags
6269 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
6270 * @timeout_reason: reason for connect timeout
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306271 *
6272 * This API is used as wrapper to send FILS key/sequence number
6273 * params etc. to supplicant in case of FILS connection
6274 *
6275 * Return: None
6276 */
6277static void hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006278 struct cfg80211_bss *bss,
6279 struct csr_roam_info *roam_info,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306280 const u8 *req_ie, size_t req_ie_len,
6281 const u8 *resp_ie, size_t resp_ie_len, u16 status,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006282 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306283 tSirResultCodes timeout_reason)
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306284{
6285 struct cfg80211_connect_resp_params fils_params;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306286 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6287 struct fils_join_rsp_params *roam_fils_params =
6288 roam_info->fils_join_rsp;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006289
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306290 qdf_mem_zero(&fils_params, sizeof(fils_params));
6291
6292 if (!roam_fils_params) {
6293 fils_params.status = WLAN_STATUS_UNSPECIFIED_FAILURE;
6294 } else {
6295 fils_params.status = status;
6296 fils_params.bssid = bssid;
Srinivas Girigowdae975f532018-01-05 14:03:05 -08006297 fils_params.timeout_reason =
6298 hdd_convert_timeout_reason(timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306299 fils_params.req_ie = req_ie;
6300 fils_params.req_ie_len = req_ie_len;
6301 fils_params.resp_ie = resp_ie;
6302 fils_params.resp_ie_len = resp_ie_len;
6303 fils_params.bss = bss;
6304 hdd_populate_fils_params(&fils_params, roam_fils_params->kek,
6305 roam_fils_params->kek_len,
6306 roam_fils_params->fils_pmk,
6307 roam_fils_params->fils_pmk_len,
6308 roam_fils_params->fils_pmkid,
6309 roam_info->fils_seq_num);
Sridhar Selvaraje5260442017-08-19 10:12:03 +05306310 hdd_save_gtk_params(adapter, roam_info, false);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306311 }
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306312 hdd_debug("FILS indicate connect status %d", fils_params.status);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306313
6314 cfg80211_connect_done(dev, &fils_params, gfp);
6315
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306316 if (roam_fils_params && roam_fils_params->hlp_data_len)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306317 hdd_update_hlp_info(dev, roam_info);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306318
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306319 /* Clear all the FILS key info */
6320 if (roam_fils_params && roam_fils_params->fils_pmk)
6321 qdf_mem_free(roam_fils_params->fils_pmk);
6322 if (roam_fils_params)
6323 qdf_mem_free(roam_fils_params);
6324 roam_info->fils_join_rsp = NULL;
6325}
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306326#else /* CFG80211_CONNECT_DONE */
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006327static inline void
6328hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006329 struct cfg80211_bss *bss, struct csr_roam_info *roam_info,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006330 const u8 *req_ie, size_t req_ie_len,
6331 const u8 *resp_ie, size_t resp_ie_len, u16 status,
6332 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306333 tSirResultCodes timeout_reason)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306334{ }
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306335#endif
Pragaspathi Thilagaraj9e619082019-01-24 15:15:45 +05306336#endif /* WLAN_FEATURE_FILS_SK */
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306337
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306338#if defined(WLAN_FEATURE_FILS_SK) && \
6339 (defined(CFG80211_CONNECT_DONE) || \
6340 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306341/**
6342 * hdd_fils_update_connect_results() - API to send fils connection status to
6343 * supplicant.
6344 * @dev: network device
6345 * @bssid: bssid to which we want to associate
6346 * @bss: cfg80211 bss info
6347 * @roam_info: information about connected bss
6348 * @req_ie: Request Information Element
6349 * @req_ie_len: len of the req IE
6350 * @resp_ie: Response IE
6351 * @resp_ie_len: len of ht response IE
6352 * @status: status
6353 * @gfp: allocation flags
6354 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
6355 * @timeout_reason: reason for connect timeout
6356 *
6357 * The API is a wrapper to send connection status to supplicant
6358 *
6359 * Return: 0 if success else failure
6360 */
6361static int hdd_fils_update_connect_results(struct net_device *dev,
6362 const u8 *bssid,
6363 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08006364 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306365 size_t req_ie_len, const u8 *resp_ie,
6366 size_t resp_ie_len, u16 status, gfp_t gfp,
6367 bool connect_timeout,
6368 tSirResultCodes timeout_reason)
6369{
Dustin Brown491d54b2018-03-14 12:39:11 -07006370 hdd_enter();
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306371 if (!roam_info || !roam_info->is_fils_connection)
6372 return -EINVAL;
6373
6374 hdd_connect_done(dev, bssid, bss, roam_info, req_ie, req_ie_len,
6375 resp_ie, resp_ie_len, status, gfp, connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306376 timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306377 return 0;
6378}
6379#else
6380static inline int hdd_fils_update_connect_results(struct net_device *dev,
6381 const u8 *bssid,
6382 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08006383 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306384 size_t req_ie_len, const u8 *resp_ie,
6385 size_t resp_ie_len, u16 status, gfp_t gfp,
6386 bool connect_timeout,
6387 tSirResultCodes timeout_reason)
6388{
6389 return -EINVAL;
6390}
6391#endif
6392
Anurag Chouhanc4092922016-09-08 15:56:11 +05306393/**
6394 * hdd_connect_result() - API to send connection status to supplicant
6395 * @dev: network device
6396 * @bssid: bssid to which we want to associate
6397 * @roam_info: information about connected bss
6398 * @req_ie: Request Information Element
6399 * @req_ie_len: len of the req IE
6400 * @resp_ie: Response IE
6401 * @resp_ie_len: len of ht response IE
6402 * @status: status
6403 * @gfp: Kernel Flag
Abhishek Singha84d3952016-09-13 13:45:05 +05306404 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306405 * @timeout_reason: reason for connect timeout
Anurag Chouhanc4092922016-09-08 15:56:11 +05306406 *
6407 * The API is a wrapper to send connection status to supplicant
6408 * and allow runtime suspend
6409 *
6410 * Return: Void
6411 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05306412void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006413 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306414 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05306415 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306416 bool connect_timeout,
6417 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05306418{
Jeff Johnsona1382382019-03-31 11:08:27 -07006419 struct hdd_adapter *adapter = netdev_priv(dev);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306420 struct cfg80211_bss *bss = NULL;
Jeff Johnsona1382382019-03-31 11:08:27 -07006421 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306422
6423 if (WLAN_STATUS_SUCCESS == status) {
6424 struct ieee80211_channel *chan;
6425 int freq;
6426 int chan_no = roam_info->pBssDesc->channelId;
6427
6428 if (chan_no <= 14)
6429 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07006430 HDD_NL80211_BAND_2GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306431 else
6432 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07006433 HDD_NL80211_BAND_5GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306434
Jeff Johnsona1382382019-03-31 11:08:27 -07006435 chan = ieee80211_get_channel(adapter->wdev.wiphy, freq);
6436 bss = wlan_cfg80211_get_bss(adapter->wdev.wiphy, chan, bssid,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306437 roam_info->u.pConnectedProfile->SSID.ssId,
6438 roam_info->u.pConnectedProfile->SSID.length);
6439 }
Komal Seelama89be8d2016-09-29 11:09:26 +05306440
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306441 if (hdd_fils_update_connect_results(dev, bssid, bss,
6442 roam_info, req_ie, req_ie_len, resp_ie,
6443 resp_ie_len, status, gfp, connect_timeout,
6444 timeout_reason) != 0) {
6445 hdd_connect_bss(dev, bssid, bss, req_ie,
6446 req_ie_len, resp_ie, resp_ie_len,
6447 status, gfp, connect_timeout, timeout_reason);
6448 }
Komal Seelama89be8d2016-09-29 11:09:26 +05306449
Jingxiang Geb49aa302018-01-17 20:54:15 +08006450 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07006451 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306452}
6453#else
6454void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006455 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306456 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05306457 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306458 bool connect_timeout,
6459 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05306460{
Jeff Johnsona1382382019-03-31 11:08:27 -07006461 struct hdd_adapter *adapter = netdev_priv(dev);
6462 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Komal Seelama89be8d2016-09-29 11:09:26 +05306463
Anurag Chouhanc4092922016-09-08 15:56:11 +05306464 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
6465 resp_ie, resp_ie_len, status, gfp);
Prashanth Bhatta87b6dc02017-01-19 15:17:58 -08006466
Jingxiang Geb49aa302018-01-17 20:54:15 +08006467 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07006468 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306469}
6470#endif
6471
Nirav Shah73713f72018-05-17 14:50:41 +05306472#ifdef FEATURE_MONITOR_MODE_SUPPORT
Jeff Johnsond9952752018-04-18 12:15:35 -07006473int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
6474 uint32_t bandwidth)
6475{
6476 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6477 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
6478 struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info;
6479 QDF_STATUS status;
Jeff Johnson43837af2018-10-17 12:44:05 -07006480 mac_handle_t mac_handle = hdd_ctx->mac_handle;
Jeff Johnsond9952752018-04-18 12:15:35 -07006481 struct qdf_mac_addr bssid;
6482 struct csr_roam_profile roam_profile;
6483 struct ch_params ch_params;
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006484 eConnectionState connstate;
Jeff Johnsond9952752018-04-18 12:15:35 -07006485
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006486 if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
6487 adapter->device_mode != QDF_STA_MODE) {
6488 hdd_err("Not supported, device is not in monitor mode or sta mission mode");
Jeff Johnsond9952752018-04-18 12:15:35 -07006489 return -EINVAL;
6490 }
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006491 if (adapter->device_mode == QDF_STA_MODE &&
Pragaspathi Thilagaraja8893752019-02-06 19:58:59 +05306492 ucfg_mlme_is_change_channel_bandwidth_enabled(hdd_ctx->psoc)) {
Jeff Johnsone7951512019-02-27 10:02:51 -08006493 connstate = sta_ctx->conn_info.conn_state;
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006494 if (eConnectionState_Associated == connstate ||
6495 eConnectionState_Connecting == connstate) {
6496 return -EINVAL;
6497 }
6498 }
Jeff Johnsond9952752018-04-18 12:15:35 -07006499
Visweswara Tanuku006313a2018-04-12 12:26:34 +05306500 /* Validate Channel */
6501 if (!WLAN_REG_IS_24GHZ_CH(chan) && !WLAN_REG_IS_5GHZ_CH(chan)) {
6502 hdd_err("Channel %d Not supported", chan);
6503 return -EINVAL;
6504 }
6505
6506 if (WLAN_REG_IS_24GHZ_CH(chan)) {
6507 if (bandwidth == CH_WIDTH_80MHZ) {
6508 hdd_err("BW80 not possible in 2.4GHz band");
6509 return -EINVAL;
6510 }
6511 if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 14) &&
6512 (bandwidth != CH_WIDTH_MAX)) {
6513 hdd_err("Only BW20 possible on channel 14");
6514 return -EINVAL;
6515 }
6516 }
6517
6518 if (WLAN_REG_IS_5GHZ_CH(chan)) {
6519 if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 165) &&
6520 (bandwidth != CH_WIDTH_MAX)) {
6521 hdd_err("Only BW20 possible on channel 165");
6522 return -EINVAL;
6523 }
6524 }
6525
Jeff Johnsond9952752018-04-18 12:15:35 -07006526 hdd_debug("Set monitor mode Channel %d", chan);
6527 qdf_mem_zero(&roam_profile, sizeof(roam_profile));
6528 roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
6529 roam_profile.ChannelInfo.numOfChannels = 1;
6530 roam_profile.phyMode = ch_info->phy_mode;
6531 roam_profile.ch_params.ch_width = bandwidth;
6532 hdd_select_cbmode(adapter, chan, &roam_profile.ch_params);
Pragaspathi Thilagaraja8893752019-02-06 19:58:59 +05306533 if (ucfg_mlme_is_change_channel_bandwidth_enabled(hdd_ctx->psoc) &&
Jeff Johnson43837af2018-10-17 12:44:05 -07006534 (!sme_find_session_by_bssid(mac_handle, adapter->mac_addr.bytes))) {
6535 status = sme_create_mon_session(mac_handle,
Rajeev Kumar Sirasanagandlae3b59912018-08-24 15:53:31 +05306536 adapter->mac_addr.bytes,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08006537 adapter->vdev_id);
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006538 if (status != QDF_STATUS_SUCCESS) {
6539 hdd_err("Status: %d Failed to create session.",
6540 status);
6541 return qdf_status_to_os_return(status);
6542 }
6543 }
Jeff Johnsond9952752018-04-18 12:15:35 -07006544 qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
6545 QDF_MAC_ADDR_SIZE);
6546
6547 ch_params.ch_width = bandwidth;
Dustin Brown07901ec2018-09-07 11:02:41 -07006548 wlan_reg_set_channel_params(hdd_ctx->pdev, chan, 0, &ch_params);
Jeff Johnsond9952752018-04-18 12:15:35 -07006549 if (ch_params.ch_width == CH_WIDTH_INVALID) {
6550 hdd_err("Invalid capture channel or bandwidth for a country");
6551 return -EINVAL;
6552 }
6553 if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan,
6554 POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
6555 hdd_err("Failed to change hw mode");
6556 return -EINVAL;
6557 }
6558
Jeff Johnson16528362018-06-14 12:34:16 -07006559 status = sme_roam_channel_change_req(hdd_ctx->mac_handle,
6560 bssid, &ch_params,
Jeff Johnsond9952752018-04-18 12:15:35 -07006561 &roam_profile);
6562 if (status) {
6563 hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
6564 status);
6565 }
6566
6567 adapter->mon_chan = chan;
6568 adapter->mon_bandwidth = bandwidth;
6569 return qdf_status_to_os_return(status);
6570}
Nirav Shah73713f72018-05-17 14:50:41 +05306571#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05306572
Wu Gaodf929f12018-05-25 18:12:25 +08006573#ifdef MSM_PLATFORM
6574/**
6575 * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO
6576 * @adapter: pointer to adapter
6577 *
6578 * This function calls cfg80211 API to stop P2P GO
6579 *
6580 * Return: None
6581 */
6582static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
6583{
6584 hdd_debug("[SSR] send stop ap to supplicant");
6585 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
6586}
6587
6588static inline void hdd_delete_sta(struct hdd_adapter *adapter)
6589{
6590}
6591#else
6592static inline void hdd_stop_p2p_go(struct hdd_adapter *adapter)
6593{
6594}
6595
6596/**
6597 * hdd_delete_sta() - call cfg80211 API to delete STA
6598 * @adapter: pointer to adapter
6599 *
6600 * This function calls cfg80211 API to delete STA
6601 *
6602 * Return: None
6603 */
6604static void hdd_delete_sta(struct hdd_adapter *adapter)
6605{
6606 struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
6607
6608 hdd_debug("[SSR] send restart supplicant");
6609 /* event supplicant to restart */
6610 cfg80211_del_sta(adapter->dev,
6611 (const u8 *)&bcast_mac.bytes[0],
6612 GFP_KERNEL);
6613}
6614#endif
6615
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006616QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006617{
Jeff Johnson9d295242017-08-29 14:39:48 -07006618 struct hdd_adapter *adapter;
Jeff Johnsone7951512019-02-27 10:02:51 -08006619 eConnectionState conn_state;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05306620 bool value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006621
Dustin Brown491d54b2018-03-14 12:39:11 -07006622 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006623
Dustin Brown920397d2017-12-13 16:27:50 -08006624 hdd_for_each_adapter(hdd_ctx, adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05306625 if (!hdd_is_interface_up(adapter))
Dustin Brown920397d2017-12-13 16:27:50 -08006626 continue;
Arun Khandavallifae92942016-08-01 13:31:08 +05306627
Yue Ma42654682018-01-11 16:55:24 -08006628 hdd_debug("[SSR] start adapter with device mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07006629 qdf_opmode_str(adapter->device_mode),
Yue Ma42654682018-01-11 16:55:24 -08006630 adapter->device_mode);
6631
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006632 hdd_wmm_init(adapter);
6633
6634 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006635 case QDF_STA_MODE:
6636 case QDF_P2P_CLIENT_MODE:
6637 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006638
Jeff Johnsone7951512019-02-27 10:02:51 -08006639 conn_state = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
6640 ->conn_info.conn_state;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006641
Krunal Sonib51eec72017-11-20 21:53:01 -08006642 hdd_start_station_adapter(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006643 /* Open the gates for HDD to receive Wext commands */
Jeff Johnsonc72c5732017-10-28 12:49:37 -07006644 adapter->is_link_up_service_needed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006645
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006646 /* Indicate disconnect event to supplicant
6647 * if associated previously
6648 */
Jeff Johnsone7951512019-02-27 10:02:51 -08006649 if (eConnectionState_Associated == conn_state ||
6650 eConnectionState_IbssConnected == conn_state ||
6651 eConnectionState_NotConnected == conn_state ||
6652 eConnectionState_IbssDisconnected == conn_state ||
6653 eConnectionState_Disconnecting == conn_state) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006654 union iwreq_data wrqu;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006655
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006656 memset(&wrqu, '\0', sizeof(wrqu));
6657 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6658 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
6659 wireless_send_event(adapter->dev, SIOCGIWAP,
6660 &wrqu, NULL);
Jeff Johnsonb9424862017-10-30 08:49:35 -07006661 adapter->session.station.
Jeff Johnson690fe952017-10-25 11:48:39 -07006662 hdd_reassoc_scenario = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006663
6664 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05306665 wlan_hdd_cfg80211_indicate_disconnect(
6666 adapter->dev, false,
6667 WLAN_REASON_UNSPECIFIED);
Jeff Johnsone7951512019-02-27 10:02:51 -08006668 } else if (eConnectionState_Connecting == conn_state) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006669 /*
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006670 * Indicate connect failure to supplicant if we
6671 * were in the process of connecting
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006672 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05306673 hdd_connect_result(adapter->dev, NULL, NULL,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306674 NULL, 0, NULL, 0,
6675 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006676 GFP_KERNEL, false, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006677 }
6678
6679 hdd_register_tx_flow_control(adapter,
6680 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08006681 hdd_tx_resume_cb,
6682 hdd_tx_flow_control_is_pause);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006683
Visweswara Tanukub5a61242019-03-26 12:24:13 +05306684 hdd_register_hl_netdev_fc_timer(
6685 adapter,
6686 hdd_tx_resume_timer_expired_handler);
6687
Arunk Khandavalli40943af2017-05-15 19:25:34 +05306688 hdd_lpass_notify_start(hdd_ctx, adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05306689 hdd_nud_ignore_tracking(adapter, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006690 break;
6691
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006692 case QDF_SAP_MODE:
Dustin Brown05d81302018-09-11 16:49:22 -07006693 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05306694 &value);
6695 if (value)
Krunal Sonib51eec72017-11-20 21:53:01 -08006696 hdd_start_ap_adapter(adapter);
Arun Khandavallicc544b32017-01-30 19:52:16 +05306697
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006698 break;
6699
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006700 case QDF_P2P_GO_MODE:
Wu Gaodf929f12018-05-25 18:12:25 +08006701 hdd_delete_sta(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006702 break;
Arunk Khandavalli062fb032017-10-04 12:18:15 +05306703 case QDF_MONITOR_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08006704 hdd_start_station_adapter(adapter);
Arunk Khandavalli062fb032017-10-04 12:18:15 +05306705 hdd_set_mon_rx_cb(adapter->dev);
6706 wlan_hdd_set_mon_chan(adapter, adapter->mon_chan,
6707 adapter->mon_bandwidth);
6708 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006709 default:
6710 break;
6711 }
Krunal Soni9c2ee032017-07-18 13:49:54 -07006712 /*
6713 * Action frame registered in one adapter which will
6714 * applicable to all interfaces
6715 */
6716 wlan_hdd_cfg80211_register_frames(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006717 }
6718
Wu Gaodf929f12018-05-25 18:12:25 +08006719 hdd_for_each_adapter(hdd_ctx, adapter) {
6720 if (!hdd_is_interface_up(adapter))
6721 continue;
6722
6723 if (adapter->device_mode == QDF_P2P_GO_MODE)
6724 hdd_stop_p2p_go(adapter);
6725 }
6726
Dustin Browne74003f2018-03-14 12:51:58 -07006727 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006728
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306729 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006730}
6731
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006732QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006733 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006734{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306735 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006736 qdf_list_node_t *node;
6737
6738 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006739
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006740 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006741 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006742 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006743
6744 if (QDF_IS_STATUS_ERROR(status))
6745 return status;
6746
6747 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6748
6749 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006750}
6751
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006752QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006753 struct hdd_adapter *current_adapter,
6754 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006755{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306756 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006757 qdf_list_node_t *node;
6758
6759 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006760
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006761 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Jeff Johnson19fc8e42017-10-30 19:53:49 -07006762 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
Dustin Brown920397d2017-12-13 16:27:50 -08006763 &current_adapter->node,
6764 &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006765 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006766
6767 if (QDF_IS_STATUS_ERROR(status))
6768 return status;
6769
6770 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6771
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006772 return status;
6773}
6774
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006775QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006776 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006777{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306778 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006779
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006780 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006781 status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006782 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006783
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006784 return status;
6785}
6786
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006787QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006788 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006789{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306790 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006791 qdf_list_node_t *node;
6792
6793 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006794
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006795 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006796 status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006797 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006798
6799 if (QDF_IS_STATUS_ERROR(status))
6800 return status;
6801
6802 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6803
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006804 return status;
6805}
6806
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006807QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006808 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006809{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306810 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006811
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006812 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006813 status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006814 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006815
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006816 return status;
6817}
6818
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006819QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006820 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006821{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306822 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006823
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006824 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006825 status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006826 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006827
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006828 return status;
6829}
6830
Liangwei Dong3abfe8f2018-09-20 02:25:44 -04006831struct hdd_adapter *hdd_get_adapter_by_rand_macaddr(
6832 struct hdd_context *hdd_ctx, tSirMacAddr mac_addr)
6833{
6834 struct hdd_adapter *adapter;
6835
6836 hdd_for_each_adapter(hdd_ctx, adapter) {
6837 if ((adapter->device_mode == QDF_STA_MODE ||
6838 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6839 adapter->device_mode == QDF_P2P_DEVICE_MODE) &&
6840 ucfg_p2p_check_random_mac(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08006841 adapter->vdev_id, mac_addr))
Liangwei Dong3abfe8f2018-09-20 02:25:44 -04006842 return adapter;
6843 }
6844
6845 return NULL;
6846}
6847
Jeff Johnson9d295242017-08-29 14:39:48 -07006848struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07006849 tSirMacAddr mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006850{
Jeff Johnson9d295242017-08-29 14:39:48 -07006851 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006852
Dustin Brown920397d2017-12-13 16:27:50 -08006853 hdd_for_each_adapter(hdd_ctx, adapter) {
6854 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
Jeff Johnsonaa6cbb82019-03-10 19:31:35 -07006855 mac_addr, sizeof(tSirMacAddr)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006856 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006857 }
6858
6859 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006860}
6861
Jeff Johnson9d295242017-08-29 14:39:48 -07006862struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
Jeff Johnson55d2ab42019-03-06 11:43:49 -08006863 uint32_t vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006864{
Jeff Johnson9d295242017-08-29 14:39:48 -07006865 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006866
Dustin Brown920397d2017-12-13 16:27:50 -08006867 hdd_for_each_adapter(hdd_ctx, adapter) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -08006868 if (adapter->vdev_id == vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006869 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006870 }
6871
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006872 return NULL;
6873}
6874
Jeff Johnson9d295242017-08-29 14:39:48 -07006875struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
Naveen Rawat4edb6822017-04-12 10:09:17 -07006876 const char *iface_name)
6877{
Jeff Johnson9d295242017-08-29 14:39:48 -07006878 struct hdd_adapter *adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07006879
Dustin Brown920397d2017-12-13 16:27:50 -08006880 hdd_for_each_adapter(hdd_ctx, adapter) {
6881 if (!qdf_str_cmp(adapter->dev->name, iface_name))
Naveen Rawat4edb6822017-04-12 10:09:17 -07006882 return adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07006883 }
Dustin Brown920397d2017-12-13 16:27:50 -08006884
Naveen Rawat4edb6822017-04-12 10:09:17 -07006885 return NULL;
6886}
6887
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006888/**
6889 * hdd_get_adapter() - to get adapter matching the mode
6890 * @hdd_ctx: hdd context
6891 * @mode: adapter mode
6892 *
6893 * This routine will return the pointer to adapter matching
6894 * with the passed mode.
6895 *
6896 * Return: pointer to adapter or null
6897 */
Jeff Johnson9d295242017-08-29 14:39:48 -07006898struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08006899 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006900{
Jeff Johnson9d295242017-08-29 14:39:48 -07006901 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006902
Dustin Brown920397d2017-12-13 16:27:50 -08006903 hdd_for_each_adapter(hdd_ctx, adapter) {
6904 if (adapter->device_mode == mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006905 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006906 }
6907
6908 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006909}
6910
Jeff Johnson55d2ab42019-03-06 11:43:49 -08006911enum QDF_OPMODE hdd_get_device_mode(uint32_t vdev_id)
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05306912{
6913 struct hdd_context *hdd_ctx;
6914 struct hdd_adapter *adapter;
6915
6916 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6917 if (!hdd_ctx) {
6918 hdd_err("Invalid HDD context");
6919 return QDF_MAX_NO_OF_MODE;
6920 }
6921
Jeff Johnson55d2ab42019-03-06 11:43:49 -08006922 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05306923 if (!adapter) {
6924 hdd_err("Invalid HDD adapter");
6925 return QDF_MAX_NO_OF_MODE;
6926 }
6927
6928 return adapter->device_mode;
6929}
6930
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006931/**
6932 * hdd_get_operating_channel() - return operating channel of the device mode
6933 * @hdd_ctx: Pointer to the HDD context.
6934 * @mode: Device mode for which operating channel is required.
Jeff Johnson77f89bb2018-05-06 16:21:36 -07006935 * Supported modes:
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006936 * QDF_STA_MODE,
6937 * QDF_P2P_CLIENT_MODE,
6938 * QDF_SAP_MODE,
6939 * QDF_P2P_GO_MODE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006940 *
6941 * This API returns the operating channel of the requested device mode
6942 *
6943 * Return: channel number. "0" id the requested device is not found OR it is
6944 * not connected.
6945 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006946uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08006947 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006948{
Jeff Johnson9d295242017-08-29 14:39:48 -07006949 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006950 uint8_t operatingChannel = 0;
6951
Dustin Brown920397d2017-12-13 16:27:50 -08006952 hdd_for_each_adapter(hdd_ctx, adapter) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006953 if (mode == adapter->device_mode) {
6954 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006955 case QDF_STA_MODE:
6956 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006957 if (hdd_conn_is_connected
6958 (WLAN_HDD_GET_STATION_CTX_PTR
6959 (adapter))) {
6960 operatingChannel =
6961 (WLAN_HDD_GET_STATION_CTX_PTR
6962 (adapter))->conn_info.
Jeff Johnson8626e932019-02-27 18:35:22 -08006963 channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006964 }
6965 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006966 case QDF_SAP_MODE:
6967 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006968 /* softap connection info */
6969 if (test_bit
6970 (SOFTAP_BSS_STARTED,
6971 &adapter->event_flags))
6972 operatingChannel =
6973 (WLAN_HDD_GET_AP_CTX_PTR
Jeff Johnson01206862017-10-27 20:55:59 -07006974 (adapter))->operating_channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006975 break;
6976 default:
6977 break;
6978 }
6979
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006980 /* Found the device of interest. break the loop */
6981 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006982 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006983 }
Dustin Brown920397d2017-12-13 16:27:50 -08006984
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006985 return operatingChannel;
6986}
6987
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006988static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006989 hdd_ctx)
6990{
Jeff Johnson9d295242017-08-29 14:39:48 -07006991 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006992
Dustin Brown491d54b2018-03-14 12:39:11 -07006993 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006994
Dustin Brown920397d2017-12-13 16:27:50 -08006995 hdd_for_each_adapter(hdd_ctx, adapter) {
6996 if (adapter->device_mode == QDF_STA_MODE ||
6997 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6998 adapter->device_mode == QDF_IBSS_MODE ||
6999 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
7000 adapter->device_mode == QDF_SAP_MODE ||
7001 adapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007002 hdd_unregister_wext(adapter->dev);
7003 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007004 }
7005
Dustin Browne74003f2018-03-14 12:51:58 -07007006 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007007
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307008 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007009}
7010
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007011QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007012{
Jeff Johnson9d295242017-08-29 14:39:48 -07007013 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007014
Dustin Brown491d54b2018-03-14 12:39:11 -07007015 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007016
Dustin Brown920397d2017-12-13 16:27:50 -08007017 hdd_for_each_adapter(hdd_ctx, adapter) {
7018 if (adapter->device_mode == QDF_STA_MODE ||
7019 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
7020 adapter->device_mode == QDF_IBSS_MODE ||
7021 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
7022 adapter->device_mode == QDF_SAP_MODE ||
7023 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brown07901ec2018-09-07 11:02:41 -07007024 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08007025 adapter->vdev_id, INVALID_SCAN_ID,
Vignesh Viswanathan19611c82018-01-16 16:20:40 +05307026 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007027 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007028 }
7029
Dustin Browne74003f2018-03-14 12:51:58 -07007030 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007031
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307032 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007033}
7034
Dustin Brownf27bce82016-11-03 12:52:27 -07007035/**
7036 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
7037 * adapters
7038 * @hdd_ctx: The HDD context containing the adapters to operate on
7039 *
7040 * return: QDF_STATUS_SUCCESS
7041 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007042static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
Dustin Brownf27bce82016-11-03 12:52:27 -07007043{
Jeff Johnson9d295242017-08-29 14:39:48 -07007044 struct hdd_adapter *adapter;
Dustin Brownf27bce82016-11-03 12:52:27 -07007045 int err;
7046
Dustin Brown491d54b2018-03-14 12:39:11 -07007047 hdd_enter();
Dustin Brownf27bce82016-11-03 12:52:27 -07007048
Dustin Brown920397d2017-12-13 16:27:50 -08007049 hdd_for_each_adapter(hdd_ctx, adapter) {
7050 if (adapter->device_mode == QDF_STA_MODE ||
7051 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
7052 adapter->device_mode == QDF_IBSS_MODE ||
7053 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
7054 adapter->device_mode == QDF_SAP_MODE ||
7055 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brownf27bce82016-11-03 12:52:27 -07007056 err = wlan_hdd_sched_scan_stop(adapter->dev);
7057 if (err)
7058 hdd_err("Unable to stop scheduled scan");
7059 }
Dustin Brownf27bce82016-11-03 12:52:27 -07007060 }
7061
Dustin Browne74003f2018-03-14 12:51:58 -07007062 hdd_exit();
Dustin Brownf27bce82016-11-03 12:52:27 -07007063
7064 return QDF_STATUS_SUCCESS;
7065}
7066
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007067#ifdef WLAN_NS_OFFLOAD
7068/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007069 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007070 * @hdd_ctx: Pointer to hdd context
7071 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007072 * Unregister for IPv6 address change notifications.
7073 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007074 * Return: None
7075 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007076static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007077{
7078 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007079}
7080
7081/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007082 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007083 * @hdd_ctx: Pointer to hdd context
7084 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007085 * Register for IPv6 address change notifications.
7086 *
7087 * Return: 0 on success and errno on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007088 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007089static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007090{
7091 int ret;
7092
7093 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
7094 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007095 if (ret) {
7096 hdd_err("Failed to register IPv6 notifier: %d", ret);
7097 goto out;
7098 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007099
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007100 hdd_debug("Registered IPv6 notifier");
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007101out:
7102 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007103}
7104#else
7105/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007106 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007107 * @hdd_ctx: Pointer to hdd context
7108 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007109 * Unregister for IPv6 address change notifications.
7110 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007111 * Return: None
7112 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007113static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007114{
7115}
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007116
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007117/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007118 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007119 * @hdd_ctx: Pointer to hdd context
7120 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007121 * Register for IPv6 address change notifications.
7122 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007123 * Return: None
7124 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007125static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007126{
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007127 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007128}
7129#endif
7130
Alok Kumarb64650c2018-03-23 17:05:11 +05307131void hdd_set_disconnect_status(struct hdd_adapter *adapter, bool status)
7132{
7133 qdf_mutex_acquire(&adapter->disconnection_status_lock);
7134 adapter->disconnection_in_progress = status;
7135 qdf_mutex_release(&adapter->disconnection_status_lock);
7136 hdd_debug("setting disconnection status: %d", status);
7137}
7138
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007139/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007140 * hdd_register_notifiers - Register netdev notifiers.
7141 * @hdd_ctx: HDD context
7142 *
7143 * Register netdev notifiers like IPv4 and IPv6.
7144 *
7145 * Return: 0 on success and errno on failure
7146 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007147static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007148{
7149 int ret;
7150
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007151 ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
7152 if (ret)
Arun Khandavalli08479ba2017-08-07 19:56:23 +05307153 goto out;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007154
7155 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
7156 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
7157 if (ret) {
7158 hdd_err("Failed to register IPv4 notifier: %d", ret);
7159 goto unregister_ip6_notifier;
7160 }
7161
Alok Kumarb64650c2018-03-23 17:05:11 +05307162 ret = hdd_nud_register_netevent_notifier(hdd_ctx);
7163 if (ret) {
7164 hdd_err("Failed to register netevent notifier: %d",
7165 ret);
7166 goto unregister_inetaddr_notifier;
7167 }
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007168 return 0;
7169
Alok Kumarb64650c2018-03-23 17:05:11 +05307170unregister_inetaddr_notifier:
7171 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007172unregister_ip6_notifier:
7173 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007174out:
7175 return ret;
7176
7177}
7178
7179/**
7180 * hdd_unregister_notifiers - Unregister netdev notifiers.
7181 * @hdd_ctx: HDD context
7182 *
7183 * Unregister netdev notifiers like IPv4 and IPv6.
7184 *
7185 * Return: None.
7186 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007187void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007188{
Alok Kumarb64650c2018-03-23 17:05:11 +05307189 hdd_nud_unregister_netevent_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007190 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
7191
7192 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007193}
7194
7195/**
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007196 * hdd_exit_netlink_services - Exit netlink services
7197 * @hdd_ctx: HDD context
7198 *
7199 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
7200 * nl service.
7201 *
7202 * Return: None.
7203 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007204static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007205{
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307206 spectral_scan_deactivate_service();
7207 cnss_diag_deactivate_service();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007208 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007209 ptt_sock_deactivate_svc();
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307210 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007211
7212 nl_srv_exit();
7213}
7214
7215/**
7216 * hdd_init_netlink_services- Init netlink services
7217 * @hdd_ctx: HDD context
7218 *
7219 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
7220 * nl service.
7221 *
7222 * Return: 0 on success and errno on failure.
7223 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007224static int hdd_init_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007225{
7226 int ret;
7227
Ryan Hsuceddceb2016-04-28 10:20:14 -07007228 ret = wlan_hdd_nl_init(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007229 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007230 hdd_err("nl_srv_init failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007231 goto out;
7232 }
Ryan Hsuceddceb2016-04-28 10:20:14 -07007233 cds_set_radio_index(hdd_ctx->radio_index);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007234
Naveen Rawat910726a2017-03-06 11:42:51 -08007235 ret = hdd_activate_wifi_pos(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007236 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007237 hdd_err("hdd_activate_wifi_pos failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007238 goto err_nl_srv;
7239 }
7240
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307241 ptt_sock_activate_svc();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007242
7243 ret = hdd_open_cesium_nl_sock();
Ryan Hsu5e2e2052016-04-28 10:19:38 -07007244 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007245 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007246
7247 ret = cnss_diag_activate_service();
7248 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007249 hdd_err("cnss_diag_activate_service failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007250 goto err_close_cesium;
7251 }
7252
Dustin Brown01520852019-02-27 12:14:16 -08007253 spectral_scan_activate_service(hdd_ctx);
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -08007254
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007255 return 0;
7256
7257err_close_cesium:
7258 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007259 ptt_sock_deactivate_svc();
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307260 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007261err_nl_srv:
7262 nl_srv_exit();
7263out:
7264 return ret;
7265}
7266
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007267/**
7268 * hdd_rx_wake_lock_destroy() - Destroy RX wakelock
7269 * @hdd_ctx: HDD context.
7270 *
7271 * Destroy RX wakelock.
7272 *
7273 * Return: None.
7274 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007275static void hdd_rx_wake_lock_destroy(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007276{
7277 qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
7278}
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007279
7280/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007281 * hdd_rx_wake_lock_create() - Create RX wakelock
7282 * @hdd_ctx: HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007283 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007284 * Create RX wakelock.
7285 *
7286 * Return: None.
7287 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007288static void hdd_rx_wake_lock_create(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007289{
7290 qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
7291}
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007292
7293/**
Houston Hoffman160db392016-10-10 17:37:51 -07007294 * hdd_context_deinit() - Deinitialize HDD context
7295 * @hdd_ctx: HDD context.
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007296 *
Houston Hoffman160db392016-10-10 17:37:51 -07007297 * Deinitialize HDD context along with all the feature specific contexts but
7298 * do not free hdd context itself. Caller of this API is supposed to free
7299 * HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007300 *
Houston Hoffman160db392016-10-10 17:37:51 -07007301 * return: 0 on success and errno on failure.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007302 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007303static int hdd_context_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007304{
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05307305 qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock);
7306
Houston Hoffman160db392016-10-10 17:37:51 -07007307 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007308
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007309 hdd_sap_context_destroy(hdd_ctx);
7310
7311 hdd_rx_wake_lock_destroy(hdd_ctx);
7312
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007313 hdd_scan_context_destroy(hdd_ctx);
7314
Jeff Johnson19fc8e42017-10-30 19:53:49 -07007315 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007316
Houston Hoffman160db392016-10-10 17:37:51 -07007317 return 0;
7318}
7319
Dustin Brown623e7e32018-09-05 14:27:50 -07007320void hdd_context_destroy(struct hdd_context *hdd_ctx)
Houston Hoffman160db392016-10-10 17:37:51 -07007321{
Rajeev Kumar493a31b2017-09-29 14:01:24 -07007322 cds_set_context(QDF_MODULE_ID_HDD, NULL);
Arunk Khandavalli3d267b42017-05-02 18:58:59 +05307323
Dustin Brown623e7e32018-09-05 14:27:50 -07007324 hdd_exit_netlink_services(hdd_ctx);
Hanumantha Reddy Pothula00c74f62016-11-24 20:13:32 +05307325 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
7326
Houston Hoffman160db392016-10-10 17:37:51 -07007327 hdd_context_deinit(hdd_ctx);
7328
Dustin Browndb2df2e2018-10-31 15:29:24 -07007329 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
7330
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307331 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007332 hdd_ctx->config = NULL;
Dustin Brown84f46ea2018-02-15 11:57:36 -08007333 cfg_release();
7334
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007335 wiphy_free(hdd_ctx->wiphy);
7336}
7337
7338/**
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05307339 * wlan_destroy_bug_report_lock() - Destroy bug report lock
7340 *
7341 * This function is used to destroy bug report lock
7342 *
7343 * Return: None
7344 */
7345static void wlan_destroy_bug_report_lock(void)
7346{
Jeff Johnson2b6982c2018-05-29 14:56:11 -07007347 struct cds_context *p_cds_context;
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05307348
7349 p_cds_context = cds_get_global_context();
7350 if (!p_cds_context) {
7351 hdd_err("cds context is NULL");
7352 return;
7353 }
7354
7355 qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
7356}
7357
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +05307358#ifdef DISABLE_CHANNEL_LIST
7359static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
7360{
7361 qdf_mutex_destroy(&hdd_ctx->cache_channel_lock);
7362}
7363#else
7364static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
7365{
7366}
7367#endif
7368
Dustin Brown92bd8382018-10-31 15:49:46 -07007369void hdd_wlan_exit(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007370{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007371 struct wiphy *wiphy = hdd_ctx->wiphy;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007372
Dustin Brown491d54b2018-03-14 12:39:11 -07007373 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007374
Arun Kumar Khandavallideda5a82019-03-11 15:32:19 +05307375 hdd_debugfs_mws_coex_info_deinit(hdd_ctx);
Dustin Brown4c663222018-10-23 14:19:36 -07007376 hdd_psoc_idle_timer_stop(hdd_ctx);
Dustin Brown6470aba2018-09-05 09:49:58 -07007377
Arun Khandavallifae92942016-08-01 13:31:08 +05307378 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007379
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007380#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +05307381 if (QDF_TIMER_STATE_RUNNING ==
7382 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
7383 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007384 }
7385
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307386 if (!QDF_IS_STATUS_SUCCESS
Anurag Chouhan210db072016-02-22 18:42:15 +05307387 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
Jeff Johnson5880d792016-08-15 13:32:30 -07007388 hdd_err("Cannot deallocate ACS Skip timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007389 }
Liangwei Dongaef84342016-10-21 05:28:00 -04007390 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
7391 qdf_mem_free(hdd_ctx->last_acs_channel_list);
7392 hdd_ctx->last_acs_channel_list = NULL;
7393 hdd_ctx->num_of_channels = 0;
7394 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007395#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007396
7397 /*
7398 * Powersave Offload Case
7399 * Disable Idle Power Save Mode
7400 */
7401 hdd_set_idle_ps_config(hdd_ctx, false);
Sandeep Puligilla8fa28fd2017-11-02 12:19:33 -07007402 /* clear the scan queue in all the scenarios */
Dustin Brown07901ec2018-09-07 11:02:41 -07007403 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007404
Dustin Brownf688ea12019-03-19 17:02:32 -07007405 if (hdd_ctx->driver_status != DRIVER_MODULES_CLOSED) {
Arun Khandavallifae92942016-08-01 13:31:08 +05307406 hdd_unregister_wext_all_adapters(hdd_ctx);
7407 /*
7408 * Cancel any outstanding scan requests. We are about to close
7409 * all of our adapters, but an adapter structure is what SME
7410 * passes back to our callback function. Hence if there
7411 * are any outstanding scan requests then there is a
7412 * race condition between when the adapter is closed and
7413 * when the callback is invoked. We try to resolve that
7414 * race condition here by canceling any outstanding scans
7415 * before we close the adapters.
7416 * Note that the scans may be cancelled in an asynchronous
7417 * manner, so ideally there needs to be some kind of
7418 * synchronization. Rather than introduce a new
7419 * synchronization here, we will utilize the fact that we are
7420 * about to Request Full Power, and since that is synchronized,
7421 * the expectation is that by the time Request Full Power has
7422 * completed, all scans will be cancelled
7423 */
7424 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Dustin Brownf27bce82016-11-03 12:52:27 -07007425 hdd_abort_sched_scan_all_adapters(hdd_ctx);
Dustin Browndb2a8be2017-12-20 11:49:56 -08007426 hdd_stop_all_adapters(hdd_ctx);
bings29c99862017-11-01 13:54:13 +08007427 hdd_deinit_all_adapters(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007428 }
7429
Arunk Khandavalli830c9692018-03-22 12:17:40 +05307430 unregister_reboot_notifier(&system_reboot_notifier);
Arun Khandavalli08479ba2017-08-07 19:56:23 +05307431 unregister_netdevice_notifier(&hdd_netdev_notifier);
7432
Rachit Kankane30807332018-06-27 18:39:36 +05307433 qdf_dp_trace_deinit();
7434
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07007435 hdd_wlan_stop_modules(hdd_ctx, false);
Hanumanth Reddy Pothula709a6362016-10-18 18:19:44 +05307436
Visweswara Tanukuc029a202018-11-27 10:42:10 +05307437 hdd_bus_bw_compute_timer_stop(hdd_ctx);
Dustin Brown86d196b2018-08-02 11:51:49 -07007438 hdd_bus_bandwidth_deinit(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -08007439 hdd_driver_memdump_deinit();
7440
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +05307441 qdf_nbuf_deinit_replenish_timer();
7442
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05307443 if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) {
7444 hdd_info("Release wakelock for monitor mode!");
7445 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
7446 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
7447 }
7448
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307449 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307450 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +05307451 wlan_hdd_cache_chann_mutex_destroy(hdd_ctx);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307452
Naveen Rawate02f8f52018-04-05 11:58:04 -07007453 osif_request_manager_deinit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007454
Dustin Brownd005ad82018-01-19 10:32:13 -08007455 hdd_close_all_adapters(hdd_ctx, false);
7456
Manishekar Chandrasekaranf7a1dad2016-06-23 06:43:47 +05307457 wlansap_global_deinit();
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05307458 /*
7459 * If there is re_init failure wiphy would have already de-registered
7460 * check the wiphy status before un-registering again
7461 */
Ashish Kumar Dhanotiyae16feb72017-03-31 19:39:37 +05307462 if (wiphy && wiphy->registered) {
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05307463 wiphy_unregister(wiphy);
7464 wlan_hdd_cfg80211_deinit(wiphy);
7465 hdd_lpass_notify_stop(hdd_ctx);
7466 }
Yuanyuan Liu3e918e52016-08-17 15:41:35 -07007467
Arun Khandavallifae92942016-08-01 13:31:08 +05307468 hdd_exit_netlink_services(hdd_ctx);
Dustin Brown8d8ab302019-03-05 16:19:36 -08007469 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05307470#ifdef FEATURE_WLAN_CH_AVOID
7471 mutex_destroy(&hdd_ctx->avoid_freq_lock);
7472#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007473}
7474
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007475#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Liangwei Dongaef84342016-10-21 05:28:00 -04007476/**
7477 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007478 * @data: pointer to struct hdd_context
Liangwei Dongaef84342016-10-21 05:28:00 -04007479 *
7480 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
7481 * Then new ACS request will do a fresh scan without reusing the cached
7482 * scan information.
7483 *
7484 * Return: void
7485 */
Tang Yingying523322d2017-01-17 23:28:43 +08007486static void hdd_skip_acs_scan_timer_handler(void *data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007487{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007488 struct hdd_context *hdd_ctx = (struct hdd_context *) data;
Jeff Johnson16528362018-06-14 12:34:16 -07007489 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007490
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007491 hdd_debug("ACS Scan result expired. Reset ACS scan skip");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007492 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
Liangwei Dongaef84342016-10-21 05:28:00 -04007493 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
7494 qdf_mem_free(hdd_ctx->last_acs_channel_list);
7495 hdd_ctx->last_acs_channel_list = NULL;
7496 hdd_ctx->num_of_channels = 0;
7497 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007498
Jeff Johnson16528362018-06-14 12:34:16 -07007499 mac_handle = hdd_ctx->mac_handle;
7500 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007501 return;
Jeff Johnson16528362018-06-14 12:34:16 -07007502 sme_scan_flush_result(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007503}
7504#endif
7505
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007506/**
7507 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
7508 * @state: state
7509 *
7510 * This function notifies FW with modem power status
7511 *
7512 * Return: 0 if successful, error number otherwise
7513 */
7514int hdd_wlan_notify_modem_power_state(int state)
7515{
7516 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307517 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007518 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -07007519 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007520
Anurag Chouhan6d760662016-02-20 16:05:43 +05307521 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007522 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307523 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007524 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307525
Jeff Johnson16528362018-06-14 12:34:16 -07007526 mac_handle = hdd_ctx->mac_handle;
7527 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007528 return -EINVAL;
7529
Jeff Johnson16528362018-06-14 12:34:16 -07007530 qdf_status = sme_notify_modem_power_state(mac_handle, state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307531 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007532 hdd_err("Fail to send notification with modem power state %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007533 state);
7534 return -EINVAL;
7535 }
7536 return 0;
7537}
7538
7539/**
7540 *
7541 * hdd_post_cds_enable_config() - HDD post cds start config helper
7542 * @adapter - Pointer to the HDD
7543 *
7544 * Return: None
7545 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007546QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007547{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307548 QDF_STATUS qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007549
7550 /*
7551 * Send ready indication to the HDD. This will kick off the MAC
7552 * into a 'running' state and should kick off an initial scan.
7553 */
Jeff Johnson16528362018-06-14 12:34:16 -07007554 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307555 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007556 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
7557 qdf_ret_status, qdf_ret_status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307558 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007559 }
7560
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307561 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007562}
7563
Sourav Mohapatra92ea8d62018-02-05 10:03:10 +05307564struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx)
7565{
7566 struct hdd_adapter *adapter;
7567
7568 hdd_for_each_adapter(hdd_ctx, adapter) {
7569 if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC)
7570 return adapter;
7571 }
7572
7573 return NULL;
7574}
7575
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007576/* wake lock APIs for HDD */
7577void hdd_prevent_suspend(uint32_t reason)
7578{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05307579 qdf_wake_lock_acquire(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007580}
7581
7582void hdd_allow_suspend(uint32_t reason)
7583{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05307584 qdf_wake_lock_release(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007585}
7586
7587void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
7588{
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05307589 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
7590 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007591}
7592
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007593/* Initialize channel list in sme based on the country code */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007594QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007595{
Jeff Johnson16528362018-06-14 12:34:16 -07007596 return sme_init_chan_list(hdd_ctx->mac_handle,
Amar Singhal6f8592b2017-04-26 14:31:58 -07007597 hdd_ctx->reg.alpha2,
7598 hdd_ctx->reg.cc_src);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007599}
7600
7601/**
7602 * hdd_is_5g_supported() - check if hardware supports 5GHz
7603 * @hdd_ctx: Pointer to the hdd context
7604 *
7605 * HDD function to know if hardware supports 5GHz
7606 *
7607 * Return: true if hardware supports 5GHz
7608 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007609bool hdd_is_5g_supported(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007610{
Amar Singhal58b45ef2017-08-01 13:43:54 -07007611 if (!hdd_ctx)
zdingf54169a2016-10-12 17:08:45 +08007612 return true;
7613
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08007614 if (hdd_ctx->curr_band != BAND_2G)
zdingf54169a2016-10-12 17:08:45 +08007615 return true;
7616 else
7617 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007618}
7619
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007620static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007621{
7622 struct wiphy *wiphy;
Amar Singhale4f28ee2015-10-21 14:36:56 -07007623 int ret_val;
Wu Gaoed616a12019-01-16 15:19:21 +08007624 uint32_t channel_bonding_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007625
7626 wiphy = hdd_ctx->wiphy;
7627
7628 /*
7629 * The channel information in
7630 * wiphy needs to be initialized before wiphy registration
7631 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07007632 ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
7633 if (ret_val) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007634 hdd_err("regulatory init failed");
Amar Singhale4f28ee2015-10-21 14:36:56 -07007635 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007636 }
7637
7638#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
7639 wiphy->wowlan = &wowlan_support_reg_init;
7640#else
7641 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
7642 WIPHY_WOWLAN_MAGIC_PKT |
7643 WIPHY_WOWLAN_DISCONNECT |
7644 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
7645 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
7646 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
7647 WIPHY_WOWLAN_4WAY_HANDSHAKE |
7648 WIPHY_WOWLAN_RFKILL_RELEASE;
7649
7650 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
7651 WOW_MAX_FILTERS_PER_LIST);
7652 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
7653 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
7654#endif
Wu Gaoed616a12019-01-16 15:19:21 +08007655 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
7656 &channel_bonding_mode);
Liangwei Dong0da14262018-07-03 03:30:23 -04007657 if (hdd_ctx->obss_scan_offload) {
7658 hdd_debug("wmi_service_obss_scan supported");
Wu Gaoed616a12019-01-16 15:19:21 +08007659 } else if (channel_bonding_mode) {
Liangwei Dong0da14262018-07-03 03:30:23 -04007660 hdd_debug("enable wpa_supp obss_scan");
7661 wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN;
7662 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007663
7664 /* registration of wiphy dev with cfg80211 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07007665 ret_val = wlan_hdd_cfg80211_register(wiphy);
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05307666 if (0 > ret_val) {
Amar Singhale4f28ee2015-10-21 14:36:56 -07007667 hdd_err("wiphy registration failed");
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05307668 return ret_val;
7669 }
Amar Singhalac26de22018-06-22 12:53:06 -07007670
Kiran Kumar Lokere0508af92018-04-23 18:38:32 -07007671 /* Check the kernel version for upstream commit aced43ce780dc5 that
7672 * has support for processing user cell_base hints when wiphy is
7673 * self managed or check the backport flag for the same.
7674 */
Amar Singhalac26de22018-06-22 12:53:06 -07007675#if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
7676 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
Kiran Kumar Lokere0508af92018-04-23 18:38:32 -07007677 hdd_send_wiphy_regd_sync_event(hdd_ctx);
7678#endif
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05307679
Amar Singhal2d812012018-02-03 15:06:47 +08007680 pld_increment_driver_load_cnt(hdd_ctx->parent_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007681
Amar Singhale4f28ee2015-10-21 14:36:56 -07007682 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007683}
7684
Mohit Khannaca4173b2017-09-12 21:52:19 -07007685#ifdef MSM_PLATFORM
7686/**
7687 * hdd_display_periodic_stats() - Function to display periodic stats
7688 * @hdd_ctx - handle to hdd context
7689 * @bool data_in_interval - true, if data detected in bw time interval
7690 *
7691 * The periodicity is determined by hdd_ctx->config->periodic_stats_disp_time.
7692 * Stats show up in wlan driver logs.
7693 *
7694 * Returns: None
7695 */
Mohit Khanna70322002018-05-15 19:21:32 -07007696static void hdd_display_periodic_stats(struct hdd_context *hdd_ctx,
7697 bool data_in_interval)
Mohit Khannaca4173b2017-09-12 21:52:19 -07007698{
Mohit Khanna70322002018-05-15 19:21:32 -07007699 static uint32_t counter;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007700 static bool data_in_time_period;
7701 ol_txrx_pdev_handle pdev;
Mohit Khanna81418772018-10-30 14:14:46 -07007702 ol_txrx_soc_handle soc;
Arif Hussaincca60432018-12-03 19:45:12 -08007703 uint32_t periodic_stats_disp_time = 0;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007704
Arif Hussaincca60432018-12-03 19:45:12 -08007705 ucfg_mlme_stats_get_periodic_display_time(hdd_ctx->psoc,
7706 &periodic_stats_disp_time);
7707 if (!periodic_stats_disp_time)
Mohit Khannaca4173b2017-09-12 21:52:19 -07007708 return;
7709
Mohit Khanna81418772018-10-30 14:14:46 -07007710 soc = cds_get_context(QDF_MODULE_ID_SOC);
7711 if (!soc) {
7712 hdd_err("soc is NULL");
7713 return;
7714 }
7715
Mohit Khannaca4173b2017-09-12 21:52:19 -07007716 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
7717 if (!pdev) {
7718 hdd_err("pdev is NULL");
7719 return;
7720 }
7721
7722 counter++;
7723 if (data_in_interval)
7724 data_in_time_period = data_in_interval;
7725
jitiphil869b9f72018-09-25 17:14:01 +05307726 if (counter * hdd_ctx->config->bus_bw_compute_interval >=
Arif Hussaincca60432018-12-03 19:45:12 -08007727 periodic_stats_disp_time * 1000) {
Mohit Khannaca4173b2017-09-12 21:52:19 -07007728 if (data_in_time_period) {
Mohit Khanna70322002018-05-15 19:21:32 -07007729 wlan_hdd_display_txrx_stats(hdd_ctx);
Mohit Khannac9649652018-11-28 18:10:28 -08007730 dp_txrx_ext_dump_stats(soc, CDP_DP_RX_THREAD_STATS);
Mohit Khanna81418772018-10-30 14:14:46 -07007731 cdp_display_stats(soc,
Mohit Khanna70322002018-05-15 19:21:32 -07007732 CDP_RX_RING_STATS,
7733 QDF_STATS_VERBOSITY_LEVEL_LOW);
Mohit Khanna81418772018-10-30 14:14:46 -07007734 cdp_display_stats(soc,
Mohit Khannaca4173b2017-09-12 21:52:19 -07007735 CDP_TXRX_PATH_STATS,
7736 QDF_STATS_VERBOSITY_LEVEL_LOW);
7737 wlan_hdd_display_netif_queue_history
7738 (hdd_ctx, QDF_STATS_VERBOSITY_LEVEL_LOW);
7739 qdf_dp_trace_dump_stats();
7740 }
7741 counter = 0;
7742 data_in_time_period = false;
7743 }
7744}
7745
Ravi Joshie2331e82015-07-01 18:18:54 -07007746/**
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007747 * hdd_clear_rps_cpu_mask - clear RPS CPU mask for interfaces
7748 * @hdd_ctx: pointer to struct hdd_context
7749 *
7750 * Return: none
7751 */
7752static void hdd_clear_rps_cpu_mask(struct hdd_context *hdd_ctx)
7753{
7754 struct hdd_adapter *adapter;
7755
7756 hdd_for_each_adapter(hdd_ctx, adapter)
7757 hdd_send_rps_disable_ind(adapter);
7758}
7759
7760/**
Yuanyuan Liu13738502016-04-06 17:41:37 -07007761 * hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
Ravi Joshie2331e82015-07-01 18:18:54 -07007762 * @hdd_ctx - handle to hdd context
7763 * @tx_packets - transmit packet count
7764 * @rx_packets - receive packet count
7765 *
7766 * The function controls the bus bandwidth and dynamic control of
7767 * tcp delayed ack configuration
7768 *
7769 * Returns: None
7770 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07007771
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007772static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07007773 const uint64_t tx_packets,
7774 const uint64_t rx_packets)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007775{
Mohit Khannaca4173b2017-09-12 21:52:19 -07007776 u64 total_pkts = tx_packets + rx_packets;
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007777 uint64_t temp_tx = 0, avg_rx = 0;
7778 uint64_t no_rx_offload_pkts = 0, avg_no_rx_offload_pkts = 0;
7779 uint64_t rx_offload_pkts = 0, avg_rx_offload_pkts = 0;
Yuanyuan Liu13738502016-04-06 17:41:37 -07007780 enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_NONE;
Mohit Khannac3da7062017-02-08 21:08:56 -08007781 static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
Mohit Khannae71e2262015-11-10 09:37:24 -08007782 enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
Ravi Joshib89e7f72016-09-07 13:43:15 -07007783 uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007784 uint16_t index = 0;
7785 bool vote_level_change = false;
7786 bool rx_level_change = false;
7787 bool tx_level_change = false;
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007788 bool rxthread_high_tput_req = false;
Mohit Khannaf7562c32018-07-05 17:42:36 -07007789 bool dptrace_high_tput_req;
Srinivas Girigowda50335342018-09-07 15:21:01 -07007790
jitiphil869b9f72018-09-25 17:14:01 +05307791 if (total_pkts > hdd_ctx->config->bus_bw_high_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007792 next_vote_level = PLD_BUS_WIDTH_HIGH;
jitiphil869b9f72018-09-25 17:14:01 +05307793 else if (total_pkts > hdd_ctx->config->bus_bw_medium_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007794 next_vote_level = PLD_BUS_WIDTH_MEDIUM;
jitiphil869b9f72018-09-25 17:14:01 +05307795 else if (total_pkts > hdd_ctx->config->bus_bw_low_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007796 next_vote_level = PLD_BUS_WIDTH_LOW;
Yue Mad6478e42015-10-20 18:49:24 -07007797 else
Yuanyuan Liu13738502016-04-06 17:41:37 -07007798 next_vote_level = PLD_BUS_WIDTH_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007799
Mohit Khannaf7562c32018-07-05 17:42:36 -07007800 dptrace_high_tput_req =
7801 next_vote_level > PLD_BUS_WIDTH_NONE ? true : false;
7802
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007803 if (hdd_ctx->cur_vote_level != next_vote_level) {
Ravi Joshie2331e82015-07-01 18:18:54 -07007804 hdd_debug("trigger level %d, tx_packets: %lld, rx_packets: %lld",
7805 next_vote_level, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007806 hdd_ctx->cur_vote_level = next_vote_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007807 vote_level_change = true;
Yuanyuan Liu13738502016-04-06 17:41:37 -07007808 pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level);
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007809 if ((next_vote_level == PLD_BUS_WIDTH_LOW) ||
7810 (next_vote_level == PLD_BUS_WIDTH_NONE)) {
Nirav Shahffc6a092016-06-09 16:09:08 +05307811 if (hdd_ctx->hbw_requested) {
7812 pld_remove_pm_qos(hdd_ctx->parent_dev);
7813 hdd_ctx->hbw_requested = false;
7814 }
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007815 if (hdd_ctx->dynamic_rps)
7816 hdd_clear_rps_cpu_mask(hdd_ctx);
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07007817 } else {
Nirav Shahffc6a092016-06-09 16:09:08 +05307818 if (!hdd_ctx->hbw_requested) {
7819 pld_request_pm_qos(hdd_ctx->parent_dev, 1);
7820 hdd_ctx->hbw_requested = true;
7821 }
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007822 if (hdd_ctx->dynamic_rps)
7823 hdd_set_rps_cpu_mask(hdd_ctx);
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07007824 }
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007825
Manjunathappa Prakashcb6df762018-05-29 18:54:58 -07007826 if (hdd_ctx->config->napi_cpu_affinity_mask)
7827 hdd_napi_apply_throughput_policy(hdd_ctx,
7828 tx_packets,
7829 rx_packets);
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007830
jitiphil869b9f72018-09-25 17:14:01 +05307831 if (rx_packets < hdd_ctx->config->bus_bw_low_threshold)
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007832 hdd_disable_rx_ol_for_low_tput(hdd_ctx, true);
7833 else
7834 hdd_disable_rx_ol_for_low_tput(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007835 }
Mohit Khannae71e2262015-11-10 09:37:24 -08007836
Mohit Khannaf7562c32018-07-05 17:42:36 -07007837 qdf_dp_trace_apply_tput_policy(dptrace_high_tput_req);
7838
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007839 /*
7840 * Includes tcp+udp, if perf core is required for tcp, then
7841 * perf core is also required for udp.
7842 */
7843 no_rx_offload_pkts = hdd_ctx->no_rx_offload_pkt_cnt;
7844 hdd_ctx->no_rx_offload_pkt_cnt = 0;
7845 rx_offload_pkts = rx_packets - no_rx_offload_pkts;
Mohit Khannae71e2262015-11-10 09:37:24 -08007846
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007847 avg_no_rx_offload_pkts = (no_rx_offload_pkts +
7848 hdd_ctx->prev_no_rx_offload_pkts) / 2;
7849 hdd_ctx->prev_no_rx_offload_pkts = no_rx_offload_pkts;
Mohit Khannab1dd1e82017-02-04 15:14:38 -08007850
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007851 avg_rx_offload_pkts = (rx_offload_pkts +
7852 hdd_ctx->prev_rx_offload_pkts) / 2;
7853 hdd_ctx->prev_rx_offload_pkts = rx_offload_pkts;
7854
7855 avg_rx = avg_no_rx_offload_pkts + avg_rx_offload_pkts;
7856 /*
7857 * Takes care to set Rx_thread affinity for below case
7858 * 1)LRO/GRO not supported ROME case
7859 * 2)when rx_ol is disabled in cases like concurrency etc
7860 * 3)For UDP cases
7861 */
7862 if (avg_no_rx_offload_pkts >
jitiphil869b9f72018-09-25 17:14:01 +05307863 hdd_ctx->config->bus_bw_high_threshold)
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007864 rxthread_high_tput_req = true;
Poddar, Siddarth47c23402017-10-25 12:17:39 +05307865 else
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007866 rxthread_high_tput_req = false;
Poddar, Siddarth47c23402017-10-25 12:17:39 +05307867
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007868 if (cds_sched_handle_throughput_req(rxthread_high_tput_req))
7869 hdd_warn("Rx thread high_tput(%d) affinity request failed",
7870 rxthread_high_tput_req);
7871
7872 /* fine-tuning parameters for RX Flows */
jitiphil869b9f72018-09-25 17:14:01 +05307873 if (avg_rx > hdd_ctx->config->tcp_delack_thres_high) {
Ravi Joshifed83572016-10-07 16:20:37 -07007874 if ((hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH) &&
7875 (++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt)) {
7876 next_rx_level = WLAN_SVC_TP_HIGH;
7877 }
Ravi Joshib89e7f72016-09-07 13:43:15 -07007878 } else {
Ravi Joshib89e7f72016-09-07 13:43:15 -07007879 hdd_ctx->rx_high_ind_cnt = 0;
Mohit Khannac3da7062017-02-08 21:08:56 -08007880 next_rx_level = WLAN_SVC_TP_LOW;
Ravi Joshib89e7f72016-09-07 13:43:15 -07007881 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007882
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007883 if (hdd_ctx->cur_rx_level != next_rx_level) {
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007884 struct wlan_rx_tp_data rx_tp_data = {0};
7885
Ravi Joshie2331e82015-07-01 18:18:54 -07007886 hdd_debug("TCP DELACK trigger level %d, average_rx: %llu",
Jeff Johnsonb9feee42018-07-08 10:34:48 -07007887 next_rx_level, avg_rx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007888 hdd_ctx->cur_rx_level = next_rx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007889 rx_level_change = true;
Ravi Joshie2331e82015-07-01 18:18:54 -07007890 /* Send throughput indication only if it is enabled.
7891 * Disabling tcp_del_ack will revert the tcp stack behavior
7892 * to default delayed ack. Note that this will disable the
7893 * dynamic delayed ack mechanism across the system
7894 */
Manjunathappa Prakashbfd12762018-04-29 22:44:52 -07007895 if (hdd_ctx->en_tcp_delack_no_lro)
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007896 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
7897
Mohit Khanna6272fb682017-04-13 09:34:36 -07007898 if (hdd_ctx->config->enable_tcp_adv_win_scale)
7899 rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
7900
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007901 rx_tp_data.level = next_rx_level;
Alok Kumar2fad6442018-11-08 19:19:28 +05307902 wlan_hdd_update_tcp_rx_param(hdd_ctx, &rx_tp_data);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007903 }
7904
Mohit Khannae71e2262015-11-10 09:37:24 -08007905 /* fine-tuning parameters for TX Flows */
7906 temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2;
7907 hdd_ctx->prev_tx = tx_packets;
7908 if (temp_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
7909 next_tx_level = WLAN_SVC_TP_HIGH;
7910 else
7911 next_tx_level = WLAN_SVC_TP_LOW;
7912
Prakash Manjunathappae73e3b52018-02-27 18:56:22 -08007913 if ((hdd_ctx->config->enable_tcp_limit_output) &&
7914 (hdd_ctx->cur_tx_level != next_tx_level)) {
Alok Kumar2fad6442018-11-08 19:19:28 +05307915 struct wlan_tx_tp_data tx_tp_data = {0};
7916
Mohit Khannae71e2262015-11-10 09:37:24 -08007917 hdd_debug("change TCP TX trigger level %d, average_tx: %llu",
7918 next_tx_level, temp_tx);
7919 hdd_ctx->cur_tx_level = next_tx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007920 tx_level_change = true;
Alok Kumar2fad6442018-11-08 19:19:28 +05307921 tx_tp_data.level = next_tx_level;
7922 tx_tp_data.tcp_limit_output = true;
7923 wlan_hdd_update_tcp_tx_param(hdd_ctx, &tx_tp_data);
Mohit Khannae71e2262015-11-10 09:37:24 -08007924 }
7925
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007926 index = hdd_ctx->hdd_txrx_hist_idx;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007927 if (vote_level_change || tx_level_change || rx_level_change) {
7928 hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level;
7929 hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level;
7930 hdd_ctx->hdd_txrx_hist[index].next_vote_level = next_vote_level;
7931 hdd_ctx->hdd_txrx_hist[index].interval_rx = rx_packets;
7932 hdd_ctx->hdd_txrx_hist[index].interval_tx = tx_packets;
7933 hdd_ctx->hdd_txrx_hist[index].qtime = qdf_get_log_timestamp();
7934 hdd_ctx->hdd_txrx_hist_idx++;
7935 hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
7936 }
Mohit Khannaca4173b2017-09-12 21:52:19 -07007937
7938 hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007939}
7940
7941#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
Dustin Browna20bad52019-03-05 12:03:30 -08007942static void __hdd_bus_bw_work_handler(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007943{
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05307944 struct hdd_adapter *adapter = NULL, *con_sap_adapter = NULL;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307945 uint64_t tx_packets = 0, rx_packets = 0;
Himanshu Agarwala6cedee2016-06-08 14:50:00 +05307946 uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
7947 uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007948 uint64_t total_tx = 0, total_rx = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307949 A_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007950 bool connected = false;
7951 uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
7952
Prashanth Bhattaab004382016-10-11 16:08:11 -07007953 if (wlan_hdd_validate_context(hdd_ctx))
Dustin Browna20bad52019-03-05 12:03:30 -08007954 goto stop_work;
Prashanth Bhattaab004382016-10-11 16:08:11 -07007955
Jeff Johnson214671b2017-10-30 19:45:23 -07007956 if (hdd_ctx->is_wiphy_suspended)
Dustin Browna20bad52019-03-05 12:03:30 -08007957 return;
Jingxiang Gec64e1932017-08-22 14:38:59 +08007958
Dustin Brown920397d2017-12-13 16:27:50 -08007959 hdd_for_each_adapter(hdd_ctx, adapter) {
Manjeet Singh01327cc2016-09-03 12:14:25 +05307960 /*
7961 * Validate magic so we don't end up accessing
7962 * an invalid adapter.
7963 */
7964 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
7965 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007966
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007967 if ((adapter->device_mode == QDF_STA_MODE ||
7968 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
Jeff Johnsone7951512019-02-27 10:02:51 -08007969 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.conn_state
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007970 != eConnectionState_Associated) {
7971
7972 continue;
7973 }
7974
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007975 if ((adapter->device_mode == QDF_SAP_MODE ||
7976 adapter->device_mode == QDF_P2P_GO_MODE) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -07007977 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007978
7979 continue;
7980 }
7981
7982 tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets,
7983 adapter->prev_tx_packets);
7984 rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets,
7985 adapter->prev_rx_packets);
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307986
7987 if (adapter->device_mode == QDF_SAP_MODE ||
7988 adapter->device_mode == QDF_P2P_GO_MODE ||
7989 adapter->device_mode == QDF_IBSS_MODE) {
7990
Dhanashri Atrea8f82f22017-01-23 12:58:24 -08007991 ret = cdp_get_intra_bss_fwd_pkts_count(
7992 cds_get_context(QDF_MODULE_ID_SOC),
Jeff Johnson5a6fc962019-02-04 14:20:25 -08007993 adapter->vdev_id,
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307994 &fwd_tx_packets, &fwd_rx_packets);
7995 if (ret == A_OK) {
7996 fwd_tx_packets_diff += HDD_BW_GET_DIFF(
7997 fwd_tx_packets,
7998 adapter->prev_fwd_tx_packets);
7999 fwd_rx_packets_diff += HDD_BW_GET_DIFF(
8000 fwd_tx_packets,
8001 adapter->prev_fwd_rx_packets);
8002 }
8003 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008004
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05308005 if (adapter->device_mode == QDF_SAP_MODE)
8006 con_sap_adapter = adapter;
8007
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008008 total_rx += adapter->stats.rx_packets;
8009 total_tx += adapter->stats.tx_packets;
8010
8011 spin_lock_bh(&hdd_ctx->bus_bw_lock);
8012 adapter->prev_tx_packets = adapter->stats.tx_packets;
8013 adapter->prev_rx_packets = adapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05308014 adapter->prev_fwd_tx_packets = fwd_tx_packets;
8015 adapter->prev_fwd_rx_packets = fwd_rx_packets;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008016 spin_unlock_bh(&hdd_ctx->bus_bw_lock);
8017 connected = true;
8018 }
8019
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008020 if (!connected) {
Jeff Johnson760350b2016-08-15 14:01:52 -07008021 hdd_err("bus bandwidth timer running in disconnected state");
Dustin Browna20bad52019-03-05 12:03:30 -08008022 goto stop_work;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008023 }
8024
Yun Parka29974a2018-04-09 12:05:49 -07008025 /* add intra bss forwarded tx and rx packets */
8026 tx_packets += fwd_tx_packets_diff;
8027 rx_packets += fwd_rx_packets_diff;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008028
Dustin Brown07901ec2018-09-07 11:02:41 -07008029 if (ucfg_ipa_is_fw_wdi_activated(hdd_ctx->pdev)) {
8030 ucfg_ipa_uc_stat_query(hdd_ctx->pdev, &ipa_tx_packets,
8031 &ipa_rx_packets);
Yun Parka29974a2018-04-09 12:05:49 -07008032 tx_packets += (uint64_t)ipa_tx_packets;
8033 rx_packets += (uint64_t)ipa_rx_packets;
8034
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05308035 if (con_sap_adapter) {
8036 con_sap_adapter->stats.tx_packets += ipa_tx_packets;
8037 con_sap_adapter->stats.rx_packets += ipa_rx_packets;
8038 }
8039
Dustin Brown07901ec2018-09-07 11:02:41 -07008040 ucfg_ipa_set_perf_level(hdd_ctx->pdev, tx_packets, rx_packets);
8041 ucfg_ipa_uc_stat_request(hdd_ctx->pdev, 2);
Yun Parka29974a2018-04-09 12:05:49 -07008042 }
8043
8044 hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008045
Dustin Browna20bad52019-03-05 12:03:30 -08008046 return;
8047
8048stop_work:
8049 qdf_periodic_work_stop_async(&hdd_ctx->bus_bw_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008050}
Prashanth Bhattaab004382016-10-11 16:08:11 -07008051
Dustin Browna20bad52019-03-05 12:03:30 -08008052static void hdd_bus_bw_work_handler(void *context)
Rajeev Kumarb2b5e692018-08-31 15:12:40 -07008053{
Dustin Brown3fdaaf62019-03-18 14:00:16 -07008054 struct hdd_context *hdd_ctx = context;
8055 struct qdf_op_sync *op_sync;
Dustin Browna20bad52019-03-05 12:03:30 -08008056
Dustin Brown3fdaaf62019-03-18 14:00:16 -07008057 if (qdf_op_protect(&op_sync))
8058 return;
8059
8060 __hdd_bus_bw_work_handler(hdd_ctx);
8061
8062 qdf_op_unprotect(op_sync);
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05308063}
8064
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008065int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07008066{
Dustin Browna20bad52019-03-05 12:03:30 -08008067 QDF_STATUS status;
8068
Dustin Brown35008ba2018-08-23 14:34:21 -07008069 hdd_enter();
8070
Prashanth Bhattaab004382016-10-11 16:08:11 -07008071 spin_lock_init(&hdd_ctx->bus_bw_lock);
Dustin Browna20bad52019-03-05 12:03:30 -08008072 status = qdf_periodic_work_create(&hdd_ctx->bus_bw_work,
8073 hdd_bus_bw_work_handler,
Dustin Brown3fdaaf62019-03-18 14:00:16 -07008074 hdd_ctx);
Dustin Brown35008ba2018-08-23 14:34:21 -07008075
8076 hdd_exit();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008077
Dustin Browna20bad52019-03-05 12:03:30 -08008078 return qdf_status_to_os_return(status);
Prashanth Bhattaab004382016-10-11 16:08:11 -07008079}
8080
Dustin Brown86d196b2018-08-02 11:51:49 -07008081void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07008082{
Dustin Brown35008ba2018-08-23 14:34:21 -07008083 hdd_enter();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008084
Dustin Browna20bad52019-03-05 12:03:30 -08008085 QDF_BUG(!qdf_periodic_work_stop_sync(&hdd_ctx->bus_bw_work));
8086 qdf_periodic_work_destroy(&hdd_ctx->bus_bw_work);
Dustin Brown35008ba2018-08-23 14:34:21 -07008087
8088 hdd_exit();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008089}
Lin Baic5c06882017-09-21 13:58:43 +08008090
Dustin Brown35008ba2018-08-23 14:34:21 -07008091#endif /* MSM_PLATFORM */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008092
8093/**
Nirav Shahed34b212016-04-25 10:59:16 +05308094 * wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
8095 * @hdd_ctx: hdd context
8096 *
8097 * Return: 0 for success or error code
8098 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008099static int wlan_hdd_init_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05308100{
8101 hdd_ctx->hdd_txrx_hist = qdf_mem_malloc(
8102 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Min Liu74a1a502018-10-10 19:59:07 +08008103 if (!hdd_ctx->hdd_txrx_hist)
Nirav Shahed34b212016-04-25 10:59:16 +05308104 return -ENOMEM;
Nirav Shahed34b212016-04-25 10:59:16 +05308105 return 0;
8106}
8107
8108/**
8109 * wlan_hdd_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
8110 * @hdd_ctx: hdd context
8111 *
8112 * Return: none
8113 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008114void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05308115{
Jeff Johnsond36fa332019-03-18 13:42:25 -07008116 if (!hdd_ctx || !hdd_ctx->hdd_txrx_hist)
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05308117 return;
8118
8119 qdf_mem_free(hdd_ctx->hdd_txrx_hist);
8120 hdd_ctx->hdd_txrx_hist = NULL;
Nirav Shahed34b212016-04-25 10:59:16 +05308121}
8122
Nirav Shahda008342016-05-17 18:50:40 +05308123static uint8_t *convert_level_to_string(uint32_t level)
8124{
8125 switch (level) {
8126 /* initialize the wlan sub system */
8127 case WLAN_SVC_TP_NONE:
8128 return "NONE";
8129 case WLAN_SVC_TP_LOW:
8130 return "LOW";
8131 case WLAN_SVC_TP_MEDIUM:
8132 return "MED";
8133 case WLAN_SVC_TP_HIGH:
8134 return "HIGH";
8135 default:
8136 return "INVAL";
8137 }
8138}
8139
Nirav Shahed34b212016-04-25 10:59:16 +05308140
8141/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008142 * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram
8143 * @hdd_ctx: hdd context
8144 *
8145 * Return: none
8146 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008147void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008148{
8149 int i;
8150
8151#ifdef MSM_PLATFORM
Nirav Shahe6194ac2018-07-13 11:04:41 +05308152 hdd_nofl_info("BW compute Interval: %dms",
jitiphil869b9f72018-09-25 17:14:01 +05308153 hdd_ctx->config->bus_bw_compute_interval);
Nirav Shahe6194ac2018-07-13 11:04:41 +05308154 hdd_nofl_info("BW High TH: %d BW Med TH: %d BW Low TH: %d",
jitiphil869b9f72018-09-25 17:14:01 +05308155 hdd_ctx->config->bus_bw_high_threshold,
8156 hdd_ctx->config->bus_bw_medium_threshold,
8157 hdd_ctx->config->bus_bw_low_threshold);
Nirav Shahe6194ac2018-07-13 11:04:41 +05308158 hdd_nofl_info("Enable TCP DEL ACK: %d",
8159 hdd_ctx->en_tcp_delack_no_lro);
8160 hdd_nofl_info("TCP DEL High TH: %d TCP DEL Low TH: %d",
jitiphil869b9f72018-09-25 17:14:01 +05308161 hdd_ctx->config->tcp_delack_thres_high,
8162 hdd_ctx->config->tcp_delack_thres_low);
Nirav Shahe6194ac2018-07-13 11:04:41 +05308163 hdd_nofl_info("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_limit)",
8164 hdd_ctx->config->tcp_tx_high_tput_thres);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008165#endif
8166
Nirav Shahe6194ac2018-07-13 11:04:41 +05308167 hdd_nofl_info("Total entries: %d Current index: %d",
8168 NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
Nirav Shahda008342016-05-17 18:50:40 +05308169
Nirav Shahe6194ac2018-07-13 11:04:41 +05308170 hdd_nofl_info("[index][timestamp]: interval_rx, interval_tx, bus_bw_level, RX TP Level, TX TP Level");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008171
8172 for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008173 /* using hdd_log to avoid printing function name */
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008174 if (hdd_ctx->hdd_txrx_hist[i].qtime > 0)
Nirav Shahe6194ac2018-07-13 11:04:41 +05308175 hdd_nofl_info("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s",
8176 i, hdd_ctx->hdd_txrx_hist[i].qtime,
8177 hdd_ctx->hdd_txrx_hist[i].interval_rx,
8178 hdd_ctx->hdd_txrx_hist[i].interval_tx,
8179 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008180 hdd_ctx->hdd_txrx_hist[i].
8181 next_vote_level),
Nirav Shahe6194ac2018-07-13 11:04:41 +05308182 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008183 hdd_ctx->hdd_txrx_hist[i].
8184 next_rx_level),
Nirav Shahe6194ac2018-07-13 11:04:41 +05308185 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008186 hdd_ctx->hdd_txrx_hist[i].
8187 next_tx_level));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008188 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008189}
8190
8191/**
8192 * wlan_hdd_clear_tx_rx_histogram() - clear tx rx histogram
8193 * @hdd_ctx: hdd context
8194 *
8195 * Return: none
8196 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008197void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008198{
8199 hdd_ctx->hdd_txrx_hist_idx = 0;
Nirav Shahed34b212016-04-25 10:59:16 +05308200 qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
8201 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008202}
8203
Mohit Khannaca4173b2017-09-12 21:52:19 -07008204/* length of the netif queue log needed per adapter */
8205#define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
8206
8207/**
8208 *
8209 * hdd_display_netif_queue_history_compact() - display compact netifq history
8210 * @hdd_ctx: hdd context
8211 *
8212 * Return: none
8213 */
8214static void
8215hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
8216{
8217 int adapter_num = 0;
8218 int i;
8219 int bytes_written;
8220 u32 tbytes;
8221 qdf_time_t total, pause, unpause, curr_time, delta;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008222 char temp_str[20 * WLAN_REASON_TYPE_MAX];
jiadbdefb252018-01-03 14:27:06 +08008223 char *comb_log_str;
8224 uint32_t comb_log_str_size;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008225 struct hdd_adapter *adapter = NULL;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008226
Dustin Brownad06be62019-02-04 14:52:56 -08008227 comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * WLAN_MAX_VDEVS) + 1;
jiadbdefb252018-01-03 14:27:06 +08008228 comb_log_str = qdf_mem_malloc(comb_log_str_size);
Min Liu74a1a502018-10-10 19:59:07 +08008229 if (!comb_log_str)
jiadbdefb252018-01-03 14:27:06 +08008230 return;
jiadbdefb252018-01-03 14:27:06 +08008231
Mohit Khannaca4173b2017-09-12 21:52:19 -07008232 bytes_written = 0;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008233
Dustin Brown920397d2017-12-13 16:27:50 -08008234 hdd_for_each_adapter(hdd_ctx, adapter) {
Mohit Khannaca4173b2017-09-12 21:52:19 -07008235 curr_time = qdf_system_ticks();
8236 total = curr_time - adapter->start_time;
8237 delta = curr_time - adapter->last_time;
8238
8239 if (adapter->pause_map) {
8240 pause = adapter->total_pause_time + delta;
8241 unpause = adapter->total_unpause_time;
8242 } else {
8243 unpause = adapter->total_unpause_time + delta;
8244 pause = adapter->total_pause_time;
8245 }
8246
8247 tbytes = 0;
hangtian127c9532019-01-12 13:29:07 +08008248 qdf_mem_zero(temp_str, sizeof(temp_str));
Mohit Khannaca4173b2017-09-12 21:52:19 -07008249 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
8250 if (adapter->queue_oper_stats[i].pause_count == 0)
8251 continue;
8252 tbytes +=
8253 snprintf(
8254 &temp_str[tbytes],
8255 (tbytes >= sizeof(temp_str) ?
8256 0 : sizeof(temp_str) - tbytes),
8257 "%d(%d,%d) ",
8258 i,
8259 adapter->queue_oper_stats[i].
8260 pause_count,
8261 adapter->queue_oper_stats[i].
8262 unpause_count);
8263 }
8264 if (tbytes >= sizeof(temp_str))
8265 hdd_warn("log truncated");
8266
8267 bytes_written += snprintf(&comb_log_str[bytes_written],
jiadbdefb252018-01-03 14:27:06 +08008268 bytes_written >= comb_log_str_size ? 0 :
8269 comb_log_str_size - bytes_written,
Mohit Khannaca4173b2017-09-12 21:52:19 -07008270 "[%d %d] (%d) %u/%ums %s|",
Jeff Johnson5a6fc962019-02-04 14:20:25 -08008271 adapter->vdev_id, adapter->device_mode,
Mohit Khannaca4173b2017-09-12 21:52:19 -07008272 adapter->pause_map,
8273 qdf_system_ticks_to_msecs(pause),
8274 qdf_system_ticks_to_msecs(total),
8275 temp_str);
8276
Mohit Khannaca4173b2017-09-12 21:52:19 -07008277 adapter_num++;
8278 }
8279
8280 /* using QDF_TRACE to avoid printing function name */
8281 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
8282 "STATS |%s", comb_log_str);
8283
jiadbdefb252018-01-03 14:27:06 +08008284 if (bytes_written >= comb_log_str_size)
Mohit Khannaca4173b2017-09-12 21:52:19 -07008285 hdd_warn("log string truncated");
jiadbdefb252018-01-03 14:27:06 +08008286
8287 qdf_mem_free(comb_log_str);
Mohit Khannaca4173b2017-09-12 21:52:19 -07008288}
8289
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008290/**
Srinivas Girigowdab841da72017-03-25 18:04:39 -07008291 * wlan_hdd_display_netif_queue_history() - display netif queue history
Jeff Johnson58adbcf2017-09-03 08:53:31 -07008292 * @hdd_ctx: hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008293 *
8294 * Return: none
8295 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07008296void
8297wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
8298 enum qdf_stats_verbosity_level verb_lvl)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008299{
8300
Jeff Johnson9d295242017-08-29 14:39:48 -07008301 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008302 int i;
Nirav Shahda008342016-05-17 18:50:40 +05308303 qdf_time_t total, pause, unpause, curr_time, delta;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008304
Mohit Khannaca4173b2017-09-12 21:52:19 -07008305 if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
8306 hdd_display_netif_queue_history_compact(hdd_ctx);
8307 return;
8308 }
8309
Dustin Brown920397d2017-12-13 16:27:50 -08008310 hdd_for_each_adapter(hdd_ctx, adapter) {
Nirav Shahe6194ac2018-07-13 11:04:41 +05308311 hdd_nofl_info("Netif queue operation statistics:");
Jeff Johnson55d2ab42019-03-06 11:43:49 -08008312 hdd_nofl_info("vdev_id %d device mode %d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -08008313 adapter->vdev_id, adapter->device_mode);
Nirav Shahe6194ac2018-07-13 11:04:41 +05308314 hdd_nofl_info("Current pause_map value %x", adapter->pause_map);
Nirav Shah617cff92016-04-25 10:24:24 +05308315 curr_time = qdf_system_ticks();
8316 total = curr_time - adapter->start_time;
Nirav Shahda008342016-05-17 18:50:40 +05308317 delta = curr_time - adapter->last_time;
Nirav Shah617cff92016-04-25 10:24:24 +05308318 if (adapter->pause_map) {
Nirav Shahda008342016-05-17 18:50:40 +05308319 pause = adapter->total_pause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05308320 unpause = adapter->total_unpause_time;
8321 } else {
Nirav Shahda008342016-05-17 18:50:40 +05308322 unpause = adapter->total_unpause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05308323 pause = adapter->total_pause_time;
8324 }
Nirav Shahe6194ac2018-07-13 11:04:41 +05308325 hdd_nofl_info("Total: %ums Pause: %ums Unpause: %ums",
8326 qdf_system_ticks_to_msecs(total),
8327 qdf_system_ticks_to_msecs(pause),
8328 qdf_system_ticks_to_msecs(unpause));
8329 hdd_nofl_info("reason_type: pause_cnt: unpause_cnt: pause_time");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008330
Nirav Shahda008342016-05-17 18:50:40 +05308331 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
8332 qdf_time_t pause_delta = 0;
8333
8334 if (adapter->pause_map & (1 << i))
8335 pause_delta = delta;
8336
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008337 /* using hdd_log to avoid printing function name */
Nirav Shahe6194ac2018-07-13 11:04:41 +05308338 hdd_nofl_info("%s: %d: %d: %ums",
8339 hdd_reason_type_to_string(i),
8340 adapter->queue_oper_stats[i].pause_count,
8341 adapter->queue_oper_stats[i].
8342 unpause_count,
8343 qdf_system_ticks_to_msecs(
8344 adapter->queue_oper_stats[i].
8345 total_pause_time + pause_delta));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008346 }
8347
Nirav Shahe6194ac2018-07-13 11:04:41 +05308348 hdd_nofl_info("Netif queue operation history:");
8349 hdd_nofl_info("Total entries: %d current index %d",
8350 WLAN_HDD_MAX_HISTORY_ENTRY,
8351 adapter->history_index);
Nirav Shahda008342016-05-17 18:50:40 +05308352
Nirav Shahe6194ac2018-07-13 11:04:41 +05308353 hdd_nofl_info("index: time: action_type: reason_type: pause_map");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008354
8355 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008356 /* using hdd_log to avoid printing function name */
8357 if (adapter->queue_oper_history[i].time == 0)
8358 continue;
Nirav Shahe6194ac2018-07-13 11:04:41 +05308359 hdd_nofl_info("%d: %u: %s: %s: %x",
8360 i, qdf_system_ticks_to_msecs(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008361 adapter->queue_oper_history[i].time),
Nirav Shahe6194ac2018-07-13 11:04:41 +05308362 hdd_action_type_to_string(
8363 adapter->queue_oper_history[i].
8364 netif_action),
8365 hdd_reason_type_to_string(
8366 adapter->queue_oper_history[i].
8367 netif_reason),
8368 adapter->queue_oper_history[i].pause_map);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008369 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008370 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008371}
8372
8373/**
8374 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
8375 * @hdd_ctx: hdd context
8376 *
8377 * Return: none
8378 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008379void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008380{
Jeff Johnson9d295242017-08-29 14:39:48 -07008381 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008382
Dustin Brown920397d2017-12-13 16:27:50 -08008383 hdd_for_each_adapter(hdd_ctx, adapter) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308384 qdf_mem_zero(adapter->queue_oper_stats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008385 sizeof(adapter->queue_oper_stats));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308386 qdf_mem_zero(adapter->queue_oper_history,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008387 sizeof(adapter->queue_oper_history));
Nirav Shah617cff92016-04-25 10:24:24 +05308388 adapter->history_index = 0;
8389 adapter->start_time = adapter->last_time = qdf_system_ticks();
8390 adapter->total_pause_time = 0;
8391 adapter->total_unpause_time = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008392 }
8393}
8394
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008395#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8396/**
8397 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
8398 * @hdd_ctx: hdd global context
8399 *
8400 * Return: none
8401 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008402static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008403{
8404 uint8_t i;
8405
8406 mutex_init(&hdd_ctx->op_ctx.op_lock);
8407 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
8408 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
8409 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
8410 }
8411}
8412#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008413static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008414{
8415}
8416#endif
8417
Yingying Tang95409972016-10-20 15:16:15 +08008418#ifdef WLAN_FEATURE_WOW_PULSE
8419/**
8420 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008421 * @hdd_ctx: struct hdd_context structure pointer
Yingying Tang95409972016-10-20 15:16:15 +08008422 * @enable: enable or disable this behaviour
8423 *
8424 * Return: int
8425 */
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008426static int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08008427{
Yingying Tang95409972016-10-20 15:16:15 +08008428 struct wow_pulse_mode wow_pulse_set_info;
8429 QDF_STATUS status;
8430
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008431 hdd_debug("wow pulse enable flag is %d", enable);
Yingying Tang95409972016-10-20 15:16:15 +08008432
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008433 if (!ucfg_pmo_is_wow_pulse_enabled(hdd_ctx->psoc))
Yingying Tang95409972016-10-20 15:16:15 +08008434 return 0;
8435
8436 /* prepare the request to send to SME */
8437 if (enable == true) {
8438 wow_pulse_set_info.wow_pulse_enable = true;
8439 wow_pulse_set_info.wow_pulse_pin =
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008440 ucfg_pmo_get_wow_pulse_pin(hdd_ctx->psoc);
Wu Gao66454f12018-09-26 19:55:41 +08008441
Yingying Tang95409972016-10-20 15:16:15 +08008442 wow_pulse_set_info.wow_pulse_interval_high =
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008443 ucfg_pmo_get_wow_pulse_interval_high(hdd_ctx->psoc);
Wu Gao66454f12018-09-26 19:55:41 +08008444
8445 wow_pulse_set_info.wow_pulse_interval_low =
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008446 ucfg_pmo_get_wow_pulse_interval_low(hdd_ctx->psoc);
Yingying Tang95409972016-10-20 15:16:15 +08008447 } else {
8448 wow_pulse_set_info.wow_pulse_enable = false;
8449 wow_pulse_set_info.wow_pulse_pin = 0;
8450 wow_pulse_set_info.wow_pulse_interval_low = 0;
8451 wow_pulse_set_info.wow_pulse_interval_high = 0;
8452 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008453 hdd_debug("enable %d pin %d low %d high %d",
Yingying Tang95409972016-10-20 15:16:15 +08008454 wow_pulse_set_info.wow_pulse_enable,
8455 wow_pulse_set_info.wow_pulse_pin,
8456 wow_pulse_set_info.wow_pulse_interval_low,
8457 wow_pulse_set_info.wow_pulse_interval_high);
8458
8459 status = sme_set_wow_pulse(&wow_pulse_set_info);
8460 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008461 hdd_debug("sme_set_wow_pulse failure!");
Yingying Tang95409972016-10-20 15:16:15 +08008462 return -EIO;
8463 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008464 hdd_debug("sme_set_wow_pulse success!");
Yingying Tang95409972016-10-20 15:16:15 +08008465 return 0;
8466}
8467#else
Jeff Johnsonfd7d1ef2019-03-31 10:41:37 -07008468static inline int wlan_hdd_set_wow_pulse(struct hdd_context *hdd_ctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08008469{
8470 return 0;
8471}
8472#endif
8473
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008474#ifdef WLAN_FEATURE_FASTPATH
jitiphil377bcc12018-10-05 19:46:08 +05308475
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008476/**
8477 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
8478 * @hdd_cfg: hdd config
8479 * @context: lower layer context
8480 *
8481 * Return: none
8482 */
jitiphil377bcc12018-10-05 19:46:08 +05308483void hdd_enable_fastpath(struct hdd_context *hdd_ctx,
8484 void *context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008485{
jitiphil377bcc12018-10-05 19:46:08 +05308486 if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008487 hif_enable_fastpath(context);
8488}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008489#endif
8490
Yuanyuan Liu13738502016-04-06 17:41:37 -07008491#if defined(FEATURE_WLAN_CH_AVOID)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008492/**
8493 * hdd_set_thermal_level_cb() - set thermal level callback function
Jeff Johnson0e963082018-07-04 19:39:20 -07008494 * @hdd_handle: opaque handle for the hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008495 * @level: thermal level
8496 *
8497 * Change IPA data path to SW path when the thermal throttle level greater
8498 * than 0, and restore the original data path when throttle level is 0
8499 *
8500 * Return: none
8501 */
Jeff Johnson0e963082018-07-04 19:39:20 -07008502static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008503{
Jeff Johnson0e963082018-07-04 19:39:20 -07008504 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008505
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008506 /* Change IPA to SW path when throttle level greater than 0 */
8507 if (level > THROTTLE_LEVEL_0)
Dustin Brown07901ec2018-09-07 11:02:41 -07008508 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008509 else
8510 /* restore original concurrency mode */
Dustin Brown07901ec2018-09-07 11:02:41 -07008511 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008512}
8513
8514/**
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05308515 * hdd_get_safe_channel() - Get safe channel from current regulatory
8516 * @hdd_ctx: pointer to hdd context
8517 * @adapter: pointer to softap adapter
8518 *
8519 * This function is used to get safe channel from current regulatory valid
8520 * channels to restart SAP if failed to get safe channel from PCL.
8521 *
8522 * Return: Channel number to restart SAP in case of success. In case of any
8523 * failure, the channel number returned is zero.
8524 */
8525static uint8_t
8526hdd_get_safe_channel(struct hdd_context *hdd_ctx,
8527 struct hdd_adapter *adapter)
8528{
8529 struct sir_pcl_list pcl = {0};
8530 uint32_t i, j;
8531 bool found = false;
8532 int ret;
8533
8534 /* Try for safe channel from all valid channel */
8535 pcl.pcl_len = MAX_NUM_CHAN;
8536 ret = hdd_get_valid_chan(hdd_ctx, pcl.pcl_list,
8537 &pcl.pcl_len);
8538 if (ret) {
8539 hdd_err("error %d in getting valid channel list", ret);
8540 return INVALID_CHANNEL_ID;
8541 }
8542
8543 for (i = 0; i < pcl.pcl_len; i++) {
8544 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
8545 found = false;
8546 for (j = 0; j < hdd_ctx->unsafe_channel_count; j++) {
8547 if (pcl.pcl_list[i] ==
8548 hdd_ctx->unsafe_channel_list[j]) {
8549 hdd_debug("unsafe chan:%d", pcl.pcl_list[i]);
8550 found = true;
8551 break;
8552 }
8553 }
8554
8555 if (found)
8556 continue;
8557
8558 if ((pcl.pcl_list[i] >=
8559 adapter->session.ap.sap_config.acs_cfg.start_ch) &&
8560 (pcl.pcl_list[i] <=
8561 adapter->session.ap.sap_config.acs_cfg.end_ch)) {
8562 hdd_debug("found safe chan:%d", pcl.pcl_list[i]);
8563 return pcl.pcl_list[i];
8564 }
8565 }
8566
8567 return INVALID_CHANNEL_ID;
8568}
8569
8570#else
8571/**
8572 * hdd_set_thermal_level_cb() - set thermal level callback function
8573 * @hdd_handle: opaque handle for the hdd context
8574 * @level: thermal level
8575 *
8576 * Change IPA data path to SW path when the thermal throttle level greater
8577 * than 0, and restore the original data path when throttle level is 0
8578 *
8579 * Return: none
8580 */
8581static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
8582{
8583}
8584
8585/**
8586 * hdd_get_safe_channel() - Get safe channel from current regulatory
8587 * @hdd_ctx: pointer to hdd context
8588 * @adapter: pointer to softap adapter
8589 *
8590 * This function is used to get safe channel from current regulatory valid
8591 * channels to restart SAP if failed to get safe channel from PCL.
8592 *
8593 * Return: Channel number to restart SAP in case of success. In case of any
8594 * failure, the channel number returned is zero.
8595 */
8596static uint8_t
8597hdd_get_safe_channel(struct hdd_context *hdd_ctx,
8598 struct hdd_adapter *adapter)
8599{
8600 return 0;
8601}
8602#endif
8603
8604/**
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308605 * hdd_get_safe_channel_from_pcl_and_acs_range() - Get safe channel for SAP
8606 * restart
Manishekar Chandrasekarandb9b8672016-06-10 23:31:19 +05308607 * @adapter: AP adapter, which should be checked for NULL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008608 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308609 * Get a safe channel to restart SAP. PCL already takes into account the
8610 * unsafe channels. So, the PCL is validated with the ACS range to provide
8611 * a safe channel for the SAP to restart.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008612 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308613 * Return: Channel number to restart SAP in case of success. In case of any
8614 * failure, the channel number returned is zero.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008615 */
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05308616static uint8_t
8617hdd_get_safe_channel_from_pcl_and_acs_range(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008618{
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308619 struct sir_pcl_list pcl;
8620 QDF_STATUS status;
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05308621 uint32_t i;
Jeff Johnson16528362018-06-14 12:34:16 -07008622 mac_handle_t mac_handle;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008623 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008624
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308625 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8626 if (!hdd_ctx) {
8627 hdd_err("invalid HDD context");
8628 return INVALID_CHANNEL_ID;
8629 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008630
Jeff Johnson16528362018-06-14 12:34:16 -07008631 mac_handle = hdd_ctx->mac_handle;
8632 if (!mac_handle) {
8633 hdd_err("invalid MAC handle");
Manishekar Chandrasekaran79746ac2016-06-24 04:45:33 +05308634 return INVALID_CHANNEL_ID;
8635 }
8636
Dustin Brown1dbefe62018-09-11 16:32:03 -07008637 status = policy_mgr_get_pcl_for_existing_conn(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08008638 PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len,
bings37bd58f2017-07-20 16:49:26 +08008639 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list),
8640 false);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308641 if (QDF_IS_STATUS_ERROR(status)) {
8642 hdd_err("Get PCL failed");
8643 return INVALID_CHANNEL_ID;
8644 }
8645
Frank Liudc2cefb2017-06-21 15:38:18 +08008646 /*
8647 * In some scenarios, like hw dbs disabled, sap+sap case, if operating
8648 * channel is unsafe channel, the pcl may be empty, instead of return,
8649 * try to choose a safe channel from acs range.
8650 */
8651 if (!pcl.pcl_len)
8652 hdd_debug("pcl length is zero!");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308653
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008654 hdd_debug("start:%d end:%d",
Jeff Johnsonb9424862017-10-30 08:49:35 -07008655 adapter->session.ap.sap_config.acs_cfg.start_ch,
8656 adapter->session.ap.sap_config.acs_cfg.end_ch);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308657
8658 /* PCL already takes unsafe channel into account */
8659 for (i = 0; i < pcl.pcl_len; i++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008660 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308661 if ((pcl.pcl_list[i] >=
Jeff Johnsonb9424862017-10-30 08:49:35 -07008662 adapter->session.ap.sap_config.acs_cfg.start_ch) &&
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308663 (pcl.pcl_list[i] <=
Jeff Johnsonb9424862017-10-30 08:49:35 -07008664 adapter->session.ap.sap_config.acs_cfg.end_ch)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008665 hdd_debug("found PCL safe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308666 return pcl.pcl_list[i];
8667 }
8668 }
8669
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008670 hdd_debug("no safe channel from PCL found in ACS range");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308671
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05308672 return hdd_get_safe_channel(hdd_ctx, adapter);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308673}
8674
8675/**
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08008676 * hdd_switch_sap_channel() - Move SAP to the given channel
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308677 * @adapter: AP adapter
8678 * @channel: Channel
Min Liu2fef5792018-01-19 17:59:42 +08008679 * @forced: Force to switch channel, ignore SCC/MCC check
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308680 *
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08008681 * Moves the SAP interface by invoking the function which
8682 * executes the callback to perform channel switch using (E)CSA.
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308683 *
8684 * Return: None
8685 */
Min Liu2fef5792018-01-19 17:59:42 +08008686void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel,
8687 bool forced)
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308688{
Jeff Johnson87251032017-08-29 13:31:11 -07008689 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008690 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -07008691 mac_handle_t mac_handle;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308692
8693 if (!adapter) {
8694 hdd_err("invalid adapter");
8695 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008696 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308697
8698 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
8699
Jeff Johnson16528362018-06-14 12:34:16 -07008700 mac_handle = hdd_adapter_get_mac_handle(adapter);
8701 if (!mac_handle) {
8702 hdd_err("invalid MAC handle");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308703 return;
8704 }
8705
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08008706 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8707
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008708 hdd_debug("chan:%d width:%d",
Jeff Johnson91df29d2017-10-27 19:29:50 -07008709 channel, hdd_ap_ctx->sap_config.ch_width_orig);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308710
Dustin Brown1dbefe62018-09-11 16:32:03 -07008711 policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08008712 adapter->vdev_id, channel,
Min Liu2fef5792018-01-19 17:59:42 +08008713 hdd_ap_ctx->sap_config.ch_width_orig, forced);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008714}
Kapil Gupta8878ad92017-02-13 11:56:04 +05308715
Jeff Johnson9d295242017-08-29 14:39:48 -07008716int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
Kapil Gupta8878ad92017-02-13 11:56:04 +05308717{
8718 struct hdd_external_acs_timer_context *timer_context;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308719 int status;
8720 QDF_STATUS qdf_status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308721
8722 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
8723
8724 if (QDF_TIMER_STATE_RUNNING ==
Jeff Johnsonb9424862017-10-30 08:49:35 -07008725 qdf_mc_timer_get_current_state(&adapter->session.
Kapil Gupta8878ad92017-02-13 11:56:04 +05308726 ap.vendor_acs_timer)) {
Jeff Johnsonb9424862017-10-30 08:49:35 -07008727 qdf_mc_timer_stop(&adapter->session.ap.vendor_acs_timer);
Kapil Gupta8878ad92017-02-13 11:56:04 +05308728 }
8729 timer_context = (struct hdd_external_acs_timer_context *)
Jeff Johnsonb9424862017-10-30 08:49:35 -07008730 adapter->session.ap.vendor_acs_timer.user_data;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308731 timer_context->reason = reason;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308732 qdf_status =
Jeff Johnsonb9424862017-10-30 08:49:35 -07008733 qdf_mc_timer_start(&adapter->session.ap.vendor_acs_timer,
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308734 WLAN_VENDOR_ACS_WAIT_TIME);
8735 if (qdf_status != QDF_STATUS_SUCCESS) {
8736 hdd_err("failed to start external acs timer");
8737 return -ENOSPC;
8738 }
8739 /* Update config to application */
8740 status = hdd_cfg80211_update_acs_config(adapter, reason);
Dustin Brown5e89ef82018-03-14 11:50:23 -07008741 hdd_info("Updated ACS config to nl with reason %d", reason);
Kapil Gupta8878ad92017-02-13 11:56:04 +05308742
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308743 return status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308744}
8745
Nirav Shaheb017be2018-02-15 11:20:58 +05308746#if defined(FEATURE_WLAN_CH_AVOID)
Agrawal Ashish467dde42016-09-08 18:44:22 +05308747/**
8748 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
8749 * @hdd_ctx: hdd context pointer
8750 *
8751 * hdd_unsafe_channel_restart_sap check all unsafe channel list
8752 * and if ACS is enabled, driver will ask userspace to restart the
8753 * sap. User space on LTE coex indication restart driver.
8754 *
8755 * Return - none
8756 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008757void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
Agrawal Ashish467dde42016-09-08 18:44:22 +05308758{
Dustin Brown920397d2017-12-13 16:27:50 -08008759 struct hdd_adapter *adapter;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308760 uint32_t i;
8761 bool found = false;
8762 uint8_t restart_chan;
Krunal Sonidf29bc42018-11-15 13:26:29 -08008763 uint8_t scc_on_lte_coex = 0;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05308764 bool value;
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07008765 QDF_STATUS status;
8766 bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE);
8767 bool is_vendor_acs_support =
8768 cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008769
Dustin Brown920397d2017-12-13 16:27:50 -08008770 hdd_for_each_adapter(hdd_ctxt, adapter) {
8771 if (!(adapter->device_mode == QDF_SAP_MODE &&
8772 adapter->session.ap.sap_config.acs_cfg.acs_mode)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008773 hdd_debug("skip device mode:%d acs:%d",
Dustin Brown920397d2017-12-13 16:27:50 -08008774 adapter->device_mode,
8775 adapter->session.ap.sap_config.
8776 acs_cfg.acs_mode);
8777 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308778 }
8779
8780 found = false;
Krunal Sonidf29bc42018-11-15 13:26:29 -08008781 status =
8782 ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctxt->psoc,
8783 &scc_on_lte_coex);
8784 if (!QDF_IS_STATUS_SUCCESS(status))
8785 hdd_err("can't get scc on lte coex chnl, use def");
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07008786 /*
8787 * If STA+SAP is doing SCC & g_sta_sap_scc_on_lte_coex_chan
8788 * is set, no need to move SAP.
8789 */
Dustin Brown1dbefe62018-09-11 16:32:03 -07008790 if (policy_mgr_is_sta_sap_scc(hdd_ctxt->psoc,
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07008791 adapter->session.ap.operating_channel) &&
Krunal Sonidf29bc42018-11-15 13:26:29 -08008792 scc_on_lte_coex)
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07008793 hdd_debug("SAP is allowed on SCC channel, no need to move SAP");
8794 else {
8795 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
8796 if (adapter->session.ap.operating_channel ==
8797 hdd_ctxt->unsafe_channel_list[i]) {
8798 found = true;
8799 hdd_debug("operating ch:%d is unsafe",
8800 adapter->session.ap.operating_channel);
8801 break;
8802 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05308803 }
8804 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05308805 if (!found) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008806 hdd_debug("ch:%d is safe. no need to change channel",
Dustin Brown920397d2017-12-13 16:27:50 -08008807 adapter->session.ap.operating_channel);
8808 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308809 }
8810
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07008811 status = ucfg_mlme_get_acs_support_for_dfs_ltecoex(
8812 hdd_ctxt->psoc,
8813 &is_acs_support_for_dfs_ltecoex);
8814 if (!QDF_IS_STATUS_SUCCESS(status))
8815 hdd_err("get_acs_support_for_dfs_ltecoex failed,set def");
8816
8817 status = ucfg_mlme_get_vendor_acs_support(
8818 hdd_ctxt->psoc,
8819 &is_vendor_acs_support);
8820 if (!QDF_IS_STATUS_SUCCESS(status))
8821 hdd_err("get_vendor_acs_support failed, set default");
8822
8823 if (is_vendor_acs_support && is_acs_support_for_dfs_ltecoex) {
Dustin Brown920397d2017-12-13 16:27:50 -08008824 hdd_update_acs_timer_reason(adapter,
Kapil Gupta8878ad92017-02-13 11:56:04 +05308825 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
Dustin Brown920397d2017-12-13 16:27:50 -08008826 continue;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308827 } else
8828 restart_chan =
8829 hdd_get_safe_channel_from_pcl_and_acs_range(
Dustin Brown920397d2017-12-13 16:27:50 -08008830 adapter);
Agrawal Ashish467dde42016-09-08 18:44:22 +05308831 if (!restart_chan) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008832 hdd_err("fail to restart SAP");
Agrawal Ashish467dde42016-09-08 18:44:22 +05308833 } else {
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08008834 /*
8835 * SAP restart due to unsafe channel. While
8836 * restarting the SAP, make sure to clear
8837 * acs_channel, channel to reset to
8838 * 0. Otherwise these settings will override
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05308839 * the ACS while restart.
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08008840 */
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05308841 hdd_ctxt->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008842 hdd_debug("sending coex indication");
Agrawal Ashish467dde42016-09-08 18:44:22 +05308843 wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index,
8844 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Dustin Brown05d81302018-09-11 16:49:22 -07008845 ucfg_mlme_get_sap_internal_restart(hdd_ctxt->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05308846 &value);
8847 hdd_debug("driver to start sap: %d", value);
8848 if (value)
Min Liu2fef5792018-01-19 17:59:42 +08008849 hdd_switch_sap_channel(adapter, restart_chan,
8850 true);
Liangwei Dong6663d162017-07-10 03:29:36 -04008851 else
8852 return;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308853 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05308854 }
8855}
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05308856
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008857/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008858 * hdd_init_channel_avoidance() - Initialize channel avoidance
8859 * @hdd_ctx: HDD global context
8860 *
8861 * Initialize the channel avoidance logic by retrieving the unsafe
Yuanyuan Liu13738502016-04-06 17:41:37 -07008862 * channel list from the platform driver and plumbing the data
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008863 * down to the lower layers. Then subscribe to subsequent channel
8864 * avoidance events.
8865 *
8866 * Return: None
8867 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008868static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008869{
8870 uint16_t unsafe_channel_count;
8871 int index;
8872
Yuanyuan Liu13738502016-04-06 17:41:37 -07008873 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
8874 hdd_ctx->unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008875 &(hdd_ctx->unsafe_channel_count),
Amar Singhalb8d4f152016-02-10 10:21:43 -08008876 sizeof(uint16_t) * NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008877
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008878 hdd_debug("num of unsafe channels is %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008879 hdd_ctx->unsafe_channel_count);
8880
Anurag Chouhan6d760662016-02-20 16:05:43 +05308881 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
Amar Singhalb8d4f152016-02-10 10:21:43 -08008882 (uint16_t)NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008883
8884 for (index = 0; index < unsafe_channel_count; index++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008885 hdd_debug("channel %d is not safe",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008886 hdd_ctx->unsafe_channel_list[index]);
8887
8888 }
8889
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008890}
Dustin Brown676a2322017-08-15 13:16:13 -07008891
Jeff Johnson9d295242017-08-29 14:39:48 -07008892static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008893 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07008894{
8895 uint8_t restart_chan;
8896
8897 restart_chan = hdd_get_safe_channel_from_pcl_and_acs_range(adapter);
8898 if (!restart_chan) {
8899 hdd_alert("fail to restart SAP");
8900 return;
8901 }
8902
8903 /* SAP restart due to unsafe channel. While restarting
8904 * the SAP, make sure to clear acs_channel, channel to
8905 * reset to 0. Otherwise these settings will override
8906 * the ACS while restart.
8907 */
8908 hdd_ctx->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Dustin Brown676a2322017-08-15 13:16:13 -07008909
8910 hdd_debug("sending coex indication");
8911
8912 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
8913 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Min Liu2fef5792018-01-19 17:59:42 +08008914 hdd_switch_sap_channel(adapter, restart_chan, true);
Dustin Brown676a2322017-08-15 13:16:13 -07008915}
Liangwei Dong6e1a2092017-08-30 16:29:06 +08008916
8917int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
8918 uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count)
8919{
8920 uint32_t size;
8921 uint16_t *unsafe_list;
8922 uint16_t chan_count;
8923
8924 if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count)
8925 return -EINVAL;
8926
8927 chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count,
8928 NUM_CHANNELS);
8929 if (chan_count) {
8930 size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]);
8931 unsafe_list = qdf_mem_malloc(size);
Min Liu74a1a502018-10-10 19:59:07 +08008932 if (!unsafe_list)
Liangwei Dong6e1a2092017-08-30 16:29:06 +08008933 return -ENOMEM;
Liangwei Dong6e1a2092017-08-30 16:29:06 +08008934 qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size);
8935 } else {
8936 unsafe_list = NULL;
8937 }
8938
8939 *local_unsafe_list = unsafe_list;
8940 *local_unsafe_list_count = chan_count;
8941
8942 return 0;
8943}
8944
8945bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
8946 uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count)
8947{
8948 int i, j;
8949
8950 if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count)
8951 return true;
8952 if (local_unsafe_list_count == 0)
8953 return false;
8954 for (i = 0; i < local_unsafe_list_count; i++) {
8955 for (j = 0; j < local_unsafe_list_count; j++)
8956 if (local_unsafe_list[i] ==
8957 hdd_ctx->unsafe_channel_list[j])
8958 break;
8959 if (j >= local_unsafe_list_count)
8960 break;
8961 }
8962 if (i >= local_unsafe_list_count) {
8963 hdd_info("unsafe chan list same");
8964 return false;
8965 }
8966
8967 return true;
8968}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008969#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008970static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008971{
8972}
Dustin Brown676a2322017-08-15 13:16:13 -07008973
Jeff Johnson9d295242017-08-29 14:39:48 -07008974static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008975 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07008976{
8977 hdd_debug("Channel avoidance is not enabled; Abort SAP restart");
8978}
Yuanyuan Liu13738502016-04-06 17:41:37 -07008979#endif /* defined(FEATURE_WLAN_CH_AVOID) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008980
8981/**
Rajeev Kumard004abc2016-02-17 12:09:56 -08008982 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
8983 * user space
8984 * @frame_ind: Management frame data to be informed.
8985 *
8986 * This function is used to indicate management frame to
8987 * user space
8988 *
8989 * Return: None
8990 *
8991 */
8992void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
8993{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008994 struct hdd_context *hdd_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07008995 struct hdd_adapter *adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08008996 int i;
Pragaspathi Thilagaraj28ffc042018-07-18 15:19:36 +05308997 struct ieee80211_mgmt *mgmt =
8998 (struct ieee80211_mgmt *)frame_ind->frameBuf;
Rajeev Kumard004abc2016-02-17 12:09:56 -08008999
Dustin Browne7e71d32018-05-11 16:00:08 -07009000 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
9001 if (wlan_hdd_validate_context(hdd_ctx))
Rajeev Kumard004abc2016-02-17 12:09:56 -08009002 return;
9003
Pragaspathi Thilagaraj28ffc042018-07-18 15:19:36 +05309004 if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) {
9005 hdd_err(" Invalid frame length");
9006 return;
9007 }
9008
Rajeev Kumard004abc2016-02-17 12:09:56 -08009009 if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
Dustin Brownad06be62019-02-04 14:52:56 -08009010 for (i = 0; i < WLAN_MAX_VDEVS; i++) {
Rajeev Kumard004abc2016-02-17 12:09:56 -08009011 adapter =
Jeff Johnson55d2ab42019-03-06 11:43:49 -08009012 hdd_get_adapter_by_vdev(hdd_ctx, i);
Rajeev Kumard004abc2016-02-17 12:09:56 -08009013 if (adapter)
9014 break;
9015 }
Wu Gaoa0230a62018-01-04 20:56:57 +08009016 } else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) {
9017 hdd_for_each_adapter(hdd_ctx, adapter) {
Jeff Johnsond36fa332019-03-18 13:42:25 -07009018 if ((adapter) &&
Wu Gaoa0230a62018-01-04 20:56:57 +08009019 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)) {
9020 __hdd_indicate_mgmt_frame(adapter,
9021 frame_ind->frame_len,
9022 frame_ind->frameBuf,
9023 frame_ind->frameType,
9024 frame_ind->rxChan,
Srinivas Dasariea1c1332019-02-18 12:43:23 +05309025 frame_ind->rxRssi,
9026 frame_ind->rx_flags);
Wu Gaoa0230a62018-01-04 20:56:57 +08009027 }
9028 }
9029 adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08009030 } else {
Jeff Johnson55d2ab42019-03-06 11:43:49 -08009031 adapter = hdd_get_adapter_by_vdev(hdd_ctx,
9032 frame_ind->sessionId);
Rajeev Kumard004abc2016-02-17 12:09:56 -08009033 }
9034
Jeff Johnsond36fa332019-03-18 13:42:25 -07009035 if ((adapter) &&
Rajeev Kumard004abc2016-02-17 12:09:56 -08009036 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
9037 __hdd_indicate_mgmt_frame(adapter,
9038 frame_ind->frame_len,
9039 frame_ind->frameBuf,
9040 frame_ind->frameType,
9041 frame_ind->rxChan,
Srinivas Dasariea1c1332019-02-18 12:43:23 +05309042 frame_ind->rxRssi,
9043 frame_ind->rx_flags);
Rajeev Kumard004abc2016-02-17 12:09:56 -08009044}
9045
Kapil Gupta8878ad92017-02-13 11:56:04 +05309046void hdd_acs_response_timeout_handler(void *context)
9047{
9048 struct hdd_external_acs_timer_context *timer_context =
9049 (struct hdd_external_acs_timer_context *)context;
Jeff Johnson9d295242017-08-29 14:39:48 -07009050 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009051 struct hdd_context *hdd_ctx;
Kapil Gupta8878ad92017-02-13 11:56:04 +05309052 uint8_t reason;
9053
Dustin Brown491d54b2018-03-14 12:39:11 -07009054 hdd_enter();
Kapil Gupta8878ad92017-02-13 11:56:04 +05309055 if (!timer_context) {
9056 hdd_err("invlaid timer context");
9057 return;
9058 }
9059 adapter = timer_context->adapter;
9060 reason = timer_context->reason;
9061
9062
9063 if ((!adapter) ||
9064 (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
9065 hdd_err("invalid adapter or adapter has invalid magic");
9066 return;
9067 }
9068 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9069 if (wlan_hdd_validate_context(hdd_ctx))
9070 return;
9071
9072 if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags))
9073 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
9074 else
9075 return;
9076
9077 hdd_err("ACS timeout happened for %s reason %d",
9078 adapter->dev->name, reason);
Jeff Johnson16528362018-06-14 12:34:16 -07009079
Kapil Gupta8878ad92017-02-13 11:56:04 +05309080 switch (reason) {
9081 /* SAP init case */
9082 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
9083 wlan_sap_set_vendor_acs(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
9084 false);
9085 wlan_hdd_cfg80211_start_acs(adapter);
9086 break;
9087 /* DFS detected on current channel */
9088 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
9089 wlan_sap_update_next_channel(
9090 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 0, 0);
Jeff Johnson16528362018-06-14 12:34:16 -07009091 sme_update_new_channel_event(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -08009092 adapter->vdev_id);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309093 break;
9094 /* LTE coex event on current channel */
9095 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
9096 hdd_lte_coex_restart_sap(adapter, hdd_ctx);
9097 break;
9098 default:
9099 hdd_info("invalid reason for timer invoke");
9100
9101 }
9102}
9103
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009104/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009105 * hdd_override_ini_config - Override INI config
9106 * @hdd_ctx: HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009107 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009108 * Override INI config based on module parameter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009109 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009110 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009111 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009112static void hdd_override_ini_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009113{
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309114 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009115
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009116 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
gaurank kathpalia97c070b2019-01-07 17:23:06 +05309117 ucfg_scan_cfg_set_dfs_chan_scan_allowed(hdd_ctx->psoc,
9118 enable_dfs_chan_scan);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009119 hdd_debug("Module enable_dfs_chan_scan set to %d",
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009120 enable_dfs_chan_scan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009121 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009122 if (0 == enable_11d || 1 == enable_11d) {
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309123 status = ucfg_mlme_set_11d_enabled(hdd_ctx->psoc, enable_11d);
9124 if (!QDF_IS_STATUS_SUCCESS(status))
9125 hdd_err("Failed to set 11d_enable flag");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009126 }
Leo Chang11545d62016-10-17 14:53:50 -07009127
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +05309128 if (hdd_ctx->config->action_oui_enable && !ucfg_action_oui_enabled()) {
9129 hdd_ctx->config->action_oui_enable = 0;
Sourav Mohapatra58841062018-11-19 16:33:27 +05309130 hdd_err("Ignore action oui ini, since no action_oui component");
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +05309131 }
Will Huang14b120f2019-01-14 17:26:14 +08009132
9133 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
9134 hdd_override_all_ps(hdd_ctx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009135}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009136
Ashish Kumar Dhanotiya12f68212018-09-04 22:00:14 +05309137#ifdef ENABLE_MTRACE_LOG
9138static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
9139{
9140 uint8_t module_id = 0;
9141 int qdf_print_idx = -1;
9142
9143 qdf_print_idx = qdf_get_pidx();
9144 for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++)
9145 qdf_print_set_category_verbose(
9146 qdf_print_idx,
9147 module_id, QDF_TRACE_LEVEL_TRACE,
9148 hdd_ctx->config->enable_mtrace);
9149}
9150#else
9151static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
9152{
9153}
9154
9155#endif
9156
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009157/**
9158 * hdd_set_trace_level_for_each - Set trace level for each INI config
9159 * @hdd_ctx - HDD context
9160 *
9161 * Set trace level for each module based on INI config.
9162 *
9163 * Return: None
9164 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009165static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009166{
Wu Gaobc6eaa12018-11-30 14:17:45 +08009167 hdd_qdf_trace_enable(QDF_MODULE_ID_DP, 0x7f);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05309168 hdd_qdf_trace_enable(QDF_MODULE_ID_MLME, 0xffff);
Sourav Mohapatra113685f2018-08-29 14:21:55 +05309169 hdd_qdf_trace_enable(QDF_MODULE_ID_FWOL, 0xffff);
Kiran Kumar Lokere4ce40482018-08-30 16:31:00 -07009170 hdd_qdf_trace_enable(QDF_MODULE_ID_CRYPTO, 0xffff);
Kiran Kumar Lokere798de7e2017-03-30 14:01:12 -07009171
Ashish Kumar Dhanotiya12f68212018-09-04 22:00:14 +05309172 hdd_set_mtrace_for_each(hdd_ctx);
9173
Nirav Shah5c083da2018-08-03 13:46:02 +05309174 hdd_cfg_print_global_config(hdd_ctx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009175}
9176
9177/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009178 * hdd_context_init() - Initialize HDD context
9179 * @hdd_ctx: HDD context.
9180 *
9181 * Initialize HDD context along with all the feature specific contexts.
9182 *
9183 * return: 0 on success and errno on failure.
9184 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009185static int hdd_context_init(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009186{
9187 int ret;
9188
9189 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
Dustin Brownad06be62019-02-04 14:52:56 -08009190 hdd_ctx->max_intf_count = WLAN_MAX_VDEVS;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009191
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009192 init_completion(&hdd_ctx->mc_sus_event_var);
9193 init_completion(&hdd_ctx->ready_to_suspend);
9194
9195 qdf_spinlock_create(&hdd_ctx->connection_status_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009196 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05309197
Dustin Brownbee82832018-07-23 10:10:51 -07009198 qdf_list_create(&hdd_ctx->hdd_adapters, 0);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009199
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009200 ret = hdd_scan_context_init(hdd_ctx);
9201 if (ret)
9202 goto list_destroy;
9203
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009204 hdd_rx_wake_lock_create(hdd_ctx);
9205
9206 ret = hdd_sap_context_init(hdd_ctx);
9207 if (ret)
9208 goto scan_destroy;
9209
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009210 wlan_hdd_cfg80211_extscan_init(hdd_ctx);
9211
9212 hdd_init_offloaded_packets_ctx(hdd_ctx);
9213
9214 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
9215 hdd_ctx->config);
9216 if (ret)
Wu Gao02bd75b2017-10-13 18:34:02 +08009217 goto sap_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009218
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05309219 qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock,
9220 "monitor_mode_wakelock");
9221
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009222 return 0;
9223
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009224sap_destroy:
9225 hdd_sap_context_destroy(hdd_ctx);
9226
9227scan_destroy:
9228 hdd_scan_context_destroy(hdd_ctx);
9229 hdd_rx_wake_lock_destroy(hdd_ctx);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009230list_destroy:
Jeff Johnson19fc8e42017-10-30 19:53:49 -07009231 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Sandeep Puligillad0004212017-02-26 18:34:56 -08009232
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009233 return ret;
9234}
9235
Dustin Brown4c663222018-10-23 14:19:36 -07009236void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx)
9237{
9238 uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time;
9239 enum wake_lock_reason reason =
9240 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER;
9241
Rajeev Kumar7b7bb3f2018-12-20 12:09:54 -08009242 if (!timeout_ms) {
9243 hdd_info("psoc idle timer is disabled");
9244 return;
9245 }
9246
Dustin Brown4c663222018-10-23 14:19:36 -07009247 hdd_debug("Starting psoc idle timer");
Dustin Brown8d8ab302019-03-05 16:19:36 -08009248 qdf_delayed_work_start(&hdd_ctx->psoc_idle_timeout_work, timeout_ms);
Dustin Brown4c663222018-10-23 14:19:36 -07009249 hdd_prevent_suspend_timeout(timeout_ms, reason);
9250}
9251
9252void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx)
9253{
Dustin Brown8d8ab302019-03-05 16:19:36 -08009254 qdf_delayed_work_stop_sync(&hdd_ctx->psoc_idle_timeout_work);
Dustin Brown4c663222018-10-23 14:19:36 -07009255 hdd_debug("Stopped psoc idle timer");
9256}
9257
Sourav Mohapatra698d6f62019-01-29 14:49:52 +05309258/*
9259 * enum hdd_block_shutdown - Control if driver allows modem shutdown
9260 * @HDD_UNBLOCK_MODEM_SHUTDOWN: Unblock shutdown
9261 * @HDD_BLOCK_MODEM_SHUTDOWN: Block shutdown
9262 *
9263 * On calling pld_block_shutdown API with the given values, modem
9264 * graceful shutdown is blocked/unblocked.
9265 */
9266enum hdd_block_shutdown {
9267 HDD_UNBLOCK_MODEM_SHUTDOWN,
9268 HDD_BLOCK_MODEM_SHUTDOWN,
9269};
9270
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009271/**
Dustin Brown3ecc8782018-09-19 16:37:13 -07009272 * hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc
9273 * @hdd_ctx: the hdd context which should be shutdown
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309274 *
Dustin Brown3ecc8782018-09-19 16:37:13 -07009275 * When no interfaces are "up" on a psoc, an idle shutdown timer is started.
9276 * If no interfaces are brought up before the timer expires, we do an
9277 * "idle shutdown," cutting power to the physical SoC to save power. This is
9278 * done completely transparently from the perspective of userspace.
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309279 *
Dustin Brown3ecc8782018-09-19 16:37:13 -07009280 * Return: None
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309281 */
Dustin Brown3ecc8782018-09-19 16:37:13 -07009282static void hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309283{
Dustin Brown363b4792019-02-05 16:11:55 -08009284 struct osif_psoc_sync *psoc_sync;
Dustin Browncfcb5762019-01-31 15:43:45 -08009285 int errno;
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309286
Dustin Brown491d54b2018-03-14 12:39:11 -07009287 hdd_enter();
Dustin Brown3ecc8782018-09-19 16:37:13 -07009288
Dustin Brown363b4792019-02-05 16:11:55 -08009289 errno = osif_psoc_sync_trans_start(hdd_ctx->parent_dev, &psoc_sync);
Dustin Browncfcb5762019-01-31 15:43:45 -08009290 if (errno) {
9291 hdd_info("psoc busy, abort idle shutdown; errno:%d", errno);
9292 goto exit;
Dustin Brown3ecc8782018-09-19 16:37:13 -07009293 }
Sourav Mohapatra698d6f62019-01-29 14:49:52 +05309294 /* Block the modem graceful shutdown till stop modules is completed */
9295 pld_block_shutdown(hdd_ctx->parent_dev, HDD_BLOCK_MODEM_SHUTDOWN);
Dustin Brown3ecc8782018-09-19 16:37:13 -07009296
Dustin Brown363b4792019-02-05 16:11:55 -08009297 osif_psoc_sync_wait_for_ops(psoc_sync);
Dustin Browncfcb5762019-01-31 15:43:45 -08009298
Dustin Brown3ecc8782018-09-19 16:37:13 -07009299 QDF_BUG(!hdd_wlan_stop_modules(hdd_ctx, false));
9300
Dustin Brown363b4792019-02-05 16:11:55 -08009301 osif_psoc_sync_trans_stop(psoc_sync);
Dustin Brown3ecc8782018-09-19 16:37:13 -07009302
Sourav Mohapatra698d6f62019-01-29 14:49:52 +05309303 pld_block_shutdown(hdd_ctx->parent_dev, HDD_UNBLOCK_MODEM_SHUTDOWN);
9304
Dustin Browncfcb5762019-01-31 15:43:45 -08009305exit:
Dustin Browne74003f2018-03-14 12:51:58 -07009306 hdd_exit();
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309307}
9308
Dustin Brown3ecc8782018-09-19 16:37:13 -07009309int hdd_psoc_idle_restart(struct hdd_context *hdd_ctx)
9310{
Dustin Brown693b5352019-01-17 10:00:31 -08009311 QDF_BUG(rtnl_is_locked());
Dustin Brown3ecc8782018-09-19 16:37:13 -07009312
Dustin Browncfcb5762019-01-31 15:43:45 -08009313 return hdd_wlan_start_modules(hdd_ctx, false);
Dustin Brown3ecc8782018-09-19 16:37:13 -07009314}
9315
9316/**
9317 * hdd_psoc_idle_timeout_callback() - Handler for psoc idle timeout
9318 * @priv: pointer to hdd context
9319 *
9320 * Return: None
9321 */
9322static void hdd_psoc_idle_timeout_callback(void *priv)
9323{
9324 struct hdd_context *hdd_ctx = priv;
9325
9326 if (wlan_hdd_validate_context(hdd_ctx))
9327 return;
9328
9329 hdd_debug("Psoc idle timeout elapsed; starting psoc shutdown");
9330 hdd_psoc_idle_shutdown(hdd_ctx);
9331}
9332
Nirav Shaheb017be2018-02-15 11:20:58 +05309333#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9334static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
9335{
9336 wlan_logging_set_log_to_console(hdd_ctx->config->
9337 wlan_logging_to_console);
9338 wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable);
9339}
9340#else
9341static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
9342{ }
9343#endif
9344
Dundi Raviteja8e338282018-09-25 17:16:04 +05309345#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9346static void hdd_init_wlan_logging_params(struct hdd_config *config,
9347 struct wlan_objmgr_psoc *psoc)
9348{
9349 config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT);
9350
9351 config->wlan_logging_to_console =
9352 cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT);
9353}
9354#else
9355static void hdd_init_wlan_logging_params(struct hdd_config *config,
9356 struct wlan_objmgr_psoc *psoc)
9357{
9358}
9359#endif
9360
9361#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
9362static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
9363 struct wlan_objmgr_psoc *psoc)
9364{
9365 config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN);
9366}
9367#else
9368static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
9369 struct wlan_objmgr_psoc *psoc)
9370{
9371}
9372#endif
9373
9374#ifndef REMOVE_PKT_LOG
9375static void hdd_init_packet_log(struct hdd_config *config,
9376 struct wlan_objmgr_psoc *psoc)
9377{
9378 config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG);
9379}
9380#else
9381static void hdd_init_packet_log(struct hdd_config *config,
9382 struct wlan_objmgr_psoc *psoc)
9383{
9384}
9385#endif
9386
Sandeep Puligilla43b6d1a2018-12-03 09:16:13 -08009387#ifdef ENABLE_MTRACE_LOG
9388static void hdd_init_mtrace_log(struct hdd_config *config,
9389 struct wlan_objmgr_psoc *psoc)
9390{
9391 config->enable_mtrace = cfg_get(psoc, CFG_ENABLE_MTRACE);
9392}
9393#else
9394static void hdd_init_mtrace_log(struct hdd_config *config,
9395 struct wlan_objmgr_psoc *psoc)
9396{
9397}
9398#endif
9399
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +05309400#ifdef FEATURE_RUNTIME_PM
9401static void hdd_init_runtime_pm(struct hdd_config *config,
9402 struct wlan_objmgr_psoc *psoc)
9403{
9404 config->runtime_pm = cfg_get(psoc, CFG_ENABLE_RUNTIME_PM);
9405}
9406#else
9407static void hdd_init_runtime_pm(struct hdd_config *config,
9408 struct wlan_objmgr_psoc *psoc)
9409
9410{
9411}
9412#endif
9413
9414#ifdef FEATURE_WLAN_DYNAMIC_CVM
9415static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
9416 struct wlan_objmgr_psoc *psoc)
9417{
9418 config->vc_mode_cfg_bitmap = cfg_get(psoc, CFG_VC_MODE_BITMAP);
9419}
9420#else
9421static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
9422 struct wlan_objmgr_psoc *psoc)
9423{
9424}
9425#endif
9426
gaurank kathpalia566c81b2019-02-20 14:31:45 +05309427#ifdef DHCP_SERVER_OFFLOAD
9428static void
9429hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx)
9430{
9431 uint8_t num_entries;
9432
9433 hdd_ctx->config->dhcp_server_ip.is_dhcp_server_ip_valid = true;
9434 hdd_string_to_u8_array(cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME),
9435 hdd_ctx->config->dhcp_server_ip.dhcp_server_ip,
9436 &num_entries, IPADDR_NUM_ENTRIES);
9437
9438 if (num_entries != IPADDR_NUM_ENTRIES) {
9439 hdd_err("Incorrect IP address (%s) assigned for DHCP server!",
9440 cfg_get(hdd_ctx->psoc, CFG_DHCP_SERVER_IP_NAME));
9441 hdd_config->dhcp_server_ip.is_dhcp_server_ip_valid = false;
9442 }
9443}
9444#else
9445static void
9446hdd_init_dhcp_server_ip(struct hdd_context *hdd_ctx)
9447{
9448}
9449#endif
9450
Dundi Raviteja8e338282018-09-25 17:16:04 +05309451/**
9452 * hdd_cfg_params_init() - Initialize hdd params in hdd_config strucuture
9453 * @hdd_ctx - Pointer to HDD context
9454 *
9455 * Return: None
9456 */
9457static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
9458{
9459 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
9460 struct hdd_config *config = hdd_ctx->config;
9461
9462 if (!psoc) {
9463 hdd_err("Invalid psoc");
9464 return;
9465 }
9466
9467 if (!config) {
9468 hdd_err("Invalid hdd config");
9469 return;
9470 }
9471
gaurank kathpalia43c52622019-02-11 12:30:05 +05309472 config->dot11Mode = cfg_get(psoc, CFG_HDD_DOT11_MODE);
Dundi Raviteja8e338282018-09-25 17:16:04 +05309473 config->bug_on_reinit_failure = cfg_get(psoc,
9474 CFG_BUG_ON_REINIT_FAILURE);
9475
9476 config->is_ramdump_enabled = cfg_get(psoc,
9477 CFG_ENABLE_RAMDUMP_COLLECTION);
9478
9479 config->iface_change_wait_time = cfg_get(psoc,
9480 CFG_INTERFACE_CHANGE_WAIT);
9481
9482 config->multicast_host_fw_msgs = cfg_get(psoc,
9483 CFG_MULTICAST_HOST_FW_MSGS);
9484
9485 config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL);
Dundi Raviteja8e338282018-09-25 17:16:04 +05309486 config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT);
9487 config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG);
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +05309488 config->operating_channel = cfg_get(psoc, CFG_OPERATING_CHANNEL);
9489 config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE);
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +05309490 qdf_str_lcopy(config->enable_concurrent_sta,
9491 cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA),
9492 CFG_CONCURRENT_IFACE_MAX_LEN);
9493 qdf_str_lcopy(config->dbs_scan_selection,
9494 cfg_get(psoc, CFG_DBS_SCAN_SELECTION),
9495 CFG_DBS_SCAN_PARAM_LENGTH);
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +05309496 config->inform_bss_rssi_raw = cfg_get(psoc, CFG_INFORM_BSS_RSSI_RAW);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +05309497 config->mac_provision = cfg_get(psoc, CFG_ENABLE_MAC_PROVISION);
9498 config->provisioned_intf_pool =
9499 cfg_get(psoc, CFG_PROVISION_INTERFACE_POOL);
9500 config->derived_intf_pool = cfg_get(psoc, CFG_DERIVED_INTERFACE_POOL);
Sourav Mohapatra58841062018-11-19 16:33:27 +05309501 config->action_oui_enable = cfg_get(psoc, CFG_ENABLE_ACTION_OUI);
Jeff Johnson15a88ac2019-03-11 14:35:25 -07009502 config->advertise_concurrent_operation =
Sandeep Puligilladc6d68a2019-01-04 16:57:12 -08009503 cfg_get(psoc,
9504 CFG_ADVERTISE_CONCURRENT_OPERATION);
Sourav Mohapatra58841062018-11-19 16:33:27 +05309505 qdf_str_lcopy(config->action_oui_str[0],
9506 cfg_get(psoc, CFG_ACTION_OUI_CONNECT_1X1),
9507 ACTION_OUI_MAX_STR_LEN);
9508 qdf_str_lcopy(config->action_oui_str[1],
9509 cfg_get(psoc, CFG_ACTION_OUI_ITO_EXTENSION),
9510 ACTION_OUI_MAX_STR_LEN);
9511 qdf_str_lcopy(config->action_oui_str[2],
9512 cfg_get(psoc, CFG_ACTION_OUI_CCKM_1X1),
9513 ACTION_OUI_MAX_STR_LEN);
9514 qdf_str_lcopy(config->action_oui_str[3],
9515 cfg_get(psoc, CFG_ACTION_OUI_ITO_ALTERNATE),
9516 ACTION_OUI_MAX_STR_LEN);
9517 qdf_str_lcopy(config->action_oui_str[4],
9518 cfg_get(psoc, CFG_ACTION_OUI_SWITCH_TO_11N_MODE),
9519 ACTION_OUI_MAX_STR_LEN);
9520 qdf_str_lcopy(config->action_oui_str[5],
9521 cfg_get(psoc,
9522 CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN),
9523 ACTION_OUI_MAX_STR_LEN);
Rajeev Kumar Sirasanagandlad7987f12018-12-08 23:24:04 +05309524 qdf_str_lcopy(config->action_oui_str[6],
9525 cfg_get(psoc,
9526 CFG_ACTION_OUI_DISABLE_AGGRESSIVE_TX),
9527 ACTION_OUI_MAX_STR_LEN);
Sourav Mohapatra9e014cf2018-12-11 09:39:33 +05309528 config->enable_rtt_support = cfg_get(psoc, CFG_ENABLE_RTT_SUPPORT);
Sandeep Puligillaefeb4a92019-01-08 00:06:51 -08009529 config->is_unit_test_framework_enabled =
9530 cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK);
Dundi Raviteja8e338282018-09-25 17:16:04 +05309531
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +05309532 hdd_init_vc_mode_cfg_bitmap(config, psoc);
9533 hdd_init_runtime_pm(config, psoc);
Dundi Raviteja8e338282018-09-25 17:16:04 +05309534 hdd_init_wlan_auto_shutdown(config, psoc);
9535 hdd_init_wlan_logging_params(config, psoc);
9536 hdd_init_packet_log(config, psoc);
Sandeep Puligilla43b6d1a2018-12-03 09:16:13 -08009537 hdd_init_mtrace_log(config, psoc);
gaurank kathpalia566c81b2019-02-20 14:31:45 +05309538 hdd_init_dhcp_server_ip(hdd_ctx);
jitiphil869b9f72018-09-25 17:14:01 +05309539 hdd_dp_cfg_update(psoc, hdd_ctx);
Dundi Raviteja8e338282018-09-25 17:16:04 +05309540}
9541
Dustin Brown623e7e32018-09-05 14:27:50 -07009542struct hdd_context *hdd_context_create(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009543{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309544 QDF_STATUS status;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009545 int ret = 0;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009546 struct hdd_context *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009547
Dustin Brown491d54b2018-03-14 12:39:11 -07009548 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009549
Dustin Brown92bd8382018-10-31 15:49:46 -07009550 hdd_ctx = hdd_cfg80211_wiphy_alloc();
9551 if (!hdd_ctx) {
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009552 ret = -ENOMEM;
9553 goto err_out;
9554 }
9555
Dustin Brown8d8ab302019-03-05 16:19:36 -08009556 status = qdf_delayed_work_create(&hdd_ctx->psoc_idle_timeout_work,
9557 hdd_psoc_idle_timeout_callback,
9558 hdd_ctx);
9559 if (QDF_IS_STATUS_ERROR(status)) {
9560 ret = qdf_status_to_os_return(status);
9561 goto wiphy_dealloc;
9562 }
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309563
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009564 hdd_ctx->parent_dev = dev;
Jeff Johnson995fd512019-03-06 08:45:10 -08009565 hdd_ctx->last_scan_reject_vdev_id = WLAN_UMAC_VDEV_ID_MAX;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009566
Anurag Chouhan600c3a02016-03-01 10:33:54 +05309567 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
Min Liu74a1a502018-10-10 19:59:07 +08009568 if (!hdd_ctx->config) {
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009569 ret = -ENOMEM;
9570 goto err_free_hdd_context;
9571 }
9572
9573 /* Read and parse the qcom_cfg.ini file */
9574 status = hdd_parse_config_ini(hdd_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309575 if (QDF_STATUS_SUCCESS != status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05309576 hdd_err("Error (status: %d) parsing INI file: %s", status,
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009577 WLAN_INI_FILE);
9578 ret = -EINVAL;
9579 goto err_free_config;
9580 }
9581
Dustin Brown84f46ea2018-02-15 11:57:36 -08009582 status = cfg_parse(WLAN_INI_FILE);
9583 if (QDF_IS_STATUS_ERROR(status))
9584 hdd_err("Failed to parse cfg %s; status:%d\n",
9585 WLAN_INI_FILE, status);
9586
Dundi Ravitejafb9357a2018-09-25 12:16:03 +05309587 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID);
9588 if (ret) {
Dundi Raviteja8e338282018-09-25 17:16:04 +05309589 QDF_DEBUG_PANIC("Psoc creation fails!");
Dundi Ravitejafb9357a2018-09-25 12:16:03 +05309590 goto err_free_config;
9591 }
9592
Dundi Raviteja8e338282018-09-25 17:16:04 +05309593 hdd_cfg_params_init(hdd_ctx);
9594
Dustin Brown4bbd5462019-03-22 11:18:13 -07009595 /* apply multiplier config, if not already set via module parameter */
9596 if (qdf_timer_get_multiplier() == 1)
9597 qdf_timer_set_multiplier(cfg_get(hdd_ctx->psoc,
9598 CFG_TIMER_MULTIPLIER));
Dustin Browna9a84522019-02-04 12:25:40 -08009599 hdd_debug("set timer multiplier: %u", qdf_timer_get_multiplier());
Dustin Brown7f939932017-05-18 15:02:17 -07009600
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309601 cds_set_fatal_event(cfg_get(hdd_ctx->psoc,
9602 CFG_ENABLE_FATAL_EVENT_TRIGGER));
Abhishek Singh5ea86532016-04-27 14:10:53 +05309603
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009604 hdd_override_ini_config(hdd_ctx);
9605
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009606 ret = hdd_context_init(hdd_ctx);
9607
9608 if (ret)
Dundi Ravitejafb9357a2018-09-25 12:16:03 +05309609 goto err_hdd_objmgr_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009610
Nirav Shah6aeecf92019-02-13 14:05:03 +05309611 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE ||
9612 hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009613 goto skip_multicast_logging;
9614
9615 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
9616
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07009617 ret = wlan_hdd_init_tx_rx_histogram(hdd_ctx);
9618 if (ret)
9619 goto err_deinit_hdd_context;
Nirav Shahed34b212016-04-25 10:59:16 +05309620
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -07009621 ret = hdd_init_netlink_services(hdd_ctx);
9622 if (ret)
9623 goto err_deinit_txrx_histogram;
9624
Nirav Shaheb017be2018-02-15 11:20:58 +05309625 hdd_set_wlan_logging(hdd_ctx);
Nirav Shahed34b212016-04-25 10:59:16 +05309626
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009627skip_multicast_logging:
9628 hdd_set_trace_level_for_each(hdd_ctx);
9629
Rajeev Kumar493a31b2017-09-29 14:01:24 -07009630 cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx);
9631
Dustin Browne74003f2018-03-14 12:51:58 -07009632 hdd_exit();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -07009633
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009634 return hdd_ctx;
9635
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -07009636err_deinit_txrx_histogram:
9637 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
9638
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07009639err_deinit_hdd_context:
9640 hdd_context_deinit(hdd_ctx);
9641
Dundi Ravitejafb9357a2018-09-25 12:16:03 +05309642err_hdd_objmgr_destroy:
9643 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
9644
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009645err_free_config:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05309646 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009647
9648err_free_hdd_context:
Dustin Brown8d8ab302019-03-05 16:19:36 -08009649 qdf_delayed_work_destroy(&hdd_ctx->psoc_idle_timeout_work);
9650
9651wiphy_dealloc:
Rajeev Kumarfa55a692018-01-09 14:12:41 -08009652 wiphy_free(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009653
9654err_out:
9655 return ERR_PTR(ret);
9656}
9657
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009658/**
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309659 * hdd_start_station_adapter()- Start the Station Adapter
9660 * @adapter: HDD adapter
9661 *
9662 * This function initializes the adapter for the station mode.
9663 *
9664 * Return: 0 on success or errno on failure.
9665 */
Jeff Johnson9d295242017-08-29 14:39:48 -07009666int hdd_start_station_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309667{
9668 QDF_STATUS status;
Krunal Sonib51eec72017-11-20 21:53:01 -08009669 int ret;
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309670
Dustin Brownfdf17c12018-03-14 12:55:34 -07009671 hdd_enter_dev(adapter->dev);
Krunal Sonib51eec72017-11-20 21:53:01 -08009672 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
9673 hdd_err("session is already opened, %d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -08009674 adapter->vdev_id);
Krunal Sonib51eec72017-11-20 21:53:01 -08009675 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
9676 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309677
Krunal Sonib51eec72017-11-20 21:53:01 -08009678 ret = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
9679 if (ret) {
9680 hdd_err("failed to create vdev: %d", ret);
9681 return ret;
9682 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309683 status = hdd_init_station_mode(adapter);
9684
9685 if (QDF_STATUS_SUCCESS != status) {
9686 hdd_err("Error Initializing station mode: %d", status);
9687 return qdf_status_to_os_return(status);
9688 }
9689
Arun Khandavallifae92942016-08-01 13:31:08 +05309690 hdd_register_tx_flow_control(adapter,
9691 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08009692 hdd_tx_resume_cb,
9693 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +05309694
Visweswara Tanukub5a61242019-03-26 12:24:13 +05309695 hdd_register_hl_netdev_fc_timer(adapter,
9696 hdd_tx_resume_timer_expired_handler);
9697
Dustin Browne74003f2018-03-14 12:51:58 -07009698 hdd_exit();
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05309699
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309700 return 0;
9701}
9702
9703/**
9704 * hdd_start_ap_adapter()- Start AP Adapter
9705 * @adapter: HDD adapter
9706 *
9707 * This function initializes the adapter for the AP mode.
9708 *
9709 * Return: 0 on success errno on failure.
9710 */
Jeff Johnson9d295242017-08-29 14:39:48 -07009711int hdd_start_ap_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309712{
9713 QDF_STATUS status;
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08009714 bool is_ssr = false;
Krunal Sonib51eec72017-11-20 21:53:01 -08009715 int ret;
Naveen Rawat1af09392018-01-03 17:28:21 -08009716 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Arif Hussainbd5194c2018-11-27 19:01:15 -08009717 uint32_t fine_time_meas_cap = 0;
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309718
Dustin Brown491d54b2018-03-14 12:39:11 -07009719 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309720
Krunal Sonib51eec72017-11-20 21:53:01 -08009721 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
9722 hdd_err("session is already opened, %d",
Jeff Johnson5a6fc962019-02-04 14:20:25 -08009723 adapter->vdev_id);
Krunal Sonib51eec72017-11-20 21:53:01 -08009724 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
9725 }
9726 /*
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08009727 * In SSR case no need to create new sap context.
9728 * Otherwise create sap context first and then create
9729 * vdev as while creating the vdev, driver needs to
9730 * register SAP callback and that callback uses sap context
Krunal Sonib51eec72017-11-20 21:53:01 -08009731 */
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08009732 if (adapter->session.ap.sap_context) {
9733 is_ssr = true;
9734 } else if (!hdd_sap_create_ctx(adapter)) {
Krunal Sonib51eec72017-11-20 21:53:01 -08009735 hdd_err("sap creation failed");
9736 return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
9737 }
9738
9739 ret = hdd_vdev_create(adapter, wlansap_roam_callback,
9740 adapter->session.ap.sap_context);
9741 if (ret) {
9742 hdd_err("failed to create vdev, status:%d", ret);
9743 hdd_sap_destroy_ctx(adapter);
9744 return ret;
9745 }
Naveen Rawat1af09392018-01-03 17:28:21 -08009746
Arif Hussainbd5194c2018-11-27 19:01:15 -08009747 if (adapter->device_mode == QDF_SAP_MODE) {
9748 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
9749 &fine_time_meas_cap);
Jeff Johnson5a6fc962019-02-04 14:20:25 -08009750 sme_cli_set_command(adapter->vdev_id,
Naveen Rawat1af09392018-01-03 17:28:21 -08009751 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE,
Arif Hussainbd5194c2018-11-27 19:01:15 -08009752 (bool)(fine_time_meas_cap & WMI_FW_AP_RTT_RESPR),
Naveen Rawat1af09392018-01-03 17:28:21 -08009753 VDEV_CMD);
Arif Hussainbd5194c2018-11-27 19:01:15 -08009754 }
Naveen Rawat1af09392018-01-03 17:28:21 -08009755
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08009756 status = hdd_init_ap_mode(adapter, is_ssr);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309757
9758 if (QDF_STATUS_SUCCESS != status) {
9759 hdd_err("Error Initializing the AP mode: %d", status);
9760 return qdf_status_to_os_return(status);
9761 }
9762
Arun Khandavallifae92942016-08-01 13:31:08 +05309763 hdd_register_tx_flow_control(adapter,
9764 hdd_softap_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08009765 hdd_softap_tx_resume_cb,
9766 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +05309767
Visweswara Tanukub5a61242019-03-26 12:24:13 +05309768 hdd_register_hl_netdev_fc_timer(adapter,
9769 hdd_tx_resume_timer_expired_handler);
9770
Dustin Browne74003f2018-03-14 12:51:58 -07009771 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309772 return 0;
9773}
9774
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309775#ifdef QCA_LL_TX_FLOW_CONTROL_V2
9776/**
9777 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
9778 * @cds_cfg: CDS Configuration
9779 * @hdd_ctx: Pointer to hdd context
9780 *
9781 * Return: none
9782 */
9783static inline void hdd_txrx_populate_cds_config(struct cds_config_info
9784 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009785 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309786{
9787 cds_cfg->tx_flow_stop_queue_th =
jitiphil47c3d9a2018-11-08 18:30:55 +05309788 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309789 cds_cfg->tx_flow_start_queue_offset =
jitiphil47c3d9a2018-11-08 18:30:55 +05309790 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
Mohit Khanna70322002018-05-15 19:21:32 -07009791 /* configuration for DP RX Threads */
9792 cds_cfg->enable_dp_rx_threads = hdd_ctx->enable_dp_rx_threads;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309793}
9794#else
9795static inline void hdd_txrx_populate_cds_config(struct cds_config_info
9796 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009797 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309798{
9799}
9800#endif
9801
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309802/**
9803 * hdd_update_cds_config() - API to update cds configuration parameters
9804 * @hdd_ctx: HDD Context
9805 *
9806 * Return: 0 for Success, errno on failure
9807 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009808static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309809{
9810 struct cds_config_info *cds_cfg;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309811 int value;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309812 uint8_t band_capability;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309813 uint8_t ito_repeat_count;
Vignesh Viswanathana851d752018-10-03 19:44:38 +05309814 bool crash_inject;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309815 bool self_recovery;
9816 bool fw_timeout_crash;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309817 QDF_STATUS status;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309818
Min Liu74a1a502018-10-10 19:59:07 +08009819 cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg));
9820 if (!cds_cfg)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309821 return -ENOMEM;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309822
Srinivas Girigowda35b00312017-06-27 21:52:03 -07009823 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
Bala Venkatesh46e29032018-11-14 18:24:55 +05309824 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
9825 &cds_cfg->sta_maxlimod_dtim);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309826
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309827 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
Vignesh Viswanathana851d752018-10-03 19:44:38 +05309828 if (QDF_IS_STATUS_ERROR(status)) {
9829 hdd_err("Failed to get crash inject ini config");
9830 goto exit;
9831 }
9832
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309833 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
9834 if (QDF_IS_STATUS_ERROR(status)) {
9835 hdd_err("Failed to get self recovery ini config");
9836 goto exit;
9837 }
9838
9839 status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc,
9840 &fw_timeout_crash);
9841 if (QDF_IS_STATUS_ERROR(status)) {
9842 hdd_err("Failed to get fw timeout crash ini config");
9843 goto exit;
9844 }
9845
9846 status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc,
9847 &ito_repeat_count);
9848 if (QDF_IS_STATUS_ERROR(status)) {
9849 hdd_err("Failed to get ITO repeat count ini config");
9850 goto exit;
9851 }
9852
Vignesh Viswanathana851d752018-10-03 19:44:38 +05309853 cds_cfg->force_target_assert_enabled = crash_inject;
SaidiReddy Yenugacc733af2016-11-09 17:45:42 +05309854
Dustin Brown05d81302018-09-11 16:49:22 -07009855 ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309856 cds_cfg->ap_maxoffload_peers = value;
Dustin Brown05d81302018-09-11 16:49:22 -07009857 ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309858 &value);
9859 cds_cfg->ap_maxoffload_reorderbuffs = value;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309860
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309861 cds_cfg->reorder_offload =
jitiphil47c3d9a2018-11-08 18:30:55 +05309862 cfg_get(hdd_ctx->psoc, CFG_DP_REORDER_OFFLOAD_SUPPORT);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309863
9864 /* IPA micro controller data path offload resource config item */
Sravan Kumar Kairam5214f652018-03-13 09:52:31 +05309865 cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled();
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309866
Jeff Johnsone2ba3cd2017-10-30 20:02:09 -07009867 cds_cfg->enable_rxthread = hdd_ctx->enable_rxthread;
Dustin Brown05d81302018-09-11 16:49:22 -07009868 ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309869 cds_cfg->max_station = value;
Naveen Rawat64e477e2016-05-20 10:34:56 -07009870 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
Orhan K AKYILDIZ30e8cbc2017-08-11 18:00:28 -07009871 cds_cfg->max_msdus_per_rxinorderind =
jitiphil8e15ea62018-11-16 18:05:34 +05309872 cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND);
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309873 cds_cfg->self_recovery_enabled = self_recovery;
9874 cds_cfg->fw_timeout_crash = fw_timeout_crash;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309875
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309876 cds_cfg->ito_repeat_count = ito_repeat_count;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309877
9878 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
9879 if (QDF_IS_STATUS_ERROR(status))
9880 goto exit;
9881
9882 cds_cfg->bandcapability = band_capability;
Rachit Kankane0106e382018-05-16 18:59:28 +05309883 cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs;
Ashish Kumar Dhanotiya9335d812017-06-30 16:57:20 +05309884
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309885 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
Jeff Johnson9078bdc2016-09-23 17:18:11 -07009886 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309887 cds_init_ini_config(cds_cfg);
9888 return 0;
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05309889
9890exit:
9891 qdf_mem_free(cds_cfg);
9892 return -EINVAL;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309893}
9894
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009895/**
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009896 * hdd_update_user_config() - API to update user configuration
9897 * parameters to obj mgr which are used by multiple components
9898 * @hdd_ctx: HDD Context
9899 *
9900 * Return: 0 for Success, errno on failure
9901 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009902static int hdd_update_user_config(struct hdd_context *hdd_ctx)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009903{
9904 struct wlan_objmgr_psoc_user_config *user_config;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309905 uint8_t band_capability;
9906 QDF_STATUS status;
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309907 bool value = false;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309908
9909 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
9910 if (QDF_IS_STATUS_ERROR(status))
9911 return -EIO;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009912
9913 user_config = qdf_mem_malloc(sizeof(*user_config));
Min Liu74a1a502018-10-10 19:59:07 +08009914 if (!user_config)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009915 return -ENOMEM;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009916
9917 user_config->dot11_mode = hdd_ctx->config->dot11Mode;
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309918 status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value);
9919 if (!QDF_IS_STATUS_SUCCESS(status))
9920 hdd_err("Invalid 11d_enable flag");
9921 user_config->is_11d_support_enabled = value;
9922
9923 value = false;
9924 status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value);
9925 if (!QDF_IS_STATUS_SUCCESS(status))
9926 hdd_err("Invalid 11h_enable flag");
9927 user_config->is_11h_support_enabled = value;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309928 user_config->band_capability = band_capability;
Dustin Brown1dbefe62018-09-11 16:32:03 -07009929 wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009930
9931 qdf_mem_free(user_config);
9932 return 0;
9933}
9934
9935/**
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009936 * hdd_init_thermal_info - Initialize thermal level
9937 * @hdd_ctx: HDD context
9938 *
9939 * Initialize thermal level at SME layer and set the thermal level callback
9940 * which would be called when a configured thermal threshold is hit.
9941 *
9942 * Return: 0 on success and errno on failure
9943 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009944static int hdd_init_thermal_info(struct hdd_context *hdd_ctx)
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009945{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309946 QDF_STATUS status;
Manikandan Mohan9045e2e2018-11-26 16:44:19 -08009947 mac_handle_t mac_handle = hdd_ctx->mac_handle;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009948
Manikandan Mohan9045e2e2018-11-26 16:44:19 -08009949 status = sme_init_thermal_info(mac_handle);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009950
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309951 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanc5548422016-02-24 18:33:27 +05309952 return qdf_status_to_os_return(status);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009953
Jeff Johnson16528362018-06-14 12:34:16 -07009954 sme_add_set_thermal_level_callback(mac_handle,
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009955 hdd_set_thermal_level_cb);
9956
9957 return 0;
9958
9959}
9960
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009961#if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
9962/**
9963 * hdd_hold_rtnl_lock - Hold RTNL lock
9964 *
9965 * Hold RTNL lock
9966 *
9967 * Return: True if held and false otherwise
9968 */
9969static inline bool hdd_hold_rtnl_lock(void)
9970{
9971 rtnl_lock();
9972 return true;
9973}
9974
9975/**
9976 * hdd_release_rtnl_lock - Release RTNL lock
9977 *
9978 * Release RTNL lock
9979 *
9980 * Return: None
9981 */
9982static inline void hdd_release_rtnl_lock(void)
9983{
9984 rtnl_unlock();
9985}
9986#else
9987static inline bool hdd_hold_rtnl_lock(void) { return false; }
9988static inline void hdd_release_rtnl_lock(void) { }
9989#endif
9990
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -08009991#if !defined(REMOVE_PKT_LOG)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -08009992
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309993/* MAX iwpriv command support */
9994#define PKTLOG_SET_BUFF_SIZE 3
Poddar, Siddarthab99a272017-04-10 12:53:26 +05309995#define PKTLOG_CLEAR_BUFF 4
Venkata Sharath Chandra Manchala27e44902019-01-28 11:29:18 -08009996/* Set Maximum pktlog file size to 64MB */
9997#define MAX_PKTLOG_SIZE 64
Poddar, Siddarth176c4362016-10-03 12:25:00 +05309998
9999/**
10000 * hdd_pktlog_set_buff_size() - set pktlog buffer size
10001 * @hdd_ctx: hdd context
10002 * @set_value2: pktlog buffer size value
10003 *
10004 *
10005 * Return: 0 for success or error.
10006 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010007static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010008{
10009 struct sir_wifi_start_log start_log = { 0 };
10010 QDF_STATUS status;
10011
10012 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10013 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
10014 start_log.ini_triggered = cds_is_packet_log_enabled();
10015 start_log.user_triggered = 1;
10016 start_log.size = set_value2;
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010017 start_log.is_pktlog_buff_clear = false;
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010018
Jeff Johnson16528362018-06-14 12:34:16 -070010019 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010020 if (!QDF_IS_STATUS_SUCCESS(status)) {
10021 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010022 hdd_exit();
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010023 return -EINVAL;
10024 }
10025
10026 return 0;
10027}
10028
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010029/**
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010030 * hdd_pktlog_clear_buff() - clear pktlog buffer
10031 * @hdd_ctx: hdd context
10032 *
10033 * Return: 0 for success or error.
10034 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010035static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010036{
10037 struct sir_wifi_start_log start_log;
10038 QDF_STATUS status;
10039
10040 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10041 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
10042 start_log.ini_triggered = cds_is_packet_log_enabled();
10043 start_log.user_triggered = 1;
10044 start_log.size = 0;
10045 start_log.is_pktlog_buff_clear = true;
10046
Jeff Johnson16528362018-06-14 12:34:16 -070010047 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010048 if (!QDF_IS_STATUS_SUCCESS(status)) {
10049 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010050 hdd_exit();
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010051 return -EINVAL;
10052 }
10053
10054 return 0;
10055}
10056
10057
10058/**
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010059 * hdd_process_pktlog_command() - process pktlog command
10060 * @hdd_ctx: hdd context
10061 * @set_value: value set by user
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010062 * @set_value2: pktlog buffer size value
10063 *
10064 * This function process pktlog command.
10065 * set_value2 only matters when set_value is 3 (set buff size)
10066 * otherwise we ignore it.
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010067 *
10068 * Return: 0 for success or error.
10069 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010070int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010071 int set_value2)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010072{
10073 int ret;
10074 bool enable;
10075 uint8_t user_triggered = 0;
10076
10077 ret = wlan_hdd_validate_context(hdd_ctx);
10078 if (0 != ret)
10079 return ret;
10080
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010081 hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010082
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010083 if (set_value > PKTLOG_CLEAR_BUFF) {
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010084 hdd_err("invalid pktlog value %d", set_value);
10085 return -EINVAL;
10086 }
10087
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010088 if (set_value == PKTLOG_SET_BUFF_SIZE) {
10089 if (set_value2 <= 0) {
10090 hdd_err("invalid pktlog size %d", set_value2);
10091 return -EINVAL;
10092 } else if (set_value2 > MAX_PKTLOG_SIZE) {
Venkata Sharath Chandra Manchala27e44902019-01-28 11:29:18 -080010093 hdd_err_rl("Pktlog size is large. max value is %uMB.",
10094 MAX_PKTLOG_SIZE);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010095 return -EINVAL;
10096 }
10097 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010098 } else if (set_value == PKTLOG_CLEAR_BUFF) {
10099 return hdd_pktlog_clear_buff(hdd_ctx);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010100 }
10101
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010102 /*
10103 * set_value = 0 then disable packetlog
10104 * set_value = 1 enable packetlog forcefully
10105 * set_vlaue = 2 then disable packetlog if disabled through ini or
10106 * enable packetlog with AUTO type.
10107 */
10108 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
10109 true : false;
10110
10111 if (1 == set_value) {
10112 enable = true;
10113 user_triggered = 1;
10114 }
10115
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010116 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010117}
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070010118
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010119/**
10120 * hdd_pktlog_enable_disable() - Enable/Disable packet logging
10121 * @hdd_ctx: HDD context
10122 * @enable: Flag to enable/disable
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010123 * @user_triggered: triggered through iwpriv
10124 * @size: buffer size to be used for packetlog
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010125 *
10126 * Return: 0 on success; error number otherwise
10127 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010128int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, bool enable,
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010129 uint8_t user_triggered, int size)
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010130{
10131 struct sir_wifi_start_log start_log;
10132 QDF_STATUS status;
10133
10134 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10135 start_log.verbose_level =
10136 enable ? WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010137 start_log.ini_triggered = cds_is_packet_log_enabled();
10138 start_log.user_triggered = user_triggered;
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010139 start_log.size = size;
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010140 start_log.is_pktlog_buff_clear = false;
Poddar, Siddartheefe3482016-09-21 18:12:59 +053010141 /*
10142 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
10143 * commands. Host uses this flag to decide whether to send pktlog
10144 * disable command to fw without sending pktlog enable command
10145 * previously. For eg, If vendor sends pktlog disable command without
10146 * sending pktlog enable command, then host discards the packet
10147 * but for iwpriv command, host will send it to fw.
10148 */
10149 start_log.is_iwpriv_command = 1;
Jeff Johnson16528362018-06-14 12:34:16 -070010150 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010151 if (!QDF_IS_STATUS_SUCCESS(status)) {
10152 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010153 hdd_exit();
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010154 return -EINVAL;
10155 }
10156
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053010157 if (enable == true)
10158 hdd_ctx->is_pktlog_enabled = 1;
10159 else
10160 hdd_ctx->is_pktlog_enabled = 0;
10161
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010162 return 0;
10163}
10164#endif /* REMOVE_PKT_LOG */
10165
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010166void hdd_free_mac_address_lists(struct hdd_context *hdd_ctx)
10167{
10168 hdd_debug("Resetting MAC address lists");
hangtian127c9532019-01-12 13:29:07 +080010169 qdf_mem_zero(hdd_ctx->provisioned_mac_addr,
10170 sizeof(hdd_ctx->provisioned_mac_addr));
10171 qdf_mem_zero(hdd_ctx->derived_mac_addr,
10172 sizeof(hdd_ctx->derived_mac_addr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010173 hdd_ctx->num_provisioned_addr = 0;
10174 hdd_ctx->num_derived_addr = 0;
10175 hdd_ctx->provisioned_intf_addr_mask = 0;
10176 hdd_ctx->derived_intf_addr_mask = 0;
10177}
10178
Komal Seelam92fff912016-03-24 11:51:41 +053010179/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010180 * hdd_get_platform_wlan_mac_buff() - API to query platform driver
10181 * for MAC address
Komal Seelam92fff912016-03-24 11:51:41 +053010182 * @dev: Device Pointer
10183 * @num: Number of Valid Mac address
10184 *
10185 * Return: Pointer to MAC address buffer
10186 */
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010187static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
10188 uint32_t *num)
Komal Seelam92fff912016-03-24 11:51:41 +053010189{
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010190 return pld_get_wlan_mac_address(dev, num);
Komal Seelam92fff912016-03-24 11:51:41 +053010191}
Komal Seelam92fff912016-03-24 11:51:41 +053010192
10193/**
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010194 * hdd_get_platform_wlan_derived_mac_buff() - API to query platform driver
10195 * for derived MAC address
10196 * @dev: Device Pointer
10197 * @num: Number of Valid Mac address
10198 *
10199 * Return: Pointer to MAC address buffer
10200 */
10201static uint8_t *hdd_get_platform_wlan_derived_mac_buff(struct device *dev,
10202 uint32_t *num)
10203{
10204 return pld_get_wlan_derived_mac_address(dev, num);
10205}
10206
10207/**
Komal Seelam92fff912016-03-24 11:51:41 +053010208 * hdd_populate_random_mac_addr() - API to populate random mac addresses
10209 * @hdd_ctx: HDD Context
10210 * @num: Number of random mac addresses needed
10211 *
10212 * Generate random addresses using bit manipulation on the base mac address
10213 *
10214 * Return: None
10215 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010216void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
Komal Seelam92fff912016-03-24 11:51:41 +053010217{
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010218 uint32_t idx = hdd_ctx->num_derived_addr;
Komal Seelam92fff912016-03-24 11:51:41 +053010219 uint32_t iter;
Komal Seelam92fff912016-03-24 11:51:41 +053010220 uint8_t *buf = NULL;
10221 uint8_t macaddr_b3, tmp_br3;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010222 /*
10223 * Consider first provisioned mac address as source address to derive
10224 * remaining addresses
10225 */
Komal Seelam92fff912016-03-24 11:51:41 +053010226
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010227 uint8_t *src = hdd_ctx->provisioned_mac_addr[0].bytes;
10228
10229 for (iter = 0; iter < num; ++iter, ++idx) {
10230 buf = hdd_ctx->derived_mac_addr[idx].bytes;
Komal Seelam92fff912016-03-24 11:51:41 +053010231 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
10232 macaddr_b3 = buf[3];
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010233 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + idx) &
Komal Seelam92fff912016-03-24 11:51:41 +053010234 INTF_MACADDR_MASK;
10235 macaddr_b3 += tmp_br3;
10236 macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
10237 buf[0] |= 0x02;
10238 buf[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010239 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010240 hdd_ctx->num_derived_addr++;
Komal Seelam92fff912016-03-24 11:51:41 +053010241 }
10242}
10243
10244/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010245 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
Komal Seelam92fff912016-03-24 11:51:41 +053010246 * @hdd_ctx: HDD Context
10247 *
10248 * API to get mac addresses from platform driver and update the driver
10249 * structures and configure FW with the base mac address.
10250 * Return: int
10251 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010252static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +053010253{
10254 uint32_t no_of_mac_addr, iter;
10255 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
10256 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
10257 uint8_t *addr, *buf;
10258 struct device *dev = hdd_ctx->parent_dev;
Komal Seelam92fff912016-03-24 11:51:41 +053010259 tSirMacAddr mac_addr;
10260 QDF_STATUS status;
10261
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010262 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
Komal Seelam92fff912016-03-24 11:51:41 +053010263
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010264 if (no_of_mac_addr == 0 || !addr) {
10265 hdd_debug("No mac configured from platform driver");
Komal Seelam92fff912016-03-24 11:51:41 +053010266 return -EINVAL;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010267 }
10268
10269 hdd_free_mac_address_lists(hdd_ctx);
Komal Seelam92fff912016-03-24 11:51:41 +053010270
10271 if (no_of_mac_addr > max_mac_addr)
10272 no_of_mac_addr = max_mac_addr;
10273
10274 qdf_mem_copy(&mac_addr, addr, mac_addr_size);
10275
10276 for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010277 buf = hdd_ctx->provisioned_mac_addr[iter].bytes;
Komal Seelam92fff912016-03-24 11:51:41 +053010278 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010279 hdd_info("provisioned MAC Addr [%d]" MAC_ADDRESS_STR, iter,
10280 MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +053010281 }
10282
Komal Seelam92fff912016-03-24 11:51:41 +053010283
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010284 hdd_ctx->num_provisioned_addr = no_of_mac_addr;
Srinivas Girigowdab841da72017-03-25 18:04:39 -070010285
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010286 if (hdd_ctx->config->mac_provision) {
10287 addr = hdd_get_platform_wlan_derived_mac_buff(dev,
10288 &no_of_mac_addr);
10289
10290 if (no_of_mac_addr == 0 || !addr)
10291 hdd_warn("No derived address from platform driver");
10292 else if (no_of_mac_addr >
10293 (max_mac_addr - hdd_ctx->num_provisioned_addr))
10294 no_of_mac_addr = (max_mac_addr -
10295 hdd_ctx->num_provisioned_addr);
10296
10297 for (iter = 0; iter < no_of_mac_addr; ++iter,
10298 addr += mac_addr_size) {
10299 buf = hdd_ctx->derived_mac_addr[iter].bytes;
10300 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
10301 hdd_debug("derived MAC Addr [%d]" MAC_ADDRESS_STR, iter,
10302 MAC_ADDR_ARRAY(buf));
10303 }
10304 hdd_ctx->num_derived_addr = no_of_mac_addr;
10305 }
10306
10307 no_of_mac_addr = hdd_ctx->num_provisioned_addr +
10308 hdd_ctx->num_derived_addr;
Komal Seelam92fff912016-03-24 11:51:41 +053010309 if (no_of_mac_addr < max_mac_addr)
10310 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
10311 no_of_mac_addr);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010312
10313 status = sme_set_custom_mac_addr(mac_addr);
10314 if (!QDF_IS_STATUS_SUCCESS(status))
10315 return -EAGAIN;
10316
Komal Seelam92fff912016-03-24 11:51:41 +053010317 return 0;
10318}
10319
10320/**
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010321 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
10322 * @hdd_ctx: HDD Context
10323 *
10324 * Update MAC address to FW. If MAC address passed by FW is invalid, host
10325 * will generate its own MAC and update it to FW.
10326 *
10327 * Return: 0 for success
10328 * Non-zero error code for failure
10329 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010330static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010331{
Jeff Johnson374c0852019-03-10 19:02:07 -070010332 tSirMacAddr custom_mac_addr;
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010333 QDF_STATUS status;
10334
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010335 if (hdd_ctx->num_provisioned_addr)
Jeff Johnson374c0852019-03-10 19:02:07 -070010336 qdf_mem_copy(&custom_mac_addr,
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010337 &hdd_ctx->provisioned_mac_addr[0].bytes[0],
10338 sizeof(tSirMacAddr));
10339 else
Jeff Johnson374c0852019-03-10 19:02:07 -070010340 qdf_mem_copy(&custom_mac_addr,
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010341 &hdd_ctx->derived_mac_addr[0].bytes[0],
10342 sizeof(tSirMacAddr));
Jeff Johnson374c0852019-03-10 19:02:07 -070010343 status = sme_set_custom_mac_addr(custom_mac_addr);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010344 if (!QDF_IS_STATUS_SUCCESS(status))
10345 return -EAGAIN;
10346 return 0;
10347}
10348
10349/**
Komal Seelam92fff912016-03-24 11:51:41 +053010350 * hdd_initialize_mac_address() - API to get wlan mac addresses
10351 * @hdd_ctx: HDD Context
10352 *
10353 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
10354 * is provisioned with mac addresses, driver uses it, else it will use
10355 * wlan_mac.bin to update HW MAC addresses.
10356 *
10357 * Return: None
10358 */
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010359static int hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +053010360{
10361 QDF_STATUS status;
10362 int ret;
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010363 bool update_mac_addr_to_fw = true;
Komal Seelam92fff912016-03-24 11:51:41 +053010364
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010365 ret = hdd_platform_wlan_mac(hdd_ctx);
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010366 if (hdd_ctx->config->mac_provision || !ret) {
Dustin Brown7e761c72018-07-31 13:50:17 -070010367 hdd_info("using MAC address from platform driver");
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010368 return ret;
Dustin Brown7e761c72018-07-31 13:50:17 -070010369 }
Komal Seelam92fff912016-03-24 11:51:41 +053010370
10371 status = hdd_update_mac_config(hdd_ctx);
Dustin Brown7e761c72018-07-31 13:50:17 -070010372 if (QDF_IS_STATUS_SUCCESS(status)) {
10373 hdd_info("using MAC address from wlan_mac.bin");
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010374 return 0;
Dustin Brown7e761c72018-07-31 13:50:17 -070010375 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010376
Dustin Brown7e761c72018-07-31 13:50:17 -070010377 hdd_info("using default MAC address");
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010378
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010379 /* Use fw provided MAC */
10380 if (!qdf_is_macaddr_zero(&hdd_ctx->hw_macaddr)) {
10381 hdd_update_macaddr(hdd_ctx, hdd_ctx->hw_macaddr, false);
10382 update_mac_addr_to_fw = false;
10383 return 0;
10384 } else if (hdd_generate_macaddr_auto(hdd_ctx) != 0) {
10385 struct qdf_mac_addr mac_addr;
10386
10387 hdd_err("MAC failure from device serial no.");
Jeff Johnson51a80522018-12-11 20:19:44 -080010388 qdf_get_random_bytes(&mac_addr, sizeof(mac_addr));
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010389 /*
10390 * Reset multicast bit (bit-0) and set
10391 * locally-administered bit
10392 */
10393 mac_addr.bytes[0] = 0x2;
10394 hdd_update_macaddr(hdd_ctx, mac_addr, true);
10395 }
10396
10397 if (update_mac_addr_to_fw) {
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010398 ret = hdd_update_mac_addr_to_fw(hdd_ctx);
Dustin Brown7e761c72018-07-31 13:50:17 -070010399 if (ret)
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -080010400 hdd_err("MAC address out-of-sync, ret:%d", ret);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010401 }
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053010402 return ret;
Komal Seelam92fff912016-03-24 11:51:41 +053010403}
10404
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010405static int hdd_set_smart_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010406{
10407 int vdev_id = 0;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053010408 QDF_STATUS status;
10409 bool smart_chainmask_enabled;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010410 int param_id = WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010411 int vpdev = PDEV_CMD;
10412 int ret;
10413
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053010414 status = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc,
10415 &smart_chainmask_enabled);
10416 if (QDF_IS_STATUS_ERROR(status))
10417 return -EINVAL;
10418
10419 ret = sme_cli_set_command(vdev_id, param_id,
10420 (int)smart_chainmask_enabled, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010421 if (ret)
10422 hdd_err("WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME failed %d", ret);
10423
10424 return ret;
10425}
10426
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010427static int hdd_set_alternative_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010428{
10429 int vdev_id = 0;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010430 QDF_STATUS status;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010431 int param_id = WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010432 bool alternative_chainmask_enabled;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010433 int vpdev = PDEV_CMD;
10434 int ret;
10435
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010436 status = ucfg_get_alternative_chainmask_enabled(
10437 hdd_ctx->psoc,
10438 &alternative_chainmask_enabled);
10439 if (QDF_IS_STATUS_ERROR(status))
10440 return -EINVAL;
10441
10442 ret = sme_cli_set_command(vdev_id, param_id,
10443 (int)alternative_chainmask_enabled, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010444 if (ret)
10445 hdd_err("WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME failed %d",
10446 ret);
10447
10448 return ret;
10449}
10450
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010451static int hdd_set_ani_enabled(struct hdd_context *hdd_ctx)
Jeff Johnson12a744b2017-04-04 08:19:37 -070010452{
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010453 QDF_STATUS status;
Jeff Johnson12a744b2017-04-04 08:19:37 -070010454 int vdev_id = 0;
10455 int param_id = WMI_PDEV_PARAM_ANI_ENABLE;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010456 bool value;
Jeff Johnson12a744b2017-04-04 08:19:37 -070010457 int vpdev = PDEV_CMD;
10458 int ret;
10459
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010460 status = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &value);
10461 if (QDF_IS_STATUS_ERROR(status))
10462 return -EINVAL;
10463
10464 ret = sme_cli_set_command(vdev_id, param_id, (int)value, vpdev);
Jeff Johnson12a744b2017-04-04 08:19:37 -070010465 if (ret)
10466 hdd_err("WMI_PDEV_PARAM_ANI_ENABLE failed %d", ret);
10467
10468 return ret;
10469}
10470
Jeff Johnson89c66ff2016-04-22 15:21:37 -070010471/**
Prashanth Bhatta07998752016-04-28 12:35:33 -070010472 * hdd_pre_enable_configure() - Configurations prior to cds_enable
10473 * @hdd_ctx: HDD context
10474 *
10475 * Pre configurations to be done at lower layer before calling cds enable.
10476 *
10477 * Return: 0 on success and errno on failure.
10478 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010479static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
Prashanth Bhatta07998752016-04-28 12:35:33 -070010480{
10481 int ret;
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053010482 uint8_t val = 0;
Prashanth Bhatta07998752016-04-28 12:35:33 -070010483 QDF_STATUS status;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010484 uint32_t arp_ac_category;
Leo Changfdb45c32016-10-28 11:09:23 -070010485 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010486
Leo Changfdb45c32016-10-28 11:09:23 -070010487 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
Ajit Pal Singh5d269612018-04-19 16:29:12 +053010488 /* Register HL netdev flow control callback */
10489 cdp_hl_fc_register(soc, wlan_hdd_txrx_pause_cb);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010490
10491 /*
10492 * Note that the cds_pre_enable() sequence triggers the cfg download.
10493 * The cfg download must occur before we update the SME config
10494 * since the SME config operation must access the cfg database
10495 */
10496 status = hdd_set_sme_config(hdd_ctx);
10497
10498 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010499 hdd_err("Failed hdd_set_sme_config: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010500 ret = qdf_status_to_os_return(status);
10501 goto out;
10502 }
10503
Tushnim Bhattacharyyaba8ee932017-03-23 09:27:40 -070010504 status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
10505 if (QDF_STATUS_SUCCESS != status) {
10506 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
10507 ret = qdf_status_to_os_return(status);
10508 goto out;
10509 }
10510
Dustin Brown1dbefe62018-09-11 16:32:03 -070010511 status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val);
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053010512 if (QDF_STATUS_SUCCESS != status) {
10513 hdd_err("Get tx_chainmask_1ss from mlme failed");
10514 ret = qdf_status_to_os_return(status);
10515 goto out;
10516 }
10517 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, val,
Prashanth Bhatta07998752016-04-28 12:35:33 -070010518 PDEV_CMD);
10519 if (0 != ret) {
10520 hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret);
10521 goto out;
10522 }
10523
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010524 ret = hdd_set_smart_chainmask_enabled(hdd_ctx);
10525 if (ret)
10526 goto out;
10527
10528 ret = hdd_set_alternative_chainmask_enabled(hdd_ctx);
10529 if (ret)
10530 goto out;
10531
Jeff Johnson12a744b2017-04-04 08:19:37 -070010532 ret = hdd_set_ani_enabled(hdd_ctx);
10533 if (ret)
10534 goto out;
10535
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010536 status = ucfg_get_arp_ac_category(hdd_ctx->psoc, &arp_ac_category);
10537
10538 if (QDF_IS_STATUS_ERROR(status))
10539 return -EINVAL;
10540
Naveen Rawat247a8682017-06-05 15:00:31 -070010541 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010542 arp_ac_category,
Srinivas Girigowda70e169a2017-03-07 23:55:57 -080010543 PDEV_CMD);
10544 if (0 != ret) {
10545 hdd_err("WMI_PDEV_PARAM_ARP_AC_OVERRIDE ac: %d ret: %d",
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010546 arp_ac_category, ret);
Srinivas Girigowda70e169a2017-03-07 23:55:57 -080010547 goto out;
10548 }
10549
Prashanth Bhatta07998752016-04-28 12:35:33 -070010550 status = hdd_set_sme_chan_list(hdd_ctx);
10551 if (status != QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010552 hdd_err("Failed to init channel list: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010553 ret = qdf_status_to_os_return(status);
10554 goto out;
10555 }
10556
10557 /* Apply the cfg.ini to cfg.dat */
Krunal Sonidf0f8742016-09-26 14:56:31 -070010558 if (!hdd_update_config_cfg(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010559 hdd_err("config update failed");
Prashanth Bhatta07998752016-04-28 12:35:33 -070010560 ret = -EINVAL;
10561 goto out;
10562 }
10563
Prashanth Bhatta07998752016-04-28 12:35:33 -070010564
10565 hdd_init_channel_avoidance(hdd_ctx);
10566
10567out:
10568 return ret;
10569}
10570
Rachit Kankane026e77a2018-07-31 16:21:09 +053010571#ifdef FEATURE_P2P_LISTEN_OFFLOAD
Prashanth Bhatta07998752016-04-28 12:35:33 -070010572/**
Peng Xu8fdaa492016-06-22 10:20:47 -070010573 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070010574 * @context: context registered with sme_register_p2p_lo_event(). HDD
10575 * always registers a hdd context pointer
10576 * @evt:event structure pointer
Peng Xu8fdaa492016-06-22 10:20:47 -070010577 *
10578 * This is the p2p listen offload stop event handler, it sends vendor
10579 * event back to supplicant to notify the stop reason.
10580 *
10581 * Return: None
10582 */
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070010583static void wlan_hdd_p2p_lo_event_callback(void *context,
10584 struct sir_p2p_lo_event *evt)
Peng Xu8fdaa492016-06-22 10:20:47 -070010585{
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070010586 struct hdd_context *hdd_ctx = context;
Peng Xu8fdaa492016-06-22 10:20:47 -070010587 struct sk_buff *vendor_event;
Jeff Johnson9d295242017-08-29 14:39:48 -070010588 struct hdd_adapter *adapter;
Peng Xu8fdaa492016-06-22 10:20:47 -070010589
Dustin Brown491d54b2018-03-14 12:39:11 -070010590 hdd_enter();
Peng Xu8fdaa492016-06-22 10:20:47 -070010591
Jeff Johnsond36fa332019-03-18 13:42:25 -070010592 if (!hdd_ctx) {
Peng Xu8fdaa492016-06-22 10:20:47 -070010593 hdd_err("Invalid HDD context pointer");
10594 return;
10595 }
10596
Peng Xu5c682812017-08-06 07:39:13 -070010597 adapter = hdd_get_adapter_by_vdev(hdd_ctx, evt->vdev_id);
10598 if (!adapter) {
10599 hdd_err("Cannot find adapter by vdev_id = %d",
10600 evt->vdev_id);
10601 return;
10602 }
10603
Peng Xu8fdaa492016-06-22 10:20:47 -070010604 vendor_event =
10605 cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
Peng Xu5c682812017-08-06 07:39:13 -070010606 &(adapter->wdev), sizeof(uint32_t) + NLMSG_HDRLEN,
Peng Xu8fdaa492016-06-22 10:20:47 -070010607 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX,
10608 GFP_KERNEL);
10609
10610 if (!vendor_event) {
10611 hdd_err("cfg80211_vendor_event_alloc failed");
10612 return;
10613 }
10614
10615 if (nla_put_u32(vendor_event,
10616 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
10617 evt->reason_code)) {
10618 hdd_err("nla put failed");
10619 kfree_skb(vendor_event);
10620 return;
10621 }
10622
10623 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Peng Xu5c682812017-08-06 07:39:13 -070010624 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
10625 evt->vdev_id);
Peng Xu8fdaa492016-06-22 10:20:47 -070010626}
Rachit Kankane026e77a2018-07-31 16:21:09 +053010627#else
10628static void wlan_hdd_p2p_lo_event_callback(void *context,
10629 struct sir_p2p_lo_event *evt)
10630{
10631}
10632#endif
Peng Xu8fdaa492016-06-22 10:20:47 -070010633
Rachit Kankanef6834c42018-08-02 18:47:50 +053010634#ifdef FEATURE_WLAN_DYNAMIC_CVM
10635static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
10636{
10637 return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap);
10638}
10639#else
10640static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
10641{
10642 return QDF_STATUS_SUCCESS;
10643}
10644#endif
10645
Peng Xu8fdaa492016-06-22 10:20:47 -070010646/**
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010647 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
10648 * @hdd_ctx: HDD context
10649 *
10650 * This function sends the adaptive dwell time config configuration to the
10651 * firmware via WMA
10652 *
10653 * Return: 0 - success, < 0 - failure
10654 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010655static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010656{
10657 QDF_STATUS status;
10658 struct adaptive_dwelltime_params dwelltime_params;
10659
Harprit Chhabadad59ae762019-01-08 16:40:43 -080010660 status = ucfg_fwol_get_all_adaptive_dwelltime_params(hdd_ctx->psoc,
10661 &dwelltime_params);
10662 status = ucfg_fwol_set_adaptive_dwelltime_config(&dwelltime_params);
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010663
10664 hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
10665 if (!QDF_IS_STATUS_SUCCESS(status)) {
10666 hdd_err("Failed to send Adaptive Dwelltime configuration!");
10667 return -EAGAIN;
10668 }
10669 return 0;
10670}
10671
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010672int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010673{
10674 QDF_STATUS status;
10675 struct wmi_dbs_scan_sel_params dbs_scan_params;
10676 uint32_t i = 0;
10677 uint8_t count = 0, numentries = 0;
Krunal Sonidf29bc42018-11-15 13:26:29 -080010678 uint8_t dual_mac_feature;
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010679 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
10680 * CDS_DBS_SCAN_CLIENTS_MAX];
10681
Krunal Sonidf29bc42018-11-15 13:26:29 -080010682 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
10683 &dual_mac_feature);
10684
10685 if (status != QDF_STATUS_SUCCESS) {
10686 hdd_err("can't get dual mac feature flag");
10687 return -EINVAL;
10688 }
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010689 /* check if DBS is enabled or supported */
Krunal Sonidf29bc42018-11-15 13:26:29 -080010690 if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) ||
10691 (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN))
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010692 return -EINVAL;
10693
10694 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
10695 dbs_scan_config, &numentries,
10696 (CDS_DBS_SCAN_PARAM_PER_CLIENT
10697 * CDS_DBS_SCAN_CLIENTS_MAX));
10698
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010699 if (!numentries) {
Dustin Brown6a8d39b2018-08-14 15:27:26 -070010700 hdd_debug("Do not send scan_selection_config");
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010701 return 0;
10702 }
10703
10704 /* hdd_set_fw_log_params */
10705 dbs_scan_params.num_clients = 0;
10706 while (count < (numentries - 2)) {
10707 dbs_scan_params.module_id[i] = dbs_scan_config[count];
10708 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
10709 dbs_scan_params.num_non_dbs_scans[i] =
10710 dbs_scan_config[count + 2];
10711 dbs_scan_params.num_clients++;
10712 hdd_debug("module:%d NDS:%d NNDS:%d",
10713 dbs_scan_params.module_id[i],
10714 dbs_scan_params.num_dbs_scans[i],
10715 dbs_scan_params.num_non_dbs_scans[i]);
10716 count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
10717 i++;
10718 }
10719
10720 dbs_scan_params.pdev_id = 0;
10721
10722 hdd_debug("clients:%d pdev:%d",
10723 dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
10724
Jeff Johnson16528362018-06-14 12:34:16 -070010725 status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle,
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010726 &dbs_scan_params);
10727 hdd_debug("Sending DBS Scan Selection Configuration to fw");
10728 if (!QDF_IS_STATUS_SUCCESS(status)) {
10729 hdd_err("Failed to send DBS Scan selection configuration!");
10730 return -EAGAIN;
10731 }
10732 return 0;
10733}
10734
Arun Khandavallid4349a92016-07-25 11:10:43 +053010735#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
10736/**
10737 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
10738 * @hdd_ctx: HDD context
10739 *
10740 * Set auto shutdown callback to get indications from firmware to indicate
10741 * userspace to shutdown WLAN after a configured amount of inactivity.
10742 *
10743 * Return: 0 on success and errno on failure.
10744 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010745static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010746{
10747 QDF_STATUS status;
10748
Dundi Raviteja8e338282018-09-25 17:16:04 +053010749 if (!hdd_ctx->config->wlan_auto_shutdown)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010750 return 0;
10751
Jeff Johnson16528362018-06-14 12:34:16 -070010752 status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle,
Arun Khandavallid4349a92016-07-25 11:10:43 +053010753 wlan_hdd_auto_shutdown_cb);
10754 if (status != QDF_STATUS_SUCCESS)
10755 hdd_err("Auto shutdown feature could not be enabled: %d",
10756 status);
10757
10758 return qdf_status_to_os_return(status);
10759}
10760#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010761static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010762{
10763 return 0;
10764}
10765#endif
10766
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053010767#ifdef MWS_COEX
10768/**
10769 * hdd_set_mws_coex() - Set MWS coex configurations
10770 * @hdd_ctx: HDD context
10771 *
10772 * This function sends MWS-COEX 4G quick FTDM and
10773 * MWS-COEX 5G-NR power limit to FW
10774 *
10775 * Return: 0 on success and errno on failure.
10776 */
10777static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
10778{
10779 int ret = 0;
lifengdb340e72018-11-20 00:50:20 +080010780 uint32_t mws_coex_4g_quick_tdm = 0, mws_coex_5g_nr_pwr_limit = 0;
10781
10782 ucfg_mlme_get_mws_coex_4g_quick_tdm(hdd_ctx->psoc,
10783 &mws_coex_4g_quick_tdm);
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053010784
10785 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM,
lifengdb340e72018-11-20 00:50:20 +080010786 mws_coex_4g_quick_tdm,
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053010787 PDEV_CMD);
10788 if (ret) {
10789 hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy");
10790 return ret;
10791 }
10792
lifengdb340e72018-11-20 00:50:20 +080010793 ucfg_mlme_get_mws_coex_5g_nr_pwr_limit(hdd_ctx->psoc,
10794 &mws_coex_5g_nr_pwr_limit);
10795
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053010796 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT,
lifengdb340e72018-11-20 00:50:20 +080010797 mws_coex_5g_nr_pwr_limit,
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053010798 PDEV_CMD);
10799 if (ret) {
10800 hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy");
10801 return ret;
10802 }
lifengdb340e72018-11-20 00:50:20 +080010803
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053010804 return ret;
10805}
10806#else
10807static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
10808{
10809 return 0;
10810}
10811#endif
10812
Arun Khandavallid4349a92016-07-25 11:10:43 +053010813/**
10814 * hdd_features_init() - Init features
10815 * @hdd_ctx: HDD context
Arun Khandavallid4349a92016-07-25 11:10:43 +053010816 *
10817 * Initialize features and their feature context after WLAN firmware is up.
10818 *
10819 * Return: 0 on success and errno on failure.
10820 */
Dustin Browne7e71d32018-05-11 16:00:08 -070010821static int hdd_features_init(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010822{
Jeff Johnson19ce8d02019-02-08 22:56:23 -080010823 struct tx_power_limit hddtxlimit;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010824 QDF_STATUS status;
10825 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -070010826 mac_handle_t mac_handle;
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070010827 struct hdd_config *cfg;
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +053010828 bool b_cts2self, is_imps_enabled;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010829
Dustin Brown491d54b2018-03-14 12:39:11 -070010830 hdd_enter();
Arun Khandavallid4349a92016-07-25 11:10:43 +053010831
Dustin Brownad698ae2018-09-05 17:19:30 -070010832 ret = hdd_update_country_code(hdd_ctx);
10833 if (ret) {
10834 hdd_err("Failed to update country code; errno:%d", ret);
10835 return -EINVAL;
10836 }
10837
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053010838 ret = hdd_init_mws_coex(hdd_ctx);
10839 if (ret)
10840 hdd_warn("Error initializing mws-coex");
10841
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070010842 cfg = hdd_ctx->config;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010843 /* FW capabilities received, Set the Dot11 mode */
Jeff Johnson16528362018-06-14 12:34:16 -070010844 mac_handle = hdd_ctx->mac_handle;
10845 sme_setdef_dot11mode(mac_handle);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010846
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +053010847 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
10848 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010849
Poddar, Siddarth37033032017-10-11 15:47:40 +053010850 /* Send Enable/Disable data stall detection cmd to FW */
10851 sme_cli_set_command(0, WMI_PDEV_PARAM_DATA_STALL_DETECT_ENABLE,
jitiphil377bcc12018-10-05 19:46:08 +053010852 cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
10853 cfg_dp_enable_data_stall), PDEV_CMD);
Poddar, Siddarth37033032017-10-11 15:47:40 +053010854
Dustin Brown1dbefe62018-09-11 16:32:03 -070010855 ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self);
Wu Gao93816212018-08-31 16:49:54 +080010856 if (b_cts2self)
Jeff Johnson16528362018-06-14 12:34:16 -070010857 sme_set_cts2self_for_p2p_go(mac_handle);
Agrawal Ashish642ec9b2017-02-22 14:45:30 +053010858
Rachit Kankanef6834c42018-08-02 18:47:50 +053010859 if (hdd_set_vc_mode_config(hdd_ctx))
Nachiket Kukade8983cf62017-10-12 18:14:48 +053010860 hdd_warn("Error in setting Voltage Corner mode config to FW");
10861
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070010862 if (hdd_rx_ol_init(hdd_ctx))
10863 hdd_err("Unable to initialize Rx LRO/GRO in fw");
Arun Khandavallid4349a92016-07-25 11:10:43 +053010864
10865 if (hdd_adaptive_dwelltime_init(hdd_ctx))
10866 hdd_err("Unable to send adaptive dwelltime setting to FW");
10867
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010868 if (hdd_dbs_scan_selection_init(hdd_ctx))
10869 hdd_err("Unable to send DBS scan selection setting to FW");
10870
Arun Khandavallid4349a92016-07-25 11:10:43 +053010871 ret = hdd_init_thermal_info(hdd_ctx);
10872 if (ret) {
10873 hdd_err("Error while initializing thermal information");
Dustin Browne7e71d32018-05-11 16:00:08 -070010874 return ret;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010875 }
10876
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053010877 /**
10878 * In case of SSR/PDR, if pktlog was enabled manually before
Rakshith Suresh Patkar6d955262019-03-13 16:51:50 +053010879 * SSR/PDR, then enable it again automatically after Wlan
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053010880 * device up.
Rakshith Suresh Patkar6d955262019-03-13 16:51:50 +053010881 * During SSR/PDR, pktlog will be disabled as part of
10882 * hdd_features_deinit if pktlog is enabled in ini.
10883 * Re-enable pktlog in SSR case, if pktlog is enabled in ini.
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053010884 */
Rakshith Suresh Patkar6d955262019-03-13 16:51:50 +053010885 if (cds_is_packet_log_enabled() ||
10886 (cds_is_driver_recovering() && hdd_ctx->is_pktlog_enabled))
Alok Kumar5a75b9d2018-08-31 10:55:43 +053010887 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
Poddar, Siddarth66a46592017-02-22 11:44:44 +053010888
gaurank kathpalia3d2e3852018-10-03 22:03:23 +053010889 hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G);
10890 hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G);
Jeff Johnson16528362018-06-14 12:34:16 -070010891 status = sme_txpower_limit(mac_handle, &hddtxlimit);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010892 if (!QDF_IS_STATUS_SUCCESS(status))
10893 hdd_err("Error setting txlimit in sme: %d", status);
10894
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010895 wlan_hdd_tsf_init(hdd_ctx);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010896
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010897 status = sme_enable_disable_chanavoidind_event(mac_handle, 0);
10898 if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) {
10899 hdd_err("Failed to disable Chan Avoidance Indication");
Sourav Mohapatra674925f2018-04-16 11:16:58 +053010900 return -EINVAL;
Selvaraj, Sridhar371f55e2017-02-21 10:36:15 +053010901 }
Arun Khandavallid4349a92016-07-25 11:10:43 +053010902
10903 /* register P2P Listen Offload event callback */
10904 if (wma_is_p2p_lo_capable())
Jeff Johnson16528362018-06-14 12:34:16 -070010905 sme_register_p2p_lo_event(mac_handle, hdd_ctx,
10906 wlan_hdd_p2p_lo_event_callback);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010907
10908 ret = hdd_set_auto_shutdown_cb(hdd_ctx);
10909
10910 if (ret)
Sourav Mohapatra674925f2018-04-16 11:16:58 +053010911 return -EINVAL;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010912
Dustin Brown11638b72018-01-25 17:37:25 +053010913 wlan_hdd_init_chan_info(hdd_ctx);
Varun Reddy Yeturu3c9f89c2018-04-18 19:10:34 -070010914 wlan_hdd_twt_init(hdd_ctx);
Dustin Brown11638b72018-01-25 17:37:25 +053010915
Dustin Browne74003f2018-03-14 12:51:58 -070010916 hdd_exit();
Arun Khandavallid4349a92016-07-25 11:10:43 +053010917 return 0;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010918}
10919
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010920/**
10921 * hdd_features_deinit() - Deinit features
10922 * @hdd_ctx: HDD context
10923 *
10924 * De-Initialize features and their feature context.
10925 *
10926 * Return: none.
10927 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010928static void hdd_features_deinit(struct hdd_context *hdd_ctx)
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010929{
Varun Reddy Yeturu3c9f89c2018-04-18 19:10:34 -070010930 wlan_hdd_twt_deinit(hdd_ctx);
Dustin Brown11638b72018-01-25 17:37:25 +053010931 wlan_hdd_deinit_chan_info(hdd_ctx);
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010932 wlan_hdd_tsf_deinit(hdd_ctx);
jitiphil4e3bef42018-11-14 14:31:13 +053010933 if (cds_is_packet_log_enabled())
10934 hdd_pktlog_enable_disable(hdd_ctx, false, 0, 0);
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010935}
10936
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010937/**
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070010938 * hdd_register_bcn_cb() - register scan beacon callback
10939 * @hdd_ctx - Pointer to the HDD context
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010940 *
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070010941 * Return: QDF_STATUS
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010942 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010943static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010944{
10945 QDF_STATUS status;
10946
Dustin Brown1dbefe62018-09-11 16:32:03 -070010947 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010948 wlan_cfg80211_inform_bss_frame,
10949 SCAN_CB_TYPE_INFORM_BCN);
10950 if (!QDF_IS_STATUS_SUCCESS(status)) {
Abhishek Singh5ffe9de2019-03-05 15:42:43 +053010951 hdd_err("failed to register SCAN_CB_TYPE_INFORM_BCN with status code %08d [x%08x]",
10952 status, status);
10953 return status;
10954 }
10955
10956 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
10957 wlan_cfg80211_unlink_bss_list,
10958 SCAN_CB_TYPE_UNLINK_BSS);
10959 if (!QDF_IS_STATUS_SUCCESS(status)) {
10960 hdd_err("failed to refister SCAN_CB_TYPE_FLUSH_BSS with status code %08d [x%08x]",
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010961 status, status);
10962 return status;
10963 }
10964
10965 return QDF_STATUS_SUCCESS;
10966}
Arun Khandavallid4349a92016-07-25 11:10:43 +053010967
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010968/**
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070010969 * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active
10970 * @vdev_id: vdev_id, corresponds to flow_pool
10971 *
10972 * Return: none.
10973 */
10974static void hdd_v2_flow_pool_map(int vdev_id)
10975{
10976 QDF_STATUS status;
10977
10978 status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC),
10979 cds_get_context(QDF_MODULE_ID_TXRX),
10980 vdev_id);
10981 /*
10982 * For Adrastea flow control v2 is based on FW MAP events,
10983 * so this above callback is not implemented.
10984 * Hence this is not actual failure. Dont return failure
10985 */
10986 if ((status != QDF_STATUS_SUCCESS) &&
10987 (status != QDF_STATUS_E_INVAL)) {
10988 hdd_err("vdev_id: %d, failed to create flow pool status %d",
10989 vdev_id, status);
10990 }
10991}
10992
10993/**
10994 * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active
10995 * @vdev_id: vdev_id, corresponds to flow_pool
10996 *
10997 * Return: none.
10998 */
10999static void hdd_v2_flow_pool_unmap(int vdev_id)
11000{
11001 cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC),
11002 cds_get_context(QDF_MODULE_ID_TXRX), vdev_id);
11003}
11004
11005/**
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011006 * hdd_action_oui_config() - Configure action_oui strings
11007 * @hdd_ctx: pointer to hdd context
11008 *
11009 * This is a HDD wrapper function which invokes ucfg api
11010 * of action_oui component to parse action oui strings.
11011 *
11012 * Return: None
11013 */
11014static void hdd_action_oui_config(struct hdd_context *hdd_ctx)
11015{
11016 QDF_STATUS status;
11017 uint32_t id;
11018 uint8_t *str;
11019
11020 if (!hdd_ctx->config->action_oui_enable)
11021 return;
11022
11023 for (id = 0; id < ACTION_OUI_MAXIMUM_ID; id++) {
11024 str = hdd_ctx->config->action_oui_str[id];
11025 if (!qdf_str_len(str))
11026 continue;
11027
Dustin Brown1dbefe62018-09-11 16:32:03 -070011028 status = ucfg_action_oui_parse(hdd_ctx->psoc, str, id);
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011029 if (!QDF_IS_STATUS_SUCCESS(status))
11030 hdd_err("Failed to parse action_oui str: %u", id);
11031 }
11032}
11033
11034/**
11035 * hdd_action_oui_send() - Send action_oui extensions to firmware
11036 * @hdd_ctx: pointer to hdd context
11037 *
11038 * This is a HDD wrapper function which invokes ucfg api
11039 * of action_oui component to send action oui extensions to firmware.
11040 *
11041 * Return: None
11042 */
11043static void hdd_action_oui_send(struct hdd_context *hdd_ctx)
11044{
11045 QDF_STATUS status;
11046
11047 if (!hdd_ctx->config->action_oui_enable)
11048 return;
11049
Dustin Brown1dbefe62018-09-11 16:32:03 -070011050 status = ucfg_action_oui_send(hdd_ctx->psoc);
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011051 if (!QDF_IS_STATUS_SUCCESS(status))
11052 hdd_err("Failed to send one or all action_ouis");
11053}
11054
Jeff Johnson0187c622019-01-04 06:39:44 -080011055static void hdd_hastings_bt_war_initialize(struct hdd_context *hdd_ctx)
11056{
11057 if (hdd_ctx->config->iface_change_wait_time)
11058 hdd_hastings_bt_war_disable_fw(hdd_ctx);
11059 else
11060 hdd_hastings_bt_war_enable_fw(hdd_ctx);
11061}
11062
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011063/**
Arun Khandavallifae92942016-08-01 13:31:08 +053011064 * hdd_configure_cds() - Configure cds modules
11065 * @hdd_ctx: HDD context
11066 * @adapter: Primary adapter context
11067 *
11068 * Enable Cds modules after WLAN firmware is up.
11069 *
11070 * Return: 0 on success and errno on failure.
11071 */
Dustin Browne7e71d32018-05-11 16:00:08 -070011072int hdd_configure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053011073{
11074 int ret;
11075 QDF_STATUS status;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011076 int set_value;
Jeff Johnson16528362018-06-14 12:34:16 -070011077 mac_handle_t mac_handle;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011078 bool enable_rts_sifsbursting;
11079 uint8_t enable_phy_reg_retention;
Krunal Sonidf29bc42018-11-15 13:26:29 -080011080 uint8_t max_mpdus_inampdu, is_force_1x1 = 0;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011081 uint32_t num_abg_tx_chains = 0;
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011082 uint16_t num_11b_tx_chains = 0;
11083 uint16_t num_11ag_tx_chains = 0;
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070011084 struct policy_mgr_dp_cbacks dp_cbs = {0};
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053011085 bool value;
Wu Gao66454f12018-09-26 19:55:41 +080011086 enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053011087 bool bval = false;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011088
Jeff Johnson16528362018-06-14 12:34:16 -070011089 mac_handle = hdd_ctx->mac_handle;
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011090
11091 hdd_action_oui_send(hdd_ctx);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011092 status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1);
11093 if (status != QDF_STATUS_SUCCESS) {
11094 hdd_err("Failed to get force 1x1 value");
11095 goto out;
11096 }
11097 if (is_force_1x1)
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011098 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_SET_IOT_PATTERN,
11099 1, PDEV_CMD);
11100 /* set chip power save failure detected callback */
Jeff Johnson16528362018-06-14 12:34:16 -070011101 sme_set_chip_pwr_save_fail_cb(mac_handle,
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011102 hdd_chip_pwr_save_fail_detected_cb);
11103
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011104 status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc,
11105 &max_mpdus_inampdu);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011106 if (status) {
11107 hdd_err("Failed to get max mpdus in ampdu value");
11108 goto out;
11109 }
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011110
11111 if (max_mpdus_inampdu) {
11112 set_value = max_mpdus_inampdu;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011113 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU,
11114 set_value, PDEV_CMD);
11115 }
11116
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011117 status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc,
11118 &enable_rts_sifsbursting);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011119 if (status) {
11120 hdd_err("Failed to get rts sifs bursting value");
11121 goto out;
11122 }
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011123
11124 if (enable_rts_sifsbursting) {
11125 set_value = enable_rts_sifsbursting;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011126 sme_cli_set_command(0,
11127 (int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING,
11128 set_value, PDEV_CMD);
11129 }
11130
Dustin Brown05d81302018-09-11 16:49:22 -070011131 ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053011132 if (value) {
11133 set_value = value;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011134 sme_cli_set_command(0,
11135 (int)WMI_PDEV_PARAM_PEER_STATS_INFO_ENABLE,
11136 set_value, PDEV_CMD);
11137 }
11138
Dustin Brown1dbefe62018-09-11 16:32:03 -070011139 status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc,
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011140 &num_11b_tx_chains);
11141 if (status != QDF_STATUS_SUCCESS) {
11142 hdd_err("Failed to get num_11b_tx_chains");
11143 goto out;
11144 }
11145
Dustin Brown1dbefe62018-09-11 16:32:03 -070011146 status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc,
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011147 &num_11ag_tx_chains);
11148 if (status != QDF_STATUS_SUCCESS) {
11149 hdd_err("Failed to get num_11ag_tx_chains");
11150 goto out;
11151 }
11152
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053011153 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
11154 if (!QDF_IS_STATUS_SUCCESS(status))
11155 hdd_err("unable to get vht_enable2x2");
11156
11157 if (!bval) {
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011158 if (num_11b_tx_chains > 1)
11159 num_11b_tx_chains = 1;
11160 if (num_11ag_tx_chains > 1)
11161 num_11ag_tx_chains = 1;
11162 }
11163 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
11164 num_11b_tx_chains);
11165 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
11166 num_11ag_tx_chains);
11167 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM,
11168 num_abg_tx_chains, PDEV_CMD);
Arun Khandavallifae92942016-08-01 13:31:08 +053011169
Paul Zhang02526cd2018-09-20 17:47:46 +080011170 if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc))
11171 ucfg_reg_program_default_cc(hdd_ctx->pdev,
11172 hdd_ctx->reg.reg_domain);
11173
Arun Khandavallifae92942016-08-01 13:31:08 +053011174 ret = hdd_pre_enable_configure(hdd_ctx);
11175 if (ret) {
11176 hdd_err("Failed to pre-configure cds");
11177 goto out;
11178 }
11179
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080011180 /* Always get latest IPA resources allocated from cds_open and configure
11181 * IPA module before configuring them to FW. Sequence required as crash
11182 * observed otherwise.
11183 */
Dustin Brown07901ec2018-09-07 11:02:41 -070011184 if (ucfg_ipa_uc_ol_init(hdd_ctx->pdev,
11185 cds_get_context(QDF_MODULE_ID_QDF_DEVICE))) {
Manikandan Mohan2e803a02017-02-14 14:57:53 -080011186 hdd_err("Failed to setup pipes");
11187 goto out;
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080011188 }
11189
Arun Khandavallifae92942016-08-01 13:31:08 +053011190 /*
11191 * Start CDS which starts up the SME/MAC/HAL modules and everything
11192 * else
11193 */
Dustin Brown1dbefe62018-09-11 16:32:03 -070011194 status = cds_enable(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053011195
11196 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011197 hdd_err("cds_enable failed");
Arun Khandavallifae92942016-08-01 13:31:08 +053011198 goto out;
11199 }
11200
11201 status = hdd_post_cds_enable_config(hdd_ctx);
11202 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011203 hdd_err("hdd_post_cds_enable_config failed");
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011204 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053011205 }
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011206 status = hdd_register_bcn_cb(hdd_ctx);
11207 if (!QDF_IS_STATUS_SUCCESS(status)) {
Paul Zhange03cf4c2018-01-19 18:33:22 +080011208 hdd_err("hdd_register_bcn_cb failed");
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011209 goto cds_disable;
11210 }
Arun Khandavallifae92942016-08-01 13:31:08 +053011211
Dustin Browne7e71d32018-05-11 16:00:08 -070011212 ret = hdd_features_init(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053011213 if (ret)
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011214 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053011215
Mohit Khanna81418772018-10-30 14:14:46 -070011216 /* Donot disable rx offload on concurrency for lithium based targets */
11217 if (!(hdd_ctx->target_type == TARGET_TYPE_QCA6290 ||
11218 hdd_ctx->target_type == TARGET_TYPE_QCA6390))
11219 if (hdd_ctx->ol_enable)
11220 dp_cbs.hdd_disable_rx_ol_in_concurrency =
11221 hdd_disable_rx_ol_in_concurrency;
Yun Parkff6a16a2017-09-26 16:38:18 -070011222 dp_cbs.hdd_set_rx_mode_rps_cb = hdd_set_rx_mode_rps;
jiadbb47e132018-03-30 16:28:30 +080011223 dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070011224 dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map;
11225 dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap;
Dustin Brown1dbefe62018-09-11 16:32:03 -070011226 status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs);
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011227 if (!QDF_IS_STATUS_SUCCESS(status)) {
Yun Parkff6a16a2017-09-26 16:38:18 -070011228 hdd_debug("Failed to register DP cb with Policy Manager");
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011229 goto cds_disable;
11230 }
Dustin Brown1dbefe62018-09-11 16:32:03 -070011231 status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc,
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011232 wlan_hdd_send_mode_change_event);
11233 if (!QDF_IS_STATUS_SUCCESS(status)) {
11234 hdd_debug("Failed to register mode change cb with Policy Manager");
11235 goto cds_disable;
11236 }
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011237
Jeff Johnson8bb61112018-03-31 13:33:54 -070011238 if (hdd_green_ap_enable_egap(hdd_ctx))
Nachiket Kukadefbd1afc2017-07-12 17:41:54 +053011239 hdd_debug("enhance green ap is not enabled");
11240
Nachiket Kukadedd302662017-07-13 17:31:44 +053011241 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
11242 hdd_debug("Failed to set wow pulse");
11243
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053011244 sme_cli_set_command(0, WMI_PDEV_PARAM_GCMP_SUPPORT_ENABLE,
Manikandan Mohan66df7fc2019-01-08 17:57:05 -080011245 ucfg_fwol_get_gcmp_enable(hdd_ctx->psoc), PDEV_CMD);
Wu Gao66454f12018-09-26 19:55:41 +080011246
11247 auto_power_fail_mode =
11248 ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc);
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +053011249 sme_cli_set_command(0, WMI_PDEV_AUTO_DETECT_POWER_FAILURE,
Wu Gao66454f12018-09-26 19:55:41 +080011250 auto_power_fail_mode, PDEV_CMD);
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +053011251
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011252 status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc,
11253 &enable_phy_reg_retention);
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053011254
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011255 if (QDF_IS_STATUS_ERROR(status))
11256 return -EINVAL;
11257
11258 if (enable_phy_reg_retention)
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053011259 wma_cli_set_command(0, WMI_PDEV_PARAM_FAST_PWR_TRANSITION,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011260 enable_phy_reg_retention, PDEV_CMD);
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053011261
Jeff Johnson0187c622019-01-04 06:39:44 -080011262 hdd_hastings_bt_war_initialize(hdd_ctx);
11263
Arun Khandavallifae92942016-08-01 13:31:08 +053011264 return 0;
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011265
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011266cds_disable:
Dustin Brown1dbefe62018-09-11 16:32:03 -070011267 cds_disable(hdd_ctx->psoc);
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011268
Arun Khandavallifae92942016-08-01 13:31:08 +053011269out:
11270 return -EINVAL;
11271}
11272
11273/**
11274 * hdd_deconfigure_cds() -De-Configure cds
11275 * @hdd_ctx: HDD context
11276 *
11277 * Deconfigure Cds modules before WLAN firmware is down.
11278 *
11279 * Return: 0 on success and errno on failure.
11280 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011281static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053011282{
11283 QDF_STATUS qdf_status;
Houston Hoffman6640cf32016-10-10 16:44:29 -070011284 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053011285
Dustin Brown491d54b2018-03-14 12:39:11 -070011286 hdd_enter();
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011287
11288 /* De-init features */
11289 hdd_features_deinit(hdd_ctx);
11290
Dustin Brown1dbefe62018-09-11 16:32:03 -070011291 qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc);
Srinivas Girigowdad2412882018-09-07 15:42:04 -070011292 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011293 hdd_debug("Failed to deregister mode change cb with Policy Manager");
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011294
Dustin Brown1dbefe62018-09-11 16:32:03 -070011295 qdf_status = cds_disable(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053011296 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11297 hdd_err("Failed to Disable the CDS Modules! :%d",
11298 qdf_status);
Houston Hoffman6640cf32016-10-10 16:44:29 -070011299 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011300 }
11301
Dustin Brown07901ec2018-09-07 11:02:41 -070011302 if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) {
Sravan Kumar Kairam71121712017-04-15 00:34:42 +053011303 hdd_err("Failed to disconnect pipes");
11304 ret = -EINVAL;
11305 }
11306
Dustin Browne74003f2018-03-14 12:51:58 -070011307 hdd_exit();
Houston Hoffman6640cf32016-10-10 16:44:29 -070011308 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053011309}
11310
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070011311#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
11312static void hdd_deregister_policy_manager_callback(
11313 struct wlan_objmgr_psoc *psoc)
11314{
11315 if (QDF_STATUS_SUCCESS !=
11316 policy_mgr_deregister_hdd_cb(psoc)) {
11317 hdd_err("HDD callback deregister with policy manager failed");
11318 }
11319}
11320#else
11321static void hdd_deregister_policy_manager_callback(
11322 struct wlan_objmgr_psoc *psoc)
11323{
11324}
11325#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053011326
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011327int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
Arun Khandavallifae92942016-08-01 13:31:08 +053011328{
11329 void *hif_ctx;
11330 qdf_device_t qdf_ctx;
11331 QDF_STATUS qdf_status;
Dustin Brown4bc0a622017-12-06 15:56:50 -080011332 bool is_recovery_stop = cds_is_driver_recovering();
Sourav Mohapatra808e3d42018-07-04 09:34:23 +053011333 int ret = 0;
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053011334 int debugfs_threads;
Arunk Khandavallia6305a32018-01-25 11:19:18 +053011335 struct target_psoc_info *tgt_hdl;
Arun Khandavallifae92942016-08-01 13:31:08 +053011336
Dustin Brown491d54b2018-03-14 12:39:11 -070011337 hdd_enter();
Arun Khandavallifae92942016-08-01 13:31:08 +053011338
Dustin Brown1dbefe62018-09-11 16:32:03 -070011339 hdd_deregister_policy_manager_callback(hdd_ctx->psoc);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070011340
Arun Khandavallifae92942016-08-01 13:31:08 +053011341 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
11342 if (!qdf_ctx) {
11343 hdd_err("QDF device context NULL");
11344 return -EINVAL;
11345 }
11346
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070011347 cds_set_module_stop_in_progress(true);
Arun Khandavallifae92942016-08-01 13:31:08 +053011348
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053011349 debugfs_threads = hdd_return_debugfs_threads_count();
Dustin Brown70111822017-03-30 15:31:40 -070011350
Dustin Brown3fdaaf62019-03-18 14:00:16 -070011351 if (debugfs_threads > 0 || hdd_ctx->is_wiphy_suspended) {
11352 hdd_warn("Debugfs threads %d, wiphy suspend %d",
11353 debugfs_threads, hdd_ctx->is_wiphy_suspended);
Dustin Brown70111822017-03-30 15:31:40 -070011354
Sourav Mohapatra808e3d42018-07-04 09:34:23 +053011355 if (IS_IDLE_STOP && !ftm_mode) {
Dustin Brown4c663222018-10-23 14:19:36 -070011356 hdd_psoc_idle_timer_start(hdd_ctx);
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070011357 cds_set_module_stop_in_progress(false);
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011358
Dustin Brown70111822017-03-30 15:31:40 -070011359 return 0;
11360 }
Rajeev Kumar86177c22017-03-16 19:44:39 -070011361 }
11362
Kabilan Kannan6edafeb2017-11-16 16:34:34 -080011363 /* free user wowl patterns */
11364 hdd_free_user_wowl_ptrns();
11365
Arun Khandavallifae92942016-08-01 13:31:08 +053011366 switch (hdd_ctx->driver_status) {
11367 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011368 hdd_debug("Modules not initialized just return");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011369 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053011370 case DRIVER_MODULES_CLOSED:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011371 hdd_debug("Modules already closed");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011372 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053011373 case DRIVER_MODULES_ENABLED:
Dustin Brown1a20b082018-08-03 17:27:15 -070011374 hdd_info("Wlan transitioning (CLOSED <- ENABLED)");
11375
Nirav Shah6aeecf92019-02-13 14:05:03 +053011376 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE ||
11377 hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
Dustin Brown1a20b082018-08-03 17:27:15 -070011378 break;
Dustin Brown550f6d22017-12-14 15:44:01 -080011379
Komal Seelamf2136bb2016-09-28 18:30:44 +053011380 hdd_disable_power_management();
Arun Khandavallifae92942016-08-01 13:31:08 +053011381 if (hdd_deconfigure_cds(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011382 hdd_err("Failed to de-configure CDS");
Arun Khandavallifae92942016-08-01 13:31:08 +053011383 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011384 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011385 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011386 hdd_debug("successfully Disabled the CDS modules!");
Dustin Brown550f6d22017-12-14 15:44:01 -080011387
Arun Khandavallifae92942016-08-01 13:31:08 +053011388 break;
11389 default:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011390 QDF_DEBUG_PANIC("Unknown driver state:%d",
Arun Khandavallifae92942016-08-01 13:31:08 +053011391 hdd_ctx->driver_status);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011392 ret = -EINVAL;
11393 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053011394 }
11395
Arunk Khandavalli890f6d92018-10-30 20:18:28 +053011396 hdd_sysfs_destroy_powerstats_interface();
Amar Singhal18081642018-01-26 16:04:13 -080011397 hdd_sysfs_destroy_version_interface();
Arunk Khandavalli890f6d92018-10-30 20:18:28 +053011398 hdd_sysfs_destroy_driver_root_obj();
Dustin Brown550f6d22017-12-14 15:44:01 -080011399 hdd_debug("Closing CDS modules!");
Amar Singhal18081642018-01-26 16:04:13 -080011400
Nirav Shah6aeecf92019-02-13 14:05:03 +053011401 if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) {
11402 qdf_status = cds_post_disable();
11403 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11404 hdd_err("Failed to process post CDS disable! :%d",
11405 qdf_status);
11406 ret = -EINVAL;
11407 QDF_ASSERT(0);
11408 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070011409
Nirav Shah6aeecf92019-02-13 14:05:03 +053011410 /* De-register the SME callbacks */
11411 hdd_deregister_cb(hdd_ctx);
Sourav Mohapatra674925f2018-04-16 11:16:58 +053011412
Nirav Shah6aeecf92019-02-13 14:05:03 +053011413 hdd_runtime_suspend_context_deinit(hdd_ctx);
psimhadeea0a12017-12-18 14:50:02 -080011414
Nirav Shah6aeecf92019-02-13 14:05:03 +053011415 qdf_status = cds_dp_close(hdd_ctx->psoc);
11416 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11417 hdd_warn("Failed to stop CDS DP: %d", qdf_status);
11418 ret = -EINVAL;
11419 QDF_ASSERT(0);
11420 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070011421
Nirav Shah6aeecf92019-02-13 14:05:03 +053011422 qdf_status = cds_close(hdd_ctx->psoc);
11423 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11424 hdd_warn("Failed to stop CDS: %d", qdf_status);
11425 ret = -EINVAL;
11426 QDF_ASSERT(0);
11427 }
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053011428
Nirav Shah6aeecf92019-02-13 14:05:03 +053011429 qdf_status = wbuff_module_deinit();
11430 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
11431 hdd_err("WBUFF de-init unsuccessful; status: %d",
11432 qdf_status);
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053011433
Nirav Shah6aeecf92019-02-13 14:05:03 +053011434 hdd_component_pdev_close(hdd_ctx->pdev);
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053011435
Nirav Shah6aeecf92019-02-13 14:05:03 +053011436 hdd_component_psoc_close(hdd_ctx->psoc);
11437 dispatcher_pdev_close(hdd_ctx->pdev);
11438 ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
11439 if (ret) {
11440 hdd_err("Failed to destroy pdev; errno:%d", ret);
11441 QDF_ASSERT(0);
11442 }
Liangwei Dong50a64a72018-01-11 01:17:00 -050011443 }
11444
11445 /*
11446 * Reset total mac phy during module stop such that during
11447 * next module start same psoc is used to populate new service
11448 * ready data
11449 */
Dustin Brown1dbefe62018-09-11 16:32:03 -070011450 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
Arunk Khandavallia6305a32018-01-25 11:19:18 +053011451 if (tgt_hdl)
11452 target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0);
11453
Liangwei Dong50a64a72018-01-11 01:17:00 -050011454
Arun Khandavallifae92942016-08-01 13:31:08 +053011455 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
11456 if (!hif_ctx) {
11457 hdd_err("Hif context is Null");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011458 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011459 }
11460
Arunk Khandavalli4b404332017-09-26 12:46:00 +053011461 if (hdd_ctx->target_hw_name) {
11462 qdf_mem_free(hdd_ctx->target_hw_name);
11463 hdd_ctx->target_hw_name = NULL;
11464 }
11465
Visweswara Tanukuc949ad22019-03-20 13:00:30 +053011466 if (hdd_get_conparam() != QDF_GLOBAL_EPPING_MODE) {
11467 epping_disable();
11468 epping_close();
11469 }
11470
Sravan Kumar Kairam27296782017-04-21 22:04:18 +053011471 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053011472
11473 ol_cds_free();
11474
Dustin Brownc2a156e2018-10-25 16:56:27 -070011475 if (IS_IDLE_STOP) {
Arun Khandavallifae92942016-08-01 13:31:08 +053011476 ret = pld_power_off(qdf_ctx->dev);
11477 if (ret)
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011478 hdd_err("Failed to power down device; errno:%d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053011479 }
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011480
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011481 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
11482 wlan_hdd_free_cache_channels(hdd_ctx);
Arunk Khandavalli847969d2017-09-25 15:15:36 +053011483
Jingxiang Ge3de02752019-01-29 15:47:03 +080011484 hdd_sap_destroy_ctx_all(hdd_ctx, is_recovery_stop);
11485
Dustin Brown29533f22018-07-24 13:11:56 -070011486 hdd_check_for_leaks(hdd_ctx, is_recovery_stop);
Dustin Brown26b3d042017-12-21 11:13:27 -080011487 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -080011488
Arunk Khandavalli847969d2017-09-25 15:15:36 +053011489 /* Once the firmware sequence is completed reset this flag */
11490 hdd_ctx->imps_enabled = false;
Arun Khandavallifae92942016-08-01 13:31:08 +053011491 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -080011492 hdd_info("Wlan transitioned (now CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +053011493
Kai Liueabb1df2018-11-08 14:58:54 +080011494 pld_request_bus_bandwidth(hdd_ctx->parent_dev, PLD_BUS_WIDTH_NONE);
11495
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011496done:
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070011497 cds_set_module_stop_in_progress(false);
Dustin Brown4bc0a622017-12-06 15:56:50 -080011498
Dustin Browne74003f2018-03-14 12:51:58 -070011499 hdd_exit();
Arun Khandavallifae92942016-08-01 13:31:08 +053011500
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011501 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053011502}
11503
Wen Gong3f003382018-05-14 14:26:37 +080011504#ifdef WLAN_FEATURE_MEMDUMP_ENABLE
Arun Khandavallifae92942016-08-01 13:31:08 +053011505/**
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011506 * hdd_state_info_dump() - prints state information of hdd layer
11507 * @buf: buffer pointer
11508 * @size: size of buffer to be filled
11509 *
11510 * This function is used to dump state information of hdd layer
11511 *
11512 * Return: None
11513 */
11514static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
11515{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011516 struct hdd_context *hdd_ctx;
Jeff Johnson40dae4e2017-08-29 14:00:25 -070011517 struct hdd_station_ctx *hdd_sta_ctx;
Jeff Johnson9d295242017-08-29 14:39:48 -070011518 struct hdd_adapter *adapter;
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011519 uint16_t len = 0;
11520 char *buf = *buf_ptr;
11521
11522 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11523 if (!hdd_ctx) {
11524 hdd_err("Failed to get hdd context ");
11525 return;
11526 }
11527
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011528 hdd_debug("size of buffer: %d", *size);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011529
11530 len += scnprintf(buf + len, *size - len,
Jeff Johnson214671b2017-10-30 19:45:23 -070011531 "\n is_wiphy_suspended %d", hdd_ctx->is_wiphy_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011532 len += scnprintf(buf + len, *size - len,
Rajeev Kumareada0d02016-12-08 17:44:17 -080011533 "\n is_scheduler_suspended %d",
11534 hdd_ctx->is_scheduler_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011535
Dustin Brown920397d2017-12-13 16:27:50 -080011536 hdd_for_each_adapter(hdd_ctx, adapter) {
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011537 if (adapter->dev)
11538 len += scnprintf(buf + len, *size - len,
11539 "\n device name: %s", adapter->dev->name);
wadesong42968e92017-06-08 14:11:21 +080011540 len += scnprintf(buf + len, *size - len,
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011541 "\n device_mode: %d", adapter->device_mode);
11542 switch (adapter->device_mode) {
11543 case QDF_STA_MODE:
11544 case QDF_P2P_CLIENT_MODE:
11545 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
11546 len += scnprintf(buf + len, *size - len,
Jeff Johnsone7951512019-02-27 10:02:51 -080011547 "\n conn_state: %d",
11548 hdd_sta_ctx->conn_info.conn_state);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011549 break;
11550
11551 default:
11552 break;
11553 }
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011554 }
11555
11556 *size -= len;
11557 *buf_ptr += len;
11558}
11559
11560/**
11561 * hdd_register_debug_callback() - registration function for hdd layer
11562 * to print hdd state information
11563 *
11564 * Return: None
11565 */
11566static void hdd_register_debug_callback(void)
11567{
11568 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
11569}
Wen Gong3f003382018-05-14 14:26:37 +080011570#else /* WLAN_FEATURE_MEMDUMP_ENABLE */
Wen Gongaa6d55d2018-04-26 16:33:21 +080011571static void hdd_register_debug_callback(void)
11572{
11573}
Wen Gong3f003382018-05-14 14:26:37 +080011574#endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011575
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053011576/*
11577 * wlan_init_bug_report_lock() - Initialize bug report lock
11578 *
11579 * This function is used to create bug report lock
11580 *
11581 * Return: None
11582 */
11583static void wlan_init_bug_report_lock(void)
11584{
Jeff Johnson2b6982c2018-05-29 14:56:11 -070011585 struct cds_context *p_cds_context;
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053011586
11587 p_cds_context = cds_get_global_context();
11588 if (!p_cds_context) {
11589 hdd_err("cds context is NULL");
11590 return;
11591 }
11592
11593 qdf_spinlock_create(&p_cds_context->bug_report_lock);
11594}
11595
Nirav Shahd21a2e32018-04-20 16:34:43 +053011596#ifdef CONFIG_DP_TRACE
Mohit Khannaf8f96822017-05-17 17:11:59 -070011597void hdd_dp_trace_init(struct hdd_config *config)
11598{
Mohit Khannaf8f96822017-05-17 17:11:59 -070011599 bool live_mode = DP_TRACE_CONFIG_DEFAULT_LIVE_MODE;
11600 uint8_t thresh = DP_TRACE_CONFIG_DEFAULT_THRESH;
11601 uint16_t thresh_time_limit = DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT;
11602 uint8_t verbosity = DP_TRACE_CONFIG_DEFAULT_VERBOSTY;
11603 uint8_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP;
11604 uint8_t config_params[DP_TRACE_CONFIG_NUM_PARAMS];
11605 uint8_t num_entries = 0;
Lin Baiaa7f8d72017-10-18 17:23:45 +080011606 uint32_t bw_compute_interval;
Mohit Khannaf8f96822017-05-17 17:11:59 -070011607
Nirav Shahd21a2e32018-04-20 16:34:43 +053011608 if (!config->enable_dp_trace) {
11609 hdd_err("dp trace is disabled from ini");
11610 return;
11611 }
11612
Mohit Khannaf8f96822017-05-17 17:11:59 -070011613 hdd_string_to_u8_array(config->dp_trace_config, config_params,
11614 &num_entries, sizeof(config_params));
11615
11616 /* calculating, num bw timer intervals in a second (1000ms) */
Lin Baiaa7f8d72017-10-18 17:23:45 +080011617 bw_compute_interval = GET_BW_COMPUTE_INTV(config);
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080011618 if (bw_compute_interval <= 1000 && bw_compute_interval > 0)
Lin Baiaa7f8d72017-10-18 17:23:45 +080011619 thresh_time_limit = 1000 / bw_compute_interval;
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080011620 else if (bw_compute_interval > 1000) {
11621 hdd_err("busBandwidthComputeInterval > 1000, using 1000");
11622 thresh_time_limit = 1;
11623 } else
Mohit Khannaf8f96822017-05-17 17:11:59 -070011624 hdd_err("busBandwidthComputeInterval is 0, using defaults");
11625
11626 switch (num_entries) {
11627 case 4:
11628 proto_bitmap = config_params[3];
Alok Kumarb5a33a22018-05-07 18:09:14 +053011629 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070011630 case 3:
11631 verbosity = config_params[2];
Alok Kumarb5a33a22018-05-07 18:09:14 +053011632 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070011633 case 2:
11634 thresh = config_params[1];
Alok Kumarb5a33a22018-05-07 18:09:14 +053011635 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070011636 case 1:
11637 live_mode = config_params[0];
Alok Kumarb5a33a22018-05-07 18:09:14 +053011638 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070011639 default:
Dustin Browna7bb6ae2018-08-16 16:51:50 -070011640 hdd_debug("live_mode %u thresh %u time_limit %u verbosity %u bitmap 0x%x",
11641 live_mode, thresh, thresh_time_limit,
11642 verbosity, proto_bitmap);
Mohit Khannaf8f96822017-05-17 17:11:59 -070011643 };
11644
11645 qdf_dp_trace_init(live_mode, thresh, thresh_time_limit,
11646 verbosity, proto_bitmap);
11647
11648}
Nirav Shahd21a2e32018-04-20 16:34:43 +053011649#endif
11650
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011651#ifdef DISABLE_CHANNEL_LIST
Dustin Brown623e7e32018-09-05 14:27:50 -070011652static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011653{
11654 return qdf_mutex_create(&hdd_ctx->cache_channel_lock);
11655}
11656#else
Dustin Brown623e7e32018-09-05 14:27:50 -070011657static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011658{
Dustin Brown623e7e32018-09-05 14:27:50 -070011659 return QDF_STATUS_SUCCESS;
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011660}
11661#endif
11662
Dustin Brown693b5352019-01-17 10:00:31 -080011663static QDF_STATUS hdd_open_adapter_no_trans(struct hdd_context *hdd_ctx,
11664 enum QDF_OPMODE op_mode,
11665 const char *iface_name,
11666 uint8_t *mac_addr_bytes)
11667{
Dustin Brown2c5e0482019-02-05 16:14:43 -080011668 struct osif_vdev_sync *vdev_sync;
Dustin Brown693b5352019-01-17 10:00:31 -080011669 struct hdd_adapter *adapter;
11670 QDF_STATUS status;
11671 int errno;
11672
11673 QDF_BUG(rtnl_is_locked());
Dustin Brown693b5352019-01-17 10:00:31 -080011674
Dustin Brown2c5e0482019-02-05 16:14:43 -080011675 errno = osif_vdev_sync_create(hdd_ctx->parent_dev, &vdev_sync);
Dustin Brown693b5352019-01-17 10:00:31 -080011676 if (errno)
11677 return qdf_status_from_os_return(errno);
11678
11679 adapter = hdd_open_adapter(hdd_ctx, op_mode, iface_name,
11680 mac_addr_bytes, NET_NAME_UNKNOWN, true);
11681 if (!adapter) {
11682 status = QDF_STATUS_E_INVAL;
11683 goto destroy_sync;
11684 }
11685
Dustin Brown2c5e0482019-02-05 16:14:43 -080011686 osif_vdev_sync_register(adapter->dev, vdev_sync);
Dustin Brown693b5352019-01-17 10:00:31 -080011687
11688 return QDF_STATUS_SUCCESS;
11689
11690destroy_sync:
Dustin Brown2c5e0482019-02-05 16:14:43 -080011691 osif_vdev_sync_destroy(vdev_sync);
Dustin Brown693b5352019-01-17 10:00:31 -080011692
11693 return status;
11694}
11695
11696#ifdef WLAN_OPEN_P2P_INTERFACE
11697/**
11698 * hdd_open_p2p_interface - Open P2P interface
11699 * @hdd_ctx: HDD context
11700 *
11701 * Return: QDF_STATUS
11702 */
11703static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
11704{
11705 QDF_STATUS status;
11706 bool p2p_dev_addr_admin;
11707 bool is_p2p_locally_administered = false;
11708
11709 cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
11710
11711 if (p2p_dev_addr_admin) {
11712 if (hdd_ctx->num_provisioned_addr &&
11713 !(hdd_ctx->provisioned_mac_addr[0].bytes[0] & 0x02)) {
11714 hdd_ctx->p2p_device_address =
11715 hdd_ctx->provisioned_mac_addr[0];
11716
11717 /*
11718 * Generate the P2P Device Address. This consists of
11719 * the device's primary MAC address with the locally
11720 * administered bit set.
11721 */
11722
11723 hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
11724 is_p2p_locally_administered = true;
11725 } else if (!(hdd_ctx->derived_mac_addr[0].bytes[0] & 0x02)) {
11726 hdd_ctx->p2p_device_address =
11727 hdd_ctx->derived_mac_addr[0];
11728 /*
11729 * Generate the P2P Device Address. This consists of
11730 * the device's primary MAC address with the locally
11731 * administered bit set.
11732 */
11733 hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
11734 is_p2p_locally_administered = true;
11735 }
11736 }
11737 if (!is_p2p_locally_administered) {
11738 uint8_t *p2p_dev_addr;
11739
11740 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx,
11741 QDF_P2P_DEVICE_MODE);
11742 if (!p2p_dev_addr) {
11743 hdd_err("Failed to get MAC address for new p2p device");
11744 return QDF_STATUS_E_INVAL;
11745 }
11746
11747 qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
11748 p2p_dev_addr, QDF_MAC_ADDR_SIZE);
11749 }
11750
11751 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_P2P_DEVICE_MODE,
11752 "p2p%d",
11753 hdd_ctx->p2p_device_address.bytes);
11754 if (QDF_IS_STATUS_ERROR(status)) {
11755 hdd_err("Failed to open p2p interface");
11756 return QDF_STATUS_E_INVAL;
11757 }
11758
11759 return QDF_STATUS_SUCCESS;
11760}
11761#else
11762static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
11763{
11764 return QDF_STATUS_SUCCESS;
11765}
11766#endif
11767
11768static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
11769{
11770 QDF_STATUS status;
11771 uint8_t *mac_addr;
11772
11773 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_OCB_MODE);
11774 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_OCB_MODE,
11775 "wlanocb%d", mac_addr);
11776 if (QDF_IS_STATUS_ERROR(status))
11777 hdd_err("Failed to open 802.11p interface");
11778
11779 return status;
11780}
11781
11782static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
11783{
11784 QDF_STATUS status;
11785 const char *iface_name;
11786 uint8_t *mac_addr;
11787
11788 if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, ""))
11789 return QDF_STATUS_SUCCESS;
11790
11791 iface_name = hdd_ctx->config->enable_concurrent_sta;
11792 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
11793 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
11794 iface_name, mac_addr);
11795 if (QDF_IS_STATUS_ERROR(status))
11796 hdd_err("Failed to open concurrent station interface");
11797
11798 return status;
11799}
11800
Dustin Brown61cc3932018-10-18 16:12:13 -070011801static QDF_STATUS
11802hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
Dustin Browna2deeb72018-10-18 14:19:27 -070011803{
Dustin Browna2deeb72018-10-18 14:19:27 -070011804 enum dot11p_mode dot11p_mode;
Dustin Brown61cc3932018-10-18 16:12:13 -070011805 QDF_STATUS status;
Dustin Brown693b5352019-01-17 10:00:31 -080011806 uint8_t *mac_addr;
Dustin Browna2deeb72018-10-18 14:19:27 -070011807
11808 ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode);
11809
11810 /* Create only 802.11p interface? */
11811 if (dot11p_mode == CFG_11P_STANDALONE)
Dustin Brown61cc3932018-10-18 16:12:13 -070011812 return hdd_open_ocb_interface(hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070011813
Dustin Brown693b5352019-01-17 10:00:31 -080011814 mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_STA_MODE);
11815 status = hdd_open_adapter_no_trans(hdd_ctx, QDF_STA_MODE,
11816 "wlan%d", mac_addr);
11817 if (QDF_IS_STATUS_ERROR(status))
11818 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070011819
Dustin Brown61cc3932018-10-18 16:12:13 -070011820 /* opening concurrent STA is best effort, continue on error */
11821 hdd_open_concurrent_interface(hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070011822
Dustin Brown61cc3932018-10-18 16:12:13 -070011823 status = hdd_open_p2p_interface(hdd_ctx);
11824 if (status)
Dustin Browna2deeb72018-10-18 14:19:27 -070011825 goto err_close_adapters;
11826
11827 /* Open 802.11p Interface */
11828 if (dot11p_mode == CFG_11P_CONCURRENT) {
Dustin Brown61cc3932018-10-18 16:12:13 -070011829 status = hdd_open_ocb_interface(hdd_ctx);
11830 if (QDF_IS_STATUS_ERROR(status))
Dustin Browna2deeb72018-10-18 14:19:27 -070011831 goto err_close_adapters;
11832 }
11833
Dustin Brown61cc3932018-10-18 16:12:13 -070011834 return QDF_STATUS_SUCCESS;
Dustin Browna2deeb72018-10-18 14:19:27 -070011835
11836err_close_adapters:
11837 hdd_close_all_adapters(hdd_ctx, true);
11838
Dustin Brown61cc3932018-10-18 16:12:13 -070011839 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070011840}
11841
Dustin Brown61cc3932018-10-18 16:12:13 -070011842static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx)
Dustin Browna2deeb72018-10-18 14:19:27 -070011843{
Dustin Brown693b5352019-01-17 10:00:31 -080011844 uint8_t *mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_FTM_MODE);
Dustin Brown61cc3932018-10-18 16:12:13 -070011845
Dustin Brown693b5352019-01-17 10:00:31 -080011846 return hdd_open_adapter_no_trans(hdd_ctx, QDF_FTM_MODE,
11847 "wlan%d", mac_addr);
Dustin Brown61cc3932018-10-18 16:12:13 -070011848}
11849
11850static QDF_STATUS
11851hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx)
11852{
Dustin Brown693b5352019-01-17 10:00:31 -080011853 uint8_t *mac_addr = wlan_hdd_get_intf_addr(hdd_ctx, QDF_MONITOR_MODE);
Dustin Brown61cc3932018-10-18 16:12:13 -070011854
Dustin Brown693b5352019-01-17 10:00:31 -080011855 return hdd_open_adapter_no_trans(hdd_ctx, QDF_MONITOR_MODE,
11856 "wlan%d", mac_addr);
Dustin Brown61cc3932018-10-18 16:12:13 -070011857}
11858
11859static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx)
11860{
Nirav Shah6aeecf92019-02-13 14:05:03 +053011861 epping_enable_adapter();
Dustin Brown61cc3932018-10-18 16:12:13 -070011862 return QDF_STATUS_SUCCESS;
Dustin Brown61cc3932018-10-18 16:12:13 -070011863}
11864
11865typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx);
11866
11867static const hdd_open_mode_handler
11868hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = {
11869 [QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode,
11870 [QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode,
11871 [QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode,
11872 [QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode,
11873};
11874
Dustin Brown92bd8382018-10-31 15:49:46 -070011875static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
11876 enum QDF_GLOBAL_MODE driver_mode)
Dustin Brown61cc3932018-10-18 16:12:13 -070011877{
11878 QDF_STATUS status;
11879
11880 if (driver_mode < 0 ||
11881 driver_mode >= QDF_GLOBAL_MAX_MODE ||
11882 !hdd_open_mode_handlers[driver_mode]) {
11883 hdd_err("Driver mode %d not supported", driver_mode);
11884 return -ENOTSUPP;
11885 }
Dustin Browna2deeb72018-10-18 14:19:27 -070011886
11887 hdd_hold_rtnl_lock();
Dustin Brown61cc3932018-10-18 16:12:13 -070011888 status = hdd_open_mode_handlers[driver_mode](hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070011889 hdd_release_rtnl_lock();
11890
Dustin Brown92bd8382018-10-31 15:49:46 -070011891 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070011892}
11893
Dustin Brown623e7e32018-09-05 14:27:50 -070011894int hdd_wlan_startup(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080011895{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011896 QDF_STATUS status;
Dustin Brown623e7e32018-09-05 14:27:50 -070011897 int errno;
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +053011898 bool is_imps_enabled;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080011899
Dustin Brown491d54b2018-03-14 12:39:11 -070011900 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080011901
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011902 hdd_action_oui_config(hdd_ctx);
11903
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +053011904 qdf_nbuf_init_replenish_timer();
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011905
Dustin Brown623e7e32018-09-05 14:27:50 -070011906 status = wlan_hdd_cache_chann_mutex_create(hdd_ctx);
11907 if (QDF_IS_STATUS_ERROR(status))
11908 return qdf_status_to_os_return(status);
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011909
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +053011910#ifdef FEATURE_WLAN_CH_AVOID
11911 mutex_init(&hdd_ctx->avoid_freq_lock);
11912#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053011913
Naveen Rawate02f8f52018-04-05 11:58:04 -070011914 osif_request_manager_init();
Dustin Brown021cecd2017-12-11 13:56:43 -080011915 hdd_driver_memdump_init();
Dustin Brown86d196b2018-08-02 11:51:49 -070011916 hdd_bus_bandwidth_init(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -080011917
Arunk Khandavalli5ff0375472019-01-11 17:26:47 +053011918#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
11919 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
11920 QDF_TIMER_TYPE_SW,
11921 hdd_skip_acs_scan_timer_handler,
11922 hdd_ctx);
11923 if (QDF_IS_STATUS_ERROR(status))
11924 hdd_err("Failed to init ACS Skip timer");
11925 qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
11926#endif
11927
Dustin Brown623e7e32018-09-05 14:27:50 -070011928 errno = hdd_wlan_start_modules(hdd_ctx, false);
11929 if (errno) {
11930 hdd_err("Failed to start modules; errno:%d", errno);
11931 goto memdump_deinit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011932 }
11933
Nirav Shah6aeecf92019-02-13 14:05:03 +053011934 if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE)
11935 return 0;
11936
Yingying Tang80e15f32016-09-27 18:23:01 +080011937 wlan_hdd_update_wiphy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011938
Dustin Brown623e7e32018-09-05 14:27:50 -070011939 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
11940 if (!hdd_ctx->mac_handle) {
Jeff Johnson16528362018-06-14 12:34:16 -070011941 hdd_err("Mac Handle is null");
Dustin Brown623e7e32018-09-05 14:27:50 -070011942 goto stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011943 }
11944
Dustin Brown623e7e32018-09-05 14:27:50 -070011945 errno = hdd_wiphy_init(hdd_ctx);
11946 if (errno) {
11947 hdd_err("Failed to initialize wiphy; errno:%d", errno);
11948 goto stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011949 }
11950
Nirav Shahd21a2e32018-04-20 16:34:43 +053011951 hdd_dp_trace_init(hdd_ctx->config);
Nirav Shahcc1f1ae2016-04-26 11:41:29 +053011952
Ashish Kumar Dhanotiya7a11e272018-11-28 13:16:55 +053011953 errno = hdd_initialize_mac_address(hdd_ctx);
11954 if (errno) {
11955 hdd_err("MAC initializtion failed: %d", errno);
11956 goto unregister_wiphy;
11957 }
Prashanth Bhatta75fa9a12016-01-11 18:30:08 -080011958
Dustin Brown623e7e32018-09-05 14:27:50 -070011959 errno = register_netdevice_notifier(&hdd_netdev_notifier);
11960 if (errno) {
11961 hdd_err("register_netdevice_notifier failed; errno:%d", errno);
11962 goto unregister_wiphy;
Paul Zhangfb02f452017-12-22 11:58:43 +080011963 }
Arun Khandavalli08479ba2017-08-07 19:56:23 +053011964
Dustin Brown623e7e32018-09-05 14:27:50 -070011965 errno = register_reboot_notifier(&system_reboot_notifier);
11966 if (errno) {
11967 hdd_err("Failed to register reboot notifier; errno:%d", errno);
11968 goto unregister_netdev;
Arunk Khandavalli830c9692018-03-22 12:17:40 +053011969 }
11970
Sandeep Puligilla34618782019-01-04 17:42:42 -080011971 wlan_hdd_update_11n_mode(hdd_ctx);
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080011972
Arunk Khandavalli40943af2017-05-15 19:25:34 +053011973 hdd_lpass_notify_wlan_version(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011974
Dustin Brown623e7e32018-09-05 14:27:50 -070011975 errno = hdd_register_notifiers(hdd_ctx);
11976 if (errno)
11977 goto unregister_reboot;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -070011978
Paul Zhangfb02f452017-12-22 11:58:43 +080011979 status = wlansap_global_init();
Dustin Brown92bd8382018-10-31 15:49:46 -070011980 if (QDF_IS_STATUS_ERROR(status))
11981 goto unregister_notifiers;
Paul Zhangfb02f452017-12-22 11:58:43 +080011982
Pragaspathi Thilagaraj784c4922018-12-02 22:47:29 +053011983 ucfg_mlme_is_imps_enabled(hdd_ctx->psoc, &is_imps_enabled);
11984 hdd_set_idle_ps_config(hdd_ctx, is_imps_enabled);
Arun Kumar Khandavallideda5a82019-03-11 15:32:19 +053011985 hdd_debugfs_mws_coex_info_init(hdd_ctx);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011986
Dustin Brown92bd8382018-10-31 15:49:46 -070011987 hdd_exit();
11988
11989 return 0;
11990
11991unregister_notifiers:
11992 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011993
Dustin Brown623e7e32018-09-05 14:27:50 -070011994unregister_reboot:
Arunk Khandavalli830c9692018-03-22 12:17:40 +053011995 unregister_reboot_notifier(&system_reboot_notifier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011996
Dustin Brown623e7e32018-09-05 14:27:50 -070011997unregister_netdev:
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011998 unregister_netdevice_notifier(&hdd_netdev_notifier);
11999
Dustin Brown623e7e32018-09-05 14:27:50 -070012000unregister_wiphy:
Rachit Kankane30807332018-06-27 18:39:36 +053012001 qdf_dp_trace_deinit();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080012002 wiphy_unregister(hdd_ctx->wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012003
Dustin Brown623e7e32018-09-05 14:27:50 -070012004stop_modules:
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070012005 hdd_wlan_stop_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +053012006
Dustin Brown623e7e32018-09-05 14:27:50 -070012007memdump_deinit:
Dustin Brown86d196b2018-08-02 11:51:49 -070012008 hdd_bus_bandwidth_deinit(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -080012009 hdd_driver_memdump_deinit();
Naveen Rawate02f8f52018-04-05 11:58:04 -070012010 osif_request_manager_deinit();
Dustin Brown623e7e32018-09-05 14:27:50 -070012011 qdf_nbuf_deinit_replenish_timer();
Ryan Hsucfef0ae2016-04-28 10:20:46 -070012012
Nachiket Kukade8003d252017-03-30 15:55:58 +053012013 if (cds_is_fw_down())
12014 hdd_err("Not setting the complete event as fw is down");
12015 else
Dustin Brown623e7e32018-09-05 14:27:50 -070012016 hdd_start_complete(errno);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012017
Dustin Browne74003f2018-03-14 12:51:58 -070012018 hdd_exit();
Dustin Brown92bd8382018-10-31 15:49:46 -070012019
Dustin Brown623e7e32018-09-05 14:27:50 -070012020 return errno;
Dustin Brown92bd8382018-10-31 15:49:46 -070012021}
12022
12023QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx)
12024{
12025 enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam();
12026 QDF_STATUS status;
12027
12028 status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode);
12029 if (QDF_IS_STATUS_ERROR(status)) {
12030 hdd_err("Failed to create vdevs; status:%d", status);
12031 return status;
12032 }
12033
12034 if (hdd_ctx->rps)
12035 hdd_set_rps_cpu_mask(hdd_ctx);
12036
12037 if (driver_mode != QDF_GLOBAL_FTM_MODE)
12038 hdd_psoc_idle_timer_start(hdd_ctx);
12039
12040 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012041}
12042
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012043/**
Arun Khandavallifae92942016-08-01 13:31:08 +053012044 * hdd_wlan_update_target_info() - update target type info
12045 * @hdd_ctx: HDD context
12046 * @context: hif context
12047 *
12048 * Update target info received from firmware in hdd context
12049 * Return:None
12050 */
12051
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012052void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
Arun Khandavallifae92942016-08-01 13:31:08 +053012053{
12054 struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
12055
12056 if (!tgt_info) {
12057 hdd_err("Target info is Null");
12058 return;
12059 }
12060
12061 hdd_ctx->target_type = tgt_info->target_type;
12062}
12063
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053012064void hdd_get_nud_stats_cb(void *data, struct rsp_stats *rsp, void *context)
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012065{
12066 struct hdd_context *hdd_ctx = (struct hdd_context *)data;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012067 int status;
12068 struct hdd_adapter *adapter = NULL;
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012069 struct osif_request *request = NULL;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012070
Dustin Brown491d54b2018-03-14 12:39:11 -070012071 hdd_enter();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012072
12073 if (!rsp) {
12074 hdd_err("data is null");
12075 return;
12076 }
12077
12078 status = wlan_hdd_validate_context(hdd_ctx);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053012079 if (status != 0)
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012080 return;
12081
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012082 request = osif_request_get(context);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053012083 if (!request) {
12084 hdd_err("obselete request");
12085 return;
12086 }
12087
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012088 adapter = hdd_get_adapter_by_vdev(hdd_ctx, rsp->vdev_id);
Jeff Johnsond36fa332019-03-18 13:42:25 -070012089 if ((!adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012090 hdd_err("Invalid adapter or adapter has invalid magic");
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012091 osif_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012092 return;
12093 }
12094
Alok Kumarce2c29a2018-10-12 15:44:02 +053012095 hdd_debug("rsp->arp_req_enqueue :%x", rsp->arp_req_enqueue);
12096 hdd_debug("rsp->arp_req_tx_success :%x", rsp->arp_req_tx_success);
12097 hdd_debug("rsp->arp_req_tx_failure :%x", rsp->arp_req_tx_failure);
12098 hdd_debug("rsp->arp_rsp_recvd :%x", rsp->arp_rsp_recvd);
12099 hdd_debug("rsp->out_of_order_arp_rsp_drop_cnt :%x",
12100 rsp->out_of_order_arp_rsp_drop_cnt);
12101 hdd_debug("rsp->dad_detected :%x", rsp->dad_detected);
12102 hdd_debug("rsp->connect_status :%x", rsp->connect_status);
12103 hdd_debug("rsp->ba_session_establishment_status :%x",
12104 rsp->ba_session_establishment_status);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012105
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012106 adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012107 adapter->dad |= rsp->dad_detected;
12108 adapter->con_status = rsp->connect_status;
12109
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053012110 /* Flag true indicates connectivity check stats present. */
12111 if (rsp->connect_stats_present) {
Alok Kumarce2c29a2018-10-12 15:44:02 +053012112 hdd_debug("rsp->tcp_ack_recvd :%x", rsp->tcp_ack_recvd);
12113 hdd_debug("rsp->icmpv4_rsp_recvd :%x", rsp->icmpv4_rsp_recvd);
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053012114 adapter->hdd_stats.hdd_tcp_stats.rx_fw_cnt = rsp->tcp_ack_recvd;
12115 adapter->hdd_stats.hdd_icmpv4_stats.rx_fw_cnt =
12116 rsp->icmpv4_rsp_recvd;
12117 }
12118
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070012119 osif_request_complete(request);
12120 osif_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012121
Dustin Browne74003f2018-03-14 12:51:58 -070012122 hdd_exit();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012123}
12124
Visweswara Tanuku633976b2019-01-07 16:13:12 +053012125#ifdef WLAN_FEATURE_MOTION_DETECTION
12126/**
12127 * hdd_md_host_evt_cb - Callback for Motion Detection Event
12128 * @ctx: HDD context
12129 * @event: motion detect event
12130 *
12131 * Callback for Motion Detection Event. Re-enables Motion
12132 * Detection again upon event
12133 *
12134 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and
12135 * QDF_STATUS_E_FAILURE on failure
12136 */
12137QDF_STATUS hdd_md_host_evt_cb(void *ctx, struct sir_md_evt *event)
12138{
12139 struct hdd_adapter *adapter = NULL;
12140 struct hdd_context *hdd_ctx;
12141 QDF_STATUS status;
12142 struct sme_motion_det_en motion_det;
12143
12144 if (!ctx || !event)
12145 return QDF_STATUS_E_INVAL;
12146
12147 hdd_ctx = (struct hdd_context *)ctx;
12148 status = wlan_hdd_validate_context(hdd_ctx);
12149 if (0 != status)
12150 return QDF_STATUS_E_INVAL;
12151
12152 adapter = hdd_get_adapter_by_vdev(hdd_ctx, event->vdev_id);
12153 if (!adapter || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
12154 hdd_err("Invalid adapter or adapter has invalid magic");
12155 return QDF_STATUS_E_INVAL;
12156 }
12157
12158 hdd_debug("Motion Detection CB vdev_id=%u, status=%u",
12159 event->vdev_id, event->status);
12160
12161 if (adapter->motion_detection_mode) {
12162 motion_det.vdev_id = event->vdev_id;
12163 motion_det.enable = 1;
12164 hdd_debug("Motion Detect CB -> Enable Motion Detection again");
12165 sme_motion_det_enable(hdd_ctx->mac_handle, &motion_det);
12166 }
12167
12168 return QDF_STATUS_SUCCESS;
12169}
12170#endif /* WLAN_FEATURE_MOTION_DETECTION */
12171
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053012172/**
Arun Khandavallifae92942016-08-01 13:31:08 +053012173 * hdd_register_cb - Register HDD callbacks.
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012174 * @hdd_ctx: HDD context
12175 *
12176 * Register the HDD callbacks to CDS/SME.
12177 *
12178 * Return: 0 for success or Error code for failure
12179 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012180int hdd_register_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012181{
12182 QDF_STATUS status;
12183 int ret = 0;
Jeff Johnson16528362018-06-14 12:34:16 -070012184 mac_handle_t mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012185
Dustin Brown491d54b2018-03-14 12:39:11 -070012186 hdd_enter();
Sourav Mohapatra674925f2018-04-16 11:16:58 +053012187 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
12188 hdd_err("in ftm mode, no need to register callbacks");
12189 return ret;
12190 }
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012191
Jeff Johnson16528362018-06-14 12:34:16 -070012192 mac_handle = hdd_ctx->mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012193
Jeff Johnson16528362018-06-14 12:34:16 -070012194 sme_register_oem_data_rsp_callback(mac_handle,
12195 hdd_send_oem_data_rsp_msg);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012196
Jeff Johnson16528362018-06-14 12:34:16 -070012197 sme_register_mgmt_frame_ind_callback(mac_handle,
Deepthi Gowrid5a58fe2016-09-03 16:01:28 +053012198 hdd_indicate_mgmt_frame);
Jeff Johnson16528362018-06-14 12:34:16 -070012199 sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx);
Jeff Johnson16528362018-06-14 12:34:16 -070012200 sme_stats_ext_register_callback(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012201 wlan_hdd_cfg80211_stats_ext_callback);
12202
Jeff Johnson16528362018-06-14 12:34:16 -070012203 sme_ext_scan_register_callback(mac_handle,
12204 wlan_hdd_cfg80211_extscan_callback);
12205 sme_stats_ext2_register_callback(mac_handle,
lifeng66831662017-05-19 16:01:35 +080012206 wlan_hdd_cfg80211_stats_ext2_callback);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012207
Jeff Johnson16528362018-06-14 12:34:16 -070012208 sme_set_rssi_threshold_breached_cb(mac_handle,
12209 hdd_rssi_threshold_breached);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012210
Jeff Johnson16528362018-06-14 12:34:16 -070012211 sme_set_link_layer_stats_ind_cb(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012212 wlan_hdd_cfg80211_link_layer_stats_callback);
12213
Jeff Johnson16528362018-06-14 12:34:16 -070012214 sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb);
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +053012215
Jeff Johnson16528362018-06-14 12:34:16 -070012216 sme_set_link_layer_ext_cb(mac_handle,
Zhang Qianca38fb12016-12-23 11:10:48 +080012217 wlan_hdd_cfg80211_link_layer_stats_ext_callback);
Abhinav Kumar338e57d2019-02-04 17:30:10 +053012218 sme_update_hidden_ssid_status_cb(mac_handle,
12219 hdd_hidden_ssid_enable_roaming);
Zhang Qianca38fb12016-12-23 11:10:48 +080012220
Jeff Johnson16528362018-06-14 12:34:16 -070012221 status = sme_set_lost_link_info_cb(mac_handle,
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +053012222 hdd_lost_link_info_cb);
12223 /* print error and not block the startup process */
12224 if (!QDF_IS_STATUS_SUCCESS(status))
12225 hdd_err("set lost link info callback failed");
12226
Poddar, Siddarth34872782017-08-10 14:08:51 +053012227 ret = hdd_register_data_stall_detect_cb();
12228 if (ret) {
12229 hdd_err("Register data stall detect detect callback failed.");
12230 return ret;
12231 }
12232
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012233 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
12234
Jeff Johnson16528362018-06-14 12:34:16 -070012235 sme_register_set_connection_info_cb(mac_handle,
12236 hdd_set_connection_in_progress,
12237 hdd_is_connection_in_progress);
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +053012238
Jeff Johnson16528362018-06-14 12:34:16 -070012239 status = sme_congestion_register_callback(mac_handle,
12240 hdd_update_cca_info_cb);
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +053012241 if (!QDF_IS_STATUS_SUCCESS(status))
12242 hdd_err("set congestion callback failed");
12243
Jeff Johnson16528362018-06-14 12:34:16 -070012244 status = sme_set_bt_activity_info_cb(mac_handle,
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053012245 hdd_bt_activity_cb);
12246 if (!QDF_IS_STATUS_SUCCESS(status))
12247 hdd_err("set bt activity info callback failed");
12248
Jeff Johnson16528362018-06-14 12:34:16 -070012249 status = sme_register_tx_queue_cb(mac_handle,
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -080012250 hdd_tx_queue_cb);
12251 if (!QDF_IS_STATUS_SUCCESS(status))
12252 hdd_err("Register tx queue callback failed");
12253
Visweswara Tanuku633976b2019-01-07 16:13:12 +053012254#ifdef WLAN_FEATURE_MOTION_DETECTION
12255 sme_set_md_host_evt_cb(mac_handle, hdd_md_host_evt_cb, (void *)hdd_ctx);
12256#endif /* WLAN_FEATURE_MOTION_DETECTION */
12257
Dustin Browne74003f2018-03-14 12:51:58 -070012258 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012259
12260 return ret;
12261}
12262
12263/**
12264 * hdd_deregister_cb() - De-Register HDD callbacks.
12265 * @hdd_ctx: HDD context
12266 *
12267 * De-Register the HDD callbacks to CDS/SME.
12268 *
12269 * Return: void
12270 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012271void hdd_deregister_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012272{
12273 QDF_STATUS status;
Poddar, Siddarth34872782017-08-10 14:08:51 +053012274 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -070012275 mac_handle_t mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012276
Dustin Brown491d54b2018-03-14 12:39:11 -070012277 hdd_enter();
Sourav Mohapatra674925f2018-04-16 11:16:58 +053012278 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
12279 hdd_err("in ftm mode, no need to deregister callbacks");
12280 return;
12281 }
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012282
Jeff Johnson16528362018-06-14 12:34:16 -070012283 mac_handle = hdd_ctx->mac_handle;
12284 sme_deregister_tx_queue_cb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012285
Jeff Johnson16528362018-06-14 12:34:16 -070012286 sme_reset_link_layer_stats_ind_cb(mac_handle);
12287 sme_reset_rssi_threshold_breached_cb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012288
Jeff Johnson16528362018-06-14 12:34:16 -070012289 sme_stats_ext_register_callback(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012290 wlan_hdd_cfg80211_stats_ext_callback);
12291
Jeff Johnson16528362018-06-14 12:34:16 -070012292 status = sme_reset_tsfcb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012293 if (!QDF_IS_STATUS_SUCCESS(status))
12294 hdd_err("Failed to de-register tsfcb the callback:%d",
12295 status);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012296
Poddar, Siddarth34872782017-08-10 14:08:51 +053012297 ret = hdd_deregister_data_stall_detect_cb();
12298 if (ret)
12299 hdd_err("Failed to de-register data stall detect event callback");
12300
Jeff Johnson16528362018-06-14 12:34:16 -070012301 sme_deregister_oem_data_rsp_callback(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012302
Dustin Browne74003f2018-03-14 12:51:58 -070012303 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012304}
12305
12306/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012307 * hdd_softap_sta_deauth() - handle deauth req from HDD
Jeff Johnson50e37e92019-03-08 11:32:25 -080012308 * @adapter: Pointer to the HDD adapter
12309 * @param: Params to the operation
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012310 *
12311 * This to take counter measure to handle deauth req from HDD
12312 *
12313 * Return: None
12314 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012315QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
Jeff Johnson50e37e92019-03-08 11:32:25 -080012316 struct csr_del_sta_params *param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012317{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012318 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012319
Dustin Brown491d54b2018-03-14 12:39:11 -070012320 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012321
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012322 /* Ignore request to deauth bcmc station */
Jeff Johnson50e37e92019-03-08 11:32:25 -080012323 if (param->peerMacAddr.bytes[0] & 0x1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012324 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012325
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012326 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012327 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Jeff Johnson50e37e92019-03-08 11:32:25 -080012328 param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012329
Dustin Browne74003f2018-03-14 12:51:58 -070012330 hdd_exit();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012331 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012332}
12333
12334/**
12335 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
Jeff Johnson50e37e92019-03-08 11:32:25 -080012336 * @adapter: Pointer to the HDD
12337 * @param: pointer to station deletion parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012338 *
12339 * This to take counter measure to handle deauth req from HDD
12340 *
12341 * Return: None
12342 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012343void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
Jeff Johnson50e37e92019-03-08 11:32:25 -080012344 struct csr_del_sta_params *param)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012345{
Dustin Brown491d54b2018-03-14 12:39:11 -070012346 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012347
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012348 /* Ignore request to disassoc bcmc station */
Jeff Johnson50e37e92019-03-08 11:32:25 -080012349 if (param->peerMacAddr.bytes[0] & 0x1)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012350 return;
12351
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012352 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Jeff Johnson50e37e92019-03-08 11:32:25 -080012353 param);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012354}
12355
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012356void wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012357{
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012358 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
12359 struct hdd_adapter *adapter = NULL;
12360 struct csr_roam_profile *roam_profile;
12361 struct hdd_station_ctx *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012362
Dustin Brown1dbefe62018-09-11 16:32:03 -070012363 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012364 hdd_debug("No active sta session");
12365 return;
12366 }
12367
12368 hdd_for_each_adapter(hdd_ctx, adapter) {
12369 roam_profile = hdd_roam_profile(adapter);
12370 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
12371
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012372 if (cur_adapter->vdev_id != adapter->vdev_id &&
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012373 adapter->device_mode == QDF_STA_MODE &&
12374 hdd_conn_is_connected(sta_ctx)) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012375 hdd_debug("%d Disable roaming", adapter->vdev_id);
Jeff Johnson16528362018-06-14 12:34:16 -070012376 sme_stop_roaming(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012377 adapter->vdev_id,
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012378 ecsr_driver_disabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012379 }
12380 }
12381}
12382
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012383void wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012384{
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012385 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
12386 struct hdd_adapter *adapter = NULL;
12387 struct csr_roam_profile *roam_profile;
12388 struct hdd_station_ctx *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012389
Dustin Brown1dbefe62018-09-11 16:32:03 -070012390 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012391 hdd_debug("No active sta session");
12392 return;
12393 }
12394
12395 hdd_for_each_adapter(hdd_ctx, adapter) {
12396 roam_profile = hdd_roam_profile(adapter);
12397 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
12398
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012399 if (cur_adapter->vdev_id != adapter->vdev_id &&
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012400 adapter->device_mode == QDF_STA_MODE &&
12401 hdd_conn_is_connected(sta_ctx)) {
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012402 hdd_debug("%d Enable roaming", adapter->vdev_id);
Jeff Johnson16528362018-06-14 12:34:16 -070012403 sme_start_roaming(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012404 adapter->vdev_id,
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012405 REASON_DRIVER_ENABLED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012406 }
12407 }
12408}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012409
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053012410/**
12411 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
12412 * @skb: sk buffer pointer
12413 *
12414 * Sends the bcast message to SVC multicast group with generic nl socket
12415 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
12416 *
12417 * Return: None
12418 */
12419static void nl_srv_bcast_svc(struct sk_buff *skb)
12420{
12421#ifdef CNSS_GENL
12422 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
12423#else
12424 nl_srv_bcast(skb);
12425#endif
12426}
12427
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012428void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012429{
12430 struct sk_buff *skb;
12431 struct nlmsghdr *nlh;
12432 tAniMsgHdr *ani_hdr;
12433 void *nl_data = NULL;
12434 int flags = GFP_KERNEL;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012435 struct radio_index_tlv *radio_info;
12436 int tlv_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012437
12438 if (in_interrupt() || irqs_disabled() || in_atomic())
12439 flags = GFP_ATOMIC;
12440
12441 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
12442
Jeff Johnsond36fa332019-03-18 13:42:25 -070012443 if (!skb)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012444 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012445
12446 nlh = (struct nlmsghdr *)skb->data;
12447 nlh->nlmsg_pid = 0; /* from kernel */
12448 nlh->nlmsg_flags = 0;
12449 nlh->nlmsg_seq = 0;
12450 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12451
12452 ani_hdr = NLMSG_DATA(nlh);
12453 ani_hdr->type = type;
12454
12455 switch (type) {
12456 case WLAN_SVC_FW_CRASHED_IND:
Komal Seelam78ff65a2016-08-18 15:25:24 +053012457 case WLAN_SVC_FW_SHUTDOWN_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012458 case WLAN_SVC_LTE_COEX_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012459 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070012460 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012461 ani_hdr->length = 0;
12462 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012463 break;
12464 case WLAN_SVC_WLAN_STATUS_IND:
12465 case WLAN_SVC_WLAN_VERSION_IND:
12466 case WLAN_SVC_DFS_CAC_START_IND:
12467 case WLAN_SVC_DFS_CAC_END_IND:
12468 case WLAN_SVC_DFS_RADAR_DETECT_IND:
12469 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
12470 case WLAN_SVC_WLAN_TP_IND:
Mohit Khannae71e2262015-11-10 09:37:24 -080012471 case WLAN_SVC_WLAN_TP_TX_IND:
Nirav Shahbd36b062016-07-18 11:12:59 +053012472 case WLAN_SVC_RPS_ENABLE_IND:
Orhan K AKYILDIZe7445a22017-01-19 21:21:47 -080012473 case WLAN_SVC_CORE_MINFREQ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012474 ani_hdr->length = len;
12475 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12476 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12477 memcpy(nl_data, data, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012478 break;
12479
12480 default:
Jeff Johnson34c88b72016-08-15 14:27:11 -070012481 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012482 type);
12483 kfree_skb(skb);
12484 return;
12485 }
12486
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012487 /*
Jeff Johnson0d52c7a2017-01-12 08:46:55 -080012488 * Add radio index at the end of the svc event in TLV format
12489 * to maintain the backward compatibility with userspace
12490 * applications.
12491 */
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012492
12493 tlv_len = 0;
12494
12495 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
12496 < WLAN_NL_MAX_PAYLOAD) {
12497 radio_info = (struct radio_index_tlv *)((char *) ani_hdr +
12498 sizeof(*ani_hdr) + len);
12499 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
12500 radio_info->length = (unsigned short) sizeof(radio_info->radio);
12501 radio_info->radio = radio;
12502 tlv_len = sizeof(*radio_info);
Dustin Browna2868622018-03-20 11:38:14 -070012503 hdd_debug("Added radio index tlv - radio index %d",
12504 radio_info->radio);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012505 }
12506
12507 nlh->nlmsg_len += tlv_len;
12508 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
12509
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053012510 nl_srv_bcast_svc(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012511}
12512
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012513#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
12514void wlan_hdd_auto_shutdown_cb(void)
12515{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012516 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012517
12518 if (!hdd_ctx)
12519 return;
12520
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012521 hdd_debug("Wlan Idle. Sending Shutdown event..");
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012522 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
12523 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012524}
12525
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012526void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012527{
Jeff Johnson9d295242017-08-29 14:39:48 -070012528 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012529 bool ap_connected = false, sta_connected = false;
Jeff Johnson16528362018-06-14 12:34:16 -070012530 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012531
Jeff Johnson16528362018-06-14 12:34:16 -070012532 mac_handle = hdd_ctx->mac_handle;
12533 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012534 return;
12535
Dundi Raviteja8e338282018-09-25 17:16:04 +053012536 if (hdd_ctx->config->wlan_auto_shutdown == 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012537 return;
12538
12539 if (enable == false) {
Jeff Johnson16528362018-06-14 12:34:16 -070012540 if (sme_set_auto_shutdown_timer(mac_handle, 0) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012541 QDF_STATUS_SUCCESS) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012542 hdd_err("Failed to stop wlan auto shutdown timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012543 }
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012544 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070012545 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012546 return;
12547 }
12548
12549 /* To enable shutdown timer check conncurrency */
Dustin Brown1dbefe62018-09-11 16:32:03 -070012550 if (policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc)) {
Dustin Brown920397d2017-12-13 16:27:50 -080012551 hdd_for_each_adapter(hdd_ctx, adapter) {
12552 if (adapter->device_mode == QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012553 if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
Jeff Johnsone7951512019-02-27 10:02:51 -080012554 conn_info.conn_state ==
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012555 eConnectionState_Associated) {
12556 sta_connected = true;
12557 break;
12558 }
12559 }
Dustin Brown920397d2017-12-13 16:27:50 -080012560
12561 if (adapter->device_mode == QDF_SAP_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012562 if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
Jeff Johnson136c51b2017-10-27 20:02:41 -070012563 ap_active == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012564 ap_connected = true;
12565 break;
12566 }
12567 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012568 }
12569 }
12570
12571 if (ap_connected == true || sta_connected == true) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012572 hdd_debug("CC Session active. Shutdown timer not enabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012573 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012574 }
Jeff Johnson68755312017-02-10 11:46:55 -080012575
Jeff Johnson16528362018-06-14 12:34:16 -070012576 if (sme_set_auto_shutdown_timer(mac_handle,
Dundi Raviteja8e338282018-09-25 17:16:04 +053012577 hdd_ctx->config->wlan_auto_shutdown)
Jeff Johnson68755312017-02-10 11:46:55 -080012578 != QDF_STATUS_SUCCESS)
12579 hdd_err("Failed to start wlan auto shutdown timer");
12580 else
Dustin Brown5e89ef82018-03-14 11:50:23 -070012581 hdd_info("Auto Shutdown timer for %d seconds enabled",
Dundi Raviteja8e338282018-09-25 17:16:04 +053012582 hdd_ctx->config->wlan_auto_shutdown);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012583}
12584#endif
12585
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070012586struct hdd_adapter *
12587hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
12588 bool check_start_bss)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012589{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012590 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070012591 struct hdd_adapter *adapter, *con_sap_adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012592
12593 con_sap_adapter = NULL;
12594
Dustin Brown920397d2017-12-13 16:27:50 -080012595 hdd_for_each_adapter(hdd_ctx, adapter) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080012596 if (adapter && ((adapter->device_mode == QDF_SAP_MODE) ||
12597 (adapter->device_mode == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012598 adapter != this_sap_adapter) {
12599 if (check_start_bss) {
12600 if (test_bit(SOFTAP_BSS_STARTED,
12601 &adapter->event_flags)) {
12602 con_sap_adapter = adapter;
12603 break;
12604 }
12605 } else {
12606 con_sap_adapter = adapter;
12607 break;
12608 }
12609 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012610 }
12611
12612 return con_sap_adapter;
12613}
12614
12615#ifdef MSM_PLATFORM
Jeff Johnson9d295242017-08-29 14:39:48 -070012616static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012617{
Dustin Brown5ec6b552017-03-31 12:11:40 -070012618 return adapter->device_mode == QDF_STA_MODE ||
12619 adapter->device_mode == QDF_P2P_CLIENT_MODE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012620}
12621
Jeff Johnson9d295242017-08-29 14:39:48 -070012622static inline bool hdd_adapter_is_ap(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012623{
Dustin Brown5ec6b552017-03-31 12:11:40 -070012624 return adapter->device_mode == QDF_SAP_MODE ||
12625 adapter->device_mode == QDF_P2P_GO_MODE;
12626}
12627
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012628static bool hdd_any_adapter_is_assoc(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012629{
Dustin Brown920397d2017-12-13 16:27:50 -080012630 struct hdd_adapter *adapter;
Dustin Brown5ec6b552017-03-31 12:11:40 -070012631
Dustin Brown920397d2017-12-13 16:27:50 -080012632 hdd_for_each_adapter(hdd_ctx, adapter) {
12633 if (hdd_adapter_is_sta(adapter) &&
Dustin Brown5ec6b552017-03-31 12:11:40 -070012634 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
Jeff Johnsone7951512019-02-27 10:02:51 -080012635 conn_info.conn_state == eConnectionState_Associated) {
Dustin Brown5ec6b552017-03-31 12:11:40 -070012636 return true;
12637 }
12638
Dustin Brown920397d2017-12-13 16:27:50 -080012639 if (hdd_adapter_is_ap(adapter) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -070012640 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active) {
Dustin Brown5ec6b552017-03-31 12:11:40 -070012641 return true;
12642 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070012643 }
12644
12645 return false;
12646}
12647
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012648static void __hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012649{
Dustin Browna20bad52019-03-05 12:03:30 -080012650 qdf_periodic_work_start(&hdd_ctx->bus_bw_work,
12651 hdd_ctx->config->bus_bw_compute_interval);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012652}
12653
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012654void hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012655{
Dustin Brown491d54b2018-03-14 12:39:11 -070012656 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012657
Dustin Brown5ec6b552017-03-31 12:11:40 -070012658 __hdd_bus_bw_compute_timer_start(hdd_ctx);
12659
Dustin Browne74003f2018-03-14 12:51:58 -070012660 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012661}
12662
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012663void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012664{
Dustin Brown491d54b2018-03-14 12:39:11 -070012665 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012666
Dustin Brown5ec6b552017-03-31 12:11:40 -070012667 if (hdd_any_adapter_is_assoc(hdd_ctx))
12668 __hdd_bus_bw_compute_timer_start(hdd_ctx);
12669
Dustin Browne74003f2018-03-14 12:51:58 -070012670 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012671}
12672
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012673static void __hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012674{
Dustin Browna20bad52019-03-05 12:03:30 -080012675 if (!qdf_periodic_work_stop_sync(&hdd_ctx->bus_bw_work))
12676 return;
12677
Dustin Brown07901ec2018-09-07 11:02:41 -070012678 ucfg_ipa_set_perf_level(hdd_ctx->pdev, 0, 0);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012679 hdd_reset_tcp_delack(hdd_ctx);
12680}
12681
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012682void hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012683{
Dustin Brown491d54b2018-03-14 12:39:11 -070012684 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012685
Dustin Brown5ec6b552017-03-31 12:11:40 -070012686 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
12687
Dustin Browne74003f2018-03-14 12:51:58 -070012688 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012689}
12690
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012691void hdd_bus_bw_compute_timer_try_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012692{
Dustin Brown491d54b2018-03-14 12:39:11 -070012693 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012694
Dustin Brown5ec6b552017-03-31 12:11:40 -070012695 if (!hdd_any_adapter_is_assoc(hdd_ctx))
12696 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
12697
Dustin Browne74003f2018-03-14 12:51:58 -070012698 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012699}
12700#endif
12701
12702/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012703 * wlan_hdd_stop_sap() - This function stops bss of SAP.
12704 * @ap_adapter: SAP adapter
12705 *
12706 * This function will process the stopping of sap adapter.
12707 *
12708 * Return: None
12709 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012710void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012711{
Jeff Johnson87251032017-08-29 13:31:11 -070012712 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070012713 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053012714 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012715 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012716
Jeff Johnsond36fa332019-03-18 13:42:25 -070012717 if (!ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012718 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012719 return;
12720 }
12721
12722 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
12723 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Abhishek Singh23edd1c2016-05-05 11:56:06 +053012724 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012725 return;
Abhishek Singh23edd1c2016-05-05 11:56:06 +053012726
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012727 mutex_lock(&hdd_ctx->sap_lock);
12728 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080012729 wlan_hdd_del_station(ap_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012730 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012731 hdd_debug("Now doing SAP STOPBSS");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053012732 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012733 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070012734 sap_context)) {
Nachiket Kukade0396b732017-11-14 16:35:16 +053012735 qdf_status = qdf_wait_for_event_completion(&hostapd_state->
Naveen Rawatb56880c2016-12-13 17:56:03 -080012736 qdf_stop_bss_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053012737 SME_CMD_STOP_BSS_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +053012738 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012739 mutex_unlock(&hdd_ctx->sap_lock);
Jeff Johnson28f8a772016-08-15 15:30:36 -070012740 hdd_err("SAP Stop Failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012741 return;
12742 }
12743 }
12744 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -070012745 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012746 ap_adapter->device_mode,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012747 ap_adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070012748 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053012749 false);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012750 hdd_debug("SAP Stop Success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012751 } else {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012752 hdd_err("Can't stop ap because its not started");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012753 }
12754 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012755}
12756
12757/**
12758 * wlan_hdd_start_sap() - this function starts bss of SAP.
12759 * @ap_adapter: SAP adapter
12760 *
12761 * This function will process the starting of sap adapter.
12762 *
12763 * Return: None
12764 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012765void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012766{
Jeff Johnson87251032017-08-29 13:31:11 -070012767 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070012768 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053012769 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012770 struct hdd_context *hdd_ctx;
Jeff Johnson8f8ceb92019-03-24 08:16:55 -070012771 struct sap_config *sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012772
Jeff Johnsond36fa332019-03-18 13:42:25 -070012773 if (!ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012774 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012775 return;
12776 }
12777
Krunal Soni9b04c9b2016-03-10 13:08:05 -080012778 if (QDF_SAP_MODE != ap_adapter->device_mode) {
Peng Xuf5d60c82015-10-02 17:17:03 -070012779 hdd_err("SoftAp role has not been enabled");
12780 return;
12781 }
12782
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012783 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
12784 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
12785 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -070012786 sap_config = &ap_adapter->session.ap.sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012787
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012788 mutex_lock(&hdd_ctx->sap_lock);
12789 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
12790 goto end;
12791
12792 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012793 hdd_err("SAP Not able to set AP IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012794 goto end;
12795 }
Dustin Brown07901ec2018-09-07 11:02:41 -070012796 wlan_reg_set_channel_params(hdd_ctx->pdev,
Abhinav Kumar6f694482018-09-04 16:07:39 +053012797 hdd_ap_ctx->sap_config.channel, 0,
12798 &hdd_ap_ctx->sap_config.ch_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012799
Wei Song2f76f642016-11-18 16:32:53 +080012800 qdf_event_reset(&hostapd_state->qdf_event);
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070012801 if (wlansap_start_bss(hdd_ap_ctx->sap_context, hdd_hostapd_sap_event_cb,
Jeff Johnson91df29d2017-10-27 19:29:50 -070012802 &hdd_ap_ctx->sap_config,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012803 ap_adapter->dev)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012804 != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012805 goto end;
12806
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012807 hdd_debug("Waiting for SAP to start");
Nachiket Kukade0396b732017-11-14 16:35:16 +053012808 qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053012809 SME_CMD_START_BSS_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +053012810 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012811 hdd_err("SAP Start failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012812 goto end;
12813 }
Jeff Johnson28f8a772016-08-15 15:30:36 -070012814 hdd_info("SAP Start Success");
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053012815 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012816 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053012817 if (hostapd_state->bss_state == BSS_START) {
Dustin Brown1dbefe62018-09-11 16:32:03 -070012818 policy_mgr_incr_active_session(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012819 ap_adapter->device_mode,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080012820 ap_adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070012821 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053012822 true);
12823 }
Sourav Mohapatra9bc67112017-11-08 09:36:11 +053012824 mutex_unlock(&hdd_ctx->sap_lock);
12825
12826 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012827end:
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053012828 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012829 mutex_unlock(&hdd_ctx->sap_lock);
Manikandan Mohan3dad1a42017-06-14 10:50:18 -070012830 /* SAP context and beacon cleanup will happen during driver unload
12831 * in hdd_stop_adapter
12832 */
12833 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
12834
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012835}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012836
12837/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012838 * hdd_get_fw_version() - Get FW version
12839 * @hdd_ctx: pointer to HDD context.
12840 * @major_spid: FW version - major spid.
12841 * @minor_spid: FW version - minor spid
12842 * @ssid: FW version - ssid
12843 * @crmid: FW version - crmid
12844 *
12845 * This function is called to get the firmware build version stored
12846 * as part of the HDD context
12847 *
12848 * Return: None
12849 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012850void hdd_get_fw_version(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012851 uint32_t *major_spid, uint32_t *minor_spid,
12852 uint32_t *siid, uint32_t *crmid)
12853{
12854 *major_spid = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
12855 *minor_spid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
12856 *siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
12857 *crmid = hdd_ctx->target_fw_version & 0x7fff;
12858}
12859
12860#ifdef QCA_CONFIG_SMP
12861/**
12862 * wlan_hdd_get_cpu() - get cpu_index
12863 *
12864 * Return: cpu_index
12865 */
12866int wlan_hdd_get_cpu(void)
12867{
12868 int cpu_index = get_cpu();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012869
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012870 put_cpu();
12871 return cpu_index;
12872}
12873#endif
12874
12875/**
12876 * hdd_get_fwpath() - get framework path
12877 *
12878 * This function is used to get the string written by
12879 * userspace to start the wlan driver
12880 *
12881 * Return: string
12882 */
12883const char *hdd_get_fwpath(void)
12884{
12885 return fwpath.string;
12886}
12887
Dustin Brown94ce20f2018-09-04 13:11:38 -070012888static inline int hdd_state_query_cb(void)
12889{
12890 return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD));
12891}
12892
Dustin Brown265e82b2019-03-18 11:07:32 -070012893static int __hdd_op_protect_cb(void **out_sync, const char *func)
12894{
12895 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
12896
12897 if (!hdd_ctx)
12898 return -EAGAIN;
12899
12900 return __osif_psoc_sync_op_start(hdd_ctx->parent_dev,
12901 (struct osif_psoc_sync **)out_sync,
12902 func);
12903}
12904
12905static void __hdd_op_unprotect_cb(void *sync, const char *func)
12906{
12907 __osif_psoc_sync_op_stop(sync, func);
12908}
12909
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012910/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012911 * hdd_init() - Initialize Driver
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012912 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012913 * This function initilizes CDS global context with the help of cds_init. This
12914 * has to be the first function called after probe to get a valid global
12915 * context.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012916 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012917 * Return: 0 for success, errno on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012918 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012919int hdd_init(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012920{
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070012921 QDF_STATUS status;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012922
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070012923 status = cds_init();
wadesongae4ffd12017-10-24 16:45:54 +080012924 if (QDF_IS_STATUS_ERROR(status)) {
12925 hdd_err("Failed to allocate CDS context");
Dustin Brownc1d81af2019-03-01 13:43:43 -080012926 return -ENOMEM;
wadesongae4ffd12017-10-24 16:45:54 +080012927 }
Dustin Brownc1d81af2019-03-01 13:43:43 -080012928
Dustin Brown265e82b2019-03-18 11:07:32 -070012929 qdf_op_callbacks_register(__hdd_op_protect_cb, __hdd_op_unprotect_cb);
Hanumanth Reddy Pothula788a37e2017-08-17 18:40:11 +053012930
12931 wlan_init_bug_report_lock();
12932
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012933#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12934 wlan_logging_sock_init_svc();
12935#endif
12936
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012937 hdd_trace_init();
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012938 hdd_register_debug_callback();
Qiwei Caiad9b01c2018-07-09 17:21:31 +080012939 wlan_roam_debug_init();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012940
Dustin Brownfe50cef2018-12-10 10:42:37 -080012941 return 0;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012942}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012943
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012944/**
12945 * hdd_deinit() - Deinitialize Driver
12946 *
12947 * This function frees CDS global context with the help of cds_deinit. This
12948 * has to be the last function call in remove callback to free the global
12949 * context.
12950 */
12951void hdd_deinit(void)
12952{
Qiwei Caiad9b01c2018-07-09 17:21:31 +080012953 wlan_roam_debug_deinit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012954
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012955#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12956 wlan_logging_sock_deinit_svc();
12957#endif
Qiwei Caiad9b01c2018-07-09 17:21:31 +080012958
12959 wlan_destroy_bug_report_lock();
Dustin Brown265e82b2019-03-18 11:07:32 -070012960 qdf_op_callbacks_register(NULL, NULL);
Qiwei Caiad9b01c2018-07-09 17:21:31 +080012961 cds_deinit();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012962}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012963
Yue Ma6e7b1a02017-04-03 14:17:46 -070012964#ifdef QCA_WIFI_NAPIER_EMULATION
12965#define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
12966#else
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012967#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
Yue Ma6e7b1a02017-04-03 14:17:46 -070012968#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012969
Sachin Ahujadddd2632017-03-07 19:07:24 +053012970static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
12971 struct file *file)
12972{
12973 return 0;
12974}
12975
12976static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
12977 const char __user *user_buf,
12978 size_t count,
12979 loff_t *f_pos)
12980{
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012981 char buf[3];
Sachin Ahujadddd2632017-03-07 19:07:24 +053012982 static const char wlan_off_str[] = "OFF";
12983 static const char wlan_on_str[] = "ON";
12984 int ret;
12985 unsigned long rc;
12986
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012987 if (copy_from_user(buf, user_buf, 3)) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053012988 pr_err("Failed to read buffer\n");
12989 return -EINVAL;
12990 }
12991
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012992 if (strncmp(buf, wlan_off_str, strlen(wlan_off_str)) == 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053012993 pr_debug("Wifi turning off from UI\n");
12994 goto exit;
12995 }
12996
Srinivas Girigowdad2412882018-09-07 15:42:04 -070012997 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) == 0)
Sachin Ahuja16904db2017-12-13 19:56:57 +053012998 pr_info("Wifi Turning On from UI\n");
Sachin Ahuja16904db2017-12-13 19:56:57 +053012999
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053013000 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) != 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053013001 pr_err("Invalid value received from framework");
13002 goto exit;
13003 }
13004
13005 if (!cds_is_driver_loaded()) {
Sachin Ahujaee62b542017-04-21 14:14:16 +053013006 init_completion(&wlan_start_comp);
Sachin Ahujadddd2632017-03-07 19:07:24 +053013007 rc = wait_for_completion_timeout(&wlan_start_comp,
13008 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
13009 if (!rc) {
Srinivas Girigowda09625b02018-09-10 15:28:09 -070013010 hdd_alert("Timed-out!!");
Sachin Ahujadddd2632017-03-07 19:07:24 +053013011 ret = -EINVAL;
Sachin Ahujadddd2632017-03-07 19:07:24 +053013012 return ret;
13013 }
13014
13015 hdd_start_complete(0);
13016 }
13017
13018exit:
13019 return count;
13020}
13021
13022
13023const struct file_operations wlan_hdd_state_fops = {
13024 .owner = THIS_MODULE,
13025 .open = wlan_hdd_state_ctrl_param_open,
13026 .write = wlan_hdd_state_ctrl_param_write,
13027};
13028
13029static int wlan_hdd_state_ctrl_param_create(void)
13030{
13031 unsigned int wlan_hdd_state_major = 0;
13032 int ret;
13033 struct device *dev;
13034
13035 device = MKDEV(wlan_hdd_state_major, 0);
13036
13037 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
13038 if (ret) {
13039 pr_err("Failed to register qcwlanstate");
13040 goto dev_alloc_err;
13041 }
13042 wlan_hdd_state_major = MAJOR(device);
13043
13044 class = class_create(THIS_MODULE, WLAN_MODULE_NAME);
13045 if (IS_ERR(class)) {
13046 pr_err("wlan_hdd_state class_create error");
13047 goto class_err;
13048 }
13049
13050 dev = device_create(class, NULL, device, NULL, WLAN_MODULE_NAME);
13051 if (IS_ERR(dev)) {
13052 pr_err("wlan_hdd_statedevice_create error");
13053 goto err_class_destroy;
13054 }
13055
13056 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
13057 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
13058 if (ret) {
13059 pr_err("Failed to add cdev error");
13060 goto cdev_add_err;
13061 }
13062
13063 pr_info("wlan_hdd_state %s major(%d) initialized",
13064 WLAN_MODULE_NAME, wlan_hdd_state_major);
13065
13066 return 0;
13067
13068cdev_add_err:
13069 device_destroy(class, device);
13070err_class_destroy:
13071 class_destroy(class);
13072class_err:
13073 unregister_chrdev_region(device, dev_num);
13074dev_alloc_err:
13075 return -ENODEV;
13076}
13077
13078static void wlan_hdd_state_ctrl_param_destroy(void)
13079{
13080 cdev_del(&wlan_hdd_state_cdev);
13081 device_destroy(class, device);
13082 class_destroy(class);
13083 unregister_chrdev_region(device, dev_num);
13084
13085 pr_info("Device node unregistered");
13086}
13087
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013088/**
Dustin Brownd585cb32018-09-12 17:12:23 -070013089 * hdd_component_init() - Initialize all components
Mukul Sharmad75a6672017-06-22 15:40:53 +053013090 *
Dustin Brownd585cb32018-09-12 17:12:23 -070013091 * Return: QDF_STATUS
Mukul Sharmad75a6672017-06-22 15:40:53 +053013092 */
Dustin Brownd585cb32018-09-12 17:12:23 -070013093static QDF_STATUS hdd_component_init(void)
Mukul Sharmad75a6672017-06-22 15:40:53 +053013094{
Dustin Brownd585cb32018-09-12 17:12:23 -070013095 QDF_STATUS status;
13096
13097 /* initialize converged components */
Arif Hussain49698112018-07-31 00:32:50 -070013098 status = target_if_init(wma_get_psoc_from_scn_handle);
Dustin Brownd585cb32018-09-12 17:12:23 -070013099 if (QDF_IS_STATUS_ERROR(status))
13100 return status;
13101
Abhishek Singhd5cf22d2019-01-08 19:51:09 +053013102 status = ucfg_mlme_global_init();
Arif Hussain49698112018-07-31 00:32:50 -070013103 if (QDF_IS_STATUS_ERROR(status))
13104 goto target_if_deinit;
13105
Abhishek Singhd5cf22d2019-01-08 19:51:09 +053013106 status = dispatcher_init();
13107 if (QDF_IS_STATUS_ERROR(status))
13108 goto mlme_global_deinit;
13109
Dustin Brownd585cb32018-09-12 17:12:23 -070013110 /* initialize non-converged components */
13111 status = ucfg_mlme_init();
13112 if (QDF_IS_STATUS_ERROR(status))
13113 goto dispatcher_deinit;
13114
13115 status = ucfg_fwol_init();
13116 if (QDF_IS_STATUS_ERROR(status))
13117 goto mlme_deinit;
13118
13119 status = disa_init();
13120 if (QDF_IS_STATUS_ERROR(status))
13121 goto fwol_deinit;
13122
13123 status = pmo_init();
13124 if (QDF_IS_STATUS_ERROR(status))
13125 goto disa_deinit;
13126
13127 status = ucfg_ocb_init();
13128 if (QDF_IS_STATUS_ERROR(status))
13129 goto pmo_deinit;
13130
13131 status = ipa_init();
13132 if (QDF_IS_STATUS_ERROR(status))
13133 goto ocb_deinit;
13134
13135 status = ucfg_action_oui_init();
13136 if (QDF_IS_STATUS_ERROR(status))
13137 goto ipa_deinit;
13138
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013139 status = nan_init();
13140 if (QDF_IS_STATUS_ERROR(status))
13141 goto action_oui_deinit;
13142
Wu Gao637d58a2018-12-08 10:37:34 +080013143 status = ucfg_p2p_init();
13144 if (QDF_IS_STATUS_ERROR(status))
13145 goto nan_deinit;
13146
Wu Gaod6b5e402018-12-03 22:09:24 +080013147 status = policy_mgr_init();
13148 if (QDF_IS_STATUS_ERROR(status))
13149 goto p2p_deinit;
13150
Wu Gao5f793402018-12-08 11:04:00 +080013151 status = ucfg_tdls_init();
13152 if (QDF_IS_STATUS_ERROR(status))
13153 goto policy_deinit;
13154
Dustin Brownd585cb32018-09-12 17:12:23 -070013155 return QDF_STATUS_SUCCESS;
13156
Wu Gao5f793402018-12-08 11:04:00 +080013157policy_deinit:
13158 policy_mgr_deinit();
Wu Gaod6b5e402018-12-03 22:09:24 +080013159p2p_deinit:
13160 ucfg_p2p_deinit();
Wu Gao637d58a2018-12-08 10:37:34 +080013161nan_deinit:
13162 nan_deinit();
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013163action_oui_deinit:
13164 ucfg_action_oui_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013165ipa_deinit:
13166 ipa_deinit();
13167ocb_deinit:
13168 ucfg_ocb_deinit();
13169pmo_deinit:
13170 pmo_deinit();
13171disa_deinit:
13172 disa_deinit();
13173fwol_deinit:
13174 ucfg_fwol_deinit();
13175mlme_deinit:
13176 ucfg_mlme_deinit();
13177dispatcher_deinit:
13178 dispatcher_deinit();
Abhishek Singhd5cf22d2019-01-08 19:51:09 +053013179mlme_global_deinit:
13180 ucfg_mlme_global_deinit();
Arif Hussain49698112018-07-31 00:32:50 -070013181target_if_deinit:
13182 target_if_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013183
13184 return status;
Mukul Sharmad75a6672017-06-22 15:40:53 +053013185}
13186
13187/**
Dustin Brownd585cb32018-09-12 17:12:23 -070013188 * hdd_component_deinit() - Deinitialize all components
Mukul Sharmad75a6672017-06-22 15:40:53 +053013189 *
13190 * Return: None
13191 */
Dustin Brownd585cb32018-09-12 17:12:23 -070013192static void hdd_component_deinit(void)
Mukul Sharmad75a6672017-06-22 15:40:53 +053013193{
Dustin Brownd585cb32018-09-12 17:12:23 -070013194 /* deinitialize non-converged components */
Wu Gao5f793402018-12-08 11:04:00 +080013195 ucfg_tdls_deinit();
Wu Gaod6b5e402018-12-03 22:09:24 +080013196 policy_mgr_deinit();
Wu Gao637d58a2018-12-08 10:37:34 +080013197 ucfg_p2p_deinit();
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013198 nan_deinit();
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053013199 ucfg_action_oui_deinit();
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +053013200 ipa_deinit();
Zhang Qian47e22ce2018-01-04 15:38:38 +080013201 ucfg_ocb_deinit();
Mukul Sharmad75a6672017-06-22 15:40:53 +053013202 pmo_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013203 disa_deinit();
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013204 ucfg_fwol_deinit();
Vignesh Viswanathana0921c42018-09-04 19:03:35 +053013205 ucfg_mlme_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013206
13207 /* deinitialize converged components */
13208 dispatcher_deinit();
Abhishek Singhd5cf22d2019-01-08 19:51:09 +053013209 ucfg_mlme_global_deinit();
Arif Hussain49698112018-07-31 00:32:50 -070013210 target_if_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013211}
13212
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013213QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc)
13214{
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013215 QDF_STATUS status;
13216
13217 status = ucfg_mlme_psoc_open(psoc);
13218 if (QDF_IS_STATUS_ERROR(status))
13219 return status;
13220
13221 status = ucfg_fwol_psoc_open(psoc);
13222 if (QDF_IS_STATUS_ERROR(status))
Wu Gao66454f12018-09-26 19:55:41 +080013223 goto err_fwol;
13224
13225 status = ucfg_pmo_psoc_open(psoc);
13226 if (QDF_IS_STATUS_ERROR(status))
13227 goto err_pmo;
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013228
Krunal Sonie9c12f52018-10-04 11:45:42 -070013229 status = ucfg_policy_mgr_psoc_open(psoc);
13230 if (QDF_IS_STATUS_ERROR(status))
13231 goto err_plcy_mgr;
13232
Wu Gao637d58a2018-12-08 10:37:34 +080013233 status = ucfg_p2p_psoc_open(psoc);
13234 if (QDF_IS_STATUS_ERROR(status))
13235 goto err_p2p;
Wu Gao5f793402018-12-08 11:04:00 +080013236
13237 status = ucfg_tdls_psoc_open(psoc);
13238 if (QDF_IS_STATUS_ERROR(status))
13239 goto err_tdls;
13240
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013241 return status;
13242
Wu Gao5f793402018-12-08 11:04:00 +080013243err_tdls:
13244 ucfg_tdls_psoc_close(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013245err_p2p:
13246 ucfg_p2p_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070013247err_plcy_mgr:
13248 ucfg_pmo_psoc_close(psoc);
Wu Gao66454f12018-09-26 19:55:41 +080013249err_pmo:
13250 ucfg_fwol_psoc_close(psoc);
13251err_fwol:
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013252 ucfg_mlme_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070013253
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013254 return status;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013255}
13256
13257void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc)
13258{
Wu Gao5f793402018-12-08 11:04:00 +080013259 ucfg_tdls_psoc_close(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013260 ucfg_p2p_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070013261 ucfg_policy_mgr_psoc_close(psoc);
Wu Gao66454f12018-09-26 19:55:41 +080013262 ucfg_pmo_psoc_close(psoc);
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013263 ucfg_fwol_psoc_close(psoc);
Vignesh Viswanathana0921c42018-09-04 19:03:35 +053013264 ucfg_mlme_psoc_close(psoc);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013265}
13266
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013267void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc)
13268{
Zhang Qian47e22ce2018-01-04 15:38:38 +080013269 ocb_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013270 disa_psoc_enable(psoc);
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013271 nan_psoc_enable(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013272 p2p_psoc_enable(psoc);
Wu Gaod6b5e402018-12-03 22:09:24 +080013273 policy_mgr_psoc_enable(psoc);
Wu Gaoa67c3802018-12-27 12:07:52 +080013274 ucfg_tdls_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013275}
13276
13277void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc)
13278{
Wu Gaoa67c3802018-12-27 12:07:52 +080013279 ucfg_tdls_psoc_disable(psoc);
Wu Gaod6b5e402018-12-03 22:09:24 +080013280 policy_mgr_psoc_disable(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013281 p2p_psoc_disable(psoc);
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013282 nan_psoc_disable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013283 disa_psoc_disable(psoc);
Zhang Qian47e22ce2018-01-04 15:38:38 +080013284 ocb_psoc_disable(psoc);
Mukul Sharmad75a6672017-06-22 15:40:53 +053013285}
13286
Sandeep Puligillab7beb472018-08-13 22:54:20 -070013287QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev)
13288{
13289 return ucfg_mlme_pdev_open(pdev);
13290}
13291
13292void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev)
13293{
13294 ucfg_mlme_pdev_close(pdev);
13295}
13296
Dustin Browna2a39dc2018-09-17 15:29:59 -070013297static QDF_STATUS hdd_qdf_print_init(void)
13298{
13299 QDF_STATUS status;
13300 int qdf_print_idx;
13301
13302 status = qdf_print_setup();
13303 if (QDF_IS_STATUS_ERROR(status)) {
13304 pr_err("Failed qdf_print_setup; status:%u\n", status);
13305 return status;
13306 }
13307
13308 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
13309 if (qdf_print_idx < 0) {
13310 pr_err("Failed to register for qdf_print_ctrl\n");
13311 return QDF_STATUS_E_FAILURE;
13312 }
13313
13314 qdf_set_pidx(qdf_print_idx);
13315
13316 return QDF_STATUS_SUCCESS;
13317}
13318
13319static void hdd_qdf_print_deinit(void)
13320{
13321 int qdf_pidx = qdf_get_pidx();
13322
13323 qdf_set_pidx(-1);
13324 qdf_print_ctrl_cleanup(qdf_pidx);
13325
13326 /* currently, no qdf print 'un-setup'*/
13327}
13328
13329static QDF_STATUS hdd_qdf_init(void)
13330{
13331 QDF_STATUS status;
13332
13333 status = hdd_qdf_print_init();
13334 if (QDF_IS_STATUS_ERROR(status))
13335 goto exit;
13336
13337 status = qdf_debugfs_init();
13338 if (QDF_IS_STATUS_ERROR(status)) {
13339 hdd_err("Failed to init debugfs; status:%u", status);
13340 goto print_deinit;
13341 }
13342
13343 qdf_lock_stats_init();
13344 qdf_mem_init();
Dustin Brownc2796312019-03-13 16:43:36 -070013345 qdf_delayed_work_feature_init();
Dustin Brown4a93bb52019-03-13 11:46:34 -070013346 qdf_periodic_work_feature_init();
Dustin Browna2a39dc2018-09-17 15:29:59 -070013347 qdf_mc_timer_manager_init();
13348 qdf_event_list_init();
13349
Dustin Brownd315c452018-11-27 11:28:48 -080013350 status = qdf_talloc_feature_init();
13351 if (QDF_IS_STATUS_ERROR(status)) {
13352 hdd_err("Failed to init talloc; status:%u", status);
13353 goto event_deinit;
13354 }
13355
Dustin Browna2a39dc2018-09-17 15:29:59 -070013356 status = qdf_cpuhp_init();
13357 if (QDF_IS_STATUS_ERROR(status)) {
13358 hdd_err("Failed to init cpuhp; status:%u", status);
Dustin Brownd315c452018-11-27 11:28:48 -080013359 goto talloc_deinit;
Dustin Browna2a39dc2018-09-17 15:29:59 -070013360 }
13361
13362 status = qdf_trace_spin_lock_init();
13363 if (QDF_IS_STATUS_ERROR(status)) {
13364 hdd_err("Failed to init spinlock; status:%u", status);
13365 goto cpuhp_deinit;
13366 }
13367
13368 qdf_trace_init();
13369 qdf_register_debugcb_init();
13370
13371 return QDF_STATUS_SUCCESS;
13372
13373cpuhp_deinit:
13374 qdf_cpuhp_deinit();
Dustin Brownd315c452018-11-27 11:28:48 -080013375talloc_deinit:
13376 qdf_talloc_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070013377event_deinit:
13378 qdf_event_list_destroy();
13379 qdf_mc_timer_manager_exit();
Dustin Brown4a93bb52019-03-13 11:46:34 -070013380 qdf_periodic_work_feature_deinit();
Dustin Brownc2796312019-03-13 16:43:36 -070013381 qdf_delayed_work_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070013382 qdf_mem_exit();
13383 qdf_lock_stats_deinit();
13384 qdf_debugfs_exit();
13385print_deinit:
13386 hdd_qdf_print_deinit();
13387
13388exit:
13389 return status;
13390}
13391
13392static void hdd_qdf_deinit(void)
13393{
13394 /* currently, no debugcb deinit */
13395
13396 qdf_trace_deinit();
13397
13398 /* currently, no trace spinlock deinit */
13399
13400 qdf_cpuhp_deinit();
Dustin Brownd315c452018-11-27 11:28:48 -080013401 qdf_talloc_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070013402 qdf_event_list_destroy();
13403 qdf_mc_timer_manager_exit();
Dustin Brown4a93bb52019-03-13 11:46:34 -070013404 qdf_periodic_work_feature_deinit();
Dustin Brownc2796312019-03-13 16:43:36 -070013405 qdf_delayed_work_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070013406 qdf_mem_exit();
13407 qdf_lock_stats_deinit();
13408 qdf_debugfs_exit();
13409 hdd_qdf_print_deinit();
13410}
Dustin Brownf0f70562018-09-14 10:29:38 -070013411
Dustin Brown26afe8f2019-03-01 12:37:24 -080013412#ifdef FEATURE_MONITOR_MODE_SUPPORT
13413static bool is_monitor_mode_supported(void)
13414{
13415 return true;
13416}
13417#else
13418static bool is_monitor_mode_supported(void)
13419{
13420 pr_err("Monitor mode not supported!");
13421 return false;
13422}
13423#endif
13424
13425#ifdef WLAN_FEATURE_EPPING
13426static bool is_epping_mode_supported(void)
13427{
13428 return true;
13429}
13430#else
13431static bool is_epping_mode_supported(void)
13432{
13433 pr_err("Epping mode not supported!");
13434 return false;
13435}
13436#endif
13437
13438#ifdef QCA_WIFI_FTM
13439static bool is_ftm_mode_supported(void)
13440{
13441 return true;
13442}
13443#else
13444static bool is_ftm_mode_supported(void)
13445{
13446 pr_err("FTM mode not supported!");
13447 return false;
13448}
13449#endif
13450
13451/**
13452 * is_con_mode_valid() check con mode is valid or not
13453 * @mode: global con mode
13454 *
13455 * Return: TRUE on success FALSE on failure
13456 */
13457static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
13458{
13459 switch (mode) {
13460 case QDF_GLOBAL_MONITOR_MODE:
13461 return is_monitor_mode_supported();
13462 case QDF_GLOBAL_EPPING_MODE:
13463 return is_epping_mode_supported();
13464 case QDF_GLOBAL_FTM_MODE:
13465 return is_ftm_mode_supported();
13466 case QDF_GLOBAL_MISSION_MODE:
13467 return true;
13468 default:
13469 return false;
13470 }
13471}
13472
13473static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
13474 enum QDF_GLOBAL_MODE curr_mode)
13475{
13476 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
13477 return;
13478
13479 switch (curr_mode) {
13480 case QDF_GLOBAL_MONITOR_MODE:
13481 hdd_info("Release wakelock for monitor mode!");
13482 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
13483 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
13484 /* fallthrough */
13485 case QDF_GLOBAL_MISSION_MODE:
13486 case QDF_GLOBAL_FTM_MODE:
13487 hdd_abort_mac_scan_all_adapters(hdd_ctx);
13488 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
13489 hdd_stop_all_adapters(hdd_ctx);
13490 hdd_deinit_all_adapters(hdd_ctx, false);
13491
13492 break;
13493 default:
13494 break;
13495 }
13496}
13497
13498static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
13499 enum QDF_GLOBAL_MODE curr_mode)
13500{
13501 int driver_status;
13502
13503 driver_status = hdd_ctx->driver_status;
13504
13505 switch (curr_mode) {
13506 case QDF_GLOBAL_MISSION_MODE:
13507 case QDF_GLOBAL_MONITOR_MODE:
13508 case QDF_GLOBAL_FTM_MODE:
13509 hdd_close_all_adapters(hdd_ctx, false);
13510 break;
13511 case QDF_GLOBAL_EPPING_MODE:
13512 epping_disable();
13513 epping_close();
13514 break;
13515 default:
13516 return;
13517 }
13518}
13519
13520static int
13521hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode)
13522{
13523 QDF_STATUS status;
13524 uint32_t mode;
13525
13526 *out_mode = QDF_GLOBAL_MAX_MODE;
13527
13528 status = qdf_uint32_parse(mode_str, &mode);
13529 if (QDF_IS_STATUS_ERROR(status))
13530 return qdf_status_to_os_return(status);
13531
13532 if (mode >= QDF_GLOBAL_MAX_MODE)
13533 return -ERANGE;
13534
13535 *out_mode = (enum QDF_GLOBAL_MODE)mode;
13536
13537 return 0;
13538}
13539
13540/**
13541 * __hdd_driver_mode_change() - Handles a driver mode change
13542 * @hdd_ctx: Pointer to the global HDD context
13543 * @next_mode: the driver mode to transition to
13544 *
13545 * This function is invoked when user updates con_mode using sys entry,
13546 * to initialize and bring-up driver in that specific mode.
13547 *
13548 * Return: Errno
13549 */
13550static int __hdd_driver_mode_change(struct hdd_context *hdd_ctx,
13551 enum QDF_GLOBAL_MODE next_mode)
13552{
13553 enum QDF_GLOBAL_MODE curr_mode;
13554 int errno;
13555
13556 hdd_info("Driver mode changing to %d", next_mode);
13557
13558 errno = wlan_hdd_validate_context(hdd_ctx);
13559 if (errno)
13560 return errno;
13561
13562 if (!is_con_mode_valid(next_mode)) {
13563 hdd_err_rl("Requested driver mode is invalid");
13564 return -EINVAL;
13565 }
13566
Dustin Brown26afe8f2019-03-01 12:37:24 -080013567 curr_mode = hdd_get_conparam();
13568 if (curr_mode == next_mode) {
13569 hdd_err_rl("Driver is already in the requested mode");
Dustin Browne0a77272019-03-19 16:28:06 -070013570 return 0;
Dustin Brown26afe8f2019-03-01 12:37:24 -080013571 }
13572
13573 /* ensure adapters are stopped */
13574 hdd_stop_present_mode(hdd_ctx, curr_mode);
13575
13576 errno = hdd_wlan_stop_modules(hdd_ctx, true);
13577 if (errno) {
13578 hdd_err("Stop wlan modules failed");
Dustin Browne0a77272019-03-19 16:28:06 -070013579 return errno;
Dustin Brown26afe8f2019-03-01 12:37:24 -080013580 }
13581
13582 /* Cleanup present mode before switching to new mode */
13583 hdd_cleanup_present_mode(hdd_ctx, curr_mode);
13584
13585 hdd_set_conparam(next_mode);
13586
13587 errno = hdd_wlan_start_modules(hdd_ctx, false);
13588 if (errno) {
13589 hdd_err("Start wlan modules failed: %d", errno);
Dustin Browne0a77272019-03-19 16:28:06 -070013590 return errno;
Dustin Brown26afe8f2019-03-01 12:37:24 -080013591 }
13592
13593 errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode);
13594 if (errno) {
13595 hdd_err("Failed to open adapters");
Dustin Browne0a77272019-03-19 16:28:06 -070013596 return errno;
Dustin Brown26afe8f2019-03-01 12:37:24 -080013597 }
13598
13599 if (next_mode == QDF_GLOBAL_MONITOR_MODE) {
13600 struct hdd_adapter *adapter =
13601 hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
13602
13603 QDF_BUG(adapter);
13604 if (!adapter) {
13605 hdd_err("Failed to get monitor adapter");
Dustin Browne0a77272019-03-19 16:28:06 -070013606 return -EINVAL;
Dustin Brown26afe8f2019-03-01 12:37:24 -080013607 }
13608
13609 errno = hdd_start_adapter(adapter);
13610 if (errno) {
13611 hdd_err("Failed to start monitor adapter");
Dustin Browne0a77272019-03-19 16:28:06 -070013612 return errno;
Dustin Brown26afe8f2019-03-01 12:37:24 -080013613 }
13614
13615 hdd_info("Acquire wakelock for monitor mode");
13616 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
13617 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
13618 }
13619
13620 /* con_mode is a global module parameter */
13621 con_mode = next_mode;
13622 hdd_info("Driver mode successfully changed to %d", next_mode);
13623
Dustin Browne0a77272019-03-19 16:28:06 -070013624 return 0;
Dustin Brown26afe8f2019-03-01 12:37:24 -080013625}
13626
13627static int hdd_driver_mode_change(enum QDF_GLOBAL_MODE mode)
13628{
Dustin Brownc1d81af2019-03-01 13:43:43 -080013629 struct osif_driver_sync *driver_sync;
Dustin Brown26afe8f2019-03-01 12:37:24 -080013630 struct hdd_context *hdd_ctx;
13631 QDF_STATUS status;
13632 int errno;
13633
13634 hdd_enter();
13635
Dustin Brownc1d81af2019-03-01 13:43:43 -080013636 status = osif_driver_sync_trans_start_wait(&driver_sync);
Dustin Brown26afe8f2019-03-01 12:37:24 -080013637 if (QDF_IS_STATUS_ERROR(status)) {
13638 hdd_err("Failed to start 'mode change'; status:%u", status);
13639 errno = qdf_status_to_os_return(status);
13640 goto exit;
13641 }
13642
Dustin Brownc1d81af2019-03-01 13:43:43 -080013643 osif_driver_sync_wait_for_ops(driver_sync);
Dustin Brown26afe8f2019-03-01 12:37:24 -080013644
13645 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
13646 errno = wlan_hdd_validate_context(hdd_ctx);
13647 if (errno)
13648 goto trans_stop;
13649
Dustin Brown26afe8f2019-03-01 12:37:24 -080013650 errno = __hdd_driver_mode_change(hdd_ctx, mode);
Dustin Brown26afe8f2019-03-01 12:37:24 -080013651
13652trans_stop:
Dustin Brownc1d81af2019-03-01 13:43:43 -080013653 osif_driver_sync_trans_stop(driver_sync);
Dustin Brown26afe8f2019-03-01 12:37:24 -080013654
13655exit:
13656 hdd_exit();
13657
13658 return errno;
13659}
13660
13661static int hdd_set_con_mode(enum QDF_GLOBAL_MODE mode)
13662{
13663 con_mode = mode;
13664
13665 return 0;
13666}
13667
13668static int (*hdd_set_con_mode_cb)(enum QDF_GLOBAL_MODE mode) = hdd_set_con_mode;
13669
13670static void hdd_driver_mode_change_register(void)
13671{
13672 hdd_set_con_mode_cb = hdd_driver_mode_change;
13673}
13674
13675static void hdd_driver_mode_change_unregister(void)
13676{
13677 hdd_set_con_mode_cb = hdd_set_con_mode;
13678}
13679
13680static int con_mode_handler(const char *kmessage, const struct kernel_param *kp)
13681{
13682 enum QDF_GLOBAL_MODE mode;
13683 int errno;
13684
13685 errno = hdd_parse_driver_mode(kmessage, &mode);
13686 if (errno) {
13687 hdd_err_rl("Failed to parse driver mode '%s'", kmessage);
13688 return errno;
13689 }
13690
13691 return hdd_set_con_mode_cb(mode);
13692}
Dustin Brown95ff00b2019-02-28 13:41:13 -080013693
Dustin Brownf0f70562018-09-14 10:29:38 -070013694/**
13695 * hdd_driver_load() - Perform the driver-level load operation
13696 *
13697 * Note: this is used in both static and DLKM driver builds
13698 *
13699 * Return: Errno
13700 */
13701static int hdd_driver_load(void)
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013702{
Dustin Brownc1d81af2019-03-01 13:43:43 -080013703 struct osif_driver_sync *driver_sync;
Dustin Brownd585cb32018-09-12 17:12:23 -070013704 QDF_STATUS status;
Dustin Brownf0f70562018-09-14 10:29:38 -070013705 int errno;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013706
Dustin Brownc1d81af2019-03-01 13:43:43 -080013707 pr_err("%s: Loading driver v%s\n", WLAN_MODULE_NAME,
Rajeev Kumare555e2d2018-09-17 11:52:37 -070013708 g_wlan_driver_version);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013709
Dustin Browna2a39dc2018-09-17 15:29:59 -070013710 status = hdd_qdf_init();
13711 if (QDF_IS_STATUS_ERROR(status)) {
13712 errno = qdf_status_to_os_return(status);
13713 goto exit;
13714 }
13715
Dustin Brownc1d81af2019-03-01 13:43:43 -080013716 osif_sync_init();
Dustin Brown21a1d462018-07-31 15:13:06 -070013717
Dustin Brownc1d81af2019-03-01 13:43:43 -080013718 status = osif_driver_sync_create_and_trans(&driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070013719 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Brownc1d81af2019-03-01 13:43:43 -080013720 hdd_err("Failed to init driver sync; status:%u", status);
Dustin Brown21a1d462018-07-31 15:13:06 -070013721 errno = qdf_status_to_os_return(status);
Dustin Brownc1d81af2019-03-01 13:43:43 -080013722 goto sync_deinit;
Dustin Brown21a1d462018-07-31 15:13:06 -070013723 }
13724
Dustin Brownf0f70562018-09-14 10:29:38 -070013725 errno = hdd_init();
13726 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013727 hdd_err("Failed to init HDD; errno:%d", errno);
Dustin Brown21a1d462018-07-31 15:13:06 -070013728 goto trans_stop;
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013729 }
13730
Dustin Brownd585cb32018-09-12 17:12:23 -070013731 status = hdd_component_init();
13732 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013733 hdd_err("Failed to init components; status:%u", status);
Dustin Brownf0f70562018-09-14 10:29:38 -070013734 errno = qdf_status_to_os_return(status);
Dustin Brownd585cb32018-09-12 17:12:23 -070013735 goto hdd_deinit;
13736 }
Mukul Sharmad75a6672017-06-22 15:40:53 +053013737
Dustin Brownf0f70562018-09-14 10:29:38 -070013738 status = qdf_wake_lock_create(&wlan_wake_lock, "wlan");
13739 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013740 hdd_err("Failed to create wake lock; status:%u", status);
Dustin Brownf0f70562018-09-14 10:29:38 -070013741 errno = qdf_status_to_os_return(status);
13742 goto comp_deinit;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013743 }
13744
Dustin Brownf0f70562018-09-14 10:29:38 -070013745 hdd_set_conparam(con_mode);
13746
Dustin Brownf0f70562018-09-14 10:29:38 -070013747 errno = wlan_hdd_state_ctrl_param_create();
13748 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013749 hdd_err("Failed to create ctrl param; errno:%d", errno);
Dustin Brown4b9dbe62018-09-14 15:41:11 -070013750 goto wakelock_destroy;
13751 }
13752
Dustin Brown25843ad2018-09-17 14:54:33 -070013753 errno = pld_init();
13754 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013755 hdd_err("Failed to init PLD; errno:%d", errno);
Dustin Brown25843ad2018-09-17 14:54:33 -070013756 goto param_destroy;
13757 }
13758
Dustin Brown95ff00b2019-02-28 13:41:13 -080013759 hdd_driver_mode_change_register();
Dustin Brownc1d81af2019-03-01 13:43:43 -080013760
13761 osif_driver_sync_register(driver_sync);
13762 osif_driver_sync_trans_stop(driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070013763
13764 /* psoc probe can happen in registration; do after 'load' transition */
Dustin Brown4b9dbe62018-09-14 15:41:11 -070013765 errno = wlan_hdd_register_driver();
13766 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013767 hdd_err("Failed to register driver; errno:%d", errno);
Dustin Brown25843ad2018-09-17 14:54:33 -070013768 goto pld_deinit;
Sachin Ahuja16904db2017-12-13 19:56:57 +053013769 }
13770
Dustin Browna2a39dc2018-09-17 15:29:59 -070013771 hdd_debug("%s: driver loaded", WLAN_MODULE_NAME);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013772
13773 return 0;
Dustin Brownd585cb32018-09-12 17:12:23 -070013774
Dustin Brown25843ad2018-09-17 14:54:33 -070013775pld_deinit:
Dustin Brownc1d81af2019-03-01 13:43:43 -080013776 status = osif_driver_sync_trans_start(&driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070013777 QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
13778
Dustin Brownc1d81af2019-03-01 13:43:43 -080013779 osif_driver_sync_unregister();
13780 osif_driver_sync_wait_for_ops(driver_sync);
13781
Dustin Brown95ff00b2019-02-28 13:41:13 -080013782 hdd_driver_mode_change_unregister();
Dustin Brown25843ad2018-09-17 14:54:33 -070013783 pld_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070013784
Dustin Brown4b9dbe62018-09-14 15:41:11 -070013785param_destroy:
13786 wlan_hdd_state_ctrl_param_destroy();
Dustin Brownf0f70562018-09-14 10:29:38 -070013787wakelock_destroy:
Anurag Chouhana37b5b72016-02-21 14:53:42 +053013788 qdf_wake_lock_destroy(&wlan_wake_lock);
Dustin Brownf0f70562018-09-14 10:29:38 -070013789comp_deinit:
Dustin Brownd585cb32018-09-12 17:12:23 -070013790 hdd_component_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013791hdd_deinit:
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013792 hdd_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070013793trans_stop:
Dustin Brownc1d81af2019-03-01 13:43:43 -080013794 osif_driver_sync_trans_stop(driver_sync);
13795 osif_driver_sync_destroy(driver_sync);
13796sync_deinit:
13797 osif_sync_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070013798 hdd_qdf_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013799
Dustin Brown25843ad2018-09-17 14:54:33 -070013800exit:
Dustin Brownf0f70562018-09-14 10:29:38 -070013801 return errno;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013802}
13803
13804/**
Dustin Brownf0f70562018-09-14 10:29:38 -070013805 * hdd_driver_unload() - Performs the driver-level unload operation
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013806 *
Dustin Brownf0f70562018-09-14 10:29:38 -070013807 * Note: this is used in both static and DLKM driver builds
13808 *
13809 * Return: None
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013810 */
Dustin Brownf0f70562018-09-14 10:29:38 -070013811static void hdd_driver_unload(void)
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013812{
Dustin Brownc1d81af2019-03-01 13:43:43 -080013813 struct osif_driver_sync *driver_sync;
Will Huang36049722018-04-13 11:48:51 +080013814 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Dustin Brown21a1d462018-07-31 15:13:06 -070013815 QDF_STATUS status;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +053013816
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013817 pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
13818 QWLAN_VERSIONSTR);
13819
Dustin Brown8c0b5e32019-01-18 13:56:02 -080013820 if (g_is_system_reboot_triggered) {
13821 hdd_info("System rebooting; Skipping unload");
13822 return;
13823 }
13824
13825 if (hdd_ctx)
13826 hdd_psoc_idle_timer_stop(hdd_ctx);
13827
13828 /* trigger SoC remove */
13829 wlan_hdd_unregister_driver();
13830
Dustin Brownc1d81af2019-03-01 13:43:43 -080013831 status = osif_driver_sync_trans_start_wait(&driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070013832 QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
13833 if (QDF_IS_STATUS_ERROR(status)) {
13834 hdd_err("Unable to unload wlan; status:%u", status);
Arunk Khandavalli830c9692018-03-22 12:17:40 +053013835 return;
Dustin Brown21a1d462018-07-31 15:13:06 -070013836 }
13837
Dustin Brownc1d81af2019-03-01 13:43:43 -080013838 osif_driver_sync_unregister();
13839 osif_driver_sync_wait_for_ops(driver_sync);
Dustin Brown21a1d462018-07-31 15:13:06 -070013840
Will Huangba035ec2018-07-05 11:13:30 +080013841 cds_set_driver_loaded(false);
13842 cds_set_unload_in_progress(true);
13843
Dustin Brown95ff00b2019-02-28 13:41:13 -080013844 hdd_driver_mode_change_unregister();
Dustin Brown25843ad2018-09-17 14:54:33 -070013845 pld_deinit();
Dustin Brown4b9dbe62018-09-14 15:41:11 -070013846 wlan_hdd_state_ctrl_param_destroy();
Dustin Brownf0f70562018-09-14 10:29:38 -070013847 hdd_set_conparam(0);
Anurag Chouhana37b5b72016-02-21 14:53:42 +053013848 qdf_wake_lock_destroy(&wlan_wake_lock);
Dustin Brownd585cb32018-09-12 17:12:23 -070013849 hdd_component_deinit();
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013850 hdd_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070013851
Dustin Brownc1d81af2019-03-01 13:43:43 -080013852 osif_driver_sync_trans_stop(driver_sync);
13853 osif_driver_sync_destroy(driver_sync);
Dustin Brown623e7e32018-09-05 14:27:50 -070013854
Dustin Brownc1d81af2019-03-01 13:43:43 -080013855 osif_sync_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070013856
Dustin Browna2a39dc2018-09-17 15:29:59 -070013857 hdd_qdf_deinit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013858}
13859
Arun Khandavallifae92942016-08-01 13:31:08 +053013860#ifndef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013861/**
Arun Khandavallifae92942016-08-01 13:31:08 +053013862 * wlan_boot_cb() - Wlan boot callback
13863 * @kobj: object whose directory we're creating the link in.
13864 * @attr: attribute the user is interacting with
13865 * @buff: the buffer containing the user data
13866 * @count: number of bytes in the buffer
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013867 *
Arun Khandavallifae92942016-08-01 13:31:08 +053013868 * This callback is invoked when the fs is ready to start the
13869 * wlan driver initialization.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013870 *
Arun Khandavallifae92942016-08-01 13:31:08 +053013871 * Return: 'count' on success or a negative error code in case of failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013872 */
Arun Khandavallifae92942016-08-01 13:31:08 +053013873static ssize_t wlan_boot_cb(struct kobject *kobj,
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013874 struct kobj_attribute *attr,
13875 const char *buf,
13876 size_t count)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013877{
Arun Khandavallifae92942016-08-01 13:31:08 +053013878
Arun Khandavallifae92942016-08-01 13:31:08 +053013879 if (wlan_loader->loaded_state) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013880 hdd_err("wlan driver already initialized");
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013881 return -EALREADY;
Arun Khandavallifae92942016-08-01 13:31:08 +053013882 }
13883
Dustin Brownf0f70562018-09-14 10:29:38 -070013884 if (hdd_driver_load())
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013885 return -EIO;
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013886
13887 wlan_loader->loaded_state = MODULE_INITIALIZED;
Arun Khandavallifae92942016-08-01 13:31:08 +053013888
13889 return count;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013890}
Arun Khandavallifae92942016-08-01 13:31:08 +053013891
13892/**
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013893 * hdd_sysfs_cleanup() - cleanup sysfs
13894 *
13895 * Return: None
13896 *
13897 */
13898static void hdd_sysfs_cleanup(void)
13899{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013900 /* remove from group */
13901 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
13902 sysfs_remove_group(wlan_loader->boot_wlan_obj,
13903 wlan_loader->attr_group);
13904
13905 /* unlink the object from parent */
13906 kobject_del(wlan_loader->boot_wlan_obj);
13907
13908 /* free the object */
13909 kobject_put(wlan_loader->boot_wlan_obj);
13910
13911 kfree(wlan_loader->attr_group);
13912 kfree(wlan_loader);
13913
13914 wlan_loader = NULL;
13915}
13916
13917/**
Arun Khandavallifae92942016-08-01 13:31:08 +053013918 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
13919 * ready
13920 *
13921 * This is creates the syfs entry boot_wlan. Which shall be invoked
13922 * when the filesystem is ready.
13923 *
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013924 * QDF API cannot be used here since this function is called even before
13925 * initializing WLAN driver.
13926 *
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070013927 * Return: 0 for success, errno on failure
Arun Khandavallifae92942016-08-01 13:31:08 +053013928 */
13929static int wlan_init_sysfs(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013930{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013931 int ret = -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053013932
13933 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070013934 if (!wlan_loader)
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013935 return -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053013936
13937 wlan_loader->boot_wlan_obj = NULL;
13938 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
13939 GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070013940 if (!wlan_loader->attr_group)
Arun Khandavallifae92942016-08-01 13:31:08 +053013941 goto error_return;
Arun Khandavallifae92942016-08-01 13:31:08 +053013942
13943 wlan_loader->loaded_state = 0;
13944 wlan_loader->attr_group->attrs = attrs;
13945
Qun Zhang4a83a462018-09-11 16:28:51 +080013946 wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME,
Arun Khandavallifae92942016-08-01 13:31:08 +053013947 kernel_kobj);
13948 if (!wlan_loader->boot_wlan_obj) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013949 hdd_err("sysfs create and add failed");
Arun Khandavallifae92942016-08-01 13:31:08 +053013950 goto error_return;
13951 }
13952
13953 ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
13954 wlan_loader->attr_group);
13955 if (ret) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013956 hdd_err("sysfs create group failed; errno:%d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053013957 goto error_return;
13958 }
13959
13960 return 0;
13961
13962error_return:
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013963 hdd_sysfs_cleanup();
Arun Khandavallifae92942016-08-01 13:31:08 +053013964
13965 return ret;
13966}
13967
13968/**
13969 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
13970 *
13971 * Return: 0 on success or errno on failure
13972 */
13973static int wlan_deinit_sysfs(void)
13974{
Arun Khandavallifae92942016-08-01 13:31:08 +053013975 if (!wlan_loader) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013976 hdd_err("wlan_loader is null");
Arun Khandavallifae92942016-08-01 13:31:08 +053013977 return -EINVAL;
13978 }
13979
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013980 hdd_sysfs_cleanup();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013981 return 0;
13982}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013983
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013984#endif /* MODULE */
Arun Khandavallifae92942016-08-01 13:31:08 +053013985
13986#ifdef MODULE
13987/**
Dustin Brownf0f70562018-09-14 10:29:38 -070013988 * hdd_module_init() - Module init helper
Arun Khandavallifae92942016-08-01 13:31:08 +053013989 *
13990 * Module init helper function used by both module and static driver.
13991 *
13992 * Return: 0 for success, errno on failure
13993 */
13994static int hdd_module_init(void)
13995{
Dustin Brownf0f70562018-09-14 10:29:38 -070013996 if (hdd_driver_load())
Dustin Brownab482ac2017-06-09 17:00:44 -070013997 return -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053013998
Dustin Brownab482ac2017-06-09 17:00:44 -070013999 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053014000}
14001#else
14002static int __init hdd_module_init(void)
14003{
14004 int ret = -EINVAL;
14005
14006 ret = wlan_init_sysfs();
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070014007 if (ret)
Dustin Browna2a39dc2018-09-17 15:29:59 -070014008 hdd_err("Failed to create sysfs entry");
Arun Khandavallifae92942016-08-01 13:31:08 +053014009
14010 return ret;
14011}
14012#endif
14013
14014
14015#ifdef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014016/**
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014017 * hdd_module_exit() - Exit function
14018 *
14019 * This is the driver exit point (invoked when module is unloaded using rmmod)
14020 *
14021 * Return: None
14022 */
14023static void __exit hdd_module_exit(void)
14024{
Dustin Brownf0f70562018-09-14 10:29:38 -070014025 hdd_driver_unload();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014026}
Arun Khandavallifae92942016-08-01 13:31:08 +053014027#else
14028static void __exit hdd_module_exit(void)
14029{
Dustin Brownf0f70562018-09-14 10:29:38 -070014030 hdd_driver_unload();
Arun Khandavallifae92942016-08-01 13:31:08 +053014031 wlan_deinit_sysfs();
14032}
14033#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014034
Srinivas Girigowda841da292018-02-21 16:33:00 -080014035static int fwpath_changed_handler(const char *kmessage,
14036 const struct kernel_param *kp)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014037{
14038 return param_set_copystring(kmessage, kp);
14039}
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080014040
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053014041static int con_mode_handler_ftm(const char *kmessage,
Srinivas Girigowda841da292018-02-21 16:33:00 -080014042 const struct kernel_param *kp)
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053014043{
14044 int ret;
14045
14046 ret = param_set_int(kmessage, kp);
14047
14048 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
14049 pr_err("Only FTM mode supported!");
14050 return -ENOTSUPP;
14051 }
14052
14053 hdd_set_conparam(con_mode_ftm);
14054 con_mode = con_mode_ftm;
14055
14056 return ret;
14057}
14058
Nirav Shah6aeecf92019-02-13 14:05:03 +053014059#ifdef WLAN_FEATURE_EPPING
14060static int con_mode_handler_epping(const char *kmessage,
14061 const struct kernel_param *kp)
14062{
14063 int ret;
14064
14065 ret = param_set_int(kmessage, kp);
14066
14067 if (con_mode_epping != QDF_GLOBAL_EPPING_MODE) {
14068 pr_err("Only EPPING mode supported!");
14069 return -ENOTSUPP;
14070 }
14071
14072 hdd_set_conparam(con_mode_epping);
14073 con_mode = con_mode_epping;
14074
14075 return ret;
14076}
14077#endif
14078
Nirav Shah73713f72018-05-17 14:50:41 +053014079#ifdef FEATURE_MONITOR_MODE_SUPPORT
Ravi Joshia307f632017-07-17 23:41:41 -070014080static int con_mode_handler_monitor(const char *kmessage,
Srinivas Girigowda841da292018-02-21 16:33:00 -080014081 const struct kernel_param *kp)
Ravi Joshia307f632017-07-17 23:41:41 -070014082{
14083 int ret;
14084
14085 ret = param_set_int(kmessage, kp);
14086
14087 if (con_mode_monitor != QDF_GLOBAL_MONITOR_MODE) {
14088 pr_err("Only Monitor mode supported!");
14089 return -ENOTSUPP;
14090 }
14091
14092 hdd_set_conparam(con_mode_monitor);
14093 con_mode = con_mode_monitor;
14094
14095 return ret;
14096}
Nirav Shah73713f72018-05-17 14:50:41 +053014097#endif
Ravi Joshia307f632017-07-17 23:41:41 -070014098
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014099/**
14100 * hdd_get_conparam() - driver exit point
14101 *
14102 * This is the driver exit point (invoked when module is unloaded using rmmod)
14103 *
Jeff Johnson876c1a62017-12-12 10:43:07 -080014104 * Return: enum QDF_GLOBAL_MODE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014105 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080014106enum QDF_GLOBAL_MODE hdd_get_conparam(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014107{
Jeff Johnson876c1a62017-12-12 10:43:07 -080014108 return (enum QDF_GLOBAL_MODE) curr_con_mode;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014109}
14110
Dustin Brownf0f70562018-09-14 10:29:38 -070014111void hdd_set_conparam(int32_t con_param)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014112{
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080014113 curr_con_mode = con_param;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080014114}
14115
Komal Seelamc11bb222016-01-27 18:57:10 +053014116/**
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014117 * hdd_clean_up_pre_cac_interface() - Clean up the pre cac interface
14118 * @hdd_ctx: HDD context
14119 *
14120 * Cleans up the pre cac interface, if it exists
14121 *
14122 * Return: None
14123 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014124void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx)
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014125{
Jeff Johnson55d2ab42019-03-06 11:43:49 -080014126 uint8_t vdev_id;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014127 QDF_STATUS status;
Jeff Johnson85b5c112017-08-11 15:15:23 -070014128 struct hdd_adapter *precac_adapter;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014129
Jeff Johnson55d2ab42019-03-06 11:43:49 -080014130 status = wlan_sap_get_pre_cac_vdev_id(hdd_ctx->mac_handle, &vdev_id);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014131 if (QDF_IS_STATUS_ERROR(status)) {
14132 hdd_err("failed to get pre cac vdev id");
14133 return;
14134 }
14135
Jeff Johnson55d2ab42019-03-06 11:43:49 -080014136 precac_adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014137 if (!precac_adapter) {
Jeff Johnsondd2f1fc2018-05-06 11:22:52 -070014138 hdd_err("invalid pre cac adapter");
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014139 return;
14140 }
14141
14142 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
14143 wlan_hdd_sap_pre_cac_failure,
14144 (void *)precac_adapter);
14145 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
14146
14147}
14148
14149/**
Komal Seelamec702b02016-02-24 18:42:16 +053014150 * hdd_update_ol_config - API to update ol configuration parameters
14151 * @hdd_ctx: HDD context
Komal Seelamc11bb222016-01-27 18:57:10 +053014152 *
Komal Seelamc11bb222016-01-27 18:57:10 +053014153 * Return: void
14154 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014155static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
Komal Seelamc11bb222016-01-27 18:57:10 +053014156{
Abhishek Singh98278ce2018-12-27 11:41:03 +053014157 struct ol_config_info cfg = {0};
Anurag Chouhandf2b2682016-02-29 14:15:27 +053014158 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014159 bool self_recovery = false;
14160 QDF_STATUS status;
Komal Seelamc11bb222016-01-27 18:57:10 +053014161
Komal Seelamec702b02016-02-24 18:42:16 +053014162 if (!ol_ctx)
14163 return;
14164
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014165 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
14166 if (QDF_IS_STATUS_ERROR(status))
14167 hdd_err("Failed to get self recovery ini config");
14168
14169 cfg.enable_self_recovery = self_recovery;
Komal Seelamec702b02016-02-24 18:42:16 +053014170 cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
14171 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
14172 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
Jeff Johnsonb8bf9072016-09-23 17:39:27 -070014173 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
Komal Seelamec702b02016-02-24 18:42:16 +053014174
14175 ol_init_ini_config(ol_ctx, &cfg);
14176}
14177
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014178#ifdef FEATURE_RUNTIME_PM
14179/**
14180 * hdd_populate_runtime_cfg() - populate runtime configuration
14181 * @hdd_ctx: hdd context
14182 * @cfg: pointer to the configuration memory being populated
14183 *
14184 * Return: void
14185 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014186static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014187 struct hif_config_info *cfg)
14188{
14189 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
Wu Gao66454f12018-09-26 19:55:41 +080014190 cfg->runtime_pm_delay =
14191 ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc);
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014192}
14193#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014194static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014195 struct hif_config_info *cfg)
14196{
14197}
14198#endif
14199
Komal Seelamec702b02016-02-24 18:42:16 +053014200/**
14201 * hdd_update_hif_config - API to update HIF configuration parameters
14202 * @hdd_ctx: HDD Context
14203 *
14204 * Return: void
14205 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014206static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053014207{
Anurag Chouhandf2b2682016-02-29 14:15:27 +053014208 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
Abhishek Singh98278ce2018-12-27 11:41:03 +053014209 struct hif_config_info cfg = {0};
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014210 bool prevent_link_down = false;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014211 bool self_recovery = false;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014212 QDF_STATUS status;
Komal Seelamec702b02016-02-24 18:42:16 +053014213
14214 if (!scn)
14215 return;
14216
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014217 status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc,
14218 &prevent_link_down);
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014219 if (QDF_IS_STATUS_ERROR(status))
14220 hdd_err("Failed to get prevent_link_down config");
14221
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014222 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
14223 if (QDF_IS_STATUS_ERROR(status))
14224 hdd_err("Failed to get self recovery ini config");
14225
14226 cfg.enable_self_recovery = self_recovery;
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014227 hdd_populate_runtime_cfg(hdd_ctx, &cfg);
Komal Seelamec702b02016-02-24 18:42:16 +053014228 hif_init_ini_config(scn, &cfg);
Dustin Brownee3e0592017-09-07 13:50:11 -070014229
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014230 if (prevent_link_down)
Dustin Brownee3e0592017-09-07 13:50:11 -070014231 hif_vote_link_up(scn);
Komal Seelamec702b02016-02-24 18:42:16 +053014232}
14233
14234/**
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014235 * hdd_update_dp_config() - Propagate config parameters to Lithium
14236 * datapath
14237 * @hdd_ctx: HDD Context
14238 *
14239 * Return: 0 for success/errno for failure
14240 */
14241static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
14242{
Abhishek Singh98278ce2018-12-27 11:41:03 +053014243 struct cdp_config_params params = {0};
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014244 QDF_STATUS status;
jitiphil377bcc12018-10-05 19:46:08 +053014245 void *soc;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014246
jitiphil377bcc12018-10-05 19:46:08 +053014247 soc = cds_get_context(QDF_MODULE_ID_SOC);
14248 params.tso_enable = cfg_get(hdd_ctx->psoc, CFG_DP_TSO);
14249 params.lro_enable = cfg_get(hdd_ctx->psoc, CFG_DP_LRO);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014250#ifdef QCA_LL_TX_FLOW_CONTROL_V2
14251 params.tx_flow_stop_queue_threshold =
jitiphil47c3d9a2018-11-08 18:30:55 +053014252 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014253 params.tx_flow_start_queue_offset =
jitiphil47c3d9a2018-11-08 18:30:55 +053014254 cfg_get(hdd_ctx->psoc,
14255 CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014256#endif
jitiphil377bcc12018-10-05 19:46:08 +053014257 params.flow_steering_enable =
14258 cfg_get(hdd_ctx->psoc, CFG_DP_FLOW_STEERING_ENABLED);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014259 params.napi_enable = hdd_ctx->napi_enable;
14260 params.tcp_udp_checksumoffload =
jitiphil377bcc12018-10-05 19:46:08 +053014261 cfg_get(hdd_ctx->psoc,
14262 CFG_DP_TCP_UDP_CKSUM_OFFLOAD);
Sravan Kumar Kairam0af1ee52018-12-12 20:37:51 +053014263 params.ipa_enable = ucfg_ipa_is_enabled();
Mohit Khanna81418772018-10-30 14:14:46 -070014264 params.gro_enable = cfg_get(hdd_ctx->psoc, CFG_DP_GRO);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014265
jitiphil377bcc12018-10-05 19:46:08 +053014266 status = cdp_update_config_parameters(soc, &params);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014267 if (status) {
Dustin Browna2868622018-03-20 11:38:14 -070014268 hdd_err("Failed to attach config parameters");
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014269 return status;
14270 }
14271
14272 return 0;
14273}
14274
14275/**
Komal Seelamec702b02016-02-24 18:42:16 +053014276 * hdd_update_config() - Initialize driver per module ini parameters
14277 * @hdd_ctx: HDD Context
14278 *
14279 * API is used to initialize all driver per module configuration parameters
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014280 * Return: 0 for success, errno for failure
Komal Seelamec702b02016-02-24 18:42:16 +053014281 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014282int hdd_update_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053014283{
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014284 int ret;
14285
Wu Gao66454f12018-09-26 19:55:41 +080014286 if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc))
14287 hdd_ctx->ns_offload_enable = true;
14288
Komal Seelamec702b02016-02-24 18:42:16 +053014289 hdd_update_ol_config(hdd_ctx);
14290 hdd_update_hif_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014291 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
14292 ret = hdd_update_cds_config_ftm(hdd_ctx);
14293 else
14294 ret = hdd_update_cds_config(hdd_ctx);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080014295 ret = hdd_update_user_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014296
14297 return ret;
Komal Seelamc11bb222016-01-27 18:57:10 +053014298}
14299
Mukul Sharma9d797a02017-01-05 20:26:03 +053014300/**
14301 * hdd_update_pmo_config - API to update pmo configuration parameters
14302 * @hdd_ctx: HDD context
14303 *
14304 * Return: void
14305 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014306static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053014307{
Abhishek Singh98278ce2018-12-27 11:41:03 +053014308 struct pmo_psoc_cfg psoc_cfg = {0};
Mukul Sharma9d797a02017-01-05 20:26:03 +053014309 QDF_STATUS status;
Wu Gao66454f12018-09-26 19:55:41 +080014310 enum pmo_wow_enable_type wow_enable;
14311
14312 ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg);
Mukul Sharma9d797a02017-01-05 20:26:03 +053014313
14314 /*
14315 * Value of hdd_ctx->wowEnable can be,
14316 * 0 - Disable both magic pattern match and pattern byte match.
14317 * 1 - Enable magic pattern match on all interfaces.
14318 * 2 - Enable pattern byte match on all interfaces.
14319 * 3 - Enable both magic patter and pattern byte match on
14320 * all interfaces.
14321 */
Wu Gao66454f12018-09-26 19:55:41 +080014322 wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc);
14323 psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false;
Mukul Sharma9d797a02017-01-05 20:26:03 +053014324 psoc_cfg.ptrn_match_enable_all_vdev =
Wu Gao66454f12018-09-26 19:55:41 +080014325 (wow_enable & 0x02) ? true : false;
Mukul Sharma9d797a02017-01-05 20:26:03 +053014326 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
Will Huang3cd2b7c2017-11-17 13:16:56 +080014327 psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
Bala Venkatesh46e29032018-11-14 18:24:55 +053014328 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
14329 &psoc_cfg.sta_max_li_mod_dtim);
14330
Mukul Sharma9d797a02017-01-05 20:26:03 +053014331
Mukul Sharma9223f232017-03-08 18:42:27 +053014332 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053014333
Dustin Brown1dbefe62018-09-11 16:32:03 -070014334 status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg);
Dustin Brownb9987af2018-03-01 17:15:11 -080014335 if (QDF_IS_STATUS_ERROR(status))
14336 hdd_err("failed pmo psoc configuration; status:%d", status);
14337
14338 return qdf_status_to_os_return(status);
Mukul Sharma9d797a02017-01-05 20:26:03 +053014339}
14340
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014341void hdd_update_ie_whitelist_attr(struct probe_req_whitelist_attr *ie_whitelist,
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014342 struct hdd_context *hdd_ctx)
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014343{
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014344 struct wlan_fwol_ie_whitelist whitelist = {0};
14345 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014346 QDF_STATUS status;
14347 bool is_ie_whitelist_enable = false;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014348 uint8_t i = 0;
14349
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014350 status = ucfg_fwol_get_ie_whitelist(psoc, &is_ie_whitelist_enable);
14351 if (QDF_IS_STATUS_ERROR(status)) {
14352 hdd_err("Unable to get IE whitelist param");
14353 return;
14354 }
14355
14356 ie_whitelist->white_list = is_ie_whitelist_enable;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014357 if (!ie_whitelist->white_list)
14358 return;
14359
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014360 status = ucfg_fwol_get_all_whitelist_params(psoc, &whitelist);
14361 if (QDF_IS_STATUS_ERROR(status)) {
14362 hdd_err("Unable to get all whitelist params");
14363 return;
14364 }
14365
14366 ie_whitelist->ie_bitmap[0] = whitelist.ie_bitmap_0;
14367 ie_whitelist->ie_bitmap[1] = whitelist.ie_bitmap_1;
14368 ie_whitelist->ie_bitmap[2] = whitelist.ie_bitmap_2;
14369 ie_whitelist->ie_bitmap[3] = whitelist.ie_bitmap_3;
14370 ie_whitelist->ie_bitmap[4] = whitelist.ie_bitmap_4;
14371 ie_whitelist->ie_bitmap[5] = whitelist.ie_bitmap_5;
14372 ie_whitelist->ie_bitmap[6] = whitelist.ie_bitmap_6;
14373 ie_whitelist->ie_bitmap[7] = whitelist.ie_bitmap_7;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014374
Dundi Raviteja9ab4e7b2018-09-28 14:18:28 +053014375 ie_whitelist->num_vendor_oui = whitelist.no_of_probe_req_ouis;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014376 for (i = 0; i < ie_whitelist->num_vendor_oui; i++)
Dundi Raviteja9ab4e7b2018-09-28 14:18:28 +053014377 ie_whitelist->voui[i] = whitelist.probe_req_voui[i];
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014378}
14379
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014380uint32_t hdd_limit_max_per_index_score(uint32_t per_index_score)
14381{
14382 uint8_t i, score;
14383
14384 for (i = 0; i < MAX_INDEX_PER_INI; i++) {
14385 score = WLAN_GET_SCORE_PERCENTAGE(per_index_score, i);
14386 if (score > MAX_INDEX_SCORE)
14387 WLAN_SET_SCORE_PERCENTAGE(per_index_score,
14388 MAX_INDEX_SCORE, i);
14389 }
14390
14391 return per_index_score;
14392}
14393
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014394QDF_STATUS hdd_update_score_config(
14395 struct scoring_config *score_config, struct hdd_context *hdd_ctx)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014396{
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014397 struct hdd_config *cfg = hdd_ctx->config;
gaurank kathpaliaae52c982018-10-04 01:35:18 +053014398 QDF_STATUS status;
gaurank kathpalia651abcd2018-11-12 22:41:23 +053014399 struct wlan_mlme_nss_chains vdev_ini_cfg;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014400 bool bval = false;
Wu Gaoed616a12019-01-16 15:19:21 +080014401 uint32_t channel_bonding_mode;
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014402
Abhishek Singh98278ce2018-12-27 11:41:03 +053014403 qdf_mem_zero(&vdev_ini_cfg, sizeof(struct wlan_mlme_nss_chains));
gaurank kathpalia651abcd2018-11-12 22:41:23 +053014404 /* Populate the nss chain params from ini for this vdev type */
14405 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
14406 QDF_STA_MODE,
14407 hdd_ctx->num_rf_chains);
14408
14409 score_config->vdev_nss_24g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ];
14410 score_config->vdev_nss_24g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ];
14411
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053014412 sme_update_score_config(hdd_ctx->mac_handle, score_config);
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014413
Wu Gaoed616a12019-01-16 15:19:21 +080014414 ucfg_mlme_get_channel_bonding_24ghz(hdd_ctx->psoc,
14415 &channel_bonding_mode);
14416 score_config->cb_mode_24G = channel_bonding_mode;
14417 ucfg_mlme_get_channel_bonding_5ghz(hdd_ctx->psoc,
14418 &channel_bonding_mode);
14419 score_config->cb_mode_5G = channel_bonding_mode;
gaurank kathpaliaae52c982018-10-04 01:35:18 +053014420
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014421 if (cfg->dot11Mode == eHDD_DOT11_MODE_AUTO ||
14422 cfg->dot11Mode == eHDD_DOT11_MODE_11ax ||
14423 cfg->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)
14424 score_config->he_cap = 1;
14425
14426 if (score_config->he_cap ||
14427 cfg->dot11Mode == eHDD_DOT11_MODE_11ac ||
14428 cfg->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)
14429 score_config->vht_cap = 1;
14430
14431 if (score_config->vht_cap || cfg->dot11Mode == eHDD_DOT11_MODE_11n ||
14432 cfg->dot11Mode == eHDD_DOT11_MODE_11n_ONLY)
14433 score_config->ht_cap = 1;
14434
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014435 status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &bval);
14436 if (!QDF_IS_STATUS_SUCCESS(status))
14437 hdd_err("Failed to get vht_for_24ghz");
14438 if (score_config->vht_cap && bval)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014439 score_config->vht_24G_cap = 1;
14440
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014441 status = ucfg_mlme_get_vht_enable_tx_bf(hdd_ctx->psoc,
14442 &bval);
14443 if (!QDF_IS_STATUS_SUCCESS(status))
14444 hdd_err("unable to get vht_enable_tx_bf");
14445
14446 if (bval)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014447 score_config->beamformee_cap = 1;
14448
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053014449 return QDF_STATUS_SUCCESS;
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014450}
14451
Abhishek Singh257a9482017-03-06 16:52:39 +053014452/**
bings81fe50a2017-11-27 14:33:26 +080014453 * hdd_update_dfs_config() - API to update dfs configuration parameters.
14454 * @hdd_ctx: HDD context
14455 *
14456 * Return: 0 if success else err
14457 */
14458static int hdd_update_dfs_config(struct hdd_context *hdd_ctx)
14459{
Dustin Brown1dbefe62018-09-11 16:32:03 -070014460 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Abhishek Singh98278ce2018-12-27 11:41:03 +053014461 struct dfs_user_config dfs_cfg = {0};
bings81fe50a2017-11-27 14:33:26 +080014462 QDF_STATUS status;
14463
Arif Hussain224d3812018-11-16 17:58:38 -080014464 ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc,
14465 &dfs_cfg.dfs_is_phyerr_filter_offload);
bings81fe50a2017-11-27 14:33:26 +080014466 status = ucfg_dfs_update_config(psoc, &dfs_cfg);
14467 if (QDF_IS_STATUS_ERROR(status)) {
14468 hdd_err("failed dfs psoc configuration");
14469 return -EINVAL;
14470 }
14471
14472 return 0;
14473}
14474
14475/**
Abhishek Singh257a9482017-03-06 16:52:39 +053014476 * hdd_update_scan_config - API to update scan configuration parameters
14477 * @hdd_ctx: HDD context
14478 *
14479 * Return: 0 if success else err
14480 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014481static int hdd_update_scan_config(struct hdd_context *hdd_ctx)
Abhishek Singh257a9482017-03-06 16:52:39 +053014482{
Dustin Brown1dbefe62018-09-11 16:32:03 -070014483 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Sandeep Puligillad7887022019-02-26 00:48:52 -080014484 struct scan_user_cfg scan_cfg;
Abhishek Singh257a9482017-03-06 16:52:39 +053014485 QDF_STATUS status;
Krunal Sonid2c33e12018-12-06 15:02:37 -080014486 uint32_t mcast_mcc_rest_time = 0;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014487
Sandeep Puligillad7887022019-02-26 00:48:52 -080014488 qdf_mem_zero(&scan_cfg, sizeof(scan_cfg));
Krunal Sonid2c33e12018-12-06 15:02:37 -080014489 status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc,
14490 &mcast_mcc_rest_time);
14491 if (!QDF_IS_STATUS_SUCCESS(status)) {
14492 hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def");
14493 return -EIO;
14494 }
14495 scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time;
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014496 hdd_update_ie_whitelist_attr(&scan_cfg.ie_whitelist, hdd_ctx);
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053014497
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014498 status = hdd_update_score_config(&scan_cfg.score_config, hdd_ctx);
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053014499 if (QDF_IS_STATUS_ERROR(status)) {
14500 hdd_err("Failed to update scoring config");
14501 return -EINVAL;
14502 }
Abhishek Singhb20db962017-03-03 21:28:46 +053014503
Abhishek Singh257a9482017-03-06 16:52:39 +053014504 status = ucfg_scan_update_user_config(psoc, &scan_cfg);
14505 if (status != QDF_STATUS_SUCCESS) {
14506 hdd_err("failed pmo psoc configuration");
14507 return -EINVAL;
14508 }
14509
14510 return 0;
14511}
Abhishek Singh257a9482017-03-06 16:52:39 +053014512
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014513int hdd_update_components_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053014514{
14515 int ret;
14516
14517 ret = hdd_update_pmo_config(hdd_ctx);
Abhishek Singh257a9482017-03-06 16:52:39 +053014518 if (ret)
14519 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014520
Abhishek Singh257a9482017-03-06 16:52:39 +053014521 ret = hdd_update_scan_config(hdd_ctx);
Frank Liud4b2fa02017-03-29 11:46:48 +080014522 if (ret)
14523 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014524
Frank Liud4b2fa02017-03-29 11:46:48 +080014525 ret = hdd_update_tdls_config(hdd_ctx);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014526 if (ret)
14527 return ret;
14528
14529 ret = hdd_update_dp_config(hdd_ctx);
bings81fe50a2017-11-27 14:33:26 +080014530 if (ret)
14531 return ret;
14532
14533 ret = hdd_update_dfs_config(hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053014534
14535 return ret;
14536}
14537
Agrawal Ashish65634612016-08-18 13:24:32 +053014538/**
14539 * wlan_hdd_get_dfs_mode() - get ACS DFS mode
14540 * @mode : cfg80211 DFS mode
14541 *
14542 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
14543 */
14544enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
14545{
14546 switch (mode) {
14547 case DFS_MODE_ENABLE:
14548 return ACS_DFS_MODE_ENABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053014549 case DFS_MODE_DISABLE:
14550 return ACS_DFS_MODE_DISABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053014551 case DFS_MODE_DEPRIORITIZE:
14552 return ACS_DFS_MODE_DEPRIORITIZE;
Agrawal Ashish65634612016-08-18 13:24:32 +053014553 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080014554 hdd_debug("ACS dfs mode is NONE");
14555 return ACS_DFS_MODE_NONE;
Agrawal Ashish65634612016-08-18 13:24:32 +053014556 }
14557}
14558
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014559/**
14560 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
14561 * @hddctx: pointer to hdd context
14562 * @set_value: enable/disable
14563 *
14564 * When Host sends vendor command enable, FW will send *ONE* CA ind to
14565 * Host(even though it is duplicate). When Host send vendor command
14566 * disable,FW doesn't perform any action. Whenever any change in
14567 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
14568 *
14569 * return - 0 on success, appropriate error values on failure.
14570 */
Jeff Johnson16528362018-06-14 12:34:16 -070014571int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value)
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014572{
14573 QDF_STATUS status;
14574
Jeff Johnson16528362018-06-14 12:34:16 -070014575 if (0 != wlan_hdd_validate_context(hdd_ctx))
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014576 return -EAGAIN;
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014577
Jeff Johnson16528362018-06-14 12:34:16 -070014578 status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle,
14579 set_value);
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014580 if (!QDF_IS_STATUS_SUCCESS(status)) {
14581 hdd_err("Failed to send chan avoid command to SME");
14582 return -EINVAL;
14583 }
14584 return 0;
14585}
Agrawal Ashish65634612016-08-18 13:24:32 +053014586
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014587/**
14588 * hdd_set_roaming_in_progress() - to set the roaming in progress flag
14589 * @value: value to set
14590 *
14591 * This function will set the passed value to roaming in progress flag.
14592 *
14593 * Return: None
14594 */
14595void hdd_set_roaming_in_progress(bool value)
14596{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014597 struct hdd_context *hdd_ctx;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014598
14599 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14600 if (!hdd_ctx) {
14601 hdd_err("HDD context is NULL");
14602 return;
14603 }
14604
14605 hdd_ctx->roaming_in_progress = value;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080014606 hdd_debug("Roaming in Progress set to %d", value);
Abhinav Kumar2b431b62019-03-18 20:23:58 +053014607 if (!hdd_ctx->roaming_in_progress) {
14608 /* Reset scan reject params on successful roam complete */
14609 hdd_debug("Reset scan reject params");
14610 hdd_init_scan_reject_params(hdd_ctx);
14611 }
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014612}
14613
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053014614bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx)
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014615{
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014616 if (!hdd_ctx) {
14617 hdd_err("HDD context is NULL");
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053014618 return false;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014619 }
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080014620
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053014621 hdd_debug("roaming_in_progress = %d", hdd_ctx->roaming_in_progress);
14622
14623 return hdd_ctx->roaming_in_progress;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014624}
14625
Jeff Johnsona2ac4e72019-03-06 08:35:29 -080014626bool hdd_is_connection_in_progress(uint8_t *out_vdev_id,
14627 enum scan_reject_states *out_reason)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014628{
Jeff Johnson40dae4e2017-08-29 14:00:25 -070014629 struct hdd_station_ctx *hdd_sta_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -070014630 struct hdd_adapter *adapter = NULL;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014631 uint8_t sta_id = 0;
14632 uint8_t *sta_mac = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014633 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -070014634 mac_handle_t mac_handle;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014635
14636 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14637 if (!hdd_ctx) {
14638 hdd_err("HDD context is NULL");
14639 return false;
14640 }
14641
Jeff Johnson16528362018-06-14 12:34:16 -070014642 mac_handle = hdd_ctx->mac_handle;
14643
Dustin Brown920397d2017-12-13 16:27:50 -080014644 hdd_for_each_adapter(hdd_ctx, adapter) {
Tushnim Bhattacharyya929afa42018-06-01 15:04:44 -070014645 hdd_debug("Adapter with device mode %s(%d) exists",
Dustin Brown458027c2018-10-19 12:26:27 -070014646 qdf_opmode_str(adapter->device_mode),
14647 adapter->device_mode);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014648 if (((QDF_STA_MODE == adapter->device_mode)
14649 || (QDF_P2P_CLIENT_MODE == adapter->device_mode)
14650 || (QDF_P2P_DEVICE_MODE == adapter->device_mode))
14651 && (eConnectionState_Connecting ==
14652 (WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
Jeff Johnsone7951512019-02-27 10:02:51 -080014653 conn_info.conn_state)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014654 hdd_debug("%pK(%d) Connection is in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014655 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson5a6fc962019-02-04 14:20:25 -080014656 adapter->vdev_id);
Jeff Johnsona2ac4e72019-03-06 08:35:29 -080014657 if (out_vdev_id && out_reason) {
14658 *out_vdev_id = adapter->vdev_id;
14659 *out_reason = CONNECTION_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014660 }
14661 return true;
14662 }
Archana Ramachandran62886ce2017-03-24 14:46:32 -070014663 /*
14664 * sme_neighbor_middle_of_roaming is for LFR2
14665 * hdd_is_roaming_in_progress is for LFR3
14666 */
14667 if (((QDF_STA_MODE == adapter->device_mode) &&
14668 sme_neighbor_middle_of_roaming(
Jeff Johnson16528362018-06-14 12:34:16 -070014669 mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080014670 adapter->vdev_id)) ||
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053014671 hdd_is_roaming_in_progress(hdd_ctx)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014672 hdd_debug("%pK(%d) Reassociation in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014673 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson5a6fc962019-02-04 14:20:25 -080014674 adapter->vdev_id);
Jeff Johnsona2ac4e72019-03-06 08:35:29 -080014675 if (out_vdev_id && out_reason) {
14676 *out_vdev_id = adapter->vdev_id;
14677 *out_reason = REASSOC_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014678 }
14679 return true;
14680 }
14681 if ((QDF_STA_MODE == adapter->device_mode) ||
14682 (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
14683 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
14684 hdd_sta_ctx =
14685 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
14686 if ((eConnectionState_Associated ==
Jeff Johnsone7951512019-02-27 10:02:51 -080014687 hdd_sta_ctx->conn_info.conn_state)
Vignesh Viswanathan0a569292018-02-14 15:34:47 +053014688 && sme_is_sta_key_exchange_in_progress(
Jeff Johnson5a6fc962019-02-04 14:20:25 -080014689 mac_handle, adapter->vdev_id)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014690 sta_mac = (uint8_t *)
Jeff Johnson1e851a12017-10-28 14:36:12 -070014691 &(adapter->mac_addr.bytes[0]);
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014692 hdd_debug("client " MAC_ADDRESS_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014693 " is in middle of WPS/EAPOL exchange.",
14694 MAC_ADDR_ARRAY(sta_mac));
Jeff Johnsona2ac4e72019-03-06 08:35:29 -080014695 if (out_vdev_id && out_reason) {
14696 *out_vdev_id = adapter->vdev_id;
14697 *out_reason = EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014698 }
14699 return true;
14700 }
14701 } else if ((QDF_SAP_MODE == adapter->device_mode) ||
14702 (QDF_P2P_GO_MODE == adapter->device_mode)) {
14703 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
14704 sta_id++) {
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070014705 if (!((adapter->sta_info[sta_id].in_use)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014706 && (OL_TXRX_PEER_STATE_CONN ==
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070014707 adapter->sta_info[sta_id].peer_state)))
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014708 continue;
14709
14710 sta_mac = (uint8_t *)
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070014711 &(adapter->sta_info[sta_id].
Jeff Johnsonf2356512017-10-21 16:04:12 -070014712 sta_mac.bytes[0]);
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014713 hdd_debug("client " MAC_ADDRESS_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014714 " of SAP/GO is in middle of WPS/EAPOL exchange",
14715 MAC_ADDR_ARRAY(sta_mac));
Jeff Johnsona2ac4e72019-03-06 08:35:29 -080014716 if (out_vdev_id && out_reason) {
14717 *out_vdev_id = adapter->vdev_id;
14718 *out_reason = SAP_EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014719 }
14720 return true;
14721 }
14722 if (hdd_ctx->connection_in_progress) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014723 hdd_debug("AP/GO: connection is in progress");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014724 return true;
14725 }
14726 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014727 }
Dustin Brown920397d2017-12-13 16:27:50 -080014728
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014729 return false;
14730}
14731
14732/**
14733 * hdd_restart_sap() - to restart SAP in driver internally
Jeff Johnson9d295242017-08-29 14:39:48 -070014734 * @ap_adapter: Pointer to SAP struct hdd_adapter structure
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014735 *
14736 * Return: None
14737 */
Jeff Johnson9d295242017-08-29 14:39:48 -070014738void hdd_restart_sap(struct hdd_adapter *ap_adapter)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014739{
Jeff Johnson87251032017-08-29 13:31:11 -070014740 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070014741 struct hdd_hostapd_state *hostapd_state;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014742 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014743 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Jeff Johnson8f8ceb92019-03-24 08:16:55 -070014744 struct sap_config *sap_config;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014745 void *sap_ctx;
14746
14747 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
Jeff Johnson91df29d2017-10-27 19:29:50 -070014748 sap_config = &hdd_ap_ctx->sap_config;
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070014749 sap_ctx = hdd_ap_ctx->sap_context;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014750
14751 mutex_lock(&hdd_ctx->sap_lock);
14752 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
14753 wlan_hdd_del_station(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014754 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
14755 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
14756 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
14757 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053014758 qdf_wait_for_event_completion(&hostapd_state->
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014759 qdf_stop_bss_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053014760 SME_CMD_STOP_BSS_TIMEOUT);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014761
14762 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014763 hdd_err("SAP Stop Failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014764 goto end;
14765 }
14766 }
14767 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -070014768 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080014769 ap_adapter->device_mode, ap_adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070014770 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053014771 false);
Jeff Johnson6867ec32017-09-29 20:30:20 -070014772 hdd_err("SAP Stop Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014773
14774 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014775 hdd_err("SAP Not able to set AP IEs");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014776 wlansap_reset_sap_config_add_ie(sap_config,
14777 eUPDATE_IE_ALL);
14778 goto end;
14779 }
14780
14781 qdf_event_reset(&hostapd_state->qdf_event);
14782 if (wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
14783 sap_config,
14784 ap_adapter->dev) != QDF_STATUS_SUCCESS) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014785 hdd_err("SAP Start Bss fail");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014786 wlansap_reset_sap_config_add_ie(sap_config,
14787 eUPDATE_IE_ALL);
14788 goto end;
14789 }
14790
Jeff Johnson6867ec32017-09-29 20:30:20 -070014791 hdd_info("Waiting for SAP to start");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014792 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053014793 qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Abhishek Singhd1f21c72019-01-21 15:16:34 +053014794 SME_CMD_START_BSS_TIMEOUT);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014795 wlansap_reset_sap_config_add_ie(sap_config,
14796 eUPDATE_IE_ALL);
14797 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014798 hdd_err("SAP Start failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014799 goto end;
14800 }
Jeff Johnson6867ec32017-09-29 20:30:20 -070014801 hdd_err("SAP Start Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014802 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053014803 if (hostapd_state->bss_state == BSS_START) {
Dustin Brown1dbefe62018-09-11 16:32:03 -070014804 policy_mgr_incr_active_session(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014805 ap_adapter->device_mode,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080014806 ap_adapter->vdev_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070014807 hdd_green_ap_start_state_mc(hdd_ctx,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053014808 ap_adapter->device_mode,
14809 true);
14810 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014811 }
14812end:
14813 mutex_unlock(&hdd_ctx->sap_lock);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014814}
14815
14816/**
14817 * hdd_check_and_restart_sap_with_non_dfs_acs() - Restart SAP
14818 * with non dfs acs
14819 *
14820 * Restarts SAP in non-DFS ACS mode when STA-AP mode DFS is not supported
14821 *
14822 * Return: None
14823 */
14824void hdd_check_and_restart_sap_with_non_dfs_acs(void)
14825{
Jeff Johnson9d295242017-08-29 14:39:48 -070014826 struct hdd_adapter *ap_adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014827 struct hdd_context *hdd_ctx;
Jeff Johnson2b6982c2018-05-29 14:56:11 -070014828 struct cds_context *cds_ctx;
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053014829 uint8_t restart_chan;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014830
14831 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14832 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014833 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014834 return;
14835 }
14836
14837 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
14838 if (!cds_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014839 hdd_err("Invalid CDS Context");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014840 return;
14841 }
14842
Dustin Brown1dbefe62018-09-11 16:32:03 -070014843 if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc)
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014844 != (QDF_STA_MASK | QDF_SAP_MASK)) {
Dustin Brown7e761c72018-07-31 13:50:17 -070014845 hdd_debug("Concurrency mode is not SAP");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014846 return;
14847 }
14848
14849 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
Dustin Brown07901ec2018-09-07 11:02:41 -070014850 if (ap_adapter &&
14851 test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags) &&
14852 wlan_reg_is_dfs_ch(hdd_ctx->pdev,
14853 ap_adapter->session.ap.operating_channel)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014854
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053014855 hdd_warn("STA-AP Mode DFS not supported, Switch SAP channel to Non DFS");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014856
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053014857 restart_chan =
14858 hdd_get_safe_channel_from_pcl_and_acs_range(ap_adapter);
14859 if (!restart_chan ||
Dustin Brown07901ec2018-09-07 11:02:41 -070014860 wlan_reg_is_dfs_ch(hdd_ctx->pdev, restart_chan))
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053014861 restart_chan = SAP_DEFAULT_5GHZ_CHANNEL;
14862
14863 hdd_switch_sap_channel(ap_adapter, restart_chan, true);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014864 }
14865}
14866
14867/**
14868 * hdd_set_connection_in_progress() - to set the connection in
14869 * progress flag
14870 * @value: value to set
14871 *
14872 * This function will set the passed value to connection in progress flag.
14873 * If value is previously being set to true then no need to set it again.
14874 *
14875 * Return: true if value is being set correctly and false otherwise.
14876 */
14877bool hdd_set_connection_in_progress(bool value)
14878{
14879 bool status = true;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014880 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014881
14882 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14883 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014884 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014885 return false;
14886 }
14887
14888 qdf_spin_lock(&hdd_ctx->connection_status_lock);
14889 /*
14890 * if the value is set to true previously and if someone is
14891 * trying to make it true again then it could be some race
14892 * condition being triggered. Avoid this situation by returning
14893 * false
14894 */
14895 if (hdd_ctx->connection_in_progress && value)
14896 status = false;
14897 else
14898 hdd_ctx->connection_in_progress = value;
14899 qdf_spin_unlock(&hdd_ctx->connection_status_lock);
14900 return status;
14901}
14902
Jeff Johnson9d295242017-08-29 14:39:48 -070014903int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070014904{
14905 if (!adapter) {
14906 hdd_err("Invalid adapter");
14907 return -EINVAL;
14908 }
14909 hdd_info("Send MCC P2P QUOTA to WMA: %d", set_value);
Jeff Johnson5a6fc962019-02-04 14:20:25 -080014910 sme_cli_set_command(adapter->vdev_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070014911 WMA_VDEV_MCC_SET_TIME_QUOTA,
14912 set_value, VDEV_CMD);
14913 return 0;
14914
14915}
14916
Jeff Johnson9d295242017-08-29 14:39:48 -070014917int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070014918{
14919 if (!adapter) {
14920 hdd_err("Invalid adapter");
14921 return -EINVAL;
14922 }
14923
14924 hdd_info("Send MCC latency WMA: %d", set_value);
Jeff Johnson5a6fc962019-02-04 14:20:25 -080014925 sme_cli_set_command(adapter->vdev_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070014926 WMA_VDEV_MCC_SET_TIME_LATENCY,
14927 set_value, VDEV_CMD);
14928 return 0;
14929}
14930
Jeff Johnson9d295242017-08-29 14:39:48 -070014931struct hdd_adapter *wlan_hdd_get_adapter_from_vdev(struct wlan_objmgr_psoc
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070014932 *psoc, uint8_t vdev_id)
14933{
Jeff Johnson9d295242017-08-29 14:39:48 -070014934 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014935 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070014936
14937 /*
14938 * Currently PSOC is not being used. But this logic will
14939 * change once we have the converged implementation of
14940 * HDD context per PSOC in place. This would break if
14941 * multiple vdev objects reuse the vdev id.
14942 */
14943 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
14944 if (!adapter)
14945 hdd_err("Get adapter by vdev id failed");
14946
14947 return adapter;
14948}
14949
Jeff Johnson9d295242017-08-29 14:39:48 -070014950int hdd_get_rssi_snr_by_bssid(struct hdd_adapter *adapter, const uint8_t *bssid,
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053014951 int8_t *rssi, int8_t *snr)
14952{
14953 QDF_STATUS status;
Jeff Johnson16528362018-06-14 12:34:16 -070014954 mac_handle_t mac_handle;
Jeff Johnson025618c2018-03-18 14:41:00 -070014955 struct csr_roam_profile *roam_profile;
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053014956
Jeff Johnson025618c2018-03-18 14:41:00 -070014957 roam_profile = hdd_roam_profile(adapter);
Jeff Johnson16528362018-06-14 12:34:16 -070014958 mac_handle = hdd_adapter_get_mac_handle(adapter);
14959 status = sme_get_rssi_snr_by_bssid(mac_handle,
Jeff Johnson025618c2018-03-18 14:41:00 -070014960 roam_profile, bssid, rssi, snr);
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053014961 if (QDF_STATUS_SUCCESS != status) {
14962 hdd_warn("sme_get_rssi_snr_by_bssid failed");
14963 return -EINVAL;
14964 }
14965
14966 return 0;
14967}
14968
Ganesh Kondabattini35739572017-06-21 16:26:39 +053014969/**
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014970 * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
14971 * @adapter - HDD adapter
14972 *
14973 * Return: 0 on success and non zero value on failure
14974 */
14975int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
14976{
14977 struct hdd_context *hdd_ctx;
14978 int ret;
14979 QDF_STATUS status;
Krunal Sonie71838d2018-09-27 10:45:05 -070014980 uint8_t sys_pref = 0;
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014981
14982 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14983 ret = wlan_hdd_validate_context(hdd_ctx);
14984 if (ret < 0)
14985 return ret;
14986
Krunal Sonie71838d2018-09-27 10:45:05 -070014987 ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc,
14988 &sys_pref);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014989 /* set the system preferece to default */
Krunal Sonie71838d2018-09-27 10:45:05 -070014990 policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014991
14992 /* clear the bitmap */
14993 adapter->active_ac = 0;
14994
14995 hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
Jeff Johnson5a6fc962019-02-04 14:20:25 -080014996 adapter->vdev_id, adapter->active_ac);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014997
Jeff Johnson16528362018-06-14 12:34:16 -070014998 status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
Jeff Johnson5a6fc962019-02-04 14:20:25 -080014999 adapter->vdev_id,
Jeff Johnson16528362018-06-14 12:34:16 -070015000 false, 0, 0, false);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053015001 if (!QDF_IS_STATUS_SUCCESS(status)) {
15002 hdd_err("failed to reset limit off chan params");
15003 ret = -EINVAL;
15004 }
Ganesh Kondabattini35739572017-06-21 16:26:39 +053015005
15006 return ret;
15007}
15008
Yun Parkff6a16a2017-09-26 16:38:18 -070015009void hdd_set_rx_mode_rps(bool enable)
15010{
15011 struct cds_config_info *cds_cfg = cds_get_ini_config();
Ryan Hsu0e878fa2018-05-04 15:22:09 -070015012 struct hdd_context *hdd_ctx;
15013 struct hdd_adapter *adapter;
Yun Parkff6a16a2017-09-26 16:38:18 -070015014
Ryan Hsu0e878fa2018-05-04 15:22:09 -070015015 if (!cds_cfg)
15016 return;
15017
15018 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15019 if (!hdd_ctx)
15020 return;
15021
15022 adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
15023 if (!adapter)
15024 return;
15025
15026 if (!hdd_ctx->rps && cds_cfg->uc_offload_enabled) {
Yun Parkff6a16a2017-09-26 16:38:18 -070015027 if (enable && !cds_cfg->rps_enabled)
15028 hdd_send_rps_ind(adapter);
15029 else if (!enable && cds_cfg->rps_enabled)
15030 hdd_send_rps_disable_ind(adapter);
15031 }
15032}
15033
Abhinav Kumar338e57d2019-02-04 17:30:10 +053015034void hdd_hidden_ssid_enable_roaming(hdd_handle_t hdd_handle, uint8_t vdev_id)
15035{
15036 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
15037 struct hdd_adapter *adapter;
15038
15039 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
15040
15041 if (!adapter) {
15042 hdd_err("Adapter is null");
15043 return;
15044 }
15045 /* enable roaming on all adapters once hdd get hidden ssid rsp */
15046 wlan_hdd_enable_roaming(adapter);
15047}
15048
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015049/* Register the module init/exit functions */
15050module_init(hdd_module_init);
15051module_exit(hdd_module_exit);
15052
15053MODULE_LICENSE("Dual BSD/GPL");
15054MODULE_AUTHOR("Qualcomm Atheros, Inc.");
15055MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
15056
Srinivas Girigowda841da292018-02-21 16:33:00 -080015057static const struct kernel_param_ops con_mode_ops = {
15058 .set = con_mode_handler,
15059 .get = param_get_int,
15060};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015061
Srinivas Girigowda841da292018-02-21 16:33:00 -080015062static const struct kernel_param_ops con_mode_ftm_ops = {
15063 .set = con_mode_handler_ftm,
15064 .get = param_get_int,
15065};
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053015066
Nirav Shah6aeecf92019-02-13 14:05:03 +053015067#ifdef WLAN_FEATURE_EPPING
15068static const struct kernel_param_ops con_mode_epping_ops = {
15069 .set = con_mode_handler_epping,
15070 .get = param_get_int,
15071};
15072#endif
15073
Nirav Shah73713f72018-05-17 14:50:41 +053015074#ifdef FEATURE_MONITOR_MODE_SUPPORT
Srinivas Girigowda841da292018-02-21 16:33:00 -080015075static const struct kernel_param_ops con_mode_monitor_ops = {
15076 .set = con_mode_handler_monitor,
15077 .get = param_get_int,
15078};
Nirav Shah73713f72018-05-17 14:50:41 +053015079#endif
Ravi Joshia307f632017-07-17 23:41:41 -070015080
Srinivas Girigowda841da292018-02-21 16:33:00 -080015081static const struct kernel_param_ops fwpath_ops = {
15082 .set = fwpath_changed_handler,
15083 .get = param_get_string,
15084};
15085
15086module_param_cb(con_mode, &con_mode_ops, &con_mode,
15087 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
15088
15089module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm,
15090 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
15091
Nirav Shah6aeecf92019-02-13 14:05:03 +053015092#ifdef WLAN_FEATURE_EPPING
15093module_param_cb(con_mode_epping, &con_mode_epping_ops,
15094 &con_mode_epping, 0644);
15095#endif
15096
Nirav Shah73713f72018-05-17 14:50:41 +053015097#ifdef FEATURE_MONITOR_MODE_SUPPORT
Srinivas Girigowda841da292018-02-21 16:33:00 -080015098module_param_cb(con_mode_monitor, &con_mode_monitor_ops, &con_mode_monitor,
15099 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Nirav Shah73713f72018-05-17 14:50:41 +053015100#endif
Srinivas Girigowda841da292018-02-21 16:33:00 -080015101
15102module_param_cb(fwpath, &fwpath_ops, &fwpath,
15103 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015104
15105module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
15106
15107module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
15108
15109module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);
Dustin Brown4bbd5462019-03-22 11:18:13 -070015110
15111static int timer_multiplier_get_handler(char *buffer,
15112 const struct kernel_param *kp)
15113{
15114 return scnprintf(buffer, PAGE_SIZE, "%u", qdf_timer_get_multiplier());
15115}
15116
15117static int timer_multiplier_set_handler(const char *kmessage,
15118 const struct kernel_param *kp)
15119{
15120 QDF_STATUS status;
15121 uint32_t scalar;
15122
15123 status = qdf_uint32_parse(kmessage, &scalar);
15124 if (QDF_IS_STATUS_ERROR(status))
15125 return qdf_status_to_os_return(status);
15126
15127 if (!cfg_in_range(CFG_TIMER_MULTIPLIER, scalar))
15128 return -ERANGE;
15129
15130 qdf_timer_set_multiplier(scalar);
15131
15132 return 0;
15133}
15134
15135static const struct kernel_param_ops timer_multiplier_ops = {
15136 .get = timer_multiplier_get_handler,
15137 .set = timer_multiplier_set_handler,
15138};
15139
15140module_param_cb(timer_multiplier, &timer_multiplier_ops, NULL, 0644);
15141