blob: d0242e4afaecb3e2587b354c56d3f70373ad7917 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Dustin Browndb2a8be2017-12-20 11:49:56 -08002 * Copyright (c) 2012-2018 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"
Dustin Brown21a1d462018-07-31 15:13:06 -070029#include "wlan_dsc.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080030#include <wlan_hdd_includes.h>
31#include <cds_api.h>
32#include <cds_sched.h>
Arun Khandavallifae92942016-08-01 13:31:08 +053033#include <linux/cpu.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080034#include <linux/etherdevice.h>
35#include <linux/firmware.h>
36#include <wlan_hdd_tx_rx.h>
37#include <wni_api.h>
38#include <wlan_hdd_cfg.h>
39#include <wlan_ptt_sock_svc.h>
40#include <dbglog_host.h>
41#include <wlan_logging_sock_svc.h>
Qiwei Caiad9b01c2018-07-09 17:21:31 +080042#include <wlan_roam_debug.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 Brownd4241942018-02-26 12:51:37 -080057#include "qdf_str.h"
58#include "qdf_trace.h"
59#include "qdf_types.h"
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070060#include <cdp_txrx_peer_ops.h>
Dhanashri Atrea8f82f22017-01-23 12:58:24 -080061#include <cdp_txrx_misc.h>
Mohit Khannaca4173b2017-09-12 21:52:19 -070062#include <cdp_txrx_stats.h>
bings0e03a982018-05-09 08:40:59 +080063#include "cdp_txrx_flow_ctrl_legacy.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080064
65#include <net/addrconf.h>
66#include <linux/wireless.h>
67#include <net/cfg80211.h>
68#include <linux/inetdevice.h>
69#include <net/addrconf.h>
70#include "wlan_hdd_cfg80211.h"
71#include "wlan_hdd_ext_scan.h"
72#include "wlan_hdd_p2p.h"
73#include <linux/rtnetlink.h>
74#include "sap_api.h"
75#include <linux/semaphore.h>
76#include <linux/ctype.h>
77#include <linux/compat.h>
Arunk Khandavalli830c9692018-03-22 12:17:40 +053078#include <linux/reboot.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080079#ifdef MSM_PLATFORM
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080080#include <soc/qcom/subsystem_restart.h>
81#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080082#include <wlan_hdd_hostapd.h>
83#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson8bb61112018-03-31 13:33:54 -070084#include <wlan_hdd_green_ap.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080085#include "cfg_api.h"
86#include "qwlan_version.h"
87#include "wma_types.h"
88#include "wlan_hdd_tdls.h"
89#ifdef FEATURE_WLAN_CH_AVOID
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +053090#include "cds_regdomain.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080091#endif /* FEATURE_WLAN_CH_AVOID */
Dustin Brownce46d1d2017-08-15 13:34:24 -070092#include "cdp_txrx_flow_ctrl_v2.h"
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070093#include "pld_common.h"
Tushnim Bhattacharyya15596cf2016-02-12 11:57:02 -080094#include "wlan_hdd_ocb.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080095#include "wlan_hdd_nan.h"
96#include "wlan_hdd_debugfs.h"
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053097#include "wlan_hdd_debugfs_csr.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080098#include "wlan_hdd_driver_ops.h"
99#include "epping_main.h"
Poddar, Siddarth34872782017-08-10 14:08:51 +0530100#include "wlan_hdd_data_stall_detection.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800101
102#include <wlan_hdd_ipa.h>
103#include "hif.h"
104#include "wma.h"
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -0800105#include "wlan_policy_mgr_api.h"
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700106#include "wlan_hdd_tsf.h"
Komal Seelamec702b02016-02-24 18:42:16 +0530107#include "bmi.h"
Amar Singhale4f28ee2015-10-21 14:36:56 -0700108#include <wlan_hdd_regulatory.h>
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700109#include "wlan_hdd_lpass.h"
Arun Khandavalli4b55da72016-07-19 19:55:01 +0530110#include "nan_api.h"
Nachiket Kukade63bb63d2018-11-21 14:42:14 +0530111#include "wlan_nan_api.h"
Orhan K AKYILDIZ1481aff2016-05-16 12:40:13 -0700112#include <wlan_hdd_napi.h>
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +0530113#include "wlan_hdd_disa.h"
Rajeev Kumar97767a02016-11-30 11:20:40 -0800114#include <dispatcher_init_deinit.h>
Rajeev Kumar699debf2017-01-06 14:17:00 -0800115#include "wlan_hdd_object_manager.h"
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +0530116#include "cds_utils.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800117#include <cdp_txrx_handle.h>
Sandeep Puligillafdd201e2017-02-02 18:43:46 -0800118#include <qca_vendor.h>
Mukul Sharma9d797a02017-01-05 20:26:03 +0530119#include "wlan_pmo_ucfg_api.h"
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +0530120#include "sir_api.h"
Naveen Rawat910726a2017-03-06 11:42:51 -0800121#include "os_if_wifi_pos.h"
122#include "wifi_pos_api.h"
123#include "wlan_hdd_oemdata.h"
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800124#include "wlan_hdd_he.h"
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700125#include "os_if_nan.h"
126#include "nan_public_structs.h"
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -0700127#include "wlan_reg_ucfg_api.h"
bings81fe50a2017-11-27 14:33:26 +0800128#include "wlan_dfs_ucfg_api.h"
Ravi Joshi4f095952017-06-29 15:39:19 -0700129#include "wlan_hdd_rx_monitor.h"
Mukul Sharmad16c2022017-07-25 18:56:12 +0530130#include "sme_power_save_api.h"
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +0530131#include "enet.h"
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700132#include <cdp_txrx_cmn_struct.h>
Mohit Khanna70322002018-05-15 19:21:32 -0700133#include <dp_txrx.h>
Amar Singhal0928b192017-12-01 10:50:54 -0800134#include "wlan_hdd_sysfs.h"
Nachiket Kukade98f562a2017-12-15 12:18:07 +0530135#include "wlan_disa_ucfg_api.h"
Wu Gao52084c12018-05-17 20:47:11 +0800136#include "wlan_disa_obj_mgmt_api.h"
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +0530137#include "wlan_action_oui_ucfg_api.h"
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +0530138#include "wlan_ipa_ucfg_api.h"
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530139#include <target_if.h>
Alok Kumarb64650c2018-03-23 17:05:11 +0530140#include "wlan_hdd_nud_tracking.h"
Nachiket Kukaded0dd62e2018-05-21 18:39:22 +0530141#include "wlan_hdd_apf.h"
Varun Reddy Yeturue93d2462018-05-22 13:54:52 -0700142#include "wlan_hdd_twt.h"
Rachit Kankane0dc3e852018-05-07 17:33:42 +0530143#include "qc_sap_ioctl.h"
Sandeep Puligillac5609d52018-05-17 19:23:41 -0700144#include "wlan_mlme_main.h"
Wu Gaoe5689792018-07-05 19:20:13 +0800145#include "wlan_p2p_cfg_api.h"
Wu Gao637d58a2018-12-08 10:37:34 +0800146#include "wlan_cfg80211_p2p.h"
Wu Gaobdb7f272018-07-05 19:33:26 +0800147#include "wlan_tdls_cfg_api.h"
Qiwei Caie689a262018-07-26 15:50:22 +0800148#include <wlan_hdd_rssi_monitor.h>
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +0530149#include "wlan_mlme_ucfg_api.h"
Sourav Mohapatra113685f2018-08-29 14:21:55 +0530150#include "wlan_fwol_ucfg_api.h"
Krunal Sonie71838d2018-09-27 10:45:05 -0700151#include "wlan_policy_mgr_ucfg.h"
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +0530152#ifdef CNSS_GENL
153#include <net/cnss_nl.h>
154#endif
Amar Singhal5cccafe2017-02-15 12:42:58 -0800155#include "wlan_reg_ucfg_api.h"
Zhang Qian47e22ce2018-01-04 15:38:38 +0800156#include "wlan_ocb_ucfg_api.h"
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -0800157#include <wlan_hdd_spectralscan.h>
gaurank kathpalia4a205fc2018-09-15 00:59:15 +0530158#include "wlan_green_ap_ucfg_api.h"
Liangwei Dong3abfe8f2018-09-20 02:25:44 -0400159#include <wlan_p2p_ucfg_api.h>
160
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800161#ifdef MODULE
162#define WLAN_MODULE_NAME module_name(THIS_MODULE)
163#else
164#define WLAN_MODULE_NAME "wlan"
165#endif
166
167#ifdef TIMER_MANAGER
168#define TIMER_MANAGER_STR " +TIMER_MANAGER"
169#else
170#define TIMER_MANAGER_STR ""
171#endif
172
173#ifdef MEMORY_DEBUG
174#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
175#else
176#define MEMORY_DEBUG_STR ""
177#endif
178
Dustin Brownc1034df2018-02-07 14:51:32 -0800179#ifdef PANIC_ON_BUG
180#define PANIC_ON_BUG_STR " +PANIC_ON_BUG"
181#else
182#define PANIC_ON_BUG_STR ""
183#endif
184
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530185bool g_is_system_reboot_triggered;
Sachin Ahujadddd2632017-03-07 19:07:24 +0530186int wlan_start_ret_val;
187static DECLARE_COMPLETION(wlan_start_comp);
188static unsigned int dev_num = 1;
189static struct cdev wlan_hdd_state_cdev;
190static struct class *class;
191static dev_t device;
Arun Khandavallifae92942016-08-01 13:31:08 +0530192#ifndef MODULE
193static struct gwlan_loader *wlan_loader;
194static ssize_t wlan_boot_cb(struct kobject *kobj,
195 struct kobj_attribute *attr,
196 const char *buf, size_t count);
197struct gwlan_loader {
198 bool loaded_state;
199 struct kobject *boot_wlan_obj;
200 struct attribute_group *attr_group;
201};
202
203static struct kobj_attribute wlan_boot_attribute =
204 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
205
206static struct attribute *attrs[] = {
207 &wlan_boot_attribute.attr,
208 NULL,
209};
210
211#define MODULE_INITIALIZED 1
Qun Zhang4a83a462018-09-11 16:28:51 +0800212
213#ifdef MULTI_IF_NAME
214#define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME
215#else
216#define WLAN_LOADER_NAME "boot_wlan"
217#endif
Arun Khandavallifae92942016-08-01 13:31:08 +0530218#endif
219
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530220#define HDD_OPS_INACTIVITY_TIMEOUT (120000)
221#define MAX_OPS_NAME_STRING_SIZE 20
Rajeev Kumar6d0b2ea2017-12-26 17:55:33 -0800222#define RATE_LIMIT_ERROR_LOG (256)
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530223
224static qdf_timer_t hdd_drv_ops_inactivity_timer;
Dustin Brown45ed4bb2017-12-18 12:00:13 -0800225static struct task_struct *hdd_drv_ops_task;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530226static char drv_ops_string[MAX_OPS_NAME_STRING_SIZE];
227
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800228/* the Android framework expects this param even though we don't use it */
229#define BUF_LEN 20
230static char fwpath_buffer[BUF_LEN];
231static struct kparam_string fwpath = {
232 .string = fwpath_buffer,
233 .maxlen = BUF_LEN,
234};
235
236static char *country_code;
237static int enable_11d = -1;
238static int enable_dfs_chan_scan = -1;
239
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800240/*
241 * spinlock for synchronizing asynchronous request/response
242 * (full description of use in wlan_hdd_main.h)
243 */
244DEFINE_SPINLOCK(hdd_context_lock);
Arunk Khandavalli16d84252017-06-21 15:26:29 +0530245DEFINE_MUTEX(hdd_init_deinit_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800246
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800247#define WLAN_NLINK_CESIUM 30
248
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530249static qdf_wake_lock_t wlan_wake_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800250
251#define WOW_MAX_FILTER_LISTS 1
252#define WOW_MAX_FILTERS_PER_LIST 4
253#define WOW_MIN_PATTERN_SIZE 6
254#define WOW_MAX_PATTERN_SIZE 64
255
Bala Venkatesh110b03e2018-07-10 16:02:08 +0530256/* max peer can be tdls peers + self peer + bss peer */
257#define HDD_MAX_VDEV_PEER_COUNT (HDD_MAX_NUM_TDLS_STA + 2)
Sourav Mohapatra808e3d42018-07-04 09:34:23 +0530258#define IS_IDLE_STOP (!cds_is_driver_unloading() && \
259 !cds_is_driver_recovering() && !cds_is_driver_loading())
Bala Venkatesh110b03e2018-07-10 16:02:08 +0530260
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800261#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
262static const struct wiphy_wowlan_support wowlan_support_reg_init = {
263 .flags = WIPHY_WOWLAN_ANY |
264 WIPHY_WOWLAN_MAGIC_PKT |
265 WIPHY_WOWLAN_DISCONNECT |
266 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
267 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
268 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
269 WIPHY_WOWLAN_4WAY_HANDSHAKE |
270 WIPHY_WOWLAN_RFKILL_RELEASE,
271 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
272 .pattern_min_len = WOW_MIN_PATTERN_SIZE,
273 .pattern_max_len = WOW_MAX_PATTERN_SIZE,
274};
275#endif
276
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700277static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
278 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL},
279 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL},
280 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL},
281 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL},
282 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL},
283 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL},
284 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL},
285 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL},
286 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL},
287 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL},
288 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL},
289 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
290 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
291 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL},
292 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL},
293 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL},
294 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL},
295 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL},
296 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL},
297 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL},
298 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL},
299 [QDF_MODULE_ID_DP] = {QDF_TRACE_LEVEL_ALL},
300 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL},
301 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL},
302 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL},
303 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL},
304 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL},
305 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL},
306 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL},
307 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL},
308 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL},
309 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL},
310 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL},
311 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL},
Arif Hussainfde76e72017-09-05 16:58:23 -0700312 [QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumarca8ef9d2017-10-06 10:43:21 -0700313 [QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL},
Deepak Dhamdheref918d422017-07-06 12:56:29 -0700314 [QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL},
Himanshu Agarwalb229a142017-12-21 10:16:45 +0530315 [QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL},
Zhang Qian47e22ce2018-01-04 15:38:38 +0800316 [QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL},
Sravan Kumar Kairam1309e7e2018-03-13 09:29:52 +0530317 [QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +0530318 [QDF_MODULE_ID_ACTION_OUI] = {QDF_TRACE_LEVEL_ALL},
Dustin Brown84f46ea2018-02-15 11:57:36 -0800319 [QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL},
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +0530320 [QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL},
Ashish Kumar Dhanotiya8d039c82018-07-11 20:41:14 +0530321 [QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL},
Kiran Kumar Lokere4ce40482018-08-30 16:31:00 -0700322 [QDF_MODULE_ID_CRYPTO] = {QDF_TRACE_LEVEL_ALL},
Sourav Mohapatra113685f2018-08-29 14:21:55 +0530323 [QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL},
Abhishek Singh0b0105f2018-09-25 10:44:16 +0530324 [QDF_MODULE_ID_SM_ENGINE] = {QDF_TRACE_LEVEL_ALL},
325 [QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL},
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700326};
327
Ashish Kumar Dhanotiyacf11bae2017-04-04 03:29:47 +0530328struct notifier_block hdd_netdev_notifier;
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530329struct notifier_block system_reboot_notifier;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800330
331struct sock *cesium_nl_srv_sock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800332#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700333static void wlan_hdd_auto_shutdown_cb(void);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800334#endif
335
Sachin Ahujadddd2632017-03-07 19:07:24 +0530336void hdd_start_complete(int ret)
337{
338 wlan_start_ret_val = ret;
339
340 complete(&wlan_start_comp);
341}
342
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800343/**
Nirav Shahbd36b062016-07-18 11:12:59 +0530344 * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700345 * @hdd_ctx: pointer to struct hdd_context
Nirav Shahbd36b062016-07-18 11:12:59 +0530346 *
347 * Return: none
348 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700349static void hdd_set_rps_cpu_mask(struct hdd_context *hdd_ctx)
Nirav Shahbd36b062016-07-18 11:12:59 +0530350{
Jeff Johnson9d295242017-08-29 14:39:48 -0700351 struct hdd_adapter *adapter;
Nirav Shahbd36b062016-07-18 11:12:59 +0530352
Dustin Brown920397d2017-12-13 16:27:50 -0800353 hdd_for_each_adapter(hdd_ctx, adapter)
354 hdd_send_rps_ind(adapter);
Nirav Shahbd36b062016-07-18 11:12:59 +0530355}
356
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530357#ifdef QCA_HL_NETDEV_FLOW_CONTROL
358void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter,
359 enum netif_action_type action)
360{
361 if (!adapter->tx_flow_timer_initialized)
362 return;
363
364 if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) {
365 qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
366 } else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) {
367 QDF_STATUS status =
368 qdf_mc_timer_start(&adapter->tx_flow_control_timer,
369 WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
370
371 if (!QDF_IS_STATUS_SUCCESS(status))
372 hdd_err("Failed to start tx_flow_control_timer");
373 else
374 adapter->
375 hdd_stats.tx_rx_stats.txflow_timer_cnt++;
376
377 adapter->hdd_stats.tx_rx_stats.txflow_pause_cnt++;
378 adapter->hdd_stats.tx_rx_stats.is_txflow_paused = true;
379 }
380}
381#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
382
Alok Kumar2fad6442018-11-08 19:19:28 +0530383#ifdef MSM_PLATFORM
384void wlan_hdd_update_tcp_rx_param(struct hdd_context *hdd_ctx, void *data)
385{
386 if (!hdd_ctx) {
387 hdd_err("HDD context is null");
388 return;
389 }
390
391 if (!data) {
392 hdd_err("Data is null");
393 return;
394 }
395 if (hdd_ctx->config->enable_tcp_param_update)
396 wlan_hdd_send_tcp_param_update_event(hdd_ctx, data, 1);
397 else
398 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
399 WLAN_SVC_WLAN_TP_IND,
400 data,
401 sizeof(struct wlan_rx_tp_data));
402}
403
404void wlan_hdd_update_tcp_tx_param(struct hdd_context *hdd_ctx, void *data)
405{
406 enum wlan_tp_level next_tx_level;
407 struct wlan_tx_tp_data *tx_tp_data;
408
409 if (!hdd_ctx) {
410 hdd_err("HDD context is null");
411 return;
412 }
413
414 if (!data) {
415 hdd_err("Data is null");
416 return;
417 }
418
419 tx_tp_data = (struct wlan_tx_tp_data *)data;
420 next_tx_level = tx_tp_data->level;
421
422 if (hdd_ctx->config->enable_tcp_param_update)
423 wlan_hdd_send_tcp_param_update_event(hdd_ctx, data, 0);
424 else
425 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
426 WLAN_SVC_WLAN_TP_TX_IND,
427 &next_tx_level,
428 sizeof(next_tx_level));
429}
430
431/**
432 * wlan_hdd_send_tcp_param_update_event() - Send vendor event to update
433 * TCP parameter through Wi-Fi HAL
434 * @hdd_ctx: Pointer to HDD context
435 * @data: Parameters to update
436 * @dir: Direction(tx/rx) to update
437 *
438 * Return: None
439 */
440void wlan_hdd_send_tcp_param_update_event(struct hdd_context *hdd_ctx,
441 void *data,
442 uint8_t dir)
443{
444 struct sk_buff *vendor_event;
445 uint32_t event_len;
446 bool tcp_limit_output = false;
447 bool tcp_del_ack_ind_enabled = false;
448 bool tcp_adv_win_scl_enabled = false;
449 enum wlan_tp_level next_tp_level = WLAN_SVC_TP_NONE;
450
451 event_len = sizeof(uint8_t) + sizeof(uint8_t) + NLMSG_HDRLEN;
452
453 if (dir == 0) /*TX Flow */ {
454 struct wlan_tx_tp_data *tx_tp_data =
455 (struct wlan_tx_tp_data *)data;
456
457 next_tp_level = tx_tp_data->level;
458
459 if (tx_tp_data->tcp_limit_output) {
460 /* TCP_LIMIT_OUTPUT_BYTES */
461 event_len += sizeof(uint32_t);
462 tcp_limit_output = true;
463 }
464 } else if (dir == 1) /* RX Flow */ {
465 struct wlan_rx_tp_data *rx_tp_data =
466 (struct wlan_rx_tp_data *)data;
467
468 next_tp_level = rx_tp_data->level;
469
470 if (rx_tp_data->rx_tp_flags & TCP_DEL_ACK_IND_MASK) {
471 event_len += sizeof(uint32_t); /* TCP_DELACK_SEG */
472 tcp_del_ack_ind_enabled = true;
473 }
474 if (rx_tp_data->rx_tp_flags & TCP_ADV_WIN_SCL_MASK) {
475 event_len += sizeof(uint32_t); /* TCP_ADV_WIN_SCALE */
476 tcp_adv_win_scl_enabled = true;
477 }
478 } else {
479 hdd_err("Invalid Direction [%d]", dir);
480 return;
481 }
482
483 vendor_event =
484 cfg80211_vendor_event_alloc(
485 hdd_ctx->wiphy,
486 NULL, event_len,
487 QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT_INDEX,
488 GFP_KERNEL);
489
490 if (!vendor_event) {
491 hdd_err("cfg80211_vendor_event_alloc failed");
492 return;
493 }
494
495 if (nla_put_u8(
496 vendor_event,
497 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION,
498 dir))
499 goto tcp_param_change_nla_failed;
500
501 if (nla_put_u8(
502 vendor_event,
503 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL,
504 (next_tp_level == WLAN_SVC_TP_LOW ?
505 QCA_WLAN_THROUGHPUT_LEVEL_LOW :
506 QCA_WLAN_THROUGHPUT_LEVEL_HIGH)))
507 goto tcp_param_change_nla_failed;
508
509 if (tcp_limit_output &&
510 nla_put_u32(
511 vendor_event,
512 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES,
513 (next_tp_level == WLAN_SVC_TP_LOW ?
514 TCP_LIMIT_OUTPUT_BYTES_LOW :
515 TCP_LIMIT_OUTPUT_BYTES_HI)))
516 goto tcp_param_change_nla_failed;
517
518 if (tcp_del_ack_ind_enabled &&
519 (nla_put_u32(
520 vendor_event,
521 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG,
522 (next_tp_level == WLAN_SVC_TP_LOW ?
523 TCP_DEL_ACK_LOW : TCP_DEL_ACK_HI))))
524 goto tcp_param_change_nla_failed;
525
526 if (tcp_adv_win_scl_enabled &&
527 (nla_put_u32(
528 vendor_event,
529 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE,
530 (next_tp_level == WLAN_SVC_TP_LOW ?
531 WIN_SCALE_LOW : WIN_SCALE_HI))))
532 goto tcp_param_change_nla_failed;
533
534 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
535 return;
536
537tcp_param_change_nla_failed:
538 hdd_err("nla_put api failed");
539 kfree_skb(vendor_event);
540}
541#endif /* MSM_PLATFORM */
542
Nirav Shahbd36b062016-07-18 11:12:59 +0530543/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800544 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
545 * @vdev_id: vdev_id
546 * @action: action type
547 * @reason: reason type
548 *
549 * Return: none
550 */
551void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
552 enum netif_action_type action, enum netif_reason_type reason)
553{
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700554 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson9d295242017-08-29 14:39:48 -0700555 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800556
557 if (!hdd_ctx) {
558 hdd_err("hdd ctx is NULL");
559 return;
560 }
561 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530562 wlan_hdd_mod_fc_timer(adapter, action);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800563 wlan_hdd_netif_queue_control(adapter, action, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564}
565
566/*
Dustin Brownab482ac2017-06-09 17:00:44 -0700567 * Store WLAN driver version and timestamp info in global variables such that
568 * crash debugger can extract them from driver debug symbol and crashdump for
569 * post processing
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800570 */
Dustin Brown96cd9632017-11-13 12:45:04 -0800571#ifdef BUILD_TAG
Rajeev Kumare555e2d2018-09-17 11:52:37 -0700572uint8_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 -0800573#else
Rajeev Kumare555e2d2018-09-17 11:52:37 -0700574uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR;
Naveen Rawat93836252017-06-20 16:30:59 -0700575#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800576
577/**
Liangwei Dong17bf2662018-01-05 02:02:05 -0500578 * hdd_get_valid_chan() - return current chan list from regulatory.
579 * @hdd_ctx: HDD context
580 * @chan_list: buf hold returned chan list
581 * @chan_num: input buf size and output returned chan num
582 *
583 * This function helps get current available chan list from regulatory
584 * module. It excludes the "disabled" and "invalid" channels.
585 *
586 * Return: 0 for success.
587 */
588static int hdd_get_valid_chan(struct hdd_context *hdd_ctx,
589 uint8_t *chan_list,
590 uint32_t *chan_num)
591{
592 int i = 0, j = 0;
593 struct regulatory_channel *cur_chan_list;
594 struct wlan_objmgr_pdev *pdev;
595
Dustin Brown07901ec2018-09-07 11:02:41 -0700596 if (!hdd_ctx || !hdd_ctx->pdev || !chan_list || !chan_num)
Liangwei Dong17bf2662018-01-05 02:02:05 -0500597 return -EINVAL;
598
Dustin Brown07901ec2018-09-07 11:02:41 -0700599 pdev = hdd_ctx->pdev;
Liangwei Dong17bf2662018-01-05 02:02:05 -0500600 cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
601 sizeof(struct regulatory_channel));
602 if (!cur_chan_list)
603 return -ENOMEM;
604
605 if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) !=
606 QDF_STATUS_SUCCESS) {
607 qdf_mem_free(cur_chan_list);
608 return -EINVAL;
609 }
610
611 for (i = 0; i < NUM_CHANNELS; i++) {
612 uint32_t ch = cur_chan_list[i].chan_num;
613 enum channel_state state = wlan_reg_get_channel_state(pdev,
614 ch);
615
616 if (state != CHANNEL_STATE_DISABLE &&
617 state != CHANNEL_STATE_INVALID &&
618 j < *chan_num) {
619 chan_list[j] = (uint8_t)ch;
620 j++;
621 }
622 }
623 *chan_num = j;
624 qdf_mem_free(cur_chan_list);
625 return 0;
626}
627
628/**
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530629 * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo
630 * @adapter: HDD adapter
631 * @chan_number: Channel number
632 * @chan_bw: Bandwidth
633 *
634 * Checks if the given bandwidth is valid for the given channel number.
635 *
636 * Return: 0 for success, non-zero for failure
637 */
Jeff Johnson9d295242017-08-29 14:39:48 -0700638int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530639 uint32_t chan_number,
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800640 enum phy_ch_width chan_bw)
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530641{
Liangwei Dong17bf2662018-01-05 02:02:05 -0500642 uint8_t chan[NUM_CHANNELS];
643 uint32_t len = NUM_CHANNELS, i;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530644 bool found = false;
Jeff Johnson16528362018-06-14 12:34:16 -0700645 mac_handle_t mac_handle;
Liangwei Dong17bf2662018-01-05 02:02:05 -0500646 int ret;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530647
Jeff Johnson16528362018-06-14 12:34:16 -0700648 mac_handle = hdd_adapter_get_mac_handle(adapter);
649 if (!mac_handle) {
650 hdd_err("Invalid MAC handle");
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530651 return -EINVAL;
652 }
653
Liangwei Dong17bf2662018-01-05 02:02:05 -0500654 ret = hdd_get_valid_chan(adapter->hdd_ctx, chan,
655 &len);
656 if (ret) {
657 hdd_err("error %d in getting valid channel list", ret);
658 return ret;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530659 }
660
661 for (i = 0; i < len; i++) {
662 if (chan[i] == chan_number) {
663 found = true;
664 break;
665 }
666 }
667
668 if (found == false) {
669 hdd_err("Channel not in driver's valid channel list");
670 return -EOPNOTSUPP;
671 }
672
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700673 if ((!WLAN_REG_IS_24GHZ_CH(chan_number)) &&
674 (!WLAN_REG_IS_5GHZ_CH(chan_number))) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530675 hdd_err("CH %d is not in 2.4GHz or 5GHz", chan_number);
676 return -EINVAL;
677 }
678
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700679 if (WLAN_REG_IS_24GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530680 if (chan_bw == CH_WIDTH_80MHZ) {
681 hdd_err("BW80 not possible in 2.4GHz band");
682 return -EINVAL;
683 }
684 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 14) &&
685 (chan_bw != CH_WIDTH_MAX)) {
686 hdd_err("Only BW20 possible on channel 14");
687 return -EINVAL;
688 }
689 }
690
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700691 if (WLAN_REG_IS_5GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530692 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 165) &&
693 (chan_bw != CH_WIDTH_MAX)) {
694 hdd_err("Only BW20 possible on channel 165");
695 return -EINVAL;
696 }
697 }
698
699 return 0;
700}
701
Arunk Khandavallie1b3a382017-09-26 12:01:26 +0530702/**
703 * hdd_wait_for_recovery_completion() - Wait for cds recovery completion
704 *
705 * Block the unloading of the driver (or) interface up until the
706 * cds recovery is completed
707 *
708 * Return: true for recovery completion else false
709 */
710static bool hdd_wait_for_recovery_completion(void)
711{
712 int retry = 0;
713
714 /* Wait for recovery to complete */
715 while (cds_is_driver_recovering()) {
716 if (retry == HDD_MOD_EXIT_SSR_MAX_RETRIES/2)
717 hdd_err("Recovery in progress; wait here!!!");
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530718
719 if (g_is_system_reboot_triggered) {
720 hdd_info("System Reboot happening ignore unload!!");
721 return false;
722 }
723
Arunk Khandavallie1b3a382017-09-26 12:01:26 +0530724 msleep(1000);
725 if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
726 hdd_err("SSR never completed, error");
727 /*
728 * Trigger the bug_on in the internal builds, in the
729 * customer builds self-recovery will be enabled
730 * in those cases just return error.
731 */
732 if (cds_is_self_recovery_enabled())
733 return false;
734 QDF_BUG(0);
735 }
736 }
737
738 hdd_info("Recovery completed successfully!");
739 return true;
740}
741
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530742
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800743static int __hdd_netdev_notifier_call(struct notifier_block *nb,
744 unsigned long state, void *data)
745{
746#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
747 struct netdev_notifier_info *dev_notif_info = data;
748 struct net_device *dev = dev_notif_info->dev;
749#else
750 struct net_device *dev = data;
751#endif
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530752 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700753 struct hdd_context *hdd_ctx;
Min Liu8c5d99e2018-09-10 17:18:44 +0800754 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800755
Dustin Brownfdf17c12018-03-14 12:55:34 -0700756 hdd_enter_dev(dev);
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800757
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800758 if (!dev->ieee80211_ptr) {
Dustin Brownaeb55642018-07-30 17:20:32 -0700759 hdd_debug("ieee80211_ptr is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800760 return NOTIFY_DONE;
761 }
762
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530763 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
764 if (!hdd_ctx) {
765 hdd_err("HDD Context is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800766 return NOTIFY_DONE;
767 }
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800768
769 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -0700770 hdd_debug("%s: Driver module is closed", __func__);
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800771 return NOTIFY_DONE;
772 }
773
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530774 /* Make sure that this callback corresponds to our device. */
775 adapter = hdd_get_adapter_by_iface_name(hdd_ctx, dev->name);
776 if (!adapter) {
Dustin Brownaeb55642018-07-30 17:20:32 -0700777 hdd_debug("failed to look up adapter for '%s'", dev->name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800778 return NOTIFY_DONE;
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530779 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800780
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530781 if (adapter != WLAN_HDD_GET_PRIV_PTR(dev)) {
782 hdd_err("HDD adapter mismatch!");
783 return NOTIFY_DONE;
784 }
785
Dustin Brownaeb55642018-07-30 17:20:32 -0700786 if (cds_is_driver_recovering()) {
787 hdd_debug("Driver is recovering");
788 return NOTIFY_DONE;
789 }
790
791 if (cds_is_driver_in_bad_state()) {
792 hdd_debug("Driver is in failed recovery state");
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530793 return NOTIFY_DONE;
794 }
795
796 hdd_debug("%s New Net Device State = %lu", dev->name, state);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800797
798 switch (state) {
799 case NETDEV_REGISTER:
800 break;
801
802 case NETDEV_UNREGISTER:
803 break;
804
805 case NETDEV_UP:
Jeff Johnson16528362018-06-14 12:34:16 -0700806 sme_ch_avoid_update_req(hdd_ctx->mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800807 break;
808
809 case NETDEV_DOWN:
810 break;
811
812 case NETDEV_CHANGE:
Jeff Johnsonc72c5732017-10-28 12:49:37 -0700813 if (adapter->is_link_up_service_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800814 complete(&adapter->linkup_event_var);
815 break;
816
817 case NETDEV_GOING_DOWN:
Min Liu8c5d99e2018-09-10 17:18:44 +0800818 vdev = hdd_objmgr_get_vdev(adapter);
819 if (!vdev)
820 break;
821 if (ucfg_scan_get_vdev_status(vdev) !=
Sandeep Puligilla5f86d992017-10-29 14:58:53 -0700822 SCAN_NOT_IN_PROGRESS) {
Dustin Brown07901ec2018-09-07 11:02:41 -0700823 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
824 adapter->session_id, INVALID_SCAN_ID,
825 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800826 }
Min Liu8c5d99e2018-09-10 17:18:44 +0800827 hdd_objmgr_put_vdev(adapter);
Min Liu9be5d4a2018-05-17 11:51:53 +0800828 cds_flush_work(&adapter->scan_block_work);
829 /* Need to clean up blocked scan request */
830 wlan_hdd_cfg80211_scan_block_cb(&adapter->scan_block_work);
Min Liu9be5d4a2018-05-17 11:51:53 +0800831 hdd_debug("Scan is not Pending from user");
Arunk Khandavallif0c0d762017-12-07 10:18:50 +0530832 /*
833 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
834 * of return status of hdd_stop call, kernel resets the IFF_UP
835 * flag after which driver does not send the cfg80211_scan_done.
836 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN
837 */
Dustin Brown07901ec2018-09-07 11:02:41 -0700838 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800839 break;
840
841 default:
842 break;
843 }
844
845 return NOTIFY_DONE;
846}
847
848/**
849 * hdd_netdev_notifier_call() - netdev notifier callback function
850 * @nb: pointer to notifier block
851 * @state: state
852 * @ndev: ndev pointer
853 *
854 * Return: 0 on success, error number otherwise.
855 */
856static int hdd_netdev_notifier_call(struct notifier_block *nb,
857 unsigned long state,
858 void *ndev)
859{
860 int ret;
861
862 cds_ssr_protect(__func__);
863 ret = __hdd_netdev_notifier_call(nb, state, ndev);
864 cds_ssr_unprotect(__func__);
865
866 return ret;
867}
868
869struct notifier_block hdd_netdev_notifier = {
870 .notifier_call = hdd_netdev_notifier_call,
871};
872
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530873static int system_reboot_notifier_call(struct notifier_block *nb,
874 unsigned long msg_type, void *_unused)
875{
876 switch (msg_type) {
877 case SYS_DOWN:
878 case SYS_HALT:
879 case SYS_POWER_OFF:
880 g_is_system_reboot_triggered = true;
881 hdd_info("reboot, reason: %ld", msg_type);
882 break;
883 default:
884 break;
885 }
886
887 return NOTIFY_OK;
888}
889
890struct notifier_block system_reboot_notifier = {
891 .notifier_call = system_reboot_notifier_call,
892};
893
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800894/* variable to hold the insmod parameters */
895static int con_mode;
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800896
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530897static int con_mode_ftm;
Ravi Joshia307f632017-07-17 23:41:41 -0700898int con_mode_monitor;
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530899
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800900/* Variable to hold connection mode including module parameter con_mode */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800901static int curr_con_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800902
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530903/**
904 * hdd_map_nl_chan_width() - Map NL channel width to internal representation
905 * @ch_width: NL channel width
906 *
907 * Converts the NL channel width to the driver's internal representation
908 *
909 * Return: Converted channel width. In case of non matching NL channel width,
910 * CH_WIDTH_MAX will be returned.
911 */
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800912enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530913{
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800914 uint8_t fw_ch_bw;
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700915
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800916 fw_ch_bw = wma_get_vht_ch_width();
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530917 switch (ch_width) {
918 case NL80211_CHAN_WIDTH_20_NOHT:
919 case NL80211_CHAN_WIDTH_20:
920 return CH_WIDTH_20MHZ;
921 case NL80211_CHAN_WIDTH_40:
922 return CH_WIDTH_40MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530923 case NL80211_CHAN_WIDTH_80:
924 return CH_WIDTH_80MHZ;
925 case NL80211_CHAN_WIDTH_80P80:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800926 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
927 return CH_WIDTH_80P80MHZ;
928 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
929 return CH_WIDTH_160MHZ;
930 else
931 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530932 case NL80211_CHAN_WIDTH_160:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800933 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
934 return CH_WIDTH_160MHZ;
935 else
936 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530937 case NL80211_CHAN_WIDTH_5:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800938 return CH_WIDTH_5MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530939 case NL80211_CHAN_WIDTH_10:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800940 return CH_WIDTH_10MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530941 default:
942 hdd_err("Invalid channel width %d, setting to default",
943 ch_width);
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800944 return CH_WIDTH_INVALID;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530945 }
946}
947
Dustin Brown56377e12018-10-10 17:04:04 -0700948QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type,
949 enum QDF_OPMODE *out_qdf_type)
950{
951 switch (nl_type) {
952 case NL80211_IFTYPE_ADHOC:
953 *out_qdf_type = QDF_IBSS_MODE;
954 break;
955 case NL80211_IFTYPE_AP:
956 *out_qdf_type = QDF_SAP_MODE;
957 break;
958 case NL80211_IFTYPE_MONITOR:
959 *out_qdf_type = QDF_MONITOR_MODE;
960 break;
961 case NL80211_IFTYPE_OCB:
962 *out_qdf_type = QDF_OCB_MODE;
963 break;
964 case NL80211_IFTYPE_P2P_CLIENT:
965 *out_qdf_type = QDF_P2P_CLIENT_MODE;
966 break;
967 case NL80211_IFTYPE_P2P_DEVICE:
968 *out_qdf_type = QDF_P2P_DEVICE_MODE;
969 break;
970 case NL80211_IFTYPE_P2P_GO:
971 *out_qdf_type = QDF_P2P_GO_MODE;
972 break;
973 case NL80211_IFTYPE_STATION:
974 *out_qdf_type = QDF_STA_MODE;
975 break;
976 case NL80211_IFTYPE_WDS:
977 *out_qdf_type = QDF_WDS_MODE;
978 break;
979 default:
980 hdd_err("Invalid nl80211 interface type %d", nl_type);
981 return QDF_STATUS_E_INVAL;
982 }
983
984 return QDF_STATUS_SUCCESS;
985}
986
Jeff Johnson16528362018-06-14 12:34:16 -0700987uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel,
988 uint8_t bw_offset)
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +0530989{
990 uint8_t opclass = 0;
991
Jeff Johnson16528362018-06-14 12:34:16 -0700992 sme_get_opclass(mac_handle, channel, bw_offset, &opclass);
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +0530993 return opclass;
994}
995
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800996/**
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530997 * hdd_qdf_trace_enable() - configure initial QDF Trace enable
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530998 * @module_id: Module whose trace level is being configured
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800999 * @bitmask: Bitmask of log levels to be enabled
1000 *
1001 * Called immediately after the cfg.ini is read in order to configure
1002 * the desired trace levels.
1003 *
1004 * Return: None
1005 */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301006int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001007{
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301008 QDF_TRACE_LEVEL level;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301009 int qdf_print_idx = -1;
1010 int status = -1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001011 /*
1012 * if the bitmask is the default value, then a bitmask was not
1013 * specified in cfg.ini, so leave the logging level alone (it
1014 * will remain at the "compiled in" default value)
1015 */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001016 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301017 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001018
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301019 qdf_print_idx = qdf_get_pidx();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001020
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301021 /* a mask was specified. start by disabling all logging */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301022 status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301023 QDF_TRACE_LEVEL_NONE, 0);
1024
1025 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301026 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001027 /* now cycle through the bitmask until all "set" bits are serviced */
Ashish Kumar Dhanotiya83f286b2017-09-15 19:52:58 +05301028 level = QDF_TRACE_LEVEL_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001029 while (0 != bitmask) {
1030 if (bitmask & 1) {
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301031 status = qdf_print_set_category_verbose(qdf_print_idx,
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301032 module_id, level, 1);
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301033 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301034 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001035 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001036
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001037 level++;
1038 bitmask >>= 1;
1039 }
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301040 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001041}
1042
Dustin Brownda351e32018-07-23 15:48:22 -07001043int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func)
Chris Guo1751acf2017-07-03 14:09:01 +08001044{
Dustin Brownda351e32018-07-23 15:48:22 -07001045 if (!hdd_ctx) {
1046 hdd_err("HDD context is null (via %s)", func);
1047 return -ENODEV;
1048 }
1049
1050 if (!hdd_ctx->config) {
1051 hdd_err("HDD config is null (via %s)", func);
Chris Guo1751acf2017-07-03 14:09:01 +08001052 return -ENODEV;
1053 }
1054
1055 if (cds_is_driver_recovering()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001056 hdd_debug("Recovery in progress (via %s); state:0x%x",
1057 func, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001058 return -EAGAIN;
1059 }
1060
Yue Ma9f275d92017-09-14 16:58:41 -07001061 if (cds_is_load_or_unload_in_progress()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001062 hdd_debug("Load/unload in progress (via %s); state:0x%x",
1063 func, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001064 return -EAGAIN;
Yue Ma9f275d92017-09-14 16:58:41 -07001065 }
Arun Khandavallia172c3e2016-08-26 17:33:13 +05301066
Dustin Brownda351e32018-07-23 15:48:22 -07001067 if (hdd_ctx->start_modules_in_progress) {
1068 hdd_debug("Start modules in progress (via %s)", func);
1069 return -EAGAIN;
1070 }
1071
1072 if (hdd_ctx->stop_modules_in_progress) {
1073 hdd_debug("Stop modules in progress (via %s)", func);
Arun Khandavallia172c3e2016-08-26 17:33:13 +05301074 return -EAGAIN;
1075 }
1076
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301077 if (cds_is_driver_in_bad_state()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001078 hdd_debug("Driver in bad state (via %s); state:0x%x",
1079 func, cds_get_driver_state());
Sourav Mohapatra21b3c982018-04-03 17:33:03 +05301080 return -EAGAIN;
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301081 }
1082
Arunk Khandavalli2859fa12018-02-14 10:46:26 +05301083 if (cds_is_fw_down()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001084 hdd_debug("FW is down (via %s); state:0x%x",
1085 func, cds_get_driver_state());
Sourav Mohapatra21b3c982018-04-03 17:33:03 +05301086 return -EAGAIN;
Arunk Khandavalli2859fa12018-02-14 10:46:26 +05301087 }
1088
Liangwei Dong858feb12018-05-21 01:52:46 -04001089 if (qdf_atomic_read(&hdd_ctx->con_mode_flag)) {
Dustin Brownda351e32018-07-23 15:48:22 -07001090 hdd_debug("Driver mode change in progress (via %s)", func);
Liangwei Dong858feb12018-05-21 01:52:46 -04001091 return -EAGAIN;
1092 }
1093
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001094 return 0;
1095}
1096
Dustin Browna8700cc2018-08-07 12:04:47 -07001097int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func)
Dustin Brownf13b8c32017-05-19 17:23:08 -07001098{
1099 if (!adapter) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001100 hdd_err("adapter is null (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001101 return -EINVAL;
1102 }
1103
1104 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001105 hdd_err("bad adapter magic (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001106 return -EINVAL;
1107 }
1108
1109 if (!adapter->dev) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001110 hdd_err("adapter net_device is null (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001111 return -EINVAL;
1112 }
1113
1114 if (!(adapter->dev->flags & IFF_UP)) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001115 hdd_debug_rl("adapter '%s' is not up (via %s)",
1116 adapter->dev->name, func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001117 return -EAGAIN;
1118 }
1119
Dustin Browna8700cc2018-08-07 12:04:47 -07001120 return __wlan_hdd_validate_session_id(adapter->session_id, func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001121}
1122
Dustin Brown63500612018-08-07 11:36:09 -07001123int __wlan_hdd_validate_session_id(uint8_t session_id, const char *func)
1124{
1125 if (session_id == CSR_SESSION_ID_INVALID) {
1126 hdd_debug_rl("adapter is not up (via %s)", func);
1127 return -EINVAL;
1128 }
1129
1130 if (session_id >= CSR_ROAM_SESSION_MAX) {
1131 hdd_err("bad session Id:%u (via %s)", session_id, func);
1132 return -EINVAL;
1133 }
1134
1135 return 0;
1136}
1137
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05301138QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr,
1139 const char *func)
1140{
1141 if (!mac_addr) {
1142 hdd_err("Received NULL mac address (via %s)", func);
1143 return QDF_STATUS_E_INVAL;
1144 }
1145
1146 if (qdf_is_macaddr_zero(mac_addr)) {
1147 hdd_err("MAC is all zero (via %s)", func);
1148 return QDF_STATUS_E_INVAL;
1149 }
1150
1151 if (qdf_is_macaddr_broadcast(mac_addr)) {
1152 hdd_err("MAC is Broadcast (via %s)", func);
1153 return QDF_STATUS_E_INVAL;
1154 }
1155
1156 if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) {
1157 hdd_err("MAC is Multicast (via %s)", func);
1158 return QDF_STATUS_E_INVAL;
1159 }
1160
1161 return QDF_STATUS_SUCCESS;
1162}
1163
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001164/**
Arun Khandavallica892f62017-05-26 14:25:50 +05301165 * wlan_hdd_validate_modules_state() - Check modules status
1166 * @hdd_ctx: HDD context pointer
1167 *
1168 * Check's the driver module's state and returns true if the
1169 * modules are enabled returns false if modules are closed.
1170 *
1171 * Return: True if modules are enabled or false.
1172 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001173bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx)
Arun Khandavallica892f62017-05-26 14:25:50 +05301174{
1175 mutex_lock(&hdd_ctx->iface_change_lock);
1176 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
1177 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown5e89ef82018-03-14 11:50:23 -07001178 hdd_info("Modules not enabled, Present status: %d",
1179 hdd_ctx->driver_status);
Arun Khandavallica892f62017-05-26 14:25:50 +05301180 return false;
1181 }
1182 mutex_unlock(&hdd_ctx->iface_change_lock);
1183 return true;
1184}
1185
1186/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001187 * hdd_set_ibss_power_save_params() - update IBSS Power Save params to WMA.
Jeff Johnson9d295242017-08-29 14:39:48 -07001188 * @struct hdd_adapter Hdd adapter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001189 *
1190 * This function sets the IBSS power save config parameters to WMA
1191 * which will send it to firmware if FW supports IBSS power save
1192 * before vdev start.
1193 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301194 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001195 * on failure.
1196 */
Jeff Johnson9d295242017-08-29 14:39:48 -07001197QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001198{
1199 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001200 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001201
1202 if (hdd_ctx == NULL) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001203 hdd_err("HDD context is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301204 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001205 }
1206
Jeff Johnson1b780e42017-10-31 14:11:45 -07001207 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001208 WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE,
1209 hdd_ctx->config->ibssATIMWinSize,
1210 VDEV_CMD);
1211 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001212 hdd_err("atim window set failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301213 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001214 }
1215
Jeff Johnson1b780e42017-10-31 14:11:45 -07001216 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001217 WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED,
1218 hdd_ctx->config->isIbssPowerSaveAllowed,
1219 VDEV_CMD);
1220 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001221 hdd_err("power save allow failed %d",
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001222 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301223 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001224 }
1225
Jeff Johnson1b780e42017-10-31 14:11:45 -07001226 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001227 WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED,
1228 hdd_ctx->config->
1229 isIbssPowerCollapseAllowed, VDEV_CMD);
1230 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001231 hdd_err("power collapse allow failed %d",
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001232 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301233 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001234 }
1235
Jeff Johnson1b780e42017-10-31 14:11:45 -07001236 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001237 WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX,
1238 hdd_ctx->config->isIbssAwakeOnTxRx,
1239 VDEV_CMD);
1240 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001241 hdd_err("set awake on tx/rx failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301242 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001243 }
1244
Jeff Johnson1b780e42017-10-31 14:11:45 -07001245 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001246 WMA_VDEV_IBSS_SET_INACTIVITY_TIME,
1247 hdd_ctx->config->ibssInactivityCount,
1248 VDEV_CMD);
1249 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001250 hdd_err("set inactivity time failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301251 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001252 }
1253
Jeff Johnson1b780e42017-10-31 14:11:45 -07001254 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001255 WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME,
1256 hdd_ctx->config->ibssTxSpEndInactivityTime,
1257 VDEV_CMD);
1258 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001259 hdd_err("set txsp end failed %d",
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001260 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301261 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001262 }
1263
Jeff Johnson1b780e42017-10-31 14:11:45 -07001264 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001265 WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS,
1266 hdd_ctx->config->ibssPsWarmupTime,
1267 VDEV_CMD);
1268 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001269 hdd_err("set ps warmup failed %d",
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001270 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301271 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001272 }
1273
Jeff Johnson1b780e42017-10-31 14:11:45 -07001274 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001275 WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW,
1276 hdd_ctx->config->ibssPs1RxChainInAtimEnable,
1277 VDEV_CMD);
1278 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001279 hdd_err("set 1rx chain atim failed %d",
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001280 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301281 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001282 }
1283
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301284 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001285}
1286
Yue Macd359b72017-10-03 15:21:00 -07001287#ifdef FEATURE_RUNTIME_PM
1288/**
1289 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
1290 * @hdd_ctx: HDD context
1291 *
1292 * Return: None
1293 */
1294static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
1295{
1296 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1297
Yue Macd359b72017-10-03 15:21:00 -07001298 qdf_runtime_lock_init(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001299 qdf_runtime_lock_init(&ctx->connect);
Yue Macd359b72017-10-03 15:21:00 -07001300
Dustin Brown07901ec2018-09-07 11:02:41 -07001301 wlan_scan_runtime_pm_init(hdd_ctx->pdev);
Yue Macd359b72017-10-03 15:21:00 -07001302}
1303
1304/**
1305 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
1306 * @hdd_ctx: HDD Context
1307 *
1308 * Return: None
1309 */
1310static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
1311{
1312 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1313
Yue Macd359b72017-10-03 15:21:00 -07001314 qdf_runtime_lock_deinit(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001315 qdf_runtime_lock_deinit(&ctx->connect);
Yue Macd359b72017-10-03 15:21:00 -07001316
Dustin Brown07901ec2018-09-07 11:02:41 -07001317 wlan_scan_runtime_pm_deinit(hdd_ctx->pdev);
Yue Macd359b72017-10-03 15:21:00 -07001318}
1319
Yue Macd359b72017-10-03 15:21:00 -07001320#else /* FEATURE_RUNTIME_PM */
1321static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {}
1322static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {}
Yue Macd359b72017-10-03 15:21:00 -07001323#endif /* FEATURE_RUNTIME_PM */
1324
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325#define INTF_MACADDR_MASK 0x7
1326
1327/**
1328 * hdd_update_macaddr() - update mac address
1329 * @config: hdd configuration
1330 * @hw_macaddr: mac address
1331 *
1332 * Mac address for multiple virtual interface is found as following
1333 * i) The mac address of the first interface is just the actual hw mac address.
1334 * ii) MSM 3 or 4 bits of byte5 of the actual mac address are used to
1335 * define the mac address for the remaining interfaces and locally
1336 * admistered bit is set. INTF_MACADDR_MASK is based on the number of
1337 * supported virtual interfaces, right now this is 0x07 (meaning 8
1338 * interface).
1339 * Byte[3] of second interface will be hw_macaddr[3](bit5..7) + 1,
1340 * for third interface it will be hw_macaddr[3](bit5..7) + 2, etc.
1341 *
1342 * Return: None
1343 */
1344void hdd_update_macaddr(struct hdd_config *config,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301345 struct qdf_mac_addr hw_macaddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001346{
1347 int8_t i;
1348 uint8_t macaddr_b3, tmp_br3;
1349
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301350 qdf_mem_copy(config->intfMacAddr[0].bytes, hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301351 QDF_MAC_ADDR_SIZE);
1352 for (i = 1; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301353 qdf_mem_copy(config->intfMacAddr[i].bytes, hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301354 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001355 macaddr_b3 = config->intfMacAddr[i].bytes[3];
1356 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
1357 INTF_MACADDR_MASK;
1358 macaddr_b3 += tmp_br3;
1359
1360 /* XOR-ing bit-24 of the mac address. This will give enough
1361 * mac address range before collision
1362 */
1363 macaddr_b3 ^= (1 << 7);
1364
1365 /* Set locally administered bit */
1366 config->intfMacAddr[i].bytes[0] |= 0x02;
1367 config->intfMacAddr[i].bytes[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001368 hdd_debug("config->intfMacAddr[%d]: "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001369 MAC_ADDRESS_STR, i,
1370 MAC_ADDR_ARRAY(config->intfMacAddr[i].bytes));
1371 }
1372}
1373
Kabilan Kannan44a58372017-12-06 18:16:11 -08001374static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1375{
Dustin Brown1dbefe62018-09-11 16:32:03 -07001376 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001377 struct tdls_start_params tdls_cfg;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001378 QDF_STATUS status;
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301379 struct wlan_mlme_nss_chains vdev_ini_cfg;
1380
1381 /* Populate the nss chain params from ini for this vdev type */
1382 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
1383 QDF_TDLS_MODE,
1384 hdd_ctx->num_rf_chains);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001385
Dustin Brown1dbefe62018-09-11 16:32:03 -07001386 cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301387 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]);
Dustin Brown1dbefe62018-09-11 16:32:03 -07001388 cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301389 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]);
jiad7b8a5e02018-11-26 16:37:57 +08001390 hdd_init_tdls_config(&tdls_cfg);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001391 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
1392 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
1393 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
1394 tdls_cfg.tdls_evt_cb_data = psoc;
Jeff Johnson1d40f5b2018-03-02 08:35:53 -08001395 tdls_cfg.tdls_peer_context = hdd_ctx;
1396 tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer;
1397 tdls_cfg.tdls_dereg_peer = hdd_tdls_deregister_peer;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001398 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
1399 tdls_cfg.tdls_wmm_cb_data = psoc;
1400 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
1401 tdls_cfg.tdls_rx_cb_data = psoc;
1402 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
1403
1404 status = ucfg_tdls_update_config(psoc, &tdls_cfg);
1405 if (status != QDF_STATUS_SUCCESS) {
1406 hdd_err("failed pmo psoc configuration");
1407 return -EINVAL;
1408 }
1409
1410 hdd_ctx->tdls_umac_comp_active = true;
1411 /* enable napier specific tdls data path */
1412 hdd_ctx->tdls_nap_active = true;
1413
1414 return 0;
1415}
1416
Wu Gaoca416ff2018-09-17 11:05:07 +08001417#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1418static void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1419 struct wma_tgt_services *cfg)
1420{
1421 bool roam_offload_enable;
1422
Dustin Brown1dbefe62018-09-11 16:32:03 -07001423 ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable);
1424 ucfg_mlme_set_roaming_offload(hdd_ctx->psoc,
Wu Gaoca416ff2018-09-17 11:05:07 +08001425 roam_offload_enable &
1426 cfg->en_roam_offload);
1427}
1428#else
1429static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1430 struct wma_tgt_services *cfg)
1431{
1432}
1433#endif
1434
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001435static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001436 struct wma_tgt_services *cfg)
1437{
1438 struct hdd_config *config = hdd_ctx->config;
Wu Gao66454f12018-09-26 19:55:41 +08001439 bool arp_offload_enable;
Wu Gao1ab05582018-11-08 16:22:49 +08001440 bool mawc_enabled;
Wu Gaobdb7f272018-07-05 19:33:26 +08001441#ifdef FEATURE_WLAN_TDLS
1442 bool tdls_support;
1443 bool tdls_off_channel;
1444 bool tdls_buffer_sta;
1445 uint32_t tdls_uapsd_mask;
1446#endif
jiad7b8a5e02018-11-26 16:37:57 +08001447 bool value;
1448
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001449 /* Set up UAPSD */
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05301450 ucfg_mlme_set_sap_uapsd_flag(hdd_ctx->psoc, cfg->uapsd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001451
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08001452 /* 11AX mode support */
1453 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
1454 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
1455 config->dot11Mode = eHDD_DOT11_MODE_11ac;
1456
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001457 /* 11AC mode support */
1458 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
1459 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
1460 config->dot11Mode = eHDD_DOT11_MODE_AUTO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001461
1462 /* ARP offload: override user setting if invalid */
Wu Gao66454f12018-09-26 19:55:41 +08001463 arp_offload_enable =
1464 ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc);
1465 ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc,
1466 arp_offload_enable & cfg->arp_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001467#ifdef FEATURE_WLAN_SCAN_PNO
1468 /* PNO offload */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001469 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001470 if (cfg->pno_offload)
1471 config->PnoOffload = true;
1472#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001473#ifdef FEATURE_WLAN_TDLS
Dustin Brown1dbefe62018-09-11 16:32:03 -07001474 cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support);
1475 cfg_tdls_set_support_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001476 tdls_support & cfg->en_tdls);
1477
Dustin Brown1dbefe62018-09-11 16:32:03 -07001478 cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel);
1479 cfg_tdls_set_off_channel_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001480 tdls_off_channel &&
1481 cfg->en_tdls_offchan);
1482
Dustin Brown1dbefe62018-09-11 16:32:03 -07001483 cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta);
1484 cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001485 tdls_buffer_sta &&
1486 cfg->en_tdls_uapsd_buf_sta);
1487
Dustin Brown1dbefe62018-09-11 16:32:03 -07001488 cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask);
Wu Gaobdb7f272018-07-05 19:33:26 +08001489 if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta)
Dustin Brown1dbefe62018-09-11 16:32:03 -07001490 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001491 else
Dustin Brown1dbefe62018-09-11 16:32:03 -07001492 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001493#endif
Wu Gaoca416ff2018-09-17 11:05:07 +08001494 hdd_update_roam_offload(hdd_ctx, cfg);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05301495
Dustin Brown05d81302018-09-11 16:49:22 -07001496 if (ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value) ==
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05301497 QDF_STATUS_SUCCESS)
1498 value &= cfg->get_peer_info_enabled;
1499
Wu Gao1ab05582018-11-08 16:22:49 +08001500 ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled);
1501 ucfg_mlme_set_mawc_enabled(hdd_ctx->psoc,
1502 mawc_enabled & cfg->is_fw_mawc_capable);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001503 hdd_update_tdls_config(hdd_ctx);
Jeff Johnson16528362018-06-14 12:34:16 -07001504 sme_update_tgt_services(hdd_ctx->mac_handle, cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001505}
1506
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001507/**
1508 * hdd_update_vdev_nss() - sets the vdev nss
1509 * @hdd_ctx: HDD context
1510 *
1511 * Sets the Nss per vdev type based on INI
1512 *
1513 * Return: None
1514 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001515static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx)
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001516{
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001517 uint8_t max_supp_nss = 1;
Jeff Johnson16528362018-06-14 12:34:16 -07001518 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301519 QDF_STATUS status;
1520 bool bval;
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001521
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301522 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
1523 if (!QDF_IS_STATUS_SUCCESS(status))
1524 hdd_err("unable to get vht_enable2x2");
1525
1526 if (bval && !cds_is_sub_20_mhz_enabled())
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001527 max_supp_nss = 2;
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301528
1529 hdd_debug("max nss %d", max_supp_nss);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001530
Jeff Johnson16528362018-06-14 12:34:16 -07001531 mac_handle = hdd_ctx->mac_handle;
1532 sme_update_vdev_type_nss(mac_handle, max_supp_nss,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301533 NSS_CHAINS_BAND_2GHZ);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001534
Jeff Johnson16528362018-06-14 12:34:16 -07001535 sme_update_vdev_type_nss(mac_handle, max_supp_nss,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301536 NSS_CHAINS_BAND_5GHZ);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001537}
1538
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301539/**
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301540 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
1541 * @hdd_ctx: HDD context
1542 *
1543 * Updates wiphy vhtcap fields
1544 *
1545 * Return: None
1546 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001547static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx)
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301548{
1549 struct ieee80211_supported_band *band_5g =
1550 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301551 QDF_STATUS status;
1552 uint8_t value = 0, value1 = 0;
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301553
1554 if (!band_5g) {
1555 hdd_debug("5GHz band disabled, skipping capability population");
1556 return;
1557 }
1558
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301559 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
1560 &value);
1561 if (!QDF_IS_STATUS_SUCCESS(status))
1562 hdd_err("unable to get tx_bfee_ant_supp");
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301563
Abhinav Kumare057b412018-10-09 17:28:16 +05301564 band_5g->vht_cap.cap |=
1565 (value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301566
1567 value1 = NUM_OF_SOUNDING_DIMENSIONS;
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301568 band_5g->vht_cap.cap |=
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301569 (value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301570
Dustin Brown7e761c72018-07-31 13:50:17 -07001571 hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301572 band_5g->vht_cap.cap, value, value1);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301573}
1574
1575/**
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301576 * hdd_update_hw_dbs_capable() - sets the dbs capability of the device
1577 * @hdd_ctx: HDD context
1578 *
1579 * Sets the DBS capability as per INI and firmware capability
1580 *
1581 * Return: None
1582 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001583static void hdd_update_hw_dbs_capable(struct hdd_context *hdd_ctx)
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301584{
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301585 uint8_t hw_dbs_capable = 0;
Krunal Sonidf29bc42018-11-15 13:26:29 -08001586 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
1587 QDF_STATUS status;
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301588
Krunal Sonidf29bc42018-11-15 13:26:29 -08001589 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
1590 &dual_mac_feature);
1591 if (status != QDF_STATUS_SUCCESS)
1592 hdd_err("can't get dual_mac_feature value");
1593 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) {
1594 switch (dual_mac_feature) {
1595 case ENABLE_DBS_CXN_AND_SCAN:
1596 case ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF:
1597 case ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN:
1598 hw_dbs_capable = 1;
1599 break;
1600 default:
1601 hw_dbs_capable = 0;
1602 break;
1603 }
1604 }
Jeff Johnson16528362018-06-14 12:34:16 -07001605 sme_update_hw_dbs_capable(hdd_ctx->mac_handle, hw_dbs_capable);
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301606}
1607
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001608static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001609 struct wma_tgt_ht_cap *cfg)
1610{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301611 QDF_STATUS status;
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301612 qdf_size_t value_len;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301613 uint32_t value;
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301614 uint8_t mpdu_density;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301615 struct mlme_ht_capabilities_info ht_cap_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001616 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301617 bool b_enable1x1;
Jeff Johnson16528362018-06-14 12:34:16 -07001618
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001619 /* get the MPDU density */
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301620 status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density);
1621 if (QDF_IS_STATUS_ERROR(status)) {
1622 hdd_err("could not get HT MPDU Density");
1623 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001624 }
1625
1626 /*
1627 * MPDU density:
1628 * override user's setting if value is larger
1629 * than the one supported by target
1630 */
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301631 if (mpdu_density > cfg->mpdu_density) {
1632 status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc,
1633 cfg->mpdu_density);
1634 if (QDF_IS_STATUS_ERROR(status))
1635 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001636 }
1637
1638 /* get the HT capability info */
Dustin Brown1dbefe62018-09-11 16:32:03 -07001639 status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301640 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001641 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001642 return;
1643 }
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301644
1645 /* check and update RX STBC */
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301646 if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc)
1647 ht_cap_info.rx_stbc = cfg->ht_rx_stbc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001648
1649 /* Set the LDPC capability */
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301650 ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001651
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301652 if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20)
1653 ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001654
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301655 if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40)
1656 ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001657
1658 hdd_ctx->num_rf_chains = cfg->num_rf_chains;
1659 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
1660
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301661 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1);
1662 if (!QDF_IS_STATUS_SUCCESS(status))
1663 hdd_err("unable to get vht_enable2x2");
1664
1665 b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2);
1666
1667 status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1);
1668 if (!QDF_IS_STATUS_SUCCESS(status))
1669 hdd_err("unable to set vht_enable2x2");
1670
Abhinav Kumare057b412018-10-09 17:28:16 +05301671 if (!b_enable1x1) {
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301672 ht_cap_info.tx_stbc = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001673
1674 /* 1x1 */
1675 /* Update Rx Highest Long GI data Rate */
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301676 status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(
1677 hdd_ctx->psoc,
1678 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1);
1679 if (!QDF_IS_STATUS_SUCCESS(status))
1680 hdd_err("Failed to set rx_supp_data_rate");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001681 /* Update Tx Highest Long GI data Rate */
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301682 status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(
1683 hdd_ctx->psoc,
1684 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1);
1685 if (!QDF_IS_STATUS_SUCCESS(status))
1686 hdd_err("Failed to set tx_supp_data_rate");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001687 }
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301688 if (!(cfg->ht_tx_stbc && b_enable1x1))
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301689 ht_cap_info.tx_stbc = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001690
Dustin Brown1dbefe62018-09-11 16:32:03 -07001691 status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301692 if (status != QDF_STATUS_SUCCESS)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001693 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001694#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301695 value_len = SIZE_OF_SUPPORTED_MCS_SET;
1696 if (ucfg_mlme_get_supported_mcs_set(
1697 hdd_ctx->psoc, mcs_set,
1698 &value_len) == QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001699 hdd_debug("Read MCS rate set");
gaurank kathpalia18b49362018-04-15 23:12:03 +05301700 if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET)
1701 cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301702
1703 if (b_enable1x1) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001704 for (value = 0; value < cfg->num_rf_chains; value++)
1705 mcs_set[value] =
1706 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
1707
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301708 status = ucfg_mlme_set_supported_mcs_set(
1709 hdd_ctx->psoc,
1710 mcs_set,
1711 (qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET);
1712 if (QDF_IS_STATUS_ERROR(status))
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001713 hdd_err("could not set MCS SET to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001714 }
1715 }
1716#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
1717}
1718
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001719static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001720 struct wma_tgt_vht_cap *cfg)
1721{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301722 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001723 struct wiphy *wiphy = hdd_ctx->wiphy;
1724 struct ieee80211_supported_band *band_5g =
Srinivas Girigowda11c28e02017-06-27 20:06:21 -07001725 wiphy->bands[HDD_NL80211_BAND_5GHZ];
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001726 uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ;
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001727 struct wma_caps_per_phy caps_per_phy;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301728 uint8_t val = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001729
Dustin Brown5e06bd32016-10-04 12:49:10 -07001730 if (!band_5g) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001731 hdd_debug("5GHz band disabled, skipping capability population");
Dustin Brown5e06bd32016-10-04 12:49:10 -07001732 return;
1733 }
1734
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301735 status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg);
1736 if (QDF_IS_STATUS_ERROR(status))
1737 hdd_err("could not update vht capabilities");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001738
1739 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
1740 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1741 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
1742 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1743 else
1744 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1745
1746
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001747 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
Abhinav Kumare057b412018-10-09 17:28:16 +05301748 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc,
1749 VHT_CAP_160_AND_80P80_SUPP);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301750 if (QDF_IS_STATUS_ERROR(status))
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001751 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001752 band_5g->vht_cap.cap |=
1753 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001754 ch_width = eHT_CHANNEL_WIDTH_80P80MHZ;
1755 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
Abhinav Kumare057b412018-10-09 17:28:16 +05301756 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc,
1757 VHT_CAP_160_SUPP);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301758 if (QDF_IS_STATUS_ERROR(status))
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001759 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001760 band_5g->vht_cap.cap |=
1761 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001762 ch_width = eHT_CHANNEL_WIDTH_160MHZ;
1763 }
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001764
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301765 status =
1766 ucfg_mlme_cfg_get_vht_chan_width(hdd_ctx->psoc, &val);
1767 if (QDF_IS_STATUS_ERROR(status))
1768 hdd_err("could not get channel_width");
1769
1770 val = QDF_MIN(val, ch_width);
Abhinav Kumare057b412018-10-09 17:28:16 +05301771 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, val);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301772 if (QDF_IS_STATUS_ERROR(status))
1773 hdd_err("could not set the channel width");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001774
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001775 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001776 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001777 hdd_debug("VHT RxLDPC capability is set");
1778 } else {
1779 /*
1780 * Get the RX LDPC capability for the NON DBS
1781 * hardware mode for 5G band
1782 */
1783 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
1784 HW_MODE_DBS_NONE, CDS_BAND_5GHZ);
1785 if ((QDF_IS_STATUS_SUCCESS(status)) &&
1786 (caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) {
1787 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
1788 hdd_debug("VHT RX LDPC capability is set");
1789 }
1790 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001791
1792 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
1793 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1794 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
1795 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1796
1797 if (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)
1798 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
1799
1800 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
1801 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1802 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)
1803 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
1804 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
1805 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
1806
1807 band_5g->vht_cap.cap |=
1808 (cfg->vht_max_ampdu_len_exp <<
1809 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
1810
1811 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
1812 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1813 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
1814 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1815 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
1816 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1817 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
1818 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1819
1820 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
1821 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1822
1823}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001824
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001825/**
1826 * hdd_generate_macaddr_auto() - Auto-generate mac address
1827 * @hdd_ctx: Pointer to the HDD context
1828 *
1829 * Auto-generate mac address using device serial number.
1830 * Keep the first 3 bytes of OUI as before and replace
1831 * the last 3 bytes with the lower 3 bytes of serial number.
1832 *
1833 * Return: 0 for success
1834 * Non zero failure code for errors
1835 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001836static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx)
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001837{
1838 unsigned int serialno = 0;
1839 struct qdf_mac_addr mac_addr = {
1840 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
1841 };
1842
Yuanyuan Liuf97e8222016-09-21 10:31:38 -07001843 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001844 if (serialno == 0)
1845 return -EINVAL;
1846
1847 serialno &= 0x00ffffff;
1848
1849 mac_addr.bytes[3] = (serialno >> 16) & 0xff;
1850 mac_addr.bytes[4] = (serialno >> 8) & 0xff;
1851 mac_addr.bytes[5] = serialno & 0xff;
1852
1853 hdd_update_macaddr(hdd_ctx->config, mac_addr);
1854 return 0;
1855}
1856
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301857/**
1858 * hdd_update_ra_rate_limit() - Update RA rate limit from target
1859 * configuration to cfg_ini in HDD
1860 * @hdd_ctx: Pointer to hdd_ctx
1861 * @cfg: target configuration
1862 *
1863 * Return: None
1864 */
1865#ifdef FEATURE_WLAN_RA_FILTERING
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001866static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301867 struct wma_tgt_cfg *cfg)
1868{
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05301869 ucfg_fwol_set_is_rate_limit_enabled(hdd_ctx->psoc,
1870 cfg->is_ra_rate_limit_enabled);
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301871}
1872#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001873static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301874 struct wma_tgt_cfg *cfg)
1875{
1876}
1877#endif
1878
Jeff Johnsonf9176382018-07-17 19:15:58 -07001879static void hdd_sar_target_config(struct hdd_context *hdd_ctx,
1880 struct wma_tgt_cfg *cfg)
1881{
1882 hdd_ctx->sar_version = cfg->sar_version;
1883}
1884
Jeff Johnson8abc5932018-06-02 22:51:37 -07001885void hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001886{
Rajeev Kumarf49dfdb2017-01-13 15:40:35 -08001887 int ret;
Jeff Johnsonea70b942018-07-02 09:42:31 -07001888 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301889 uint8_t temp_band_cap, band_capability;
Naveen Rawat64e477e2016-05-20 10:34:56 -07001890 struct cds_config_info *cds_cfg = cds_get_ini_config();
Nitesh Shahe50711f2017-04-26 16:30:45 +05301891 uint8_t antenna_mode;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301892 uint8_t sub_20_chan_width;
Arif Hussainee10f902017-12-27 16:30:17 -08001893 QDF_STATUS status;
Jeff Johnson16528362018-06-14 12:34:16 -07001894 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301895 bool bval = false;
1896 uint8_t value = 0;
Arif Hussainbd5194c2018-11-27 19:01:15 -08001897 uint32_t fine_time_meas_cap = 0;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301898
gaurank kathpalia843f7c32018-07-02 18:04:14 +05301899 if (!hdd_ctx) {
1900 hdd_err("HDD context is NULL");
1901 return;
1902 }
Dustin Brownbd68fe12017-11-21 15:28:52 -08001903 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
1904 if (ret) {
Dustin Brown64204d22018-08-15 16:35:19 -07001905 QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret);
1906 return;
1907 }
1908
1909 hdd_debug("New pdev has been created with pdev_id = %u",
Dustin Brown07901ec2018-09-07 11:02:41 -07001910 hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id);
Dustin Brown64204d22018-08-15 16:35:19 -07001911
Dustin Brown07901ec2018-09-07 11:02:41 -07001912 status = dispatcher_pdev_open(hdd_ctx->pdev);
Dustin Brown64204d22018-08-15 16:35:19 -07001913 if (QDF_IS_STATUS_ERROR(status)) {
1914 QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d",
1915 status);
1916 return;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301917 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001918
Sandeep Puligillab7beb472018-08-13 22:54:20 -07001919 status = hdd_component_pdev_open(hdd_ctx->pdev);
1920 if (QDF_IS_STATUS_ERROR(status)) {
1921 QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d",
1922 status);
1923 return;
1924 }
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05301925 cdp_pdev_set_ctrl_pdev(cds_get_context(QDF_MODULE_ID_SOC),
1926 cds_get_context(QDF_MODULE_ID_TXRX),
Dustin Brown07901ec2018-09-07 11:02:41 -07001927 (struct cdp_ctrl_objmgr_pdev *)hdd_ctx->pdev);
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05301928
Dustin Brown07901ec2018-09-07 11:02:41 -07001929 wlan_pdev_set_dp_handle(hdd_ctx->pdev,
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05301930 cds_get_context(QDF_MODULE_ID_TXRX));
1931
Will Huang07244172018-05-14 14:23:30 +08001932 hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count);
1933
Dustin Brown1dbefe62018-09-11 16:32:03 -07001934 ucfg_ipa_set_dp_handle(hdd_ctx->psoc,
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05301935 cds_get_context(QDF_MODULE_ID_SOC));
Dustin Brown1dbefe62018-09-11 16:32:03 -07001936 ucfg_ipa_set_txrx_handle(hdd_ctx->psoc,
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05301937 cds_get_context(QDF_MODULE_ID_TXRX));
Dustin Brown07901ec2018-09-07 11:02:41 -07001938 ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev,
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05301939 hdd_softap_hard_start_xmit);
Dustin Brown07901ec2018-09-07 11:02:41 -07001940 ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev,
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05301941 hdd_ipa_send_skb_to_network);
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05301942
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301943 status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
1944 &sub_20_chan_width);
1945 if (QDF_IS_STATUS_ERROR(status)) {
1946 hdd_err("Failed to get sub_20_chan_width config");
1947 return;
1948 }
1949
Naveen Rawat64e477e2016-05-20 10:34:56 -07001950 if (cds_cfg) {
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301951 if (sub_20_chan_width !=
1952 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
Naveen Rawat64e477e2016-05-20 10:34:56 -07001953 hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
1954 cds_cfg->sub_20_channel_width =
1955 WLAN_SUB_20_CH_WIDTH_NONE;
1956 } else {
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301957 cds_cfg->sub_20_channel_width = sub_20_chan_width;
Naveen Rawat64e477e2016-05-20 10:34:56 -07001958 }
1959 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001960
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301961 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
1962 if (QDF_IS_STATUS_ERROR(status)) {
1963 hdd_err("Failed to get MLME band capability");
1964 return;
1965 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001966
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301967 /* first store the INI band capability */
1968 temp_band_cap = band_capability;
1969
1970 band_capability = cfg->band_cap;
Vignesh Viswanathan731186f2017-09-18 13:47:37 +05301971 hdd_ctx->is_fils_roaming_supported =
1972 cfg->services.is_fils_roaming_supported;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001973
Vignesh Viswanathan694e28e2018-01-18 20:53:57 +05301974 hdd_ctx->config->is_11k_offload_supported =
1975 cfg->services.is_11k_offload_supported;
1976
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08001977 /*
1978 * now overwrite the target band capability with INI
1979 * setting if INI setting is a subset
1980 */
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301981 if ((band_capability == BAND_ALL) &&
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001982 (temp_band_cap != BAND_ALL))
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301983 band_capability = temp_band_cap;
1984 else if ((band_capability != BAND_ALL) &&
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001985 (temp_band_cap != BAND_ALL) &&
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301986 (band_capability != temp_band_cap)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001987 hdd_warn("ini BandCapability not supported by the target");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001988 }
1989
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301990 status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability);
1991 if (QDF_IS_STATUS_ERROR(status)) {
1992 hdd_err("Failed to set MLME Band Capability");
1993 return;
1994 }
1995
1996 hdd_ctx->curr_band = band_capability;
Amar Singhal58b45ef2017-08-01 13:43:54 -07001997
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301998 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001999 hdd_ctx->reg.reg_domain = cfg->reg_domain;
2000 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
2001 }
2002
2003 /* This can be extended to other configurations like ht, vht cap... */
2004
Anurag Chouhanc5548422016-02-24 18:33:27 +05302005 if (!qdf_is_macaddr_zero(&cfg->hw_macaddr)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002006 hdd_update_macaddr(hdd_ctx->config, cfg->hw_macaddr);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07002007 hdd_ctx->update_mac_addr_to_fw = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002008 } else {
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07002009 static struct qdf_mac_addr default_mac_addr = {
2010 {0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}
2011 };
2012 if (qdf_is_macaddr_equal(&hdd_ctx->config->intfMacAddr[0],
2013 &default_mac_addr)) {
2014 if (hdd_generate_macaddr_auto(hdd_ctx) != 0)
2015 hdd_err("Fail to auto-generate MAC, using MAC from ini file "
2016 MAC_ADDRESS_STR,
2017 MAC_ADDR_ARRAY(hdd_ctx->config->
2018 intfMacAddr[0].bytes));
2019 } else {
2020 hdd_err("Invalid MAC passed from target, using MAC from ini file "
2021 MAC_ADDRESS_STR,
2022 MAC_ADDR_ARRAY(hdd_ctx->config->
2023 intfMacAddr[0].bytes));
2024 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07002025 hdd_ctx->update_mac_addr_to_fw = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002026 }
2027
2028 hdd_ctx->target_fw_version = cfg->target_fw_version;
Sandeep Puligilla3d6a8e22016-10-11 18:57:14 -07002029 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002030
Ryan Hsuc6918552018-05-16 13:29:59 -07002031 hdd_ctx->hw_bd_id = cfg->hw_bd_id;
2032 qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info,
2033 sizeof(cfg->hw_bd_info));
2034
Dustin Brownbee82832018-07-23 10:10:51 -07002035 if (cfg->max_intf_count > CSR_ROAM_SESSION_MAX) {
2036 hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u",
2037 cfg->max_intf_count, CSR_ROAM_SESSION_MAX,
2038 CSR_ROAM_SESSION_MAX);
2039 hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
2040 } else {
2041 hdd_ctx->max_intf_count = cfg->max_intf_count;
2042 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002043
Jeff Johnsonf9176382018-07-17 19:15:58 -07002044 hdd_sar_target_config(hdd_ctx, cfg);
Jeff Johnsonc875e242016-09-23 18:12:34 -07002045 hdd_lpass_target_config(hdd_ctx, cfg);
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08002046
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002047 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
2048 hdd_update_tgt_services(hdd_ctx, &cfg->services);
2049
2050 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
2051
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002052 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
Krishna Kumaar Natarajaned1efd92016-09-24 18:05:47 -07002053 if (cfg->services.en_11ax) {
2054 hdd_info("11AX: 11ax is enabled - update HDD config");
2055 hdd_update_tgt_he_cap(hdd_ctx, cfg);
2056 }
Varun Reddy Yeturue93d2462018-05-22 13:54:52 -07002057 hdd_update_tgt_twt_cap(hdd_ctx, cfg);
Tushnim Bhattacharyyaf44a9d82016-07-05 10:52:06 -07002058
2059 hdd_update_vdev_nss(hdd_ctx);
2060
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05302061 hdd_update_hw_dbs_capable(hdd_ctx);
gaurank kathpalia5fcefa92018-10-24 15:03:15 +05302062 hdd_ctx->dynamic_nss_chains_support =
2063 cfg->dynamic_nss_chains_support;
Arif Hussainbd5194c2018-11-27 19:01:15 -08002064 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap);
2065 fine_time_meas_cap &= cfg->fine_time_measurement_cap;
2066 status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc,
2067 fine_time_meas_cap);
2068 if (QDF_IS_STATUS_ERROR(status)) {
2069 hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x",
2070 fine_time_meas_cap, cfg->fine_time_measurement_cap);
2071 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
2072 &fine_time_meas_cap);
2073 }
2074
Krunal Sonie3531942016-04-12 17:43:53 -07002075 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
Arif Hussainbd5194c2018-11-27 19:01:15 -08002076 hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap);
Archana Ramachandran393f3792015-11-13 17:13:21 -08002077
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302078 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
2079 if (!QDF_IS_STATUS_SUCCESS(status))
2080 hdd_err("unable to get vht_enable2x2");
2081
2082 antenna_mode = (bval == 0x01) ?
Nitesh Shahe50711f2017-04-26 16:30:45 +05302083 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
2084 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002085 hdd_debug("Init current antenna mode: %d",
Arif Hussainee10f902017-12-27 16:30:17 -08002086 hdd_ctx->current_antenna_mode);
Archana Ramachandran393f3792015-11-13 17:13:21 -08002087
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05302088 hdd_ctx->rcpi_enabled = cfg->rcpi_enabled;
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05302089 hdd_update_ra_rate_limit(hdd_ctx, cfg);
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05302090
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302091 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
Abhinav Kumare057b412018-10-09 17:28:16 +05302092 &value);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302093 if (QDF_IS_STATUS_ERROR(status)) {
2094 status = false;
2095 hdd_err("set tx_bfee_ant_supp failed");
2096 }
2097
2098 if ((value >
Arif Hussainee10f902017-12-27 16:30:17 -08002099 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302100 !cfg->tx_bfee_8ss_enabled) {
2101 status =
2102 ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
2103 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF);
2104 if (QDF_IS_STATUS_ERROR(status)) {
2105 status = false;
2106 hdd_err("set tx_bfee_ant_supp failed");
2107 }
2108 }
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302109
Jeff Johnson16528362018-06-14 12:34:16 -07002110 mac_handle = hdd_ctx->mac_handle;
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302111
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302112 hdd_debug("txBFCsnValue %d", value);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05302113
2114 /*
2115 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
2116 */
2117 hdd_update_wiphy_vhtcap(hdd_ctx);
Manjeet Singh70d3d932016-12-20 20:41:10 +05302118
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05302119 hdd_ctx->wmi_max_len = cfg->wmi_max_len;
2120
Yue Macd359b72017-10-03 15:21:00 -07002121 /*
2122 * This needs to be done after HDD pdev is created and stored since
2123 * it will access the HDD pdev object lock.
2124 */
2125 hdd_runtime_suspend_context_init(hdd_ctx);
2126
Deepak Dhamdhere13230d32016-05-26 00:46:53 -07002127 /* Configure NAN datapath features */
2128 hdd_nan_datapath_target_config(hdd_ctx, cfg);
Arif Hussain759a0232017-03-20 13:17:18 -07002129 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08002130 hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share;
Liangwei Dong0da14262018-07-03 03:30:23 -04002131 hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload;
Jeff Johnson16528362018-06-14 12:34:16 -07002132 status = sme_cfg_set_int(mac_handle, WNI_CFG_OBSS_DETECTION_OFFLOAD,
Arif Hussainee10f902017-12-27 16:30:17 -08002133 cfg->obss_detection_offloaded);
2134 if (QDF_IS_STATUS_ERROR(status))
2135 hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG");
Arif Hussain05fb4872018-01-03 16:02:55 -08002136
Jeff Johnson16528362018-06-14 12:34:16 -07002137 status = sme_cfg_set_int(mac_handle,
Arif Hussain05fb4872018-01-03 16:02:55 -08002138 WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD,
2139 cfg->obss_color_collision_offloaded);
2140 if (QDF_IS_STATUS_ERROR(status))
2141 hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002142}
2143
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002144bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002145{
Jeff Johnson9d295242017-08-29 14:39:48 -07002146 struct hdd_adapter *adapter;
Jeff Johnson87251032017-08-29 13:31:11 -07002147 struct hdd_ap_ctx *ap_ctx;
Arif Hussain224d3812018-11-16 17:58:38 -08002148 bool dfs_disable_channel_switch = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002149
Jiachao Wuf610d912018-01-23 17:47:32 +08002150 if (!hdd_ctx) {
2151 hdd_info("Couldn't get hdd_ctx");
2152 return true;
2153 }
2154
Arif Hussain224d3812018-11-16 17:58:38 -08002155 ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc,
2156 &dfs_disable_channel_switch);
2157 if (dfs_disable_channel_switch) {
Jeff Johnson36e74c42017-09-18 08:15:42 -07002158 hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d",
Arif Hussain224d3812018-11-16 17:58:38 -08002159 hdd_ctx, dfs_disable_channel_switch);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302160 return true;
Arif Hussaincd151632017-02-11 16:57:19 -08002161 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002162
Dustin Brown920397d2017-12-13 16:27:50 -08002163 hdd_for_each_adapter(hdd_ctx, adapter) {
Arif Hussaincd151632017-02-11 16:57:19 -08002164 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
2165
2166 if ((QDF_SAP_MODE == adapter->device_mode ||
2167 QDF_P2P_GO_MODE == adapter->device_mode) &&
Dustin Brown07901ec2018-09-07 11:02:41 -07002168 (wlan_reg_is_passive_or_disable_ch(hdd_ctx->pdev,
Jeff Johnson01206862017-10-27 20:55:59 -07002169 ap_ctx->operating_channel))) {
Arif Hussaincd151632017-02-11 16:57:19 -08002170 WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx =
2171 true;
2172 hdd_info("tx blocked for session: %d",
Jeff Johnson1b780e42017-10-31 14:11:45 -07002173 adapter->session_id);
bings6fb9bf62018-07-05 14:01:53 +08002174 if (adapter->txrx_vdev)
2175 cdp_fc_vdev_flush(
2176 cds_get_context(QDF_MODULE_ID_SOC),
bings0e03a982018-05-09 08:40:59 +08002177 adapter->txrx_vdev);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302178 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002179 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302180
2181 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002182}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002183
Jeff Johnson030cd902018-11-11 10:19:40 -08002184bool hdd_is_valid_mac_address(const uint8_t *mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002185{
2186 int xdigit = 0;
2187 int separator = 0;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002188
Jeff Johnson030cd902018-11-11 10:19:40 -08002189 while (*mac_addr) {
2190 if (isxdigit(*mac_addr)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002191 xdigit++;
Jeff Johnson030cd902018-11-11 10:19:40 -08002192 } else if (':' == *mac_addr) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002193 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
2194 break;
2195
2196 ++separator;
2197 } else {
2198 /* Invalid MAC found */
Jeff Johnson030cd902018-11-11 10:19:40 -08002199 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002200 }
Jeff Johnson030cd902018-11-11 10:19:40 -08002201 ++mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002202 }
2203 return xdigit == 12 && (separator == 5 || separator == 0);
2204}
2205
2206/**
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302207 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
2208 * @dev: Handle to struct net_device to be updated.
2209 *
2210 * Return: None
2211 */
2212static void hdd_mon_mode_ether_setup(struct net_device *dev)
2213{
2214 dev->header_ops = NULL;
2215 dev->type = ARPHRD_IEEE80211_RADIOTAP;
2216 dev->hard_header_len = ETH_HLEN;
2217 dev->mtu = ETH_DATA_LEN;
2218 dev->addr_len = ETH_ALEN;
2219 dev->tx_queue_len = 1000; /* Ethernet wants good queues */
2220 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
2221 dev->priv_flags |= IFF_TX_SKB_SHARING;
2222
2223 memset(dev->broadcast, 0xFF, ETH_ALEN);
2224}
2225
Nirav Shah73713f72018-05-17 14:50:41 +05302226#ifdef FEATURE_MONITOR_MODE_SUPPORT
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302227/**
chenguo71303962018-10-24 19:44:34 +08002228 * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device.
2229 * @hdd_ctx: Pointer to HDD context.
2230 *
2231 * Return: None
2232 */
2233static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx)
2234{
2235 ucfg_pmo_set_power_save_mode(hdd_ctx->psoc, PS_NOT_SUPPORTED);
2236 ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH);
2237}
2238
2239/**
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002240 * __hdd__mon_open() - HDD Open function
2241 * @dev: Pointer to net_device structure
2242 *
2243 * This is called in response to ifconfig up
2244 *
2245 * Return: 0 for success; non-zero for failure
2246 */
2247static int __hdd_mon_open(struct net_device *dev)
2248{
2249 int ret;
Ravi Joshia307f632017-07-17 23:41:41 -07002250 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2251 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002252
Dustin Brownfdf17c12018-03-14 12:55:34 -07002253 hdd_enter_dev(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002254
2255 ret = wlan_hdd_validate_context(hdd_ctx);
2256 if (ret)
2257 return ret;
2258
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302259 hdd_mon_mode_ether_setup(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002260
2261 if (con_mode == QDF_GLOBAL_MONITOR_MODE) {
Dustin Brown3ecc8782018-09-19 16:37:13 -07002262 ret = hdd_psoc_idle_restart(hdd_ctx);
Ravi Joshia307f632017-07-17 23:41:41 -07002263 if (ret) {
2264 hdd_err("Failed to start WLAN modules return");
2265 return ret;
2266 }
2267 hdd_err("hdd_wlan_start_modules() successful !");
2268
2269 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
2270 ret = hdd_start_adapter(adapter);
2271 if (ret) {
2272 hdd_err("Failed to start adapter :%d",
2273 adapter->device_mode);
2274 return ret;
2275 }
2276 hdd_err("hdd_start_adapters() successful !");
2277 }
chenguo71303962018-10-24 19:44:34 +08002278 hdd_mon_turn_off_ps_and_wow(hdd_ctx);
Ravi Joshia307f632017-07-17 23:41:41 -07002279 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
2280 }
2281
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002282 ret = hdd_set_mon_rx_cb(dev);
Ravi Joshi4f095952017-06-29 15:39:19 -07002283
2284 if (!ret)
2285 ret = hdd_enable_monitor_mode(dev);
2286
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002287 return ret;
2288}
2289
2290/**
2291 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
2292 * @dev: Pointer to net_device structure
2293 *
2294 * This is called in response to ifconfig up
2295 *
2296 * Return: 0 for success; non-zero for failure
2297 */
Jeff Johnson590e2012016-10-05 16:16:24 -07002298static int hdd_mon_open(struct net_device *dev)
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002299{
2300 int ret;
2301
2302 cds_ssr_protect(__func__);
2303 ret = __hdd_mon_open(dev);
2304 cds_ssr_unprotect(__func__);
2305
2306 return ret;
2307}
Nirav Shah73713f72018-05-17 14:50:41 +05302308#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002309
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002310static QDF_STATUS
2311wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
2312{
2313 struct policy_mgr_dual_mac_config cfg = {0};
2314 QDF_STATUS status;
Krunal Soni13b50f82018-09-27 12:37:03 -07002315 uint32_t channel_select_logic_conc = 0;
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002316 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Krunal Sonidf29bc42018-11-15 13:26:29 -08002317 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002318
2319 if (!hdd_ctx) {
2320 hdd_err("HDD context is NULL");
2321 return QDF_STATUS_E_FAILURE;
2322 }
2323
2324
Dustin Brown1dbefe62018-09-11 16:32:03 -07002325 if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc))
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002326 return QDF_STATUS_SUCCESS;
2327
2328 cfg.scan_config = 0;
2329 cfg.fw_mode_config = 0;
2330 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
Krunal Sonidf29bc42018-11-15 13:26:29 -08002331 status =
Krunal Soni13b50f82018-09-27 12:37:03 -07002332 ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc,
2333 &channel_select_logic_conc);
Krunal Sonidf29bc42018-11-15 13:26:29 -08002334 if (status != QDF_STATUS_SUCCESS) {
2335 hdd_err("ucfg_policy_mgr_get_chnl_select_plcy failed, use def");
2336 return status;
2337 }
2338 status =
2339 ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
2340 &dual_mac_feature);
2341 if (status != QDF_STATUS_SUCCESS) {
2342 hdd_err("ucfg_policy_mgr_get_dual_mac_feature failed, use def");
2343 return status;
2344 }
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002345
Krunal Sonidf29bc42018-11-15 13:26:29 -08002346 if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) {
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002347 status = policy_mgr_get_updated_scan_and_fw_mode_config(
Dustin Brown1dbefe62018-09-11 16:32:03 -07002348 hdd_ctx->psoc, &cfg.scan_config,
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002349 &cfg.fw_mode_config,
Krunal Sonidf29bc42018-11-15 13:26:29 -08002350 dual_mac_feature,
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002351 channel_select_logic_conc);
2352
2353 if (status != QDF_STATUS_SUCCESS) {
2354 hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",
2355 status);
2356 return status;
2357 }
2358 }
2359
2360 hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw",
2361 cfg.scan_config, cfg.fw_mode_config);
2362
2363 status = sme_soc_set_dual_mac_config(cfg);
2364 if (status != QDF_STATUS_SUCCESS) {
2365 hdd_err("sme_soc_set_dual_mac_config failed %d", status);
2366 return status;
2367 }
2368
2369 return QDF_STATUS_SUCCESS;
2370}
2371
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002372/**
Arun Khandavallifae92942016-08-01 13:31:08 +05302373 * hdd_start_adapter() - Wrapper function for device specific adapter
2374 * @adapter: pointer to HDD adapter
2375 *
2376 * This function is called to start the device specific adapter for
2377 * the mode passed in the adapter's device_mode.
2378 *
2379 * Return: 0 for success; non-zero for failure
2380 */
Jeff Johnson9d295242017-08-29 14:39:48 -07002381int hdd_start_adapter(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05302382{
2383
2384 int ret;
Jeff Johnsonc1e62782017-11-09 09:50:17 -08002385 enum QDF_OPMODE device_mode = adapter->device_mode;
Arun Khandavallifae92942016-08-01 13:31:08 +05302386
Dustin Brownfdf17c12018-03-14 12:55:34 -07002387 hdd_enter_dev(adapter->dev);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002388 hdd_debug("Start_adapter for mode : %d", adapter->device_mode);
Arun Khandavallifae92942016-08-01 13:31:08 +05302389
2390 switch (device_mode) {
2391 case QDF_P2P_CLIENT_MODE:
2392 case QDF_P2P_DEVICE_MODE:
2393 case QDF_OCB_MODE:
2394 case QDF_STA_MODE:
2395 case QDF_MONITOR_MODE:
2396 ret = hdd_start_station_adapter(adapter);
2397 if (ret)
2398 goto err_start_adapter;
Alok Kumar81e1d732018-09-04 11:10:36 +05302399
2400 hdd_nud_ignore_tracking(adapter, false);
Arun Khandavallifae92942016-08-01 13:31:08 +05302401 break;
2402 case QDF_P2P_GO_MODE:
2403 case QDF_SAP_MODE:
2404 ret = hdd_start_ap_adapter(adapter);
2405 if (ret)
2406 goto err_start_adapter;
2407 break;
Arun Khandavallib2f6c262016-08-18 19:07:19 +05302408 case QDF_IBSS_MODE:
2409 /*
2410 * For IBSS interface is initialized as part of
2411 * hdd_init_station_mode()
2412 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08002413 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302414 case QDF_FTM_MODE:
Dustin Browndb2a8be2017-12-20 11:49:56 -08002415 /* vdevs are dynamically managed by firmware in FTM */
2416 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302417 default:
2418 hdd_err("Invalid session type %d", device_mode);
2419 QDF_ASSERT(0);
2420 goto err_start_adapter;
2421 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08002422
Arun Khandavallifae92942016-08-01 13:31:08 +05302423 if (hdd_set_fw_params(adapter))
2424 hdd_err("Failed to set the FW params for the adapter!");
2425
Dustin Browne7e71d32018-05-11 16:00:08 -07002426 if (adapter->session_id != HDD_SESSION_ID_INVALID) {
2427 ret = wlan_hdd_cfg80211_register_frames(adapter);
2428 if (ret < 0) {
2429 hdd_err("Failed to register frames - ret %d", ret);
2430 goto err_start_adapter;
2431 }
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302432 }
Dustin Browne7e71d32018-05-11 16:00:08 -07002433
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002434 wlan_hdd_update_dbs_scan_and_fw_mode_config();
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302435
Dustin Browndb2a8be2017-12-20 11:49:56 -08002436exit_with_success:
Dustin Browne74003f2018-03-14 12:51:58 -07002437 hdd_exit();
Dustin Browndb2a8be2017-12-20 11:49:56 -08002438
Arun Khandavallifae92942016-08-01 13:31:08 +05302439 return 0;
Dustin Browndb2a8be2017-12-20 11:49:56 -08002440
Arun Khandavallifae92942016-08-01 13:31:08 +05302441err_start_adapter:
2442 return -EINVAL;
2443}
2444
2445/**
Komal Seelamf2136bb2016-09-28 18:30:44 +05302446 * hdd_enable_power_management() - API to Enable Power Management
2447 *
2448 * API invokes Bus Interface Layer power management functionality
2449 *
2450 * Return: None
2451 */
2452static void hdd_enable_power_management(void)
2453{
2454 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2455
2456 if (!hif_ctx) {
2457 hdd_err("Bus Interface Context is Invalid");
2458 return;
2459 }
2460
2461 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
2462}
2463
2464/**
2465 * hdd_disable_power_management() - API to disable Power Management
2466 *
2467 * API disable Bus Interface Layer Power management functionality
2468 *
2469 * Return: None
2470 */
2471static void hdd_disable_power_management(void)
2472{
2473 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2474
2475 if (!hif_ctx) {
2476 hdd_err("Bus Interface Context is Invalid");
2477 return;
2478 }
2479
2480 hif_disable_power_management(hif_ctx);
2481}
2482
Ryan Hsuaadba072018-04-20 13:01:53 -07002483void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx)
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302484{
2485 void *hif_sc;
Dustin Brown6f17a022017-07-19 13:40:55 -07002486 size_t target_hw_name_len;
2487 const char *target_hw_name;
Ryan Hsuaadba072018-04-20 13:01:53 -07002488 uint8_t *buf;
2489 uint32_t buf_len;
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302490
2491 hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
2492 if (!hif_sc) {
2493 hdd_err("HIF context is NULL");
2494 return;
2495 }
2496
Ryan Hsuaadba072018-04-20 13:01:53 -07002497 hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302498 &hdd_ctx->target_hw_revision,
Dustin Brown6f17a022017-07-19 13:40:55 -07002499 &target_hw_name);
2500
2501 if (hdd_ctx->target_hw_name)
2502 qdf_mem_free(hdd_ctx->target_hw_name);
2503
2504 target_hw_name_len = strlen(target_hw_name) + 1;
2505 hdd_ctx->target_hw_name = qdf_mem_malloc(target_hw_name_len);
2506 if (hdd_ctx->target_hw_name)
2507 qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name,
2508 target_hw_name_len);
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302509
Ryan Hsuaadba072018-04-20 13:01:53 -07002510 buf = qdf_mem_malloc(WE_MAX_STR_LEN);
2511 if (buf) {
2512 buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf);
2513 hdd_info("%s", buf);
2514 qdf_mem_free(buf);
2515 }
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302516}
2517
2518/**
gbian62edd7e2017-03-07 13:12:13 +08002519 * hdd_update_cds_ac_specs_params() - update cds ac_specs params
2520 * @hdd_ctx: Pointer to hdd context
2521 *
2522 * Return: none
2523 */
2524static void
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002525hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx)
gbian62edd7e2017-03-07 13:12:13 +08002526{
jitiphil8e15ea62018-11-16 18:05:34 +05302527 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM] = {0};
2528 qdf_size_t out_size = 0;
gbian62edd7e2017-03-07 13:12:13 +08002529 int i;
Jeff Johnson2b6982c2018-05-29 14:56:11 -07002530 struct cds_context *cds_ctx;
gbian62edd7e2017-03-07 13:12:13 +08002531
2532 if (NULL == hdd_ctx)
2533 return;
2534
2535 if (NULL == hdd_ctx->config) {
2536 /* Do nothing if hdd_ctx is invalid */
2537 hdd_err("%s: Warning: hdd_ctx->cfg_ini is NULL", __func__);
2538 return;
2539 }
2540
2541 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2542
2543 if (!cds_ctx) {
2544 hdd_err("Invalid CDS Context");
2545 return;
2546 }
2547
2548 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
2549 switch (i) {
2550 case OL_TX_WMM_AC_BE:
jitiphil8e15ea62018-11-16 18:05:34 +05302551 qdf_uint8_array_parse(
2552 cfg_get(hdd_ctx->psoc,
2553 CFG_DP_ENABLE_TX_SCHED_WRR_BE),
2554 tx_sched_wrr_param,
2555 sizeof(tx_sched_wrr_param),
2556 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002557 break;
2558 case OL_TX_WMM_AC_BK:
jitiphil8e15ea62018-11-16 18:05:34 +05302559 qdf_uint8_array_parse(
2560 cfg_get(hdd_ctx->psoc,
2561 CFG_DP_ENABLE_TX_SCHED_WRR_BK),
2562 tx_sched_wrr_param,
2563 sizeof(tx_sched_wrr_param),
2564 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002565 break;
2566 case OL_TX_WMM_AC_VI:
jitiphil8e15ea62018-11-16 18:05:34 +05302567 qdf_uint8_array_parse(
2568 cfg_get(hdd_ctx->psoc,
2569 CFG_DP_ENABLE_TX_SCHED_WRR_VI),
2570 tx_sched_wrr_param,
2571 sizeof(tx_sched_wrr_param),
2572 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002573 break;
2574 case OL_TX_WMM_AC_VO:
jitiphil8e15ea62018-11-16 18:05:34 +05302575 qdf_uint8_array_parse(
2576 cfg_get(hdd_ctx->psoc,
2577 CFG_DP_ENABLE_TX_SCHED_WRR_VO),
2578 tx_sched_wrr_param,
2579 sizeof(tx_sched_wrr_param),
2580 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002581 break;
2582 default:
gbian62edd7e2017-03-07 13:12:13 +08002583 break;
2584 }
2585
jitiphil8e15ea62018-11-16 18:05:34 +05302586 if (out_size == TX_SCHED_WRR_PARAMS_NUM) {
gbian62edd7e2017-03-07 13:12:13 +08002587 cds_ctx->ac_specs[i].wrr_skip_weight =
2588 tx_sched_wrr_param[0];
2589 cds_ctx->ac_specs[i].credit_threshold =
2590 tx_sched_wrr_param[1];
2591 cds_ctx->ac_specs[i].send_limit =
2592 tx_sched_wrr_param[2];
2593 cds_ctx->ac_specs[i].credit_reserve =
2594 tx_sched_wrr_param[3];
2595 cds_ctx->ac_specs[i].discard_weight =
2596 tx_sched_wrr_param[4];
2597 }
2598
jitiphil8e15ea62018-11-16 18:05:34 +05302599 out_size = 0;
gbian62edd7e2017-03-07 13:12:13 +08002600 }
2601}
2602
Ryan Hsuaadba072018-04-20 13:01:53 -07002603uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx,
2604 const size_t version_len, uint8_t *version)
2605{
2606 uint32_t size;
2607 uint32_t msp_id = 0, mspid = 0, siid = 0, crmid = 0, sub_id = 0;
2608
2609 if (!hdd_ctx) {
2610 hdd_err("Invalid context, HDD context is null");
2611 return 0;
2612 }
2613
Ashish Kumar Dhanotiya7353f882018-05-15 12:50:19 +05302614 if (!version || version_len == 0) {
Ryan Hsuaadba072018-04-20 13:01:53 -07002615 hdd_err("Invalid buffer pointr or buffer len\n");
2616 return 0;
2617 }
2618
2619 msp_id = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
2620 mspid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
2621 siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
2622 crmid = hdd_ctx->target_fw_version & 0x7fff;
2623 sub_id = (hdd_ctx->target_fw_vers_ext & 0xf0000000) >> 28;
2624
2625 size = scnprintf(version, version_len,
Ryan Hsuc6918552018-05-16 13:29:59 -07002626 "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 -07002627 QWLAN_VERSIONSTR,
2628 msp_id, mspid, siid, crmid, sub_id,
Ryan Hsuc6918552018-05-16 13:29:59 -07002629 hdd_ctx->target_hw_name,
2630 hdd_ctx->hw_bd_info.bdf_version,
2631 hdd_ctx->hw_bd_info.ref_design_id,
2632 hdd_ctx->hw_bd_info.customer_id,
2633 hdd_ctx->hw_bd_info.project_id,
2634 hdd_ctx->hw_bd_info.board_data_rev);
Ryan Hsuaadba072018-04-20 13:01:53 -07002635
2636 return size;
2637}
2638
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302639int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value,
2640 struct sap_config *sap_config)
2641{
2642 uint8_t preamble = 0, nss = 0, rix = 0;
2643 int ret;
2644 mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
2645
2646 if (!sap_config) {
2647 if (!sme_is_feature_supported_by_fw(DOT11AX)) {
2648 hdd_err("Target does not support 11ax");
2649 return -EIO;
2650 }
2651 } else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax &&
2652 sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) {
2653 hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch = %d",
2654 sap_config->SapHw_mode, sap_config->channel);
2655 return -EIO;
2656 }
2657
2658 if (set_value != 0xff) {
2659 rix = RC_2_RATE_IDX_11AX(set_value);
2660 preamble = WMI_RATE_PREAMBLE_HE;
2661 nss = HT_RC_2_STREAMS_11AX(set_value);
2662
2663 set_value = hdd_assemble_rate_code(preamble, nss, rix);
2664 } else {
2665 ret = sme_set_auto_rate_he_ltf(mac_handle, adapter->session_id,
2666 QCA_WLAN_HE_LTF_AUTO);
2667 }
2668
2669 hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d",
2670 set_value, rix, preamble, nss);
2671
2672 ret = wma_cli_set_command(adapter->session_id,
2673 WMI_VDEV_PARAM_FIXED_RATE,
2674 set_value, VDEV_CMD);
2675
2676 return ret;
2677}
2678
2679int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate)
2680{
2681 int set_value;
2682
2683 if (sme_is_feature_supported_by_fw(DOT11AX))
2684 set_value = WMI_ASSEMBLE_RATECODE_V1(rate, nss, preamble);
2685 else
2686 set_value = (preamble << 6) | (nss << 4) | rate;
2687
2688 return set_value;
2689}
2690
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002691#ifdef FEATURE_WLAN_WAPI
2692/**
2693 * hdd_wapi_security_sta_exist() - return wapi security sta exist or not
2694 *
2695 * This API returns the wapi security station exist or not
2696 *
2697 * Return: true - wapi security station exist
2698 */
2699static bool hdd_wapi_security_sta_exist(void)
2700{
2701 struct hdd_adapter *adapter = NULL;
2702 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2703
2704 hdd_for_each_adapter(hdd_ctx, adapter) {
2705 if ((adapter->device_mode == QDF_STA_MODE) &&
2706 adapter->wapi_info.wapi_mode &&
2707 (adapter->wapi_info.wapi_auth_mode != WAPI_AUTH_MODE_OPEN))
2708 return true;
2709 }
2710 return false;
2711}
2712#else
2713static bool hdd_wapi_security_sta_exist(void)
2714{
2715 return false;
2716}
2717#endif
2718
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002719#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002720static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
2721 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
2722{
Jeff Johnson9d295242017-08-29 14:39:48 -07002723 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002724 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002725
2726 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2727 if (!adapter) {
2728 hdd_err("Adapter is NULL");
2729 return PM_MAX_NUM_OF_MODE;
2730 }
2731
2732 return policy_mgr_convert_device_mode_to_qdf_type(
2733 adapter->device_mode);
2734}
2735
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002736static void hdd_register_policy_manager_callback(
2737 struct wlan_objmgr_psoc *psoc)
2738{
2739 struct policy_mgr_hdd_cbacks hdd_cbacks;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07002740
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002741 qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks));
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002742 hdd_cbacks.sap_restart_chan_switch_cb =
Jeff Johnson23812942017-10-06 11:33:55 -07002743 hdd_sap_restart_chan_switch_cb;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002744 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
2745 wlan_hdd_get_channel_for_sap_restart;
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002746 hdd_cbacks.get_mode_for_non_connected_vdev =
2747 wlan_hdd_get_mode_for_non_connected_vdev;
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05302748 hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode;
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002749 hdd_cbacks.hdd_wapi_security_sta_exist =
2750 hdd_wapi_security_sta_exist;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002751 if (QDF_STATUS_SUCCESS !=
2752 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
2753 hdd_err("HDD callback registration with policy manager failed");
2754 }
2755}
2756#else
2757static void hdd_register_policy_manager_callback(
2758 struct wlan_objmgr_psoc *psoc)
2759{
2760}
2761#endif
2762
jiadff1ac132018-11-26 16:27:48 +08002763#ifdef WLAN_FEATURE_NAN_DATAPATH
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002764static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002765{
2766 struct nan_callbacks cb_obj = {0};
2767
2768 cb_obj.ndi_open = hdd_ndi_open;
2769 cb_obj.ndi_close = hdd_ndi_close;
2770 cb_obj.ndi_start = hdd_ndi_start;
2771 cb_obj.ndi_delete = hdd_ndi_delete;
2772 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
2773 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
2774
Naveen Rawat37f62c82017-03-26 22:24:43 -07002775 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
2776 cb_obj.get_peer_idx = hdd_ndp_get_peer_idx;
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002777 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
Naveen Rawat37f62c82017-03-26 22:24:43 -07002778
Dustin Brown1dbefe62018-09-11 16:32:03 -07002779 os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002780}
jiadff1ac132018-11-26 16:27:48 +08002781#else
2782static inline void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
2783{
2784}
2785#endif
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002786
Dustin Brown26b3d042017-12-21 11:13:27 -08002787#ifdef CONFIG_LEAK_DETECTION
Dustin Brown4c5b9902017-12-19 11:17:19 -08002788/**
2789 * hdd_check_for_leaks() - Perform runtime memory leak checks
Dustin Browna6246dd2018-05-24 14:35:58 -07002790 * @hdd_ctx: the global HDD context
Dustin Brown29533f22018-07-24 13:11:56 -07002791 * @is_ssr: true if SSR is in progress
Dustin Brown4c5b9902017-12-19 11:17:19 -08002792 *
2793 * This API triggers runtime memory leak detection. This feature enforces the
2794 * policy that any memory allocated at runtime must also be released at runtime.
2795 *
2796 * Allocating memory at runtime and releasing it at unload is effectively a
2797 * memory leak for configurations which never unload (e.g. LONU, statically
2798 * compiled driver). Such memory leaks are NOT false positives, and must be
2799 * fixed.
2800 *
2801 * Return: None
2802 */
Dustin Brown29533f22018-07-24 13:11:56 -07002803static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
Dustin Brown4bc0a622017-12-06 15:56:50 -08002804{
Dustin Brown4c5b9902017-12-19 11:17:19 -08002805 /* DO NOT REMOVE these checks; for false positives, read above first */
2806
Dustin Brown1dbefe62018-09-11 16:32:03 -07002807 wlan_objmgr_psoc_check_for_peer_leaks(hdd_ctx->psoc);
2808 wlan_objmgr_psoc_check_for_vdev_leaks(hdd_ctx->psoc);
2809 wlan_objmgr_psoc_check_for_pdev_leaks(hdd_ctx->psoc);
Dustin Brown29533f22018-07-24 13:11:56 -07002810
2811 /* many adapter resources are not freed by design during SSR */
2812 if (is_ssr)
2813 return;
2814
Dustin Brown677e0862017-10-10 16:30:09 -07002815 qdf_mc_timer_check_for_leaks();
Dustin Brown8e711502017-12-07 16:49:11 -08002816 qdf_nbuf_map_check_for_leaks();
Dustin Browne6b9d5a2017-12-14 15:18:49 -08002817 qdf_mem_check_for_leaks();
Dustin Brown4bc0a622017-12-06 15:56:50 -08002818}
2819
Dustin Brown26b3d042017-12-21 11:13:27 -08002820#define hdd_debug_domain_set(domain) qdf_debug_domain_set(domain)
2821#else
Dustin Brown29533f22018-07-24 13:11:56 -07002822static inline void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
2823{ }
Dustin Brown26b3d042017-12-21 11:13:27 -08002824
2825#define hdd_debug_domain_set(domain)
2826#endif /* CONFIG_LEAK_DETECTION */
2827
gbian62edd7e2017-03-07 13:12:13 +08002828/**
Paul Zhange03cf4c2018-01-19 18:33:22 +08002829 * hdd_update_country_code - Update country code
2830 * @hdd_ctx: HDD context
2831 *
2832 * Update country code based on module parameter country_code
2833 *
2834 * Return: 0 on success and errno on failure
2835 */
2836static int hdd_update_country_code(struct hdd_context *hdd_ctx)
2837{
2838 if (!country_code)
2839 return 0;
2840
2841 return hdd_reg_set_country(hdd_ctx, country_code);
2842}
2843
Dustin Browne7e71d32018-05-11 16:00:08 -07002844int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
Arun Khandavallifae92942016-08-01 13:31:08 +05302845{
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07002846 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05302847 qdf_device_t qdf_dev;
2848 QDF_STATUS status;
Arun Khandavallifae92942016-08-01 13:31:08 +05302849 bool unint = false;
2850 void *hif_ctx;
Jingxiang Ge95912f82018-04-19 12:01:26 +08002851 struct target_psoc_info *tgt_hdl;
Arun Khandavallifae92942016-08-01 13:31:08 +05302852
Arun Khandavallifae92942016-08-01 13:31:08 +05302853 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
2854 if (!qdf_dev) {
2855 hdd_err("QDF Device Context is Invalid return");
2856 return -EINVAL;
2857 }
2858
Dustin Brown4c663222018-10-23 14:19:36 -07002859 hdd_psoc_idle_timer_stop(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05302860
Dustin Brown1fe30a82017-10-03 16:13:36 -07002861 mutex_lock(&hdd_ctx->iface_change_lock);
Arun Khandavalli5a62a822017-11-14 19:43:00 +05302862 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
2863 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07002864 hdd_debug("Driver modules already Enabled");
Dustin Browne74003f2018-03-14 12:51:58 -07002865 hdd_exit();
Arun Khandavalli5a62a822017-11-14 19:43:00 +05302866 return 0;
2867 }
2868
Dustin Brown1fe30a82017-10-03 16:13:36 -07002869 hdd_ctx->start_modules_in_progress = true;
2870
Arun Khandavallifae92942016-08-01 13:31:08 +05302871 switch (hdd_ctx->driver_status) {
2872 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown550f6d22017-12-14 15:44:01 -08002873 hdd_info("Wlan transitioning (UNINITIALIZED -> CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +05302874 unint = true;
2875 /* Fall through dont add break here */
2876 case DRIVER_MODULES_CLOSED:
Dustin Brown1a20b082018-08-03 17:27:15 -07002877 hdd_info("Wlan transitioning (CLOSED -> ENABLED)");
Dustin Brown550f6d22017-12-14 15:44:01 -08002878
Dustin Brown26b3d042017-12-21 11:13:27 -08002879 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
Dustin Brown4bc0a622017-12-06 15:56:50 -08002880
Arun Khandavallifae92942016-08-01 13:31:08 +05302881 if (!reinit && !unint) {
2882 ret = pld_power_on(qdf_dev->dev);
2883 if (ret) {
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07002884 hdd_err("Failed to power up device; errno:%d",
Dustin Browndca39692017-11-09 15:30:25 -08002885 ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05302886 goto release_lock;
2887 }
2888 }
Yuanyuan Liuf8fe4bc2017-06-07 16:55:58 -07002889
2890 pld_set_fw_log_mode(hdd_ctx->parent_dev,
2891 hdd_ctx->config->enable_fw_log);
Arun Khandavallifae92942016-08-01 13:31:08 +05302892 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
2893 qdf_dev->bus_type,
2894 (reinit == true) ? HIF_ENABLE_TYPE_REINIT :
2895 HIF_ENABLE_TYPE_PROBE);
2896 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002897 hdd_err("Failed to open hif; errno: %d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05302898 goto power_down;
2899 }
2900
2901 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
Arun Khandavalli1318b992016-08-09 11:04:57 +05302902 if (!hif_ctx) {
2903 hdd_err("hif context is null!!");
Dustin Browndca39692017-11-09 15:30:25 -08002904 ret = -EINVAL;
Arun Khandavalli1318b992016-08-09 11:04:57 +05302905 goto power_down;
2906 }
2907
Arun Khandavallifae92942016-08-01 13:31:08 +05302908 status = ol_cds_init(qdf_dev, hif_ctx);
2909 if (status != QDF_STATUS_SUCCESS) {
Dustin Browndca39692017-11-09 15:30:25 -08002910 hdd_err("No Memory to Create BMI Context; status: %d",
2911 status);
2912 ret = qdf_status_to_os_return(status);
Arun Khandavallifae92942016-08-01 13:31:08 +05302913 goto hif_close;
2914 }
2915
jitiphil4c256a32018-09-07 08:51:52 +05302916 ucfg_ipa_component_config_update(hdd_ctx->psoc);
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05302917
gbian62edd7e2017-03-07 13:12:13 +08002918 hdd_update_cds_ac_specs_params(hdd_ctx);
2919
Dustin Brown1dbefe62018-09-11 16:32:03 -07002920 status = hdd_component_psoc_open(hdd_ctx->psoc);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05302921 if (QDF_IS_STATUS_ERROR(status)) {
2922 hdd_err("Failed to Open legacy components; status: %d",
2923 status);
2924 ret = qdf_status_to_os_return(status);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05302925 goto cds_free;
2926 }
2927
2928 ret = hdd_update_config(hdd_ctx);
2929 if (ret) {
2930 hdd_err("Failed to update configuration; errno: %d",
2931 ret);
2932 goto cds_free;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05302933 }
2934
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +05302935 status = wbuff_module_init();
2936 if (QDF_IS_STATUS_ERROR(status))
2937 hdd_err("WBUFF init unsuccessful; status: %d", status);
2938
Dustin Brown1dbefe62018-09-11 16:32:03 -07002939 status = cds_open(hdd_ctx->psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07002940 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002941 hdd_err("Failed to Open CDS; status: %d", status);
Dustin Brown28b17892017-10-10 13:29:38 -07002942 ret = qdf_status_to_os_return(status);
Krunal Sonie71838d2018-09-27 10:45:05 -07002943 goto psoc_close;
Arun Khandavallifae92942016-08-01 13:31:08 +05302944 }
2945
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +05302946 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
2947
Manjunathappa Prakashb6b4ff12018-06-04 12:32:33 -07002948 if (hdd_ctx->config->rx_thread_affinity_mask)
2949 cds_set_rx_thread_cpu_mask(
2950 hdd_ctx->config->rx_thread_affinity_mask);
2951
2952 /* initialize components configurations after psoc open */
Mukul Sharma9d797a02017-01-05 20:26:03 +05302953 ret = hdd_update_components_config(hdd_ctx);
2954 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002955 hdd_err("Failed to update component configs; errno: %d",
Mukul Sharma9d797a02017-01-05 20:26:03 +05302956 ret);
2957 goto close;
2958 }
Sourav Mohapatra674925f2018-04-16 11:16:58 +05302959
Dustin Brown1dbefe62018-09-11 16:32:03 -07002960 status = cds_dp_open(hdd_ctx->psoc);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002961 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002962 hdd_err("Failed to Open cds post open; status: %d",
2963 status);
2964 ret = qdf_status_to_os_return(status);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002965 goto close;
2966 }
Mukul Sharma9d797a02017-01-05 20:26:03 +05302967
Sourav Mohapatra674925f2018-04-16 11:16:58 +05302968 ret = hdd_register_cb(hdd_ctx);
2969 if (ret) {
2970 hdd_err("Failed to register HDD callbacks!");
2971 goto cds_txrx_free;
2972 }
2973
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002974 /*
2975 * NAN compoenet requires certian operations like, open adapter,
2976 * close adapter, etc. to be initiated by HDD, for those
2977 * register HDD callbacks with UMAC's NAN componenet.
2978 */
2979 hdd_nan_register_callbacks(hdd_ctx);
2980
Jeff Johnson3a280122017-09-13 07:42:00 -07002981 status = cds_pre_enable();
Arun Khandavallifae92942016-08-01 13:31:08 +05302982 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002983 hdd_err("Failed to pre-enable CDS; status: %d", status);
2984 ret = qdf_status_to_os_return(status);
Sourav Mohapatra674925f2018-04-16 11:16:58 +05302985 goto deregister_cb;
Arun Khandavallifae92942016-08-01 13:31:08 +05302986 }
2987
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002988 hdd_register_policy_manager_callback(
Dustin Brown1dbefe62018-09-11 16:32:03 -07002989 hdd_ctx->psoc);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002990
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05302991 hdd_sysfs_create_driver_root_obj();
Dustin Brown1dbefe62018-09-11 16:32:03 -07002992 hdd_sysfs_create_version_interface(hdd_ctx->psoc);
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05302993 hdd_sysfs_create_powerstats_interface();
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302994 hdd_update_hw_sw_info(hdd_ctx);
Dustin Brown550f6d22017-12-14 15:44:01 -08002995
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05302996 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
2997 hdd_err("in ftm mode, no need to configure cds modules");
Dustin Browndca39692017-11-09 15:30:25 -08002998 ret = -EINVAL;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05302999 break;
3000 }
Dustin Browndca39692017-11-09 15:30:25 -08003001
Dustin Browne7e71d32018-05-11 16:00:08 -07003002 ret = hdd_configure_cds(hdd_ctx);
Dustin Browndca39692017-11-09 15:30:25 -08003003 if (ret) {
3004 hdd_err("Failed to Enable cds modules; errno: %d", ret);
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05303005 goto destroy_driver_sysfs;
Arun Khandavallifae92942016-08-01 13:31:08 +05303006 }
Dustin Browndca39692017-11-09 15:30:25 -08003007
Komal Seelamf2136bb2016-09-28 18:30:44 +05303008 hdd_enable_power_management();
Dustin Brown550f6d22017-12-14 15:44:01 -08003009
Arun Khandavallifae92942016-08-01 13:31:08 +05303010 break;
Dustin Brown550f6d22017-12-14 15:44:01 -08003011
Arun Khandavallifae92942016-08-01 13:31:08 +05303012 default:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07003013 QDF_DEBUG_PANIC("Unknown driver state:%d",
Arun Khandavallifae92942016-08-01 13:31:08 +05303014 hdd_ctx->driver_status);
Dustin Browndca39692017-11-09 15:30:25 -08003015 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05303016 goto release_lock;
3017 }
Dustin Brown550f6d22017-12-14 15:44:01 -08003018
Dustin Brown1a20b082018-08-03 17:27:15 -07003019 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
3020 hdd_info("Wlan transitioned (now ENABLED)");
3021
Arun Khandavallia172c3e2016-08-26 17:33:13 +05303022 hdd_ctx->start_modules_in_progress = false;
Dustin Brownad698ae2018-09-05 17:19:30 -07003023
Arun Khandavallifae92942016-08-01 13:31:08 +05303024 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown550f6d22017-12-14 15:44:01 -08003025
Dustin Browne74003f2018-03-14 12:51:58 -07003026 hdd_exit();
Dustin Brown550f6d22017-12-14 15:44:01 -08003027
Arun Khandavallifae92942016-08-01 13:31:08 +05303028 return 0;
3029
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05303030destroy_driver_sysfs:
3031 hdd_sysfs_destroy_powerstats_interface();
3032 hdd_sysfs_destroy_version_interface();
3033 hdd_sysfs_destroy_driver_root_obj();
Rajeev Kumarbe021242017-02-16 16:12:23 -08003034 cds_post_disable();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003035
Sourav Mohapatra674925f2018-04-16 11:16:58 +05303036deregister_cb:
3037 hdd_deregister_cb(hdd_ctx);
3038
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003039cds_txrx_free:
Dustin Brown1dbefe62018-09-11 16:32:03 -07003040 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
Jingxiang Ge95912f82018-04-19 12:01:26 +08003041
3042 if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl)) {
3043 hdd_runtime_suspend_context_deinit(hdd_ctx);
Dustin Brown07901ec2018-09-07 11:02:41 -07003044 dispatcher_pdev_close(hdd_ctx->pdev);
Jingxiang Ge95912f82018-04-19 12:01:26 +08003045 hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
3046 }
3047
Dustin Brown1dbefe62018-09-11 16:32:03 -07003048 cds_dp_close(hdd_ctx->psoc);
Dustin Brown550f6d22017-12-14 15:44:01 -08003049
Arun Khandavallifae92942016-08-01 13:31:08 +05303050close:
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003051 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -08003052 hdd_info("Wlan transition aborted (now CLOSED)");
3053
Dustin Brown1dbefe62018-09-11 16:32:03 -07003054 cds_close(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +05303055
Krunal Sonie71838d2018-09-27 10:45:05 -07003056psoc_close:
Dustin Brown1dbefe62018-09-11 16:32:03 -07003057 hdd_component_psoc_close(hdd_ctx->psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07003058 cds_deinit_ini_config();
3059
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003060cds_free:
Arun Khandavallifae92942016-08-01 13:31:08 +05303061 ol_cds_free();
3062
3063hif_close:
Jeff Johnson60dc2b12017-09-28 14:56:02 -07003064 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
3065 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303066power_down:
3067 if (!reinit && !unint)
3068 pld_power_off(qdf_dev->dev);
3069release_lock:
Arun Khandavallia172c3e2016-08-26 17:33:13 +05303070 hdd_ctx->start_modules_in_progress = false;
Arun Khandavallifae92942016-08-01 13:31:08 +05303071 mutex_unlock(&hdd_ctx->iface_change_lock);
Abhinav Kumar7ae9b7b2017-12-19 15:11:54 +05303072 if (hdd_ctx->target_hw_name) {
3073 qdf_mem_free(hdd_ctx->target_hw_name);
3074 hdd_ctx->target_hw_name = NULL;
3075 }
Dustin Brown29533f22018-07-24 13:11:56 -07003076
3077 hdd_check_for_leaks(hdd_ctx, reinit);
Dustin Brown26b3d042017-12-21 11:13:27 -08003078 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -08003079
Dustin Browne74003f2018-03-14 12:51:58 -07003080 hdd_exit();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003081
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07003082 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05303083}
3084
Naveen Rawat910726a2017-03-06 11:42:51 -08003085#ifdef WIFI_POS_CONVERGED
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003086static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003087{
3088 int ret = os_if_wifi_pos_register_nl();
3089
3090 if (ret)
3091 hdd_err("os_if_wifi_pos_register_nl failed");
3092
3093 return ret;
3094}
3095
3096static int hdd_deactivate_wifi_pos(void)
3097{
3098 int ret = os_if_wifi_pos_deregister_nl();
3099
3100 if (ret)
3101 hdd_err("os_if_wifi_pos_deregister_nl failed");
3102
3103 return ret;
3104}
3105
3106/**
3107 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
3108 * @hdd_ctx: hdd context
3109 *
3110 * Return: status of operation
3111 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003112static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003113{
Dustin Brown1dbefe62018-09-11 16:32:03 -07003114 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Wu Gao1ab05582018-11-08 16:22:49 +08003115 uint16_t neighbor_scan_max_chan_time;
3116 uint16_t neighbor_scan_min_chan_time;
Naveen Rawat910726a2017-03-06 11:42:51 -08003117
3118 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
3119 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
3120 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
3121 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
3122 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
3123 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
Wu Gao1ab05582018-11-08 16:22:49 +08003124 ucfg_mlme_get_neighbor_scan_max_chan_time(psoc,
3125 &neighbor_scan_max_chan_time);
3126 ucfg_mlme_get_neighbor_scan_min_chan_time(psoc,
3127 &neighbor_scan_min_chan_time);
3128 wifi_pos_set_dwell_time_min(psoc, neighbor_scan_min_chan_time);
3129 wifi_pos_set_dwell_time_max(psoc, neighbor_scan_max_chan_time);
Naveen Rawat910726a2017-03-06 11:42:51 -08003130}
3131#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003132static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003133{
3134 return oem_activate_service(hdd_ctx);
3135}
3136
3137static int hdd_deactivate_wifi_pos(void)
3138{
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05303139 return oem_deactivate_service();
Naveen Rawat910726a2017-03-06 11:42:51 -08003140}
3141
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003142static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003143{
3144}
3145#endif
3146
Arun Khandavallifae92942016-08-01 13:31:08 +05303147/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003148 * __hdd_open() - HDD Open function
3149 * @dev: Pointer to net_device structure
3150 *
3151 * This is called in response to ifconfig up
3152 *
3153 * Return: 0 for success; non-zero for failure
3154 */
3155static int __hdd_open(struct net_device *dev)
3156{
Jeff Johnson9d295242017-08-29 14:39:48 -07003157 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003158 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003159 int ret;
3160
Dustin Brownfdf17c12018-03-14 12:55:34 -07003161 hdd_enter_dev(dev);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303162 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
Jeff Johnson1b780e42017-10-31 14:11:45 -07003163 adapter->session_id, adapter->device_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003164
Ashish Kumar Dhanotiya15a7db52017-08-03 10:27:34 +05303165 /* Nothing to be done if device is unloading */
3166 if (cds_is_driver_unloading()) {
3167 hdd_err("Driver is unloading can not open the hdd");
3168 return -EBUSY;
3169 }
3170
Dustin Brown01847752017-10-25 13:56:27 -07003171 if (cds_is_driver_recovering()) {
3172 hdd_err("WLAN is currently recovering; Please try again.");
3173 return -EBUSY;
3174 }
3175
Sourav Mohapatra421d42b2017-12-29 16:33:23 +05303176 if (qdf_atomic_read(&hdd_ctx->con_mode_flag)) {
3177 hdd_err("con_mode_handler is in progress; Please try again.");
3178 return -EBUSY;
3179 }
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303180
Sourav Mohapatra421d42b2017-12-29 16:33:23 +05303181 mutex_lock(&hdd_init_deinit_lock);
Jeff Johnson5794d4f2018-12-04 11:57:09 -08003182 hdd_start_driver_ops_timer(HDD_DRV_OP_IFF_UP);
Hanumanth Reddy Pothula006f3832017-10-12 15:52:43 +05303183
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303184 /*
3185 * This scenario can be hit in cases where in the wlan driver after
3186 * registering the netdevices and there is a failure in driver
3187 * initialization. So return error gracefully because the netdevices
3188 * will be de-registered as part of the load failure.
3189 */
3190
3191 if (!cds_is_driver_loaded()) {
3192 hdd_err("Failed to start the wlan driver!!");
3193 ret = -EIO;
3194 goto err_hdd_hdd_init_deinit_lock;
3195 }
Abhishek Singh23edd1c2016-05-05 11:56:06 +05303196
Dustin Brown3ecc8782018-09-19 16:37:13 -07003197 ret = hdd_psoc_idle_restart(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303198 if (ret) {
3199 hdd_err("Failed to start WLAN modules return");
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303200 goto err_hdd_hdd_init_deinit_lock;
Arun Khandavallifae92942016-08-01 13:31:08 +05303201 }
3202
Arun Khandavallifae92942016-08-01 13:31:08 +05303203 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
3204 ret = hdd_start_adapter(adapter);
3205 if (ret) {
3206 hdd_err("Failed to start adapter :%d",
3207 adapter->device_mode);
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303208 goto err_hdd_hdd_init_deinit_lock;
Arun Khandavallifae92942016-08-01 13:31:08 +05303209 }
3210 }
3211
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003212 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3213 if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003214 hdd_debug("Enabling Tx Queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003215 /* Enable TX queues only when we are connected */
3216 wlan_hdd_netif_queue_control(adapter,
Arun Khandavallifae92942016-08-01 13:31:08 +05303217 WLAN_START_ALL_NETIF_QUEUE,
3218 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003219 }
3220
Naveen Rawat286def52016-09-23 15:38:02 -07003221 /* Enable carrier and transmit queues for NDI */
3222 if (WLAN_HDD_IS_NDI(adapter)) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003223 hdd_debug("Enabling Tx Queues");
Naveen Rawat286def52016-09-23 15:38:02 -07003224 wlan_hdd_netif_queue_control(adapter,
3225 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
3226 WLAN_CONTROL_PATH);
3227 }
3228
Naveen Rawat910726a2017-03-06 11:42:51 -08003229 hdd_populate_wifi_pos_cfg(hdd_ctx);
Arunk Khandavalli40943af2017-05-15 19:25:34 +05303230 hdd_lpass_notify_start(hdd_ctx, adapter);
Naveen Rawat910726a2017-03-06 11:42:51 -08003231
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303232err_hdd_hdd_init_deinit_lock:
Hanumanth Reddy Pothula006f3832017-10-12 15:52:43 +05303233 hdd_stop_driver_ops_timer();
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303234 mutex_unlock(&hdd_init_deinit_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003235 return ret;
3236}
3237
Arun Khandavallifae92942016-08-01 13:31:08 +05303238
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003239/**
3240 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
3241 * @dev: Pointer to net_device structure
3242 *
3243 * This is called in response to ifconfig up
3244 *
3245 * Return: 0 for success; non-zero for failure
3246 */
Jeff Johnson590e2012016-10-05 16:16:24 -07003247static int hdd_open(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003248{
3249 int ret;
3250
3251 cds_ssr_protect(__func__);
3252 ret = __hdd_open(dev);
3253 cds_ssr_unprotect(__func__);
3254
3255 return ret;
3256}
3257
3258/**
3259 * __hdd_stop() - HDD stop function
3260 * @dev: Pointer to net_device structure
3261 *
3262 * This is called in response to ifconfig down
3263 *
3264 * Return: 0 for success; non-zero for failure
3265 */
3266static int __hdd_stop(struct net_device *dev)
3267{
Jeff Johnson9d295242017-08-29 14:39:48 -07003268 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003269 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003270 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -07003271 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003272
Dustin Brownfdf17c12018-03-14 12:55:34 -07003273 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003274
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303275 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Jeff Johnson1b780e42017-10-31 14:11:45 -07003276 adapter->session_id, adapter->device_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003277
3278 ret = wlan_hdd_validate_context(hdd_ctx);
Arunk Khandavalli987c8d52018-06-21 17:40:31 +05303279 if (ret) {
3280 set_bit(DOWN_DURING_SSR, &adapter->event_flags);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003281 return ret;
Arunk Khandavalli987c8d52018-06-21 17:40:31 +05303282 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003283
3284 /* Nothing to be done if the interface is not opened */
3285 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003286 hdd_err("NETDEV Interface is not OPENED");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003287 return -ENODEV;
3288 }
3289
3290 /* Make sure the interface is marked as closed */
3291 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303292
Jeff Johnson16528362018-06-14 12:34:16 -07003293 mac_handle = hdd_ctx->mac_handle;
3294
Mukul Sharmad16c2022017-07-25 18:56:12 +05303295 hdd_debug("Disabling Auto Power save timer");
3296 sme_ps_disable_auto_ps_timer(
Jeff Johnson16528362018-06-14 12:34:16 -07003297 mac_handle,
Jeff Johnson1b780e42017-10-31 14:11:45 -07003298 adapter->session_id);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303299
3300 /*
3301 * Disable TX on the interface, after this hard_start_xmit() will not
3302 * be called on that interface
3303 */
Dustin Browna7bb6ae2018-08-16 16:51:50 -07003304 hdd_debug("Disabling queues, adapter device mode: %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07003305 qdf_opmode_str(adapter->device_mode), adapter->device_mode);
Kabilan Kannan8dac3502017-10-30 12:40:27 -07003306
Himanshu Agarwal865201d2017-04-12 15:45:31 +05303307 wlan_hdd_netif_queue_control(adapter,
3308 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
3309 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003310
Arunk Khandavalli40943af2017-05-15 19:25:34 +05303311 if (adapter->device_mode == QDF_STA_MODE)
3312 hdd_lpass_notify_stop(hdd_ctx);
3313
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003314 /*
Naveen Rawat286def52016-09-23 15:38:02 -07003315 * NAN data interface is different in some sense. The traffic on NDI is
3316 * bursty in nature and depends on the need to transfer. The service
3317 * layer may down the interface after the usage and up again when
3318 * required. In some sense, the NDI is expected to be available
3319 * (like SAP) iface until NDI delete request is issued by the service
3320 * layer. Skip BSS termination and adapter deletion for NAN Data
3321 * interface (NDI).
3322 */
3323 if (WLAN_HDD_IS_NDI(adapter))
3324 return 0;
3325
3326 /*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003327 * The interface is marked as down for outside world (aka kernel)
3328 * But the driver is pretty much alive inside. The driver needs to
3329 * tear down the existing connection on the netdev (session)
3330 * cleanup the data pipes and wait until the control plane is stabilized
3331 * for this interface. The call also needs to wait until the above
3332 * mentioned actions are completed before returning to the caller.
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003333 * Notice that hdd_stop_adapter is requested not to close the session
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003334 * That is intentional to be able to scan if it is a STA/P2P interface
3335 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08003336 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003337
3338 /* DeInit the adapter. This ensures datapath cleanup as well */
3339 hdd_deinit_adapter(hdd_ctx, adapter, true);
3340
Dustin Brown4c663222018-10-23 14:19:36 -07003341 if (!hdd_is_any_interface_open(hdd_ctx))
3342 hdd_psoc_idle_timer_start(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303343
Dustin Browne74003f2018-03-14 12:51:58 -07003344 hdd_exit();
Dustin Brown4c663222018-10-23 14:19:36 -07003345
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003346 return 0;
3347}
3348
3349/**
3350 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
3351 * @dev: pointer to net_device structure
3352 *
3353 * This is called in response to ifconfig down
3354 *
3355 * Return: 0 for success and error number for failure
3356 */
Jeff Johnson590e2012016-10-05 16:16:24 -07003357static int hdd_stop(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003358{
3359 int ret;
3360
3361 cds_ssr_protect(__func__);
3362 ret = __hdd_stop(dev);
3363 cds_ssr_unprotect(__func__);
3364
3365 return ret;
3366}
3367
3368/**
3369 * __hdd_uninit() - HDD uninit function
3370 * @dev: Pointer to net_device structure
3371 *
3372 * This is called during the netdev unregister to uninitialize all data
3373 * associated with the device
3374 *
3375 * Return: None
3376 */
3377static void __hdd_uninit(struct net_device *dev)
3378{
Jeff Johnson9d295242017-08-29 14:39:48 -07003379 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson399c6272017-08-30 10:51:00 -07003380 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003381
Dustin Brownfdf17c12018-03-14 12:55:34 -07003382 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003383
3384 do {
3385 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003386 hdd_err("Invalid magic");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003387 break;
3388 }
3389
Jeff Johnson399c6272017-08-30 10:51:00 -07003390 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3391 if (!hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003392 hdd_err("NULL hdd_ctx");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003393 break;
3394 }
3395
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003396 if (dev != adapter->dev)
3397 hdd_err("Invalid device reference");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003398
Jeff Johnson399c6272017-08-30 10:51:00 -07003399 hdd_deinit_adapter(hdd_ctx, adapter, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003400
3401 /* after uninit our adapter structure will no longer be valid */
3402 adapter->dev = NULL;
3403 adapter->magic = 0;
3404 } while (0);
3405
Dustin Browne74003f2018-03-14 12:51:58 -07003406 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003407}
3408
3409/**
3410 * hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
3411 * @dev: pointer to net_device structure
3412 *
3413 * This is called during the netdev unregister to uninitialize all data
3414 * associated with the device
3415 *
3416 * Return: none
3417 */
3418static void hdd_uninit(struct net_device *dev)
3419{
3420 cds_ssr_protect(__func__);
3421 __hdd_uninit(dev);
3422 cds_ssr_unprotect(__func__);
3423}
3424
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003425static int hdd_open_cesium_nl_sock(void)
3426{
3427#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3428 struct netlink_kernel_cfg cfg = {
3429 .groups = WLAN_NLINK_MCAST_GRP_ID,
3430 .input = NULL
3431 };
3432#endif
3433 int ret = 0;
3434
3435#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3436 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3437#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
3438 THIS_MODULE,
3439#endif
3440 &cfg);
3441#else
3442 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3443 WLAN_NLINK_MCAST_GRP_ID,
3444 NULL, NULL, THIS_MODULE);
3445#endif
3446
3447 if (cesium_nl_srv_sock == NULL) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003448 hdd_err("NLINK: cesium netlink_kernel_create failed");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003449 ret = -ECONNREFUSED;
3450 }
3451
3452 return ret;
3453}
3454
3455static void hdd_close_cesium_nl_sock(void)
3456{
3457 if (NULL != cesium_nl_srv_sock) {
3458 netlink_kernel_release(cesium_nl_srv_sock);
3459 cesium_nl_srv_sock = NULL;
3460 }
3461}
3462
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303463void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx,
3464 struct qdf_mac_addr *curr_mac_addr,
3465 struct qdf_mac_addr *new_mac_addr)
3466{
3467 uint8_t i;
3468
3469 hdd_enter();
3470
3471 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
3472 if (!qdf_mem_cmp(curr_mac_addr->bytes,
3473 &hdd_ctx->dynamic_mac_list[i].bytes[0],
3474 sizeof(struct qdf_mac_addr))) {
3475 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i],
3476 new_mac_addr->bytes,
3477 sizeof(struct qdf_mac_addr));
3478 break;
3479 }
3480 }
3481
3482 hdd_exit();
3483}
3484
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003485/**
3486 * __hdd_set_mac_address() - set the user specified mac address
3487 * @dev: Pointer to the net device.
3488 * @addr: Pointer to the sockaddr.
3489 *
3490 * This function sets the user specified mac address using
Jeff Johnson06095fb2018-05-06 16:16:42 -07003491 * the command ifconfig wlanX hw ether <mac address>.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003492 *
3493 * Return: 0 for success, non zero for failure
3494 */
3495static int __hdd_set_mac_address(struct net_device *dev, void *addr)
3496{
Jeff Johnson9d295242017-08-29 14:39:48 -07003497 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +05303498 struct hdd_adapter *adapter_temp;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003499 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003500 struct sockaddr *psta_mac_addr = addr;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303501 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003502 int ret;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303503 struct qdf_mac_addr mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003504
Dustin Brownfdf17c12018-03-14 12:55:34 -07003505 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003506
Hanumanth Reddy Pothula5c7a7812018-03-09 12:55:32 +05303507 if (netif_running(dev)) {
3508 hdd_err("On iface up, set mac address change isn't supported");
3509 return -EBUSY;
3510 }
3511
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003512 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3513 ret = wlan_hdd_validate_context(hdd_ctx);
3514 if (0 != ret)
3515 return ret;
3516
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303517 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +05303518 adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
3519 if (adapter_temp) {
3520 if (!qdf_str_cmp(adapter_temp->dev->name, dev->name))
3521 return 0;
3522 hdd_err("%s adapter exist with same address " MAC_ADDRESS_STR,
3523 adapter_temp->dev->name,
Ashish Kumar Dhanotiyaf974f332018-04-19 16:03:15 +05303524 MAC_ADDR_ARRAY(mac_addr.bytes));
3525 return -EINVAL;
3526 }
3527
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05303528 qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr);
3529 if (QDF_IS_STATUS_ERROR(qdf_ret_status))
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303530 return -EINVAL;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303531
Ashish Kumar Dhanotiya8bfef122018-04-18 16:48:27 +05303532 hdd_info("Changing MAC to " MAC_ADDRESS_STR " of the interface %s ",
3533 MAC_ADDR_ARRAY(mac_addr.bytes), dev->name);
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303534
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303535 hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr);
Jeff Johnson1e851a12017-10-28 14:36:12 -07003536 memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003537 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
3538
Dustin Browne74003f2018-03-14 12:51:58 -07003539 hdd_exit();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303540 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003541}
3542
3543/**
3544 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
3545 * function from SSR
3546 * @dev: pointer to net_device structure
3547 * @addr: Pointer to the sockaddr
3548 *
3549 * This function sets the user specified mac address using
Jeff Johnson06095fb2018-05-06 16:16:42 -07003550 * the command ifconfig wlanX hw ether <mac address>.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003551 *
3552 * Return: 0 for success.
3553 */
3554static int hdd_set_mac_address(struct net_device *dev, void *addr)
3555{
3556 int ret;
3557
3558 cds_ssr_protect(__func__);
3559 ret = __hdd_set_mac_address(dev, addr);
3560 cds_ssr_unprotect(__func__);
3561
3562 return ret;
3563}
3564
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003565uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003566{
3567 int i;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003568
Dustin Brown61cc3932018-10-18 16:12:13 -07003569 i = qdf_ffz(hdd_ctx->config->intfAddrMask);
3570 if (i < 0 || i >= QDF_MAX_CONCURRENCY_PERSONA)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003571 return NULL;
3572
3573 hdd_ctx->config->intfAddrMask |= (1 << i);
Dustin Brown61cc3932018-10-18 16:12:13 -07003574
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303575 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].bytes,
3576 &hdd_ctx->config->intfMacAddr[i].bytes,
3577 sizeof(struct qdf_mac_addr));
Dustin Brown61cc3932018-10-18 16:12:13 -07003578 return hdd_ctx->config->intfMacAddr[i].bytes;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003579}
3580
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07003581void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
3582 uint8_t *releaseAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003583{
3584 int i;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003585
Anurag Chouhan6d760662016-02-20 16:05:43 +05303586 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003587 if (!memcmp(releaseAddr,
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303588 hdd_ctx->dynamic_mac_list[i].bytes,
Dustin Brown61cc3932018-10-18 16:12:13 -07003589 QDF_MAC_ADDR_SIZE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003590 hdd_ctx->config->intfAddrMask &= ~(1 << i);
3591 break;
3592 }
3593 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003594}
3595
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003596/**
3597 * __hdd_set_multicast_list() - set the multicast address list
3598 * @dev: Pointer to the WLAN device.
3599 * @skb: Pointer to OS packet (sk_buff).
3600 *
3601 * This funciton sets the multicast address list.
3602 *
3603 * Return: None
3604 */
3605static void __hdd_set_multicast_list(struct net_device *dev)
3606{
Jeff Johnson9d295242017-08-29 14:39:48 -07003607 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Dustin Brown0f874482018-06-13 14:39:22 -07003608 int i = 0, errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003609 struct netdev_hw_addr *ha;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003610 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303611 struct pmo_mc_addr_list_params *mc_list_request = NULL;
Dustin Brown1dbefe62018-09-11 16:32:03 -07003612 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303613 int mc_count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003614
Dustin Brownfdf17c12018-03-14 12:55:34 -07003615 hdd_enter_dev(dev);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303616 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303617 goto out;
Mukul Sharma51c44942015-10-30 19:30:19 +05303618
Dustin Brown0f874482018-06-13 14:39:22 -07003619 errno = wlan_hdd_validate_context(hdd_ctx);
3620 if (errno)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303621 goto out;
3622
Dustin Brown0f874482018-06-13 14:39:22 -07003623 errno = hdd_validate_adapter(adapter);
3624 if (errno)
Dustin Brownc788acb2017-08-01 17:43:51 -07003625 goto out;
3626
Arunk Khandavalli6a227882017-12-12 19:31:08 +05303627 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
3628 hdd_err("%s: Driver module is closed", __func__);
Dustin Brown0f874482018-06-13 14:39:22 -07003629 goto out;
Arunk Khandavalli6a227882017-12-12 19:31:08 +05303630 }
3631
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303632 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
Min Liu74a1a502018-10-10 19:59:07 +08003633 if (!mc_list_request)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303634 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003635
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05303636 /* Delete already configured multicast address list */
3637 if (adapter->mc_addr_list.mc_cnt > 0) {
Dustin Brown0f874482018-06-13 14:39:22 -07003638 hdd_debug("clear previously configured MC address list");
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05303639 hdd_disable_and_flush_mc_addr_list(adapter,
3640 pmo_mc_list_change_notify);
3641 }
3642
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003643 if (dev->flags & IFF_ALLMULTI) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003644 hdd_debug("allow all multicast frames");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303645 hdd_disable_and_flush_mc_addr_list(adapter,
3646 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003647 } else {
3648 mc_count = netdev_mc_count(dev);
Wu Gaod7dd6e42018-10-16 17:22:56 +08003649 if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003650 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
Wu Gaod7dd6e42018-10-16 17:22:56 +08003651 ucfg_pmo_max_mc_addr_supported(psoc));
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303652 hdd_disable_and_flush_mc_addr_list(adapter,
3653 pmo_mc_list_change_notify);
stonezdf2bdfd2018-11-20 14:45:06 +08003654 adapter->mc_addr_list.mc_cnt = 0;
Dustin Brown0f874482018-06-13 14:39:22 -07003655 goto free_req;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003656 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003657 netdev_for_each_mc_addr(ha, dev) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003658 hdd_debug("ha_addr[%d] "MAC_ADDRESS_STR,
Sachin Ahujaa69c72a2016-09-03 15:59:33 +05303659 i, MAC_ADDR_ARRAY(ha->addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003660 if (i == mc_count)
3661 break;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303662 memset(&(mc_list_request->mc_addr[i].bytes),
3663 0, ETH_ALEN);
3664 memcpy(&(mc_list_request->mc_addr[i].bytes),
3665 ha->addr, ETH_ALEN);
Dustin Brown0f874482018-06-13 14:39:22 -07003666 hdd_debug("mlist[%d] = %pM", i,
3667 mc_list_request->mc_addr[i].bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003668 i++;
3669 }
3670 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303671
stonezdf2bdfd2018-11-20 14:45:06 +08003672 adapter->mc_addr_list.mc_cnt = mc_count;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303673 mc_list_request->psoc = psoc;
Jeff Johnson1b780e42017-10-31 14:11:45 -07003674 mc_list_request->vdev_id = adapter->session_id;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303675 mc_list_request->count = mc_count;
Dustin Brown0f874482018-06-13 14:39:22 -07003676
3677 errno = hdd_cache_mc_addr_list(mc_list_request);
3678 if (errno) {
3679 hdd_err("Failed to cache MC address list for vdev %u; errno:%d",
3680 adapter->session_id, errno);
3681 goto free_req;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003682 }
Dustin Brown0f874482018-06-13 14:39:22 -07003683
3684 hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify);
3685
3686free_req:
3687 qdf_mem_free(mc_list_request);
3688
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303689out:
Dustin Browne74003f2018-03-14 12:51:58 -07003690 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003691}
3692
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303693
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003694/**
3695 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
3696 * @dev: pointer to net_device
3697 *
3698 * Return: none
3699 */
3700static void hdd_set_multicast_list(struct net_device *dev)
3701{
3702 cds_ssr_protect(__func__);
3703 __hdd_set_multicast_list(dev);
3704 cds_ssr_unprotect(__func__);
3705}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003706
3707/**
3708 * hdd_select_queue() - used by Linux OS to decide which queue to use first
3709 * @dev: Pointer to the WLAN device.
3710 * @skb: Pointer to OS packet (sk_buff).
3711 *
3712 * This function is registered with the Linux OS for network
3713 * core to decide which queue to use first.
3714 *
3715 * Return: ac, Queue Index/access category corresponding to UP in IP header
3716 */
3717static uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb
3718#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
3719 , void *accel_priv
3720#endif
3721#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
3722 , select_queue_fallback_t fallback
3723#endif
3724)
3725{
3726 return hdd_wmm_select_queue(dev, skb);
3727}
3728
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003729static const struct net_device_ops wlan_drv_ops = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003730 .ndo_open = hdd_open,
3731 .ndo_stop = hdd_stop,
3732 .ndo_uninit = hdd_uninit,
3733 .ndo_start_xmit = hdd_hard_start_xmit,
3734 .ndo_tx_timeout = hdd_tx_timeout,
3735 .ndo_get_stats = hdd_get_stats,
3736 .ndo_do_ioctl = hdd_ioctl,
3737 .ndo_set_mac_address = hdd_set_mac_address,
3738 .ndo_select_queue = hdd_select_queue,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003739 .ndo_set_rx_mode = hdd_set_multicast_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003740};
3741
Nirav Shah73713f72018-05-17 14:50:41 +05303742#ifdef FEATURE_MONITOR_MODE_SUPPORT
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003743/* Monitor mode net_device_ops, doesnot Tx and most of operations. */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003744static const struct net_device_ops wlan_mon_drv_ops = {
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003745 .ndo_open = hdd_mon_open,
3746 .ndo_stop = hdd_stop,
3747 .ndo_get_stats = hdd_get_stats,
3748};
3749
3750/**
3751 * hdd_set_station_ops() - update net_device ops for monitor mode
Jeff Johnson5505db82017-11-02 21:19:23 -07003752 * @dev: Handle to struct net_device to be updated.
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003753 * Return: None
3754 */
Jeff Johnson5505db82017-11-02 21:19:23 -07003755void hdd_set_station_ops(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003756{
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003757 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
Jeff Johnson5505db82017-11-02 21:19:23 -07003758 dev->netdev_ops = &wlan_mon_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003759 else
Jeff Johnson5505db82017-11-02 21:19:23 -07003760 dev->netdev_ops = &wlan_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003761}
Nirav Shah73713f72018-05-17 14:50:41 +05303762#else
3763void hdd_set_station_ops(struct net_device *dev)
3764{
3765 dev->netdev_ops = &wlan_drv_ops;
3766}
3767#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003768
3769/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08003770 * hdd_alloc_station_adapter() - allocate the station hdd adapter
3771 * @hdd_ctx: global hdd context
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003772 * @mac_addr: mac address to assign to the interface
Ryan Hsu07495ea2016-01-21 15:25:39 -08003773 * @name: User-visible name of the interface
3774 *
3775 * hdd adapter pointer would point to the netdev->priv space, this function
Jeff Johnson62018292018-05-06 16:18:35 -07003776 * would retrieve the pointer, and setup the hdd adapter configuration.
Ryan Hsu07495ea2016-01-21 15:25:39 -08003777 *
3778 * Return: the pointer to hdd adapter, otherwise NULL
3779 */
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003780static struct hdd_adapter *
3781hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr,
3782 unsigned char name_assign_type, const char *name)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003783{
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003784 struct net_device *dev;
3785 struct hdd_adapter *adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07003786 struct hdd_station_ctx *sta_ctx;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303787 QDF_STATUS qdf_status;
jitiphil377bcc12018-10-05 19:46:08 +05303788 void *soc;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003789
jitiphil377bcc12018-10-05 19:46:08 +05303790 soc = cds_get_context(QDF_MODULE_ID_SOC);
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003791 /* cfg80211 initialization and registration */
3792 dev = alloc_netdev_mq(sizeof(*adapter), name,
Ryan Hsu07495ea2016-01-21 15:25:39 -08003793#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003794 name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003795#endif
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003796 (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE ?
3797 hdd_mon_mode_ether_setup : ether_setup),
3798 NUM_TX_QUEUES);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003799
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003800 if (!dev) {
3801 hdd_err("Failed to allocate new net_device '%s'", name);
3802 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003803 }
3804
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003805 adapter = netdev_priv(dev);
3806
3807 qdf_mem_zero(adapter, sizeof(*adapter));
3808 sta_ctx = &adapter->session.station;
3809 qdf_mem_set(sta_ctx->conn_info.staId, sizeof(sta_ctx->conn_info.staId),
3810 HDD_WLAN_INVALID_STA_ID);
3811 adapter->dev = dev;
3812 adapter->hdd_ctx = hdd_ctx;
3813 adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
3814 adapter->session_id = HDD_SESSION_ID_INVALID;
3815
3816 qdf_status = qdf_event_create(&adapter->qdf_session_open_event);
3817 if (QDF_IS_STATUS_ERROR(qdf_status))
3818 goto free_net_dev;
3819
3820 qdf_status = qdf_event_create(&adapter->qdf_session_close_event);
3821 if (QDF_IS_STATUS_ERROR(qdf_status))
3822 goto free_net_dev;
3823
3824 adapter->offloads_configured = false;
3825 adapter->is_link_up_service_needed = false;
3826 adapter->disconnection_in_progress = false;
3827 adapter->send_mode_change = true;
3828
3829 /* Init the net_device structure */
3830 strlcpy(dev->name, name, IFNAMSIZ);
3831
3832 qdf_mem_copy(dev->dev_addr, mac_addr, sizeof(tSirMacAddr));
3833 qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr));
3834 dev->watchdog_timeo = HDD_TX_TIMEOUT;
3835
jitiphil377bcc12018-10-05 19:46:08 +05303836 if (cdp_cfg_get(soc,
3837 cfg_dp_enable_ip_tcp_udp_checksum_offload))
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003838 dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
3839 dev->features |= NETIF_F_RXCSUM;
3840
3841 hdd_set_tso_flags(hdd_ctx, dev);
3842 hdd_set_station_ops(adapter->dev);
3843
3844 hdd_dev_setup_destructor(dev);
3845 dev->ieee80211_ptr = &adapter->wdev;
3846 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
3847 adapter->wdev.wiphy = hdd_ctx->wiphy;
3848 adapter->wdev.netdev = dev;
3849
3850 /* set dev's parent to underlying device */
3851 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
3852 hdd_wmm_init(adapter);
3853 spin_lock_init(&adapter->pause_map_lock);
3854 adapter->start_time = qdf_system_ticks();
3855 adapter->last_time = adapter->start_time;
3856
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003857 return adapter;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003858
3859free_net_dev:
3860 free_netdev(adapter->dev);
3861
3862 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003863}
3864
Jeff Johnson9d295242017-08-29 14:39:48 -07003865static QDF_STATUS hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003866{
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003867 struct net_device *dev = adapter->dev;
3868 int ret;
3869
Dustin Brown491d54b2018-03-14 12:39:11 -07003870 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003871
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08003872 if (rtnl_held) {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003873 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
3874
3875 ret = dev_alloc_name(dev, dev->name);
3876 if (ret < 0) {
3877 hdd_err(
3878 "unable to get dev name: %s, err = 0x%x",
3879 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303880 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003881 }
3882 }
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003883
3884 ret = register_netdevice(dev);
3885 if (ret) {
3886 hdd_err("register_netdevice(%s) failed, err = 0x%x",
3887 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303888 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003889 }
3890 } else {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003891 ret = register_netdev(dev);
3892 if (ret) {
3893 hdd_err("register_netdev(%s) failed, err = 0x%x",
3894 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303895 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003896 }
3897 }
3898 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
3899
Dustin Browne74003f2018-03-14 12:51:58 -07003900 hdd_exit();
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003901
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303902 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003903}
3904
Pragaspathi Thilagaraj3551caa2018-09-26 15:52:56 +05303905QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id,
3906 QDF_STATUS qdf_status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003907{
Krunal Sonib51eec72017-11-20 21:53:01 -08003908 struct hdd_adapter *adapter;
3909 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003910
Krunal Sonib51eec72017-11-20 21:53:01 -08003911 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3912 if (!hdd_ctx) {
3913 hdd_err("Invalid HDD_CTX");
3914 return QDF_STATUS_E_FAILURE;
3915 }
3916
3917 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
3918 if (NULL == adapter) {
Naveen Rawat23a3b912018-05-30 17:45:52 -07003919 hdd_err("NULL adapter for %d", session_id);
Krunal Sonib51eec72017-11-20 21:53:01 -08003920 return QDF_STATUS_E_INVAL;
3921 }
Pragaspathi Thilagaraj3551caa2018-09-26 15:52:56 +05303922
3923 if (qdf_status == QDF_STATUS_SUCCESS)
3924 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
3925
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303926 qdf_event_set(&adapter->qdf_session_open_event);
Krunal Sonib51eec72017-11-20 21:53:01 -08003927 hdd_debug("session %d opened", adapter->session_id);
3928
3929 return QDF_STATUS_SUCCESS;
3930}
3931
3932QDF_STATUS hdd_sme_close_session_callback(uint8_t session_id)
3933{
3934 struct hdd_adapter *adapter;
3935 struct hdd_context *hdd_ctx;
3936
3937 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3938 if (!hdd_ctx) {
3939 hdd_err("Invalid HDD_CTX");
3940 return QDF_STATUS_E_FAILURE;
3941 }
3942
3943 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003944 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003945 hdd_err("NULL adapter");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303946 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003947 }
3948
3949 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003950 hdd_err("Invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303951 return QDF_STATUS_NOT_INITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003952 }
3953
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003954 /*
3955 * For NAN Data interface, the close session results in the final
3956 * indication to the userspace
3957 */
Rakesh Sunki3480f962016-08-29 17:29:53 -07003958 if (adapter->device_mode == QDF_NDI_MODE)
3959 hdd_ndp_session_end_handler(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003960
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003961 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
3962
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003963 /*
3964 * We can be blocked while waiting for scheduled work to be
3965 * flushed, and the adapter structure can potentially be freed, in
3966 * which case the magic will have been reset. So make sure the
3967 * magic is still good, and hence the adapter structure is still
3968 * valid, before signaling completion
3969 */
3970 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303971 qdf_event_set(&adapter->qdf_session_close_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003972
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303973 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003974}
3975
Jeff Johnson9d295242017-08-29 14:39:48 -07003976int hdd_vdev_ready(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003977{
Min Liu8c5d99e2018-09-10 17:18:44 +08003978 struct wlan_objmgr_vdev *vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07003979 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003980
Min Liu8c5d99e2018-09-10 17:18:44 +08003981 vdev = hdd_objmgr_get_vdev(adapter);
3982 if (!vdev)
3983 return -EINVAL;
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003984
Min Liu8c5d99e2018-09-10 17:18:44 +08003985 status = pmo_vdev_ready(vdev);
3986 if (QDF_IS_STATUS_ERROR(status)) {
3987 hdd_objmgr_put_vdev(adapter);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003988 return qdf_status_to_os_return(status);
Min Liu8c5d99e2018-09-10 17:18:44 +08003989 }
3990
3991 status = ucfg_reg_11d_vdev_created_update(vdev);
3992 if (QDF_IS_STATUS_ERROR(status)) {
3993 hdd_objmgr_put_vdev(adapter);
3994 return qdf_status_to_os_return(status);
3995 }
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003996
3997 if (wma_capability_enhanced_mcast_filter())
Min Liu8c5d99e2018-09-10 17:18:44 +08003998 status = ucfg_pmo_enhanced_mc_filter_enable(vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003999 else
Min Liu8c5d99e2018-09-10 17:18:44 +08004000 status = ucfg_pmo_enhanced_mc_filter_disable(vdev);
4001
4002 hdd_objmgr_put_vdev(adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -07004003
4004 return qdf_status_to_os_return(status);
4005}
4006
Jeff Johnson9d295242017-08-29 14:39:48 -07004007int hdd_vdev_destroy(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07004008{
4009 QDF_STATUS status;
Dustin Brown2da29eb2018-07-13 14:23:12 -07004010 int errno;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004011 struct hdd_context *hdd_ctx;
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004012 uint8_t vdev_id;
Min Liu8c5d99e2018-09-10 17:18:44 +08004013 struct wlan_objmgr_vdev *vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004014
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004015 vdev_id = adapter->session_id;
4016 hdd_info("destroying vdev %d", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004017
4018 /* vdev created sanity check */
4019 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
Dustin Brown2da29eb2018-07-13 14:23:12 -07004020 hdd_err("vdev %u does not exist", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004021 return -EINVAL;
4022 }
Dustin Brown2da29eb2018-07-13 14:23:12 -07004023
Min Liu8c5d99e2018-09-10 17:18:44 +08004024 vdev = hdd_objmgr_get_vdev(adapter);
4025 if (!vdev)
4026 return -EINVAL;
Ashish Kumar Dhanotiya68ee2e42018-11-19 21:15:14 +05304027
4028 ucfg_pmo_del_wow_pattern(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08004029 status = ucfg_reg_11d_vdev_delete_update(vdev);
Abhishek Singh935e4772018-11-21 14:14:10 +05304030 ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN);
Min Liu8c5d99e2018-09-10 17:18:44 +08004031 hdd_objmgr_put_vdev(adapter);
Yue Maf9782842017-05-08 12:49:49 -07004032
Dustin Brownd28772b2017-03-17 14:16:07 -07004033 /* close sme session (destroy vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304034 qdf_event_reset(&adapter->qdf_session_close_event);
Dustin Brownd28772b2017-03-17 14:16:07 -07004035 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson16528362018-06-14 12:34:16 -07004036 status = sme_close_session(hdd_ctx->mac_handle, adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004037 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Brown2da29eb2018-07-13 14:23:12 -07004038 hdd_err("failed to close sme session; status:%d", status);
Jiachao Wu2c42c222018-01-15 18:13:19 +08004039 goto release_vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004040 }
4041
4042 /* block on a completion variable until sme session is closed */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304043 status = qdf_wait_for_event_completion(
4044 &adapter->qdf_session_close_event,
Abhishek Singh13bf0ce2018-10-24 14:26:14 +05304045 SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
Dustin Brown2da29eb2018-07-13 14:23:12 -07004046
4047 if (QDF_IS_STATUS_ERROR(status)) {
4048 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
4049
Dustin Brownd28772b2017-03-17 14:16:07 -07004050 if (adapter->device_mode == QDF_NDI_MODE)
4051 hdd_ndp_session_end_handler(adapter);
Dustin Brown2da29eb2018-07-13 14:23:12 -07004052
4053 if (status == QDF_STATUS_E_TIMEOUT)
4054 hdd_err("timed out waiting for sme close session");
4055 else if (adapter->qdf_session_close_event.force_set)
4056 hdd_info("SSR occurred during sme close session");
4057 else
4058 hdd_err("failed to wait for sme close session; status:%u",
4059 status);
Dustin Brownd28772b2017-03-17 14:16:07 -07004060 }
Jiachao Wu2c42c222018-01-15 18:13:19 +08004061
Yue Maf9782842017-05-08 12:49:49 -07004062release_vdev:
Jiachao Wu2c42c222018-01-15 18:13:19 +08004063
Sandeep Puligillaef415362017-08-30 16:37:13 -07004064 /* do vdev logical destroy via objmgr */
Dustin Brownb277dd62018-01-26 15:17:33 -08004065 errno = hdd_objmgr_release_and_destroy_vdev(adapter);
Sandeep Puligillaef415362017-08-30 16:37:13 -07004066 if (errno) {
Dustin Brownb277dd62018-01-26 15:17:33 -08004067 hdd_err("failed to destroy objmgr vdev; errno:%d", errno);
Sandeep Puligillaef415362017-08-30 16:37:13 -07004068 return errno;
4069 }
4070
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004071 hdd_info("vdev %d destroyed successfully", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004072
4073 return 0;
4074}
4075
Krunal Sonib51eec72017-11-20 21:53:01 -08004076static int hdd_set_sme_session_param(struct hdd_adapter *adapter,
4077 struct sme_session_params *session_param,
Jeff Johnson6a18c962018-07-01 09:09:37 -07004078 csr_roam_complete_cb callback,
Krunal Sonib51eec72017-11-20 21:53:01 -08004079 void *callback_ctx)
Dustin Brownd28772b2017-03-17 14:16:07 -07004080{
Dustin Brownd28772b2017-03-17 14:16:07 -07004081 uint32_t type;
4082 uint32_t sub_type;
Krunal Sonib51eec72017-11-20 21:53:01 -08004083 QDF_STATUS status;
Dustin Brownd28772b2017-03-17 14:16:07 -07004084
4085 /* determine vdev (sub)type */
4086 status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304087 if (QDF_STATUS_SUCCESS != status) {
Dustin Brownd28772b2017-03-17 14:16:07 -07004088 hdd_err("failed to get vdev type: %d", status);
4089 return qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004090 }
Krunal Sonib51eec72017-11-20 21:53:01 -08004091 session_param->sme_session_id = adapter->session_id;
4092 session_param->self_mac_addr = (uint8_t *)&adapter->mac_addr;
4093 session_param->type_of_persona = type;
4094 session_param->subtype_of_persona = sub_type;
4095 session_param->session_open_cb = hdd_sme_open_session_callback;
4096 session_param->session_close_cb = hdd_sme_close_session_callback;
4097 session_param->callback = callback;
4098 session_param->callback_ctx = callback_ctx;
4099
4100 return 0;
4101}
4102
gaurank kathpalia78af1932018-10-27 20:33:10 +05304103static void
4104hdd_store_nss_chains_cfg_in_vdev(struct hdd_adapter *adapter)
4105{
4106 struct wlan_mlme_nss_chains vdev_ini_cfg;
4107 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4108
gaurank kathpaliab414bce2018-11-09 18:44:46 +05304109 /* Populate the nss chain params from ini for this vdev type */
gaurank kathpalia78af1932018-10-27 20:33:10 +05304110 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
4111 adapter->device_mode,
4112 hdd_ctx->num_rf_chains);
gaurank kathpaliab414bce2018-11-09 18:44:46 +05304113
4114 /* Store the nss chain config into the vdev */
4115 sme_store_nss_chains_cfg_in_vdev(adapter->vdev, &vdev_ini_cfg);
gaurank kathpalia78af1932018-10-27 20:33:10 +05304116}
gaurank kathpalia6982d472018-10-31 21:54:15 +05304117
4118bool hdd_is_vdev_in_conn_state(struct hdd_adapter *adapter)
4119{
4120 switch (adapter->device_mode) {
4121 case QDF_STA_MODE:
4122 case QDF_P2P_CLIENT_MODE:
4123 case QDF_P2P_DEVICE_MODE:
4124 return hdd_conn_is_connected(
4125 WLAN_HDD_GET_STATION_CTX_PTR(adapter));
4126 case QDF_SAP_MODE:
4127 case QDF_P2P_GO_MODE:
4128 return (test_bit(SOFTAP_BSS_STARTED,
4129 &adapter->event_flags));
4130 default:
4131 hdd_err("Device mode %d invalid", adapter->device_mode);
4132 return 0;
4133 }
4134
4135 return 0;
4136}
4137
Krunal Sonib51eec72017-11-20 21:53:01 -08004138int hdd_vdev_create(struct hdd_adapter *adapter,
Jeff Johnson6a18c962018-07-01 09:09:37 -07004139 csr_roam_complete_cb callback, void *ctx)
Krunal Sonib51eec72017-11-20 21:53:01 -08004140{
4141 QDF_STATUS status;
4142 int errno;
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304143 bool bval;
Krunal Sonib51eec72017-11-20 21:53:01 -08004144 struct hdd_context *hdd_ctx;
4145 struct sme_session_params sme_session_params = {0};
Min Liu8c5d99e2018-09-10 17:18:44 +08004146 struct wlan_objmgr_vdev *vdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08004147
4148 hdd_info("creating new vdev");
Dustin Brownd28772b2017-03-17 14:16:07 -07004149
4150 /* do vdev create via objmgr */
4151 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Dustin Brown07901ec2018-09-07 11:02:41 -07004152 errno = hdd_objmgr_create_and_store_vdev(hdd_ctx->pdev, adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -07004153 if (errno) {
4154 hdd_err("failed to create objmgr vdev: %d", errno);
4155 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004156 }
Dustin Brownd28772b2017-03-17 14:16:07 -07004157
4158 /* Open a SME session (prepare vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304159 status = qdf_event_reset(&adapter->qdf_session_open_event);
4160 if (QDF_STATUS_SUCCESS != status) {
4161 hdd_err("failed to reinit session open event");
4162 return -EINVAL;
4163 }
Krunal Sonib51eec72017-11-20 21:53:01 -08004164 errno = hdd_set_sme_session_param(adapter, &sme_session_params,
4165 callback, ctx);
4166 if (errno) {
4167 hdd_err("failed to populating SME params");
4168 goto objmgr_vdev_destroy_procedure;
4169 }
Jeff Johnson16528362018-06-14 12:34:16 -07004170 status = sme_open_session(hdd_ctx->mac_handle, &sme_session_params);
Dustin Brownd28772b2017-03-17 14:16:07 -07004171 if (QDF_IS_STATUS_ERROR(status)) {
4172 hdd_err("failed to open sme session: %d", status);
4173 errno = qdf_status_to_os_return(status);
Krunal Soni4a020c72017-10-30 20:58:40 -07004174 goto objmgr_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004175 }
4176
4177 /* block on a completion variable until sme session is opened */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304178 status = qdf_wait_for_event_completion(&adapter->qdf_session_open_event,
Abhishek Singh13bf0ce2018-10-24 14:26:14 +05304179 SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304180 if (QDF_STATUS_SUCCESS != status) {
4181 if (adapter->qdf_session_open_event.force_set) {
4182 /*
4183 * SSR/PDR has caused shutdown, which has forcefully
4184 * set the event. Return without the closing session.
4185 */
4186 adapter->session_id = HDD_SESSION_ID_INVALID;
4187 hdd_err("Session open event forcefully set");
4188 return -EINVAL;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304189 }
Jeff Johnsonc66d3102018-02-28 11:58:26 -08004190
4191 if (QDF_STATUS_E_TIMEOUT == status)
4192 hdd_err("Session failed to open within timeout period");
4193 else
4194 hdd_err("Failed to wait for session open event(status-%d)",
4195 status);
4196 errno = -ETIMEDOUT;
4197 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
4198 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004199 }
4200
Pragaspathi Thilagaraj3551caa2018-09-26 15:52:56 +05304201 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
4202 hdd_err("Session failed to open due to vdev create failure");
4203 errno = -EINVAL;
4204 goto objmgr_vdev_destroy_procedure;
4205 }
4206
Dustin Brownd28772b2017-03-17 14:16:07 -07004207 /* firmware ready for component communication, raise vdev_ready event */
4208 errno = hdd_vdev_ready(adapter);
4209 if (errno) {
4210 hdd_err("failed to dispatch vdev ready event: %d", errno);
Krunal Soni4a020c72017-10-30 20:58:40 -07004211 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004212 }
4213
Naveen Rawat2b430892018-03-13 13:58:18 -07004214 if (adapter->device_mode == QDF_STA_MODE) {
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304215 bval = false;
4216 status = ucfg_mlme_get_rtt_mac_randomization(hdd_ctx->psoc,
4217 &bval);
4218 if (QDF_IS_STATUS_ERROR(status))
4219 hdd_err("unable to get RTT MAC randomization value");
4220
4221 hdd_debug("setting RTT mac randomization param: %d", bval);
Naveen Rawat2b430892018-03-13 13:58:18 -07004222 errno = sme_cli_set_command(adapter->session_id,
4223 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC,
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304224 bval,
Naveen Rawat2b430892018-03-13 13:58:18 -07004225 VDEV_CMD);
4226 if (0 != errno)
4227 hdd_err("RTT mac randomization param set failed %d",
4228 errno);
4229 }
4230
Bala Venkatesh110b03e2018-07-10 16:02:08 +05304231 if (adapter->device_mode == QDF_STA_MODE ||
Min Liu8c5d99e2018-09-10 17:18:44 +08004232 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
4233 vdev = hdd_objmgr_get_vdev(adapter);
4234 if (!vdev)
4235 goto hdd_vdev_destroy_procedure;
4236 wlan_vdev_set_max_peer_count(vdev, HDD_MAX_VDEV_PEER_COUNT);
4237 hdd_objmgr_put_vdev(adapter);
4238 }
Bala Venkatesh110b03e2018-07-10 16:02:08 +05304239
gaurank kathpalia78af1932018-10-27 20:33:10 +05304240 hdd_store_nss_chains_cfg_in_vdev(adapter);
4241
Jeff Johnson1b780e42017-10-31 14:11:45 -07004242 hdd_info("vdev %d created successfully", adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004243
4244 return 0;
4245
4246 /*
4247 * Due to legacy constraints, we need to destroy in the same order as
4248 * create. So, split error handling into 2 cases to accommodate.
4249 */
4250
Krunal Soni4a020c72017-10-30 20:58:40 -07004251objmgr_vdev_destroy_procedure:
Dustin Brown7d043f62017-03-27 12:07:36 -07004252 QDF_BUG(!hdd_objmgr_release_and_destroy_vdev(adapter));
Dustin Brownd28772b2017-03-17 14:16:07 -07004253
4254 return errno;
4255
Krunal Soni4a020c72017-10-30 20:58:40 -07004256hdd_vdev_destroy_procedure:
Dustin Brownd28772b2017-03-17 14:16:07 -07004257 QDF_BUG(!hdd_vdev_destroy(adapter));
4258
4259 return errno;
4260}
4261
Jeff Johnson9d295242017-08-29 14:39:48 -07004262QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07004263{
Jeff Johnsonb9424862017-10-30 08:49:35 -07004264 struct hdd_station_ctx *sta_ctx = &adapter->session.station;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004265 struct hdd_context *hdd_ctx;
Dustin Brownd28772b2017-03-17 14:16:07 -07004266 QDF_STATUS status;
4267 int ret_val;
Jeff Johnson16528362018-06-14 12:34:16 -07004268 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304269 bool bval = false;
Dustin Brownd28772b2017-03-17 14:16:07 -07004270
Dustin Brownd28772b2017-03-17 14:16:07 -07004271 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson16528362018-06-14 12:34:16 -07004272 mac_handle = hdd_ctx->mac_handle;
4273 sme_set_curr_device_mode(mac_handle, adapter->device_mode);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304274 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
4275 if (!QDF_IS_STATUS_SUCCESS(status))
4276 hdd_err("unable to get vht_enable2x2");
4277 sme_set_pdev_ht_vht_ies(mac_handle, bval);
4278
Jeff Johnson16528362018-06-14 12:34:16 -07004279 sme_set_vdev_ies_per_band(mac_handle, adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004280
Jeff Johnson7f2c5912018-03-23 11:42:28 -07004281 hdd_roam_profile_init(adapter);
4282 hdd_register_wext(adapter->dev);
4283
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -07004284 hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004285
Jeff Johnsond377dce2017-10-04 10:32:42 -07004286 qdf_mem_set(sta_ctx->conn_info.staId,
4287 sizeof(sta_ctx->conn_info.staId), HDD_WLAN_INVALID_STA_ID);
Hanumanth Reddy Pothulab2d729c2017-05-30 11:49:53 +05304288
Deepak Dhamdherea2785822016-11-17 01:17:45 -08004289 /* set fast roaming capability in sme session */
Jeff Johnson16528362018-06-14 12:34:16 -07004290 status = sme_config_fast_roaming(mac_handle, adapter->session_id,
Abhishek Singh1f217ec2017-12-22 11:48:27 +05304291 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004292 /* Set the default operation channel */
Jeff Johnsond377dce2017-10-04 10:32:42 -07004293 sta_ctx->conn_info.operationChannel =
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +05304294 hdd_ctx->config->operating_channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004295
4296 /* Make the default Auth Type as OPEN */
Jeff Johnsond377dce2017-10-04 10:32:42 -07004297 sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004298
4299 status = hdd_init_tx_rx(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304300 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004301 hdd_err("hdd_init_tx_rx() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004302 status, status);
4303 goto error_init_txrx;
4304 }
4305
4306 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4307
4308 status = hdd_wmm_adapter_init(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304309 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004310 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004311 status, status);
4312 goto error_wmm_init;
4313 }
4314
4315 set_bit(WMM_INIT_DONE, &adapter->event_flags);
4316
Jeff Johnson1b780e42017-10-31 14:11:45 -07004317 ret_val = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004318 WMI_PDEV_PARAM_BURST_ENABLE,
Dundi Raviteja3aa01be2018-05-21 18:58:59 +05304319 HDD_ENABLE_SIFS_BURST_DEFAULT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004320 PDEV_CMD);
Dustin Brownd28772b2017-03-17 14:16:07 -07004321 if (ret_val)
4322 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004323
Poddar, Siddarth4b3f7312017-11-02 17:00:20 +05304324 /*
4325 * In case of USB tethering, LRO is disabled. If SSR happened
4326 * during that time, then as part of SSR init, do not enable
4327 * the LRO again. Keep the LRO state same as before SSR.
4328 */
jitiphil377bcc12018-10-05 19:46:08 +05304329 if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
4330 cfg_dp_lro_enable) &&
4331 !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -07004332 adapter->dev->features |= NETIF_F_LRO;
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05304333
4334 /* rcpi info initialization */
4335 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
4336
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304337 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004338
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004339error_wmm_init:
4340 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4341 hdd_deinit_tx_rx(adapter);
4342error_init_txrx:
Dustin Brownd28772b2017-03-17 14:16:07 -07004343 hdd_unregister_wext(adapter->dev);
Dustin Brownd28772b2017-03-17 14:16:07 -07004344 QDF_BUG(!hdd_vdev_destroy(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004345
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004346 return status;
4347}
4348
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304349/**
Krunal Soni4a020c72017-10-30 20:58:40 -07004350 * hdd_deinit_station_mode() - De-initialize the station adapter
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304351 * @hdd_ctx: global hdd context
4352 * @adapter: HDD adapter
Jeff Johnson590e2012016-10-05 16:16:24 -07004353 * @rtnl_held: Used to indicate whether or not the caller is holding
4354 * the kernel rtnl_mutex
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304355 *
4356 * This function De-initializes the STA/P2P/OCB adapter.
4357 *
4358 * Return: None.
4359 */
Krunal Soni4a020c72017-10-30 20:58:40 -07004360static void hdd_deinit_station_mode(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004361 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004362 bool rtnl_held)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304363{
Dustin Brownfdf17c12018-03-14 12:55:34 -07004364 hdd_enter_dev(adapter->dev);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304365
Hanumanth Reddy Pothula7a657402016-09-07 20:59:18 +05304366 if (adapter->dev) {
4367 if (rtnl_held)
4368 adapter->dev->wireless_handlers = NULL;
4369 else {
4370 rtnl_lock();
4371 adapter->dev->wireless_handlers = NULL;
4372 rtnl_unlock();
4373 }
4374 }
4375
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304376 if (test_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags)) {
4377 hdd_deinit_tx_rx(adapter);
4378 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4379 }
4380
4381 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
4382 hdd_wmm_adapter_close(adapter);
4383 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
4384 }
4385
Krunal Sonib51eec72017-11-20 21:53:01 -08004386
Dustin Browne74003f2018-03-14 12:51:58 -07004387 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304388}
4389
Krunal Sonib51eec72017-11-20 21:53:01 -08004390void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
4391 struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004392 bool rtnl_held)
4393{
Dustin Brown491d54b2018-03-14 12:39:11 -07004394 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304395
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004396 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004397 case QDF_STA_MODE:
4398 case QDF_P2P_CLIENT_MODE:
4399 case QDF_P2P_DEVICE_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08004400 case QDF_IBSS_MODE:
4401 case QDF_NDI_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004402 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004403 hdd_deinit_station_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004404 break;
4405 }
4406
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004407 case QDF_SAP_MODE:
4408 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004409 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004410 hdd_deinit_ap_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004411 break;
4412 }
4413
4414 default:
4415 break;
4416 }
4417
Dustin Browne74003f2018-03-14 12:51:58 -07004418 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004419}
4420
Min Liu8c5d99e2018-09-10 17:18:44 +08004421static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
4422 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004423 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004424{
Jeff Johnson5505db82017-11-02 21:19:23 -07004425 struct net_device *dev = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004426
4427 if (adapter)
Jeff Johnson5505db82017-11-02 21:19:23 -07004428 dev = adapter->dev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004429 else {
Jeff Johnson5880d792016-08-15 13:32:30 -07004430 hdd_err("adapter is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004431 return;
4432 }
4433
Alok Kumarb64650c2018-03-23 17:05:11 +05304434 hdd_nud_deinit_tracking(adapter);
4435 qdf_mutex_destroy(&adapter->disconnection_status_lock);
Nachiket Kukade5f0ce4f2018-06-15 19:47:37 +05304436 hdd_apf_context_destroy(adapter);
Min Liu8c5d99e2018-09-10 17:18:44 +08004437 qdf_spinlock_destroy(&adapter->vdev_lock);
Alok Kumarb64650c2018-03-23 17:05:11 +05304438
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05304439 wlan_hdd_debugfs_csr_deinit(adapter);
Arunk Khandavallica56d4b2018-11-29 15:46:00 +05304440 if (adapter->device_mode == QDF_STA_MODE)
4441 hdd_sysfs_destroy_adapter_root_obj(adapter);
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05304442
Rajeev Kumardca5f812016-02-04 17:28:06 -08004443 hdd_debugfs_exit(adapter);
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05304444
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004445 /*
4446 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
4447 * the driver is almost closed and cannot handle either control
4448 * messages or data. However, unregister_netdevice() call above will
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004449 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
4450 * to close the active connections(basically excites control path) which
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004451 * is not right. Setting this flag helps hdd_stop() to recognize that
4452 * the interface is closed and restricts any operations on that
4453 */
4454 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
4455
4456 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004457 if (rtnl_held)
Jeff Johnson5505db82017-11-02 21:19:23 -07004458 unregister_netdevice(dev);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004459 else
Jeff Johnson5505db82017-11-02 21:19:23 -07004460 unregister_netdev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004461 /*
4462 * Note that the adapter is no longer valid at this point
4463 * since the memory has been reclaimed
4464 */
4465 }
4466}
4467
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004468static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07004469 tSirMacAddr macAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004470{
Jeff Johnson9d295242017-08-29 14:39:48 -07004471 struct hdd_adapter *adapter;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004472
Dustin Brown920397d2017-12-13 16:27:50 -08004473 hdd_for_each_adapter(hdd_ctx, adapter) {
4474 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
4475 macAddr, sizeof(tSirMacAddr))) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304476 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004477 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004478 }
Dustin Brown920397d2017-12-13 16:27:50 -08004479
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304480 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004481}
Ryan Hsu07495ea2016-01-21 15:25:39 -08004482
Arun Khandavalli2358d522016-05-16 18:05:37 +05304483#ifdef CONFIG_FW_LOGS_BASED_ON_INI
4484/**
4485 * hdd_set_fw_log_params() - Set log parameters to FW
4486 * @hdd_ctx: HDD Context
4487 * @adapter: HDD Adapter
4488 *
4489 * This function set the FW Debug log level based on the INI.
4490 *
4491 * Return: None
4492 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004493static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004494 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304495{
4496 uint8_t count = 0, numentries = 0,
4497 moduleloglevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH];
4498 uint32_t value = 0;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304499 QDF_STATUS status;
4500 uint16_t enable_fw_log_level, enable_fw_log_type;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304501 int ret;
4502
Arun Khandavallifae92942016-08-01 13:31:08 +05304503 if (QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
4504 (!hdd_ctx->config->enable_fw_log)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004505 hdd_debug("enable_fw_log not enabled in INI or in FTM mode return");
Arun Khandavalli2358d522016-05-16 18:05:37 +05304506 return;
4507 }
4508
Arun Khandavallifae92942016-08-01 13:31:08 +05304509 /* Enable FW logs based on INI configuration */
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304510 status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc,
4511 &enable_fw_log_type);
4512 if (QDF_IS_STATUS_ERROR(status))
4513 return;
Jeff Johnson1b780e42017-10-31 14:11:45 -07004514 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304515 WMI_DBGLOG_TYPE,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304516 enable_fw_log_type,
Arun Khandavallifae92942016-08-01 13:31:08 +05304517 DBG_CMD);
4518 if (ret != 0)
4519 hdd_err("Failed to enable FW log type ret %d",
4520 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304521
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304522 status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc,
4523 &enable_fw_log_level);
4524 if (QDF_IS_STATUS_ERROR(status))
4525 return;
Jeff Johnson1b780e42017-10-31 14:11:45 -07004526 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304527 WMI_DBGLOG_LOG_LEVEL,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304528 enable_fw_log_level,
Arun Khandavallifae92942016-08-01 13:31:08 +05304529 DBG_CMD);
4530 if (ret != 0)
4531 hdd_err("Failed to enable FW log level ret %d",
4532 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304533
4534 hdd_string_to_u8_array(
4535 hdd_ctx->config->enableFwModuleLogLevel,
4536 moduleloglevel,
4537 &numentries,
4538 FW_MODULE_LOG_LEVEL_STRING_LENGTH);
4539
4540 while (count < numentries) {
4541 /*
4542 * FW module log level input string looks like
4543 * below:
4544 * gFwDebugModuleLoglevel=<FW Module ID>,
4545 * <Log Level>,...
4546 * For example:
4547 * gFwDebugModuleLoglevel=
4548 * 1,0,2,1,3,2,4,3,5,4,6,5,7,6
4549 * Above input string means :
4550 * For FW module ID 1 enable log level 0
4551 * For FW module ID 2 enable log level 1
4552 * For FW module ID 3 enable log level 2
4553 * For FW module ID 4 enable log level 3
4554 * For FW module ID 5 enable log level 4
4555 * For FW module ID 6 enable log level 5
4556 * For FW module ID 7 enable log level 6
4557 */
4558
Nishank Aggarwale239d962017-03-03 12:26:02 +05304559 if ((moduleloglevel[count] > WLAN_MODULE_ID_MAX)
4560 || (moduleloglevel[count + 1] > DBGLOG_LVL_MAX)) {
4561 hdd_err("Module id %d and dbglog level %d input length is more than max",
4562 moduleloglevel[count],
4563 moduleloglevel[count + 1]);
4564 return;
4565 }
4566
4567 value = moduleloglevel[count] << 16;
4568 value |= moduleloglevel[count + 1];
Jeff Johnson1b780e42017-10-31 14:11:45 -07004569 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304570 WMI_DBGLOG_MOD_LOG_LEVEL,
4571 value, DBG_CMD);
4572 if (ret != 0)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304573 hdd_err("Failed to enable FW module log level %d ret %d",
4574 value, ret);
4575
4576 count += 2;
4577 }
Arun Khandavallifae92942016-08-01 13:31:08 +05304578
Arun Khandavalli2358d522016-05-16 18:05:37 +05304579}
4580#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004581static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004582 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304583{
4584}
4585
4586#endif
4587
4588/**
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004589 * hdd_configure_chain_mask() - programs chain mask to firmware
4590 * @adapter: HDD adapter
4591 *
4592 * Return: 0 on success or errno on failure
4593 */
4594static int hdd_configure_chain_mask(struct hdd_adapter *adapter)
4595{
Naveen Rawat98322472018-03-06 10:29:42 -08004596 QDF_STATUS status;
4597 struct wma_caps_per_phy non_dbs_phy_cap;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004598 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304599 bool enable2x2 = false, enable_bt_chain_sep = false;
Krunal Sonidf29bc42018-11-15 13:26:29 -08004600 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
4601
4602 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
4603 &dual_mac_feature);
4604 if (!QDF_IS_STATUS_SUCCESS(status))
4605 hdd_err("unable to get dual mac feature");
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304606
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304607 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &enable2x2);
4608 if (QDF_IS_STATUS_ERROR(status))
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304609 hdd_err("unable to get vht_enable2x2");
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004610
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304611 status = ucfg_mlme_get_bt_chain_separation_flag(hdd_ctx->psoc,
4612 &enable_bt_chain_sep);
4613 if (QDF_IS_STATUS_ERROR(status))
4614 hdd_debug("unable to get BT chain separation. using default");
4615
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304616 hdd_debug("enable2x2: %d, lte_coex: %d, disable_DBS: %d",
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304617 enable2x2, hdd_ctx->lte_coex_ant_share,
Krunal Sonidf29bc42018-11-15 13:26:29 -08004618 dual_mac_feature);
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304619 hdd_debug("enable_bt_chain_separation %d", enable_bt_chain_sep);
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004620
Naveen Rawat98322472018-03-06 10:29:42 -08004621 status = wma_get_caps_for_phyidx_hwmode(&non_dbs_phy_cap,
4622 HW_MODE_DBS_NONE,
4623 CDS_BAND_ALL);
4624 if (QDF_IS_STATUS_ERROR(status)) {
4625 hdd_err("couldn't get phy caps. skip chain mask programming");
4626 return qdf_status_to_os_return(status);
4627 }
4628
4629 if (non_dbs_phy_cap.tx_chain_mask_2G < 3 ||
4630 non_dbs_phy_cap.rx_chain_mask_2G < 3 ||
4631 non_dbs_phy_cap.tx_chain_mask_5G < 3 ||
4632 non_dbs_phy_cap.rx_chain_mask_5G < 3) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07004633 hdd_debug("firmware not capable. skip chain mask programming");
Naveen Rawat98322472018-03-06 10:29:42 -08004634 return 0;
4635 }
4636
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304637 if (enable2x2 && !enable_bt_chain_sep) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07004638 hdd_debug("2x2 enabled. skip chain mask programming");
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004639 return 0;
4640 }
4641
Krunal Sonidf29bc42018-11-15 13:26:29 -08004642 if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07004643 hdd_debug("DBS enabled(%d). skip chain mask programming",
Krunal Sonidf29bc42018-11-15 13:26:29 -08004644 dual_mac_feature);
Naveen Rawatb54c72b2018-02-05 10:39:06 -08004645 return 0;
4646 }
4647
Naveen Rawatdacb5032018-02-08 15:23:24 -08004648 if (hdd_ctx->lte_coex_ant_share) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07004649 hdd_debug("lte ant sharing enabled. skip chainmask programming");
Naveen Rawatdacb5032018-02-08 15:23:24 -08004650 return 0;
4651 }
4652
Dustin Brown1dbefe62018-09-11 16:32:03 -07004653 status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc,
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304654 adapter->session_id);
4655 if (status != QDF_STATUS_SUCCESS)
4656 goto error;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004657
4658 return 0;
4659
4660error:
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304661 hdd_err("WMI PDEV set param failed");
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004662 return -EINVAL;
4663}
4664
4665/**
Dundi Raviteja3b637092018-09-12 13:42:50 +05304666 * hdd_send_coex_config_params() - Send coex config params to FW
4667 * @hdd_ctx: HDD context
4668 * @adapter: Primary adapter context
4669 *
4670 * This function is used to send all coex config related params to FW
4671 *
4672 * Return: 0 on success and -EINVAL on failure
4673 */
4674static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx,
4675 struct hdd_adapter *adapter)
4676{
4677 struct coex_config_params coex_cfg_params = {0};
4678 struct wlan_fwol_coex_config config = {0};
Dustin Brown05d81302018-09-11 16:49:22 -07004679 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Dundi Raviteja3b637092018-09-12 13:42:50 +05304680 QDF_STATUS status;
4681
4682 if (!hdd_ctx) {
4683 hdd_err("hdd_ctx is invalid");
4684 goto err;
4685 }
4686
4687 if (!adapter) {
4688 hdd_err("adapter is invalid");
4689 goto err;
4690 }
4691
4692 if (!psoc) {
4693 hdd_err("HDD psoc is invalid");
4694 goto err;
4695 }
4696
4697 status = ucfg_fwol_get_coex_config_params(psoc, &config);
4698 if (QDF_IS_STATUS_ERROR(status)) {
4699 hdd_err("Unable to get coex config params");
4700 goto err;
4701 }
4702
4703 coex_cfg_params.vdev_id = adapter->session_id;
4704 coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER;
4705 coex_cfg_params.config_arg1 = config.max_tx_power_for_btc;
4706
4707 status = sme_send_coex_config_cmd(&coex_cfg_params);
4708 if (QDF_IS_STATUS_ERROR(status)) {
4709 hdd_err("Failed to send coex Tx power");
4710 goto err;
4711 }
4712
4713 coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI;
4714 coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold;
4715
4716 status = sme_send_coex_config_cmd(&coex_cfg_params);
4717 if (QDF_IS_STATUS_ERROR(status)) {
4718 hdd_err("Failed to send coex handover RSSI");
4719 goto err;
4720 }
4721
4722 coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE;
4723 coex_cfg_params.config_arg1 = config.btc_mode;
4724
4725 status = sme_send_coex_config_cmd(&coex_cfg_params);
4726 if (QDF_IS_STATUS_ERROR(status)) {
4727 hdd_err("Failed to send coex BTC mode");
4728 goto err;
4729 }
4730
4731 coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION;
4732 coex_cfg_params.config_arg1 = config.antenna_isolation;
4733
4734 status = sme_send_coex_config_cmd(&coex_cfg_params);
4735 if (QDF_IS_STATUS_ERROR(status)) {
4736 hdd_err("Failed to send coex antenna isolation");
4737 goto err;
4738 }
4739
4740 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD;
4741 coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold;
4742
4743 status = sme_send_coex_config_cmd(&coex_cfg_params);
4744 if (QDF_IS_STATUS_ERROR(status)) {
4745 hdd_err("Failed to send coex BT low RSSI threshold");
4746 goto err;
4747 }
4748
4749 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL;
4750 coex_cfg_params.config_arg1 = config.bt_interference_low_ll;
4751 coex_cfg_params.config_arg2 = config.bt_interference_low_ul;
4752 coex_cfg_params.config_arg3 = config.bt_interference_medium_ll;
4753 coex_cfg_params.config_arg4 = config.bt_interference_medium_ul;
4754 coex_cfg_params.config_arg5 = config.bt_interference_high_ll;
4755 coex_cfg_params.config_arg6 = config.bt_interference_high_ul;
4756
4757 status = sme_send_coex_config_cmd(&coex_cfg_params);
4758 if (QDF_IS_STATUS_ERROR(status)) {
4759 hdd_err("Failed to send coex BT interference level");
4760 goto err;
4761 }
4762 return 0;
4763err:
4764 return -EINVAL;
4765}
4766
4767/**
Arun Khandavalli2358d522016-05-16 18:05:37 +05304768 * hdd_set_fw_params() - Set parameters to firmware
4769 * @adapter: HDD adapter
4770 *
4771 * This function Sets various parameters to fw once the
4772 * adapter is started.
4773 *
4774 * Return: 0 on success or errno on failure
4775 */
Jeff Johnson9d295242017-08-29 14:39:48 -07004776int hdd_set_fw_params(struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304777{
4778 int ret;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304779 uint16_t upper_brssi_thresh, lower_brssi_thresh, rts_profile;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304780 bool enable_dtim_1chrx;
4781 QDF_STATUS status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004782 struct hdd_context *hdd_ctx;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304783 bool bval = false;
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05304784 uint8_t max_amsdu_len;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304785
Dustin Brownfdf17c12018-03-14 12:55:34 -07004786 hdd_enter_dev(adapter->dev);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304787
4788 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4789 if (!hdd_ctx)
4790 return -EINVAL;
4791
Dustin Brown732ab9c2017-06-15 13:24:09 -07004792 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
4793 hdd_debug("FTM Mode is active; nothing to do");
4794 return 0;
4795 }
4796
Jeff Johnson1b780e42017-10-31 14:11:45 -07004797 ret = sme_cli_set_command(adapter->session_id,
Ashish Kumar Dhanotiyab8630ab2017-07-21 14:18:14 +05304798 WMI_PDEV_PARAM_DTIM_SYNTH,
4799 hdd_ctx->config->enable_lprx, PDEV_CMD);
4800 if (ret) {
4801 hdd_err("Failed to set LPRx");
4802 goto error;
4803 }
4804
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05304805
4806 ret = sme_cli_set_command(
4807 adapter->session_id,
4808 WMI_PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION,
4809 hdd_ctx->config->enable_dtim_selection_diversity,
4810 PDEV_CMD);
4811 if (ret) {
4812 hdd_err("Failed to set DTIM_OPTIMIZED_CHAIN_SELECTION");
4813 goto error;
4814 }
4815
Ashish Kumar Dhanotiya48dac7d2018-03-28 14:59:50 +05304816 ret = sme_cli_set_command(
4817 adapter->session_id,
4818 WMI_PDEV_PARAM_TX_SCH_DELAY,
4819 hdd_ctx->config->enable_tx_sch_delay,
4820 PDEV_CMD);
4821 if (ret) {
4822 hdd_err("Failed to set WMI_PDEV_PARAM_TX_SCH_DELAY");
4823 goto error;
4824 }
4825
Ashish Kumar Dhanotiya959b38c2018-04-06 21:07:57 +05304826 ret = sme_cli_set_command(
4827 adapter->session_id,
4828 WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE,
4829 hdd_ctx->config->enable_secondary_rate,
4830 PDEV_CMD);
4831 if (ret) {
4832 hdd_err("Failed to set WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE");
4833 goto error;
4834 }
4835
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304836 if (adapter->device_mode == QDF_STA_MODE) {
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304837 status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc,
4838 &upper_brssi_thresh);
4839 if (QDF_IS_STATUS_ERROR(status))
4840 return -EINVAL;
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304841
Jeff Johnson1b780e42017-10-31 14:11:45 -07004842 sme_set_smps_cfg(adapter->session_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304843 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH,
4844 upper_brssi_thresh);
4845
4846 status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc,
4847 &lower_brssi_thresh);
4848 if (QDF_IS_STATUS_ERROR(status))
4849 return -EINVAL;
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304850
Jeff Johnson1b780e42017-10-31 14:11:45 -07004851 sme_set_smps_cfg(adapter->session_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304852 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH,
4853 lower_brssi_thresh);
4854
4855 status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc,
4856 &enable_dtim_1chrx);
4857 if (QDF_IS_STATUS_ERROR(status))
4858 return -EINVAL;
4859
4860 sme_set_smps_cfg(adapter->session_id,
4861 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE,
4862 enable_dtim_1chrx);
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304863 }
4864
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304865 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
4866 if (!QDF_IS_STATUS_SUCCESS(status))
4867 hdd_err("unable to get vht_enable2x2");
4868
4869 if (bval) {
Dustin Brown732ab9c2017-06-15 13:24:09 -07004870 hdd_debug("configuring 2x2 mode fw params");
4871
Vignesh Viswanathana851d752018-10-03 19:44:38 +05304872 ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle,
4873 adapter->session_id);
Dustin Brown732ab9c2017-06-15 13:24:09 -07004874 if (ret) {
4875 hdd_err("WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE set failed %d",
4876 ret);
4877 goto error;
4878 }
Liangwei Dong22810e82018-03-15 03:42:12 -04004879
4880 if (hdd_configure_chain_mask(adapter))
4881 goto error;
Dustin Brown732ab9c2017-06-15 13:24:09 -07004882 } else {
Arun Khandavalli2358d522016-05-16 18:05:37 +05304883#define HDD_DTIM_1CHAIN_RX_ID 0x5
4884#define HDD_SMPS_PARAM_VALUE_S 29
Dustin Brown732ab9c2017-06-15 13:24:09 -07004885 hdd_debug("configuring 1x1 mode fw params");
4886
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004887 /*
4888 * Disable DTIM 1 chain Rx when in 1x1,
4889 * we are passing two value
4890 * as param_id << 29 | param_value.
4891 * Below param_value = 0(disable)
4892 */
Jeff Johnson1b780e42017-10-31 14:11:45 -07004893 ret = sme_cli_set_command(adapter->session_id,
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004894 WMI_STA_SMPS_PARAM_CMDID,
4895 HDD_DTIM_1CHAIN_RX_ID <<
4896 HDD_SMPS_PARAM_VALUE_S,
4897 VDEV_CMD);
4898 if (ret) {
4899 hdd_err("DTIM 1 chain set failed %d", ret);
4900 goto error;
4901 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05304902
Arun Khandavalli2358d522016-05-16 18:05:37 +05304903#undef HDD_DTIM_1CHAIN_RX_ID
4904#undef HDD_SMPS_PARAM_VALUE_S
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004905
4906 if (hdd_configure_chain_mask(adapter))
4907 goto error;
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004908 }
4909
Vignesh Viswanathana851d752018-10-03 19:44:38 +05304910 ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle,
4911 adapter->session_id);
Dustin Brown732ab9c2017-06-15 13:24:09 -07004912 if (ret) {
4913 hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d", ret);
4914 goto error;
4915 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05304916
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304917 status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile);
4918 if (QDF_IS_STATUS_ERROR(status))
4919 return -EINVAL;
4920
Jeff Johnson1b780e42017-10-31 14:11:45 -07004921 ret = sme_cli_set_command(adapter->session_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004922 WMI_VDEV_PARAM_ENABLE_RTSCTS,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304923 rts_profile,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004924 VDEV_CMD);
4925 if (ret) {
4926 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
4927 goto error;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304928 }
4929
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05304930 status = ucfg_mlme_get_max_amsdu_num(hdd_ctx->psoc, &max_amsdu_len);
4931 if (QDF_IS_STATUS_ERROR(status)) {
4932 hdd_err("Failed to get Max AMSDU Num");
4933 goto error;
4934 }
4935
4936 hdd_debug("SET AMSDU num %d", max_amsdu_len);
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004937
Jeff Johnson1b780e42017-10-31 14:11:45 -07004938 ret = wma_cli_set_command(adapter->session_id,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004939 GEN_VDEV_PARAM_AMSDU,
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05304940 max_amsdu_len,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004941 GEN_CMD);
4942 if (ret != 0) {
4943 hdd_err("GEN_VDEV_PARAM_AMSDU set failed %d", ret);
4944 goto error;
4945 }
4946
Arun Khandavalli2358d522016-05-16 18:05:37 +05304947 hdd_set_fw_log_params(hdd_ctx, adapter);
Dundi Raviteja3b637092018-09-12 13:42:50 +05304948
4949 ret = hdd_send_coex_config_params(hdd_ctx, adapter);
4950 if (ret) {
4951 hdd_warn("Error initializing coex config params");
4952 goto error;
4953 }
4954
Dustin Browne74003f2018-03-14 12:51:58 -07004955 hdd_exit();
Dustin Brown732ab9c2017-06-15 13:24:09 -07004956
Arun Khandavalli2358d522016-05-16 18:05:37 +05304957 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05304958
Arun Khandavalli2358d522016-05-16 18:05:37 +05304959error:
4960 return -EINVAL;
4961}
4962
Ryan Hsu07495ea2016-01-21 15:25:39 -08004963/**
Abhinav Kumarcc959f12018-08-09 13:58:30 +05304964 * hdd_init_completion() - Initialize Completion Variables
4965 * @adapter: HDD adapter
4966 *
4967 * This function Initialize the completion variables for
4968 * a particular adapter
4969 *
4970 * Return: None
4971 */
4972static void hdd_init_completion(struct hdd_adapter *adapter)
4973{
4974 init_completion(&adapter->disconnect_comp_var);
4975 init_completion(&adapter->roaming_comp_var);
4976 init_completion(&adapter->linkup_event_var);
4977 init_completion(&adapter->cancel_rem_on_chan_var);
4978 init_completion(&adapter->rem_on_chan_ready_event);
4979 init_completion(&adapter->sta_authorized_event);
4980 init_completion(&adapter->offchannel_tx_event);
4981 init_completion(&adapter->tx_action_cnf_event);
4982 init_completion(&adapter->ibss_peer_info_comp);
4983 init_completion(&adapter->lfr_fw_status.disable_lfr_event);
4984}
4985
4986/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08004987 * hdd_open_adapter() - open and setup the hdd adatper
4988 * @hdd_ctx: global hdd context
4989 * @session_type: type of the interface to be created
4990 * @iface_name: User-visible name of the interface
4991 * @macAddr: MAC address to assign to the interface
4992 * @name_assign_type: the name of assign type of the netdev
4993 * @rtnl_held: the rtnl lock hold flag
4994 *
4995 * This function open and setup the hdd adpater according to the device
4996 * type request, assign the name, the mac address assigned, and then prepared
4997 * the hdd related parameters, queue, lock and ready to start.
4998 *
4999 * Return: the pointer of hdd adapter, otherwise NULL.
5000 */
Jeff Johnson9d295242017-08-29 14:39:48 -07005001struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t session_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005002 const char *iface_name, tSirMacAddr macAddr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08005003 unsigned char name_assign_type,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08005004 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005005{
Jeff Johnson9d295242017-08-29 14:39:48 -07005006 struct hdd_adapter *adapter = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305007 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05305008 uint8_t i;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005009
5010 if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
5011 /*
5012 * Max limit reached on the number of vdevs configured by the
5013 * host. Return error
5014 */
Arun Khandavallifae92942016-08-01 13:31:08 +05305015 hdd_err("Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
5016 hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005017 return NULL;
5018 }
5019
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05305020 status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)macAddr);
5021 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005022 /* Not received valid macAddr */
Arun Khandavallifae92942016-08-01 13:31:08 +05305023 hdd_err("Unable to add virtual intf: Not able to get valid mac address");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005024 return NULL;
5025 }
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05305026
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005027 status = hdd_check_for_existing_macaddr(hdd_ctx, macAddr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305028 if (QDF_STATUS_E_FAILURE == status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05305029 hdd_err("Duplicate MAC addr: " MAC_ADDRESS_STR
5030 " already exists",
5031 MAC_ADDR_ARRAY(macAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005032 return NULL;
5033 }
5034
5035 switch (session_type) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005036 case QDF_STA_MODE:
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05305037 /*
5038 * Reset locally administered bit for dynamic_mac_list
5039 * also as while releasing the MAC address for any interface
5040 * mac will be compared with dynamic mac list
5041 */
5042 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
5043 if (!qdf_mem_cmp(
5044 macAddr,
5045 &hdd_ctx->dynamic_mac_list[i].bytes[0],
5046 sizeof(struct qdf_mac_addr))) {
5047 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(
5048 hdd_ctx->dynamic_mac_list[i].bytes);
5049 break;
5050 }
5051 }
5052
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005053 /* Reset locally administered bit if the device mode is STA */
5054 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macAddr);
Dustin Brown7e761c72018-07-31 13:50:17 -07005055 hdd_debug("locally administered bit reset in sta mode: "
5056 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005057 /* fall through */
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005058 case QDF_P2P_CLIENT_MODE:
5059 case QDF_P2P_DEVICE_MODE:
5060 case QDF_OCB_MODE:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07005061 case QDF_NDI_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305062 case QDF_MONITOR_MODE:
Ryan Hsu07495ea2016-01-21 15:25:39 -08005063 adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
5064 name_assign_type,
5065 iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005066
5067 if (NULL == adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05305068 hdd_err("failed to allocate adapter for session %d",
5069 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005070 return NULL;
5071 }
5072
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005073 if (QDF_P2P_CLIENT_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005074 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005075 else if (QDF_P2P_DEVICE_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005076 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305077 else if (QDF_MONITOR_MODE == session_type)
5078 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005079 else
5080 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
5081
5082 adapter->device_mode = session_type;
5083
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005084
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005085 /*
5086 * Workqueue which gets scheduled in IPv4 notification
5087 * callback
5088 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005089 INIT_WORK(&adapter->ipv4_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005090 hdd_ipv4_notifier_work_queue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005091
5092#ifdef WLAN_NS_OFFLOAD
5093 /*
5094 * Workqueue which gets scheduled in IPv6
5095 * notification callback.
5096 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005097 INIT_WORK(&adapter->ipv6_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005098 hdd_ipv6_notifier_work_queue);
5099#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005100 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005101 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08005102 goto err_free_netdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005103
5104 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005105 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005106 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305107 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5108 WLAN_CONTROL_PATH);
Arun Khandavallifae92942016-08-01 13:31:08 +05305109
Alok Kumarb64650c2018-03-23 17:05:11 +05305110 hdd_nud_init_tracking(adapter);
Arunk Khandavallica56d4b2018-11-29 15:46:00 +05305111 if (adapter->device_mode == QDF_STA_MODE ||
5112 adapter->device_mode == QDF_P2P_DEVICE_MODE)
5113 hdd_sysfs_create_adapter_root_obj(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305114 qdf_mutex_create(&adapter->disconnection_status_lock);
5115
Ravi Joshi1a292562017-05-18 16:28:54 -07005116 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005117
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005118 case QDF_P2P_GO_MODE:
5119 case QDF_SAP_MODE:
Ryan Hsu07495ea2016-01-21 15:25:39 -08005120 adapter = hdd_wlan_create_ap_dev(hdd_ctx, macAddr,
5121 name_assign_type,
5122 (uint8_t *) iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005123 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005124 hdd_err("failed to allocate adapter for session %d",
Arun Khandavallifae92942016-08-01 13:31:08 +05305125 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005126 return NULL;
5127 }
5128
5129 adapter->wdev.iftype =
5130 (session_type ==
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005131 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005132 NL80211_IFTYPE_P2P_GO;
5133 adapter->device_mode = session_type;
5134
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07005135 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005136 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005137 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08005138
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005139 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005140 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305141 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5142 WLAN_CONTROL_PATH);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305143
5144 /*
5145 * Workqueue which gets scheduled in IPv4 notification
5146 * callback
5147 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005148 INIT_WORK(&adapter->ipv4_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305149 hdd_ipv4_notifier_work_queue);
5150
5151#ifdef WLAN_NS_OFFLOAD
5152 /*
5153 * Workqueue which gets scheduled in IPv6
5154 * notification callback.
5155 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005156 INIT_WORK(&adapter->ipv6_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305157 hdd_ipv6_notifier_work_queue);
5158#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005159 break;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305160 case QDF_FTM_MODE:
5161 adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
5162 name_assign_type,
Lin Bai1c678482017-12-18 18:29:11 +08005163 iface_name);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305164 if (NULL == adapter) {
5165 hdd_err("Failed to allocate adapter for FTM mode");
5166 return NULL;
5167 }
5168 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
5169 adapter->device_mode = session_type;
5170 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005171 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08005172 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08005173
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305174 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005175 hdd_debug("Disabling queues");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305176 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305177 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5178 WLAN_CONTROL_PATH);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305179 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005180 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005181 hdd_err("Invalid session type %d", session_type);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305182 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005183 return NULL;
5184 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005185
Min Liu8c5d99e2018-09-10 17:18:44 +08005186 qdf_spinlock_create(&adapter->vdev_lock);
5187
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305188 hdd_init_completion(adapter);
hqueaa33ee2017-05-04 17:56:35 +08005189 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
Min Liu9be5d4a2018-05-17 11:51:53 +08005190 qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT);
5191 qdf_mutex_create(&adapter->blocked_scan_request_q_lock);
hqueaa33ee2017-05-04 17:56:35 +08005192
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305193 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005194 /* Add it to the hdd's session list. */
Dustin Brown920397d2017-12-13 16:27:50 -08005195 status = hdd_add_adapter_back(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005196 }
5197
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305198 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005199 if (NULL != adapter) {
5200 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
5201 adapter = NULL;
5202 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005203
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005204 return NULL;
5205 }
Nachiket Kukade5f0ce4f2018-06-15 19:47:37 +05305206 hdd_apf_context_init(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005207
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305208 if (QDF_STATUS_SUCCESS == status) {
Dustin Brown1dbefe62018-09-11 16:32:03 -07005209 policy_mgr_set_concurrency_mode(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005210 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005211
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005212 /* Adapter successfully added. Increment the vdev count */
5213 hdd_ctx->current_intf_count++;
5214
Jeff Johnson5880d792016-08-15 13:32:30 -07005215 hdd_debug("current_intf_count=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005216 hdd_ctx->current_intf_count);
5217
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08005218 hdd_check_and_restart_sap_with_non_dfs_acs();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005219 }
5220
Rajeev Kumardca5f812016-02-04 17:28:06 -08005221 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
Mahesh Kumar Kalikot Veetil80dda9a2017-07-17 11:38:03 -07005222 hdd_err("Interface %s wow debug_fs init failed",
5223 netdev_name(adapter->dev));
5224
Ajit Pal Singh106c1412018-04-18 18:08:49 +05305225 hdd_register_hl_netdev_fc_timer(adapter,
5226 hdd_tx_resume_timer_expired_handler);
5227
Mahesh Kumar Kalikot Veetil80dda9a2017-07-17 11:38:03 -07005228 hdd_info("%s interface created. iftype: %d", netdev_name(adapter->dev),
5229 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005230
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05305231 if (adapter->device_mode == QDF_STA_MODE)
5232 wlan_hdd_debugfs_csr_init(adapter);
5233
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005234 return adapter;
5235
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005236err_free_netdev:
Jeff Johnson1e851a12017-10-28 14:36:12 -07005237 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
Hanumanth Reddy Pothula00a39e72016-11-09 21:32:16 +05305238 free_netdev(adapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005239
5240 return NULL;
5241}
5242
Dustin Brown728d65a2018-10-02 16:27:52 -07005243static void __hdd_close_adapter(struct hdd_context *hdd_ctx,
5244 struct hdd_adapter *adapter,
5245 bool rtnl_held)
5246{
5247 qdf_list_destroy(&adapter->blocked_scan_request_q);
5248 qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock);
5249 policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
5250
5251 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
5252
5253 if (hdd_ctx->current_intf_count != 0)
5254 hdd_ctx->current_intf_count--;
5255}
5256
5257void hdd_close_adapter(struct hdd_context *hdd_ctx,
5258 struct hdd_adapter *adapter,
5259 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005260{
Dustin Brown920397d2017-12-13 16:27:50 -08005261 /*
Dustin Brown728d65a2018-10-02 16:27:52 -07005262 * Stop the global bus bandwidth timer while touching the adapter list
5263 * to avoid bad memory access by the timer handler.
Dustin Brown920397d2017-12-13 16:27:50 -08005264 */
Dustin Brown920397d2017-12-13 16:27:50 -08005265 hdd_bus_bw_compute_timer_stop(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005266
Dustin Brown920397d2017-12-13 16:27:50 -08005267 hdd_remove_adapter(hdd_ctx, adapter);
Dustin Brown728d65a2018-10-02 16:27:52 -07005268 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005269
Dustin Brown920397d2017-12-13 16:27:50 -08005270 /* conditionally restart the bw timer */
5271 hdd_bus_bw_compute_timer_try_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005272}
5273
Dustin Brown728d65a2018-10-02 16:27:52 -07005274void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005275{
Dustin Brown920397d2017-12-13 16:27:50 -08005276 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005277
Dustin Brown491d54b2018-03-14 12:39:11 -07005278 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005279
Dustin Brown728d65a2018-10-02 16:27:52 -07005280 while (QDF_IS_STATUS_SUCCESS(hdd_remove_front_adapter(hdd_ctx,
5281 &adapter))) {
5282 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
5283 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
5284 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005285
Dustin Browne74003f2018-03-14 12:51:58 -07005286 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005287}
5288
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005289void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005290{
Anurag Chouhan6d760662016-02-20 16:05:43 +05305291 struct qdf_mac_addr *bssid = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005292 tSirUpdateIE updateIE;
Jeff Johnson16528362018-06-14 12:34:16 -07005293 mac_handle_t mac_handle;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005294
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005295 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005296 case QDF_STA_MODE:
5297 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005298 {
Jeff Johnsond377dce2017-10-04 10:32:42 -07005299 struct hdd_station_ctx *sta_ctx =
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005300 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnsond377dce2017-10-04 10:32:42 -07005301 bssid = &sta_ctx->conn_info.bssId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005302 break;
5303 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005304 case QDF_SAP_MODE:
5305 case QDF_P2P_GO_MODE:
5306 case QDF_IBSS_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005307 {
Jeff Johnson1e851a12017-10-28 14:36:12 -07005308 bssid = &adapter->mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005309 break;
5310 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005311 case QDF_FTM_MODE:
5312 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005313 default:
5314 /*
5315 * wlan_hdd_reset_prob_rspies should not have been called
5316 * for these kind of devices
5317 */
Jeff Johnson5880d792016-08-15 13:32:30 -07005318 hdd_err("Unexpected request for the current device type %d",
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005319 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005320 return;
5321 }
5322
Anurag Chouhanc5548422016-02-24 18:33:27 +05305323 qdf_copy_macaddr(&updateIE.bssid, bssid);
Jeff Johnson1b780e42017-10-31 14:11:45 -07005324 updateIE.smeSessionId = adapter->session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005325 updateIE.ieBufferlength = 0;
5326 updateIE.pAdditionIEBuffer = NULL;
5327 updateIE.append = true;
5328 updateIE.notify = false;
Jeff Johnson16528362018-06-14 12:34:16 -07005329 mac_handle = hdd_adapter_get_mac_handle(adapter);
5330 if (sme_update_add_ie(mac_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005331 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305332 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005333 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005334 }
5335}
5336
Dustin Browndb2a8be2017-12-20 11:49:56 -08005337QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
5338 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005339{
Liangwei Dongad89c762018-06-01 01:56:23 -04005340 return hdd_stop_adapter_ext(hdd_ctx, adapter, 0);
5341}
5342
5343QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx,
5344 struct hdd_adapter *adapter,
5345 enum hdd_adapter_stop_flag_t flag)
5346{
Dustin Brownd747ecd2018-10-26 16:32:22 -07005347 QDF_STATUS status = QDF_STATUS_SUCCESS;
5348 struct hdd_station_ctx *sta_ctx;
Jeff Johnson025618c2018-03-18 14:41:00 -07005349 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005350 union iwreq_data wrqu;
5351 tSirUpdateIE updateIE;
5352 unsigned long rc;
Jeff Johnsone4c11db2018-05-05 23:22:32 -07005353 tsap_config_t *sap_config;
Jeff Johnson16528362018-06-14 12:34:16 -07005354 mac_handle_t mac_handle;
Min Liu8c5d99e2018-09-10 17:18:44 +08005355 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005356
Dustin Brown491d54b2018-03-14 12:39:11 -07005357 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005358
Dustin Browne7e71d32018-05-11 16:00:08 -07005359 if (adapter->session_id != HDD_SESSION_ID_INVALID)
5360 wlan_hdd_cfg80211_deregister_frames(adapter);
5361
Alok Kumarb64650c2018-03-23 17:05:11 +05305362 hdd_nud_ignore_tracking(adapter, true);
5363 hdd_nud_reset_tracking(adapter);
Alok Kumar016a1ac2018-09-16 09:55:50 +05305364 hdd_nud_flush_work(adapter);
hangtian9c47aaf2018-11-26 17:59:39 +08005365 hdd_stop_tsf_sync(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305366
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005367 hdd_debug("Disabling queues");
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305368 wlan_hdd_netif_queue_control(adapter,
5369 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5370 WLAN_CONTROL_PATH);
Tushnim Bhattacharyya9bd058f2017-12-27 14:01:31 -08005371 /*
5372 * if this is the last active connection check & stop the
5373 * opportunistic timer first
5374 */
Dustin Brownd747ecd2018-10-26 16:32:22 -07005375 if ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 1 &&
5376 policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
5377 policy_mgr_convert_device_mode_to_qdf_type(
5378 adapter->device_mode), NULL) == 1) ||
5379 !policy_mgr_get_connection_count(hdd_ctx->psoc))
Tushnim Bhattacharyya9bd058f2017-12-27 14:01:31 -08005380 policy_mgr_check_and_stop_opportunistic_timer(
Dustin Brown1dbefe62018-09-11 16:32:03 -07005381 hdd_ctx->psoc, adapter->session_id);
Jeff Johnson16528362018-06-14 12:34:16 -07005382
5383 mac_handle = hdd_ctx->mac_handle;
5384
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005385 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005386 case QDF_STA_MODE:
5387 case QDF_P2P_CLIENT_MODE:
5388 case QDF_IBSS_MODE:
5389 case QDF_P2P_DEVICE_MODE:
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005390 case QDF_NDI_MODE:
Dustin Brownd747ecd2018-10-26 16:32:22 -07005391 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5392
5393 if (adapter->device_mode == QDF_NDI_MODE ||
5394 hdd_conn_is_connected(sta_ctx) ||
5395 hdd_is_connecting(sta_ctx)) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005396 INIT_COMPLETION(adapter->disconnect_comp_var);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005397
Jeff Johnson025618c2018-03-18 14:41:00 -07005398 roam_profile = hdd_roam_profile(adapter);
5399 /* For NDI do not use roam_profile */
Dustin Brownd747ecd2018-10-26 16:32:22 -07005400 if (adapter->device_mode == QDF_NDI_MODE)
5401 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005402 mac_handle,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005403 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005404 eCSR_DISCONNECT_REASON_NDI_DELETE);
Jeff Johnson025618c2018-03-18 14:41:00 -07005405 else if (roam_profile->BSSType ==
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005406 eCSR_BSS_TYPE_START_IBSS)
Dustin Brownd747ecd2018-10-26 16:32:22 -07005407 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005408 mac_handle,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005409 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005410 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Abhinav Kumar19a7a402018-07-12 17:36:57 +05305411 else if (adapter->device_mode == QDF_STA_MODE)
5412 wlan_hdd_disconnect(adapter,
5413 eCSR_DISCONNECT_REASON_DEAUTH);
5414 else
Dustin Brownd747ecd2018-10-26 16:32:22 -07005415 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005416 mac_handle,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005417 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005418 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005419 /* success implies disconnect is queued */
5420 if (QDF_IS_STATUS_SUCCESS(status) &&
5421 adapter->device_mode != QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005422 rc = wait_for_completion_timeout(
5423 &adapter->disconnect_comp_var,
5424 msecs_to_jiffies
5425 (WLAN_WAIT_TIME_DISCONNECT));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005426 if (!rc)
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005427 hdd_warn("disconn_comp_var wait fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005428 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005429 if (QDF_IS_STATUS_ERROR(status))
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005430 hdd_warn("failed to post disconnect");
Dustin Brownd747ecd2018-10-26 16:32:22 -07005431
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005432 memset(&wrqu, '\0', sizeof(wrqu));
5433 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
5434 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
5435 wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu,
5436 NULL);
Sachin Ahuja988fd102016-09-15 17:16:25 +05305437 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005438
Dustin Brownd747ecd2018-10-26 16:32:22 -07005439 wlan_hdd_scan_abort(adapter);
Wu Gao4a1ec8c2018-07-23 19:18:40 +08005440 wlan_hdd_cleanup_actionframe(adapter);
Abhishek Singh1e94d7a2015-11-30 17:26:54 +05305441 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05305442 hdd_clear_fils_connection_info(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005443 hdd_deregister_tx_flow_control(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005444
5445#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005446 cancel_work_sync(&adapter->ipv4_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005447#ifdef WLAN_NS_OFFLOAD
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005448 cancel_work_sync(&adapter->ipv6_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005449#endif
5450#endif
5451
Min Liu8c5d99e2018-09-10 17:18:44 +08005452 if (adapter->device_mode == QDF_STA_MODE) {
5453 struct wlan_objmgr_vdev *vdev;
5454
5455 vdev = hdd_objmgr_get_vdev(adapter);
5456 if (vdev) {
5457 wlan_cfg80211_sched_scan_stop(vdev);
5458 hdd_objmgr_put_vdev(adapter);
5459 }
5460 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08005461
5462 if (wlan_hdd_try_disconnect(adapter)) {
Dustin Brownd747ecd2018-10-26 16:32:22 -07005463 hdd_err("Can't disconnect adapter");
Dustin Browndb2a8be2017-12-20 11:49:56 -08005464 return QDF_STATUS_E_FAILURE;
Krunal Soni985b8132017-02-10 18:49:08 -08005465 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08005466
Himanshu Agarwalb229a142017-12-21 10:16:45 +05305467 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005468 break;
5469
Rajeev Kumar3b906202018-02-01 10:55:14 -08005470 case QDF_MONITOR_MODE:
5471 wlan_hdd_scan_abort(adapter);
5472 hdd_deregister_tx_flow_control(adapter);
5473 hdd_vdev_destroy(adapter);
5474 break;
5475
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005476 case QDF_SAP_MODE:
Will Huang7049bae2018-08-13 17:25:02 +08005477 if (test_bit(ACS_PENDING, &adapter->event_flags)) {
5478 cds_flush_delayed_work(&adapter->acs_pending_work);
5479 clear_bit(ACS_PENDING, &adapter->event_flags);
5480 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005481
wadesongf9b15ed2017-12-14 14:12:32 +08005482 wlan_hdd_scan_abort(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005483
Arunk Khandavalli96c122f2017-10-17 11:49:36 +05305484 sap_config = &adapter->session.ap.sap_config;
Dustin Brownd747ecd2018-10-26 16:32:22 -07005485 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
5486
Dustin Brown07901ec2018-09-07 11:02:41 -07005487 ucfg_ipa_flush(hdd_ctx->pdev);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005488
Liangwei Dongad89c762018-06-01 01:56:23 -04005489 if (!(flag & HDD_IN_CAC_WORK_TH_CONTEXT))
5490 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
Jeff Johnson46807cd2018-04-29 21:32:22 -07005491 /* fallthrough */
Dustin Browna5cf8e02017-10-19 16:04:19 -07005492
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005493 case QDF_P2P_GO_MODE:
Krunal Soni22208392017-09-29 18:10:34 -07005494 cds_flush_work(&adapter->sap_stop_bss_work);
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05305495 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Dustin Browna5cf8e02017-10-19 16:04:19 -07005496 wlan_hdd_undo_acs(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005497
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005498 if (adapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005499 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5500
5501 hdd_deregister_tx_flow_control(adapter);
Kapil Guptac1224bf2017-06-22 21:22:40 +05305502 hdd_destroy_acs_timer(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005503
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005504 mutex_lock(&hdd_ctx->sap_lock);
5505 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005506 status = wlansap_stop_bss(
5507 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005508
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305509 if (QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonca2530c2017-09-30 18:25:40 -07005510 struct hdd_hostapd_state *hostapd_state =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005511 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +05305512 qdf_event_reset(&hostapd_state->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305513 qdf_stop_bss_event);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005514 status = qdf_wait_for_event_completion(
Nachiket Kukade0396b732017-11-14 16:35:16 +05305515 &hostapd_state->qdf_stop_bss_event,
Vignesh Viswanathan865daaa2018-10-11 19:30:44 +05305516 SME_CMD_START_STOP_BSS_TIMEOUT);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005517 if (QDF_IS_STATUS_ERROR(status))
Jeff Johnson5880d792016-08-15 13:32:30 -07005518 hdd_err("failure waiting for wlansap_stop_bss %d",
Dustin Brownd747ecd2018-10-26 16:32:22 -07005519 status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005520 } else {
Jeff Johnson5880d792016-08-15 13:32:30 -07005521 hdd_err("failure in wlansap_stop_bss");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005522 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005523
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005524 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -07005525 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005526 adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005527 adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07005528 hdd_green_ap_start_state_mc(hdd_ctx,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305529 adapter->device_mode,
5530 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005531
Anurag Chouhanc5548422016-02-24 18:33:27 +05305532 qdf_copy_macaddr(&updateIE.bssid,
Jeff Johnson1e851a12017-10-28 14:36:12 -07005533 &adapter->mac_addr);
Jeff Johnson1b780e42017-10-31 14:11:45 -07005534 updateIE.smeSessionId = adapter->session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005535 updateIE.ieBufferlength = 0;
5536 updateIE.pAdditionIEBuffer = NULL;
5537 updateIE.append = false;
5538 updateIE.notify = false;
Dustin Brownd747ecd2018-10-26 16:32:22 -07005539
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005540 /* Probe bcn reset */
Dustin Brownd747ecd2018-10-26 16:32:22 -07005541 status = sme_update_add_ie(mac_handle, &updateIE,
5542 eUPDATE_IE_PROBE_BCN);
5543 if (status == QDF_STATUS_E_FAILURE)
5544 hdd_err("Could not pass PROBE_RSP_BCN to PE");
5545
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005546 /* Assoc resp reset */
Dustin Brownd747ecd2018-10-26 16:32:22 -07005547 status = sme_update_add_ie(mac_handle, &updateIE,
5548 eUPDATE_IE_ASSOC_RESP);
5549 if (status == QDF_STATUS_E_FAILURE)
5550 hdd_err("Could not pass ASSOC_RSP to PE");
5551
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005552 /* Reset WNI_CFG_PROBE_RSP Flags */
5553 wlan_hdd_reset_prob_rspies(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005554 }
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08005555 clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
Jeff Johnsonb9424862017-10-30 08:49:35 -07005556 qdf_mem_free(adapter->session.ap.beacon);
5557 adapter->session.ap.beacon = NULL;
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08005558
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305559 /*
5560 * If Do_Not_Break_Stream was enabled clear avoid channel list.
5561 */
Min Liu8c5d99e2018-09-10 17:18:44 +08005562 vdev = hdd_objmgr_get_vdev(adapter);
5563 if (vdev) {
5564 if (policy_mgr_is_dnsc_set(vdev))
5565 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
5566 hdd_objmgr_put_vdev(adapter);
5567 }
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305568
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305569#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005570 cancel_work_sync(&adapter->ipv4_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305571#ifdef WLAN_NS_OFFLOAD
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005572 cancel_work_sync(&adapter->ipv6_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305573#endif
5574#endif
Dustin Browndb2a8be2017-12-20 11:49:56 -08005575
5576 hdd_vdev_destroy(adapter);
5577
Krunal Sonib51eec72017-11-20 21:53:01 -08005578 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005579 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005580 case QDF_OCB_MODE:
Dustin Brownd747ecd2018-10-26 16:32:22 -07005581 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Krishna Kumaar Natarajane58b4092017-01-25 15:47:35 -08005582 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
Dustin Brownd747ecd2018-10-26 16:32:22 -07005583 cds_get_context(QDF_MODULE_ID_TXRX),
5584 sta_ctx->conn_info.staId[0]);
Zhang Qian79d0d132018-02-05 13:40:16 +08005585 hdd_deregister_tx_flow_control(adapter);
5586 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005587 break;
5588 default:
5589 break;
5590 }
5591
Ajit Pal Singh106c1412018-04-18 18:08:49 +05305592 hdd_deregister_hl_netdev_fc_timer(adapter);
5593
Dustin Brown04348372017-12-14 16:13:39 -08005594 if (adapter->scan_info.default_scan_ies) {
5595 qdf_mem_free(adapter->scan_info.default_scan_ies);
5596 adapter->scan_info.default_scan_ies = NULL;
5597 }
5598
Dustin Browne74003f2018-03-14 12:51:58 -07005599 hdd_exit();
Dustin Brownd747ecd2018-10-26 16:32:22 -07005600
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305601 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005602}
5603
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305604/**
5605 * hdd_deinit_all_adapters - deinit all adapters
5606 * @hdd_ctx: HDD context
5607 * @rtnl_held: True if RTNL lock held
5608 *
5609 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005610void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305611{
Jeff Johnson9d295242017-08-29 14:39:48 -07005612 struct hdd_adapter *adapter;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305613
Dustin Brown491d54b2018-03-14 12:39:11 -07005614 hdd_enter();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305615
Dustin Brown920397d2017-12-13 16:27:50 -08005616 hdd_for_each_adapter(hdd_ctx, adapter)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305617 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305618
Dustin Browne74003f2018-03-14 12:51:58 -07005619 hdd_exit();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305620}
5621
Dustin Browndb2a8be2017-12-20 11:49:56 -08005622QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005623{
Jeff Johnson9d295242017-08-29 14:39:48 -07005624 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005625
Dustin Brown491d54b2018-03-14 12:39:11 -07005626 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005627
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05305628 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
5629
Dustin Brown920397d2017-12-13 16:27:50 -08005630 hdd_for_each_adapter(hdd_ctx, adapter)
Dustin Browndb2a8be2017-12-20 11:49:56 -08005631 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005632
Dustin Browne74003f2018-03-14 12:51:58 -07005633 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005634
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305635 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005636}
5637
Paul Zhang84fa9382017-11-10 21:18:21 +08005638static void hdd_reset_scan_operation(struct hdd_context *hdd_ctx,
5639 struct hdd_adapter *adapter)
5640{
5641 switch (adapter->device_mode) {
5642 case QDF_STA_MODE:
5643 case QDF_P2P_CLIENT_MODE:
5644 case QDF_IBSS_MODE:
5645 case QDF_P2P_DEVICE_MODE:
5646 case QDF_NDI_MODE:
5647 wlan_hdd_scan_abort(adapter);
5648 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Min Liu8c5d99e2018-09-10 17:18:44 +08005649 if (adapter->device_mode == QDF_STA_MODE) {
5650 struct wlan_objmgr_vdev *vdev;
5651
5652 vdev = hdd_objmgr_get_vdev(adapter);
5653 if (vdev) {
5654 wlan_cfg80211_sched_scan_stop(vdev);
5655 hdd_objmgr_put_vdev(adapter);
5656 }
5657 }
Paul Zhang84fa9382017-11-10 21:18:21 +08005658 break;
5659 case QDF_P2P_GO_MODE:
5660 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5661 break;
5662 case QDF_SAP_MODE:
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05305663 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Paul Zhang84fa9382017-11-10 21:18:21 +08005664 wlan_hdd_undo_acs(adapter);
5665 break;
5666 default:
5667 break;
5668 }
5669}
5670
Ke Huangc067b8d2018-05-21 15:50:13 +08005671#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
5672/**
5673 * hdd_adapter_abort_tx_flow() - Abort the tx flow control
5674 * @pAdapter: pointer to hdd_adapter_t
5675 *
5676 * Resume tx and stop the tx flow control timer if the tx is paused
5677 * and the flow control timer is running. This function is called by
5678 * SSR to avoid the inconsistency of tx status before and after SSR.
5679 *
5680 * Return: void
5681 */
5682static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
5683{
5684 if (adapter->hdd_stats.tx_rx_stats.is_txflow_paused &&
5685 QDF_TIMER_STATE_RUNNING ==
5686 qdf_mc_timer_get_current_state(
5687 &adapter->tx_flow_control_timer)) {
5688 hdd_tx_resume_timer_expired_handler(adapter);
5689 qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
5690 }
5691}
5692#endif
5693
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005694QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005695{
Jeff Johnson9d295242017-08-29 14:39:48 -07005696 struct hdd_adapter *adapter;
Jeff Johnsond377dce2017-10-04 10:32:42 -07005697 struct hdd_station_ctx *sta_ctx;
Yue Mad5b4b9f2017-05-26 16:23:40 -07005698 struct qdf_mac_addr peerMacAddr;
Yue Ma42654682018-01-11 16:55:24 -08005699 int sta_id;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05305700 bool value;
Min Liu8c5d99e2018-09-10 17:18:44 +08005701 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005702
Dustin Brown491d54b2018-03-14 12:39:11 -07005703 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005704
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05305705 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
5706
Dustin Brown920397d2017-12-13 16:27:50 -08005707 hdd_for_each_adapter(hdd_ctx, adapter) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07005708 hdd_info("[SSR] reset adapter with device mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07005709 qdf_opmode_str(adapter->device_mode),
Dustin Brown5e89ef82018-03-14 11:50:23 -07005710 adapter->device_mode);
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305711
Ke Huangc067b8d2018-05-21 15:50:13 +08005712#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
5713 hdd_adapter_abort_tx_flow(adapter);
5714#endif
5715
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305716 if ((adapter->device_mode == QDF_STA_MODE) ||
Paul Zhang679025e2018-03-08 22:39:44 +08005717 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305718 /* Stop tdls timers */
Min Liu8c5d99e2018-09-10 17:18:44 +08005719 vdev = hdd_objmgr_get_vdev(adapter);
5720 if (vdev) {
5721 hdd_notify_tdls_reset_adapter(vdev);
5722 hdd_objmgr_put_vdev(adapter);
5723 }
Paul Zhang679025e2018-03-08 22:39:44 +08005724 adapter->session.station.hdd_reassoc_scenario = false;
5725 }
Dustin Brown05d81302018-09-11 16:49:22 -07005726 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05305727 if (value &&
Arun Khandavallicc544b32017-01-30 19:52:16 +05305728 adapter->device_mode == QDF_SAP_MODE) {
5729 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305730 WLAN_STOP_ALL_NETIF_QUEUE,
Arun Khandavallicc544b32017-01-30 19:52:16 +05305731 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005732 if (test_bit(SOFTAP_BSS_STARTED,
Krunal Sonib51eec72017-11-20 21:53:01 -08005733 &adapter->event_flags))
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005734 hdd_sap_indicate_disconnect_for_sta(adapter);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005735 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
5736 } else {
Arun Khandavallicc544b32017-01-30 19:52:16 +05305737 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305738 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005739 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005740 }
Nijun Gong104ccc72018-08-07 10:43:56 +08005741 /*
5742 * Clear fc flag if it was set before SSR to avoid TX queues
5743 * permanently stopped after SSR.
5744 * Here WLAN_START_ALL_NETIF_QUEUE will actually not start any
5745 * queue since it's blocked by reason WLAN_CONTROL_PATH.
5746 */
5747 if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL))
5748 wlan_hdd_netif_queue_control(adapter,
5749 WLAN_START_ALL_NETIF_QUEUE,
5750 WLAN_DATA_FLOW_CONTROL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005751
Paul Zhang84fa9382017-11-10 21:18:21 +08005752 hdd_reset_scan_operation(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005753
5754 hdd_deinit_tx_rx(adapter);
Dustin Brown1dbefe62018-09-11 16:32:03 -07005755 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005756 adapter->device_mode, adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07005757 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305758 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005759 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
5760 hdd_wmm_adapter_close(adapter);
5761 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
5762 }
5763
Vignesh Viswanathan2eb18742017-09-08 11:18:59 +05305764 if (adapter->device_mode == QDF_STA_MODE)
5765 hdd_clear_fils_connection_info(adapter);
5766
Wu Gao3545e642017-07-14 19:24:41 +08005767 if (adapter->device_mode == QDF_SAP_MODE) {
Jingxiang Geec113592018-08-09 15:40:39 +08005768 wlansap_cleanup_cac_timer(
5769 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Wu Gao3545e642017-07-14 19:24:41 +08005770 /*
5771 * If adapter is SAP, set session ID to invalid
5772 * since SAP session will be cleanup during SSR.
5773 */
Wu Gao36717432016-11-21 15:09:48 +08005774 wlansap_set_invalid_session(
5775 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Wu Gao3545e642017-07-14 19:24:41 +08005776 }
5777
Yue Ma42654682018-01-11 16:55:24 -08005778 /* Delete connection peers if any to avoid peer object leaks */
Yue Mad5b4b9f2017-05-26 16:23:40 -07005779 if (adapter->device_mode == QDF_STA_MODE ||
5780 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
Jeff Johnsond377dce2017-10-04 10:32:42 -07005781 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Yue Mad5b4b9f2017-05-26 16:23:40 -07005782 qdf_copy_macaddr(&peerMacAddr,
Jeff Johnsond377dce2017-10-04 10:32:42 -07005783 &sta_ctx->conn_info.bssId);
Yue Mad5b4b9f2017-05-26 16:23:40 -07005784
Yue Ma42654682018-01-11 16:55:24 -08005785 } else if (adapter->device_mode == QDF_P2P_GO_MODE) {
Wu Gao6b81fc52018-05-24 19:27:27 +08005786 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Yue Ma42654682018-01-11 16:55:24 -08005787 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
5788 if (adapter->sta_info[sta_id].in_use) {
5789 hdd_debug("[SSR] deregister STA with ID %d",
5790 sta_id);
5791 hdd_softap_deregister_sta(adapter,
5792 sta_id);
5793 adapter->sta_info[sta_id].in_use = 0;
5794 }
5795 }
Yue Mad5b4b9f2017-05-26 16:23:40 -07005796 }
5797
Alok Kumarb64650c2018-03-23 17:05:11 +05305798 hdd_nud_ignore_tracking(adapter, true);
Alok Kumar016a1ac2018-09-16 09:55:50 +05305799 hdd_nud_reset_tracking(adapter);
5800 hdd_nud_flush_work(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305801 hdd_set_disconnect_status(adapter, false);
hangtian9c47aaf2018-11-26 17:59:39 +08005802 hdd_stop_tsf_sync(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305803
Tiger Yu94a5a5c2018-03-09 21:22:26 +08005804 hdd_softap_deinit_tx_rx(adapter);
Tiger Yu8c387702018-07-06 16:56:42 +08005805 hdd_deregister_tx_flow_control(adapter);
Tiger Yu94a5a5c2018-03-09 21:22:26 +08005806
Yue Maf9782842017-05-08 12:49:49 -07005807 /* Destroy vdev which will be recreated during reinit. */
5808 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005809 }
5810
Dustin Browne74003f2018-03-14 12:51:58 -07005811 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005812
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305813 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005814}
5815
Dustin Brown4c663222018-10-23 14:19:36 -07005816bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305817{
Dustin Brown920397d2017-12-13 16:27:50 -08005818 struct hdd_adapter *adapter;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305819
Dustin Brown4c663222018-10-23 14:19:36 -07005820 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
Arun Khandavalliba479c42017-07-26 21:29:40 +05305821 hdd_info("FTM mode, don't close the module");
Dustin Brown4c663222018-10-23 14:19:36 -07005822 return true;
Arun Khandavalliba479c42017-07-26 21:29:40 +05305823 }
5824
Dustin Brown920397d2017-12-13 16:27:50 -08005825 hdd_for_each_adapter(hdd_ctx, adapter) {
5826 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
Dustin Brown4c663222018-10-23 14:19:36 -07005827 test_bit(SME_SESSION_OPENED, &adapter->event_flags))
5828 return true;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305829 }
5830
Dustin Brown4c663222018-10-23 14:19:36 -07005831 return false;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305832}
5833
yeshwanth sriram guntukaea63f632017-08-30 19:31:56 +05305834bool hdd_is_interface_up(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05305835{
5836 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
5837 return true;
5838 else
5839 return false;
5840}
5841
Anurag Chouhanc4092922016-09-08 15:56:11 +05305842#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
bingsbdcd4a22017-06-20 09:27:00 +08005843 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
Anurag Chouhanc4092922016-09-08 15:56:11 +05305844struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
5845 struct ieee80211_channel *channel,
5846 const u8 *bssid, const u8 *ssid,
5847 size_t ssid_len)
5848{
5849 return cfg80211_get_bss(wiphy, channel, bssid,
5850 ssid, ssid_len,
5851 WLAN_CAPABILITY_ESS,
5852 WLAN_CAPABILITY_ESS);
5853}
5854#else
5855struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
5856 struct ieee80211_channel *channel,
5857 const u8 *bssid, const u8 *ssid,
5858 size_t ssid_len)
5859{
5860 return cfg80211_get_bss(wiphy, channel, bssid,
5861 ssid, ssid_len,
5862 IEEE80211_BSS_TYPE_ESS,
5863 IEEE80211_PRIVACY_ANY);
5864}
5865#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05305866
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305867#if defined CFG80211_CONNECT_BSS || \
5868 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305869#if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305870 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305871/**
5872 * hdd_convert_timeout_reason() - Convert to kernel specific enum
5873 * @timeout_reason: reason for connect timeout
5874 *
5875 * This function is used to convert host timeout
5876 * reason enum to kernel specific enum.
5877 *
5878 * Return: nl timeout enum
5879 */
5880static enum nl80211_timeout_reason hdd_convert_timeout_reason(
5881 tSirResultCodes timeout_reason)
5882{
5883 switch (timeout_reason) {
5884 case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
5885 return NL80211_TIMEOUT_SCAN;
5886 case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
5887 return NL80211_TIMEOUT_AUTH;
5888 case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
5889 return NL80211_TIMEOUT_ASSOC;
5890 default:
5891 return NL80211_TIMEOUT_UNSPECIFIED;
5892 }
5893}
5894
5895/**
5896 * hdd_cfg80211_connect_timeout() - API to send connection timeout reason
5897 * @dev: network device
5898 * @bssid: bssid to which we want to associate
5899 * @timeout_reason: reason for connect timeout
5900 *
5901 * This API is used to send connection timeout reason to supplicant
5902 *
5903 * Return: void
5904 */
5905static void hdd_cfg80211_connect_timeout(struct net_device *dev,
5906 const u8 *bssid,
5907 tSirResultCodes timeout_reason)
5908{
5909 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005910
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305911 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
5912
5913 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL,
5914 nl_timeout_reason);
5915}
5916
5917/**
5918 * __hdd_connect_bss() - API to send connection status to supplicant
5919 * @dev: network device
5920 * @bssid: bssid to which we want to associate
5921 * @req_ie: Request Information Element
5922 * @req_ie_len: len of the req IE
5923 * @resp_ie: Response IE
5924 * @resp_ie_len: len of ht response IE
5925 * @status: status
5926 * @gfp: Kernel Flag
5927 * @timeout_reason: reason for connect timeout
5928 *
5929 * Return: void
5930 */
5931static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5932 struct cfg80211_bss *bss, const u8 *req_ie,
5933 size_t req_ie_len, const u8 *resp_ie,
5934 size_t resp_ie_len, int status, gfp_t gfp,
5935 tSirResultCodes timeout_reason)
5936{
5937 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005938
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305939 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
5940
5941 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
5942 resp_ie, resp_ie_len, status, gfp,
5943 nl_timeout_reason);
5944}
5945#else
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305946#if defined CFG80211_CONNECT_TIMEOUT || \
5947 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305948static void hdd_cfg80211_connect_timeout(struct net_device *dev,
5949 const u8 *bssid,
5950 tSirResultCodes timeout_reason)
5951{
5952 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL);
5953}
5954#endif
5955
5956static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5957 struct cfg80211_bss *bss, const u8 *req_ie,
5958 size_t req_ie_len, const u8 *resp_ie,
5959 size_t resp_ie_len, int status, gfp_t gfp,
5960 tSirResultCodes timeout_reason)
5961{
5962 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
5963 resp_ie, resp_ie_len, status, gfp);
5964}
5965#endif
5966
Abhishek Singha84d3952016-09-13 13:45:05 +05305967/**
5968 * hdd_connect_bss() - API to send connection status to supplicant
5969 * @dev: network device
5970 * @bssid: bssid to which we want to associate
5971 * @req_ie: Request Information Element
5972 * @req_ie_len: len of the req IE
5973 * @resp_ie: Response IE
5974 * @resp_ie_len: len of ht response IE
5975 * @status: status
5976 * @gfp: Kernel Flag
5977 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305978 * @timeout_reason: reason for connect timeout
Abhishek Singha84d3952016-09-13 13:45:05 +05305979 *
5980 * The API is a wrapper to send connection status to supplicant
5981 *
5982 * Return: Void
5983 */
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305984#if defined CFG80211_CONNECT_TIMEOUT || \
5985 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
Abhishek Singha84d3952016-09-13 13:45:05 +05305986static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5987 struct cfg80211_bss *bss, const u8 *req_ie,
5988 size_t req_ie_len, const u8 *resp_ie,
5989 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305990 bool connect_timeout,
5991 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05305992{
5993 if (connect_timeout)
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305994 hdd_cfg80211_connect_timeout(dev, bssid, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305995 else
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305996 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
5997 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305998}
5999#else
6000static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6001 struct cfg80211_bss *bss, const u8 *req_ie,
6002 size_t req_ie_len, const u8 *resp_ie,
6003 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306004 bool connect_timeout,
6005 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05306006{
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306007 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
6008 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05306009}
6010#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05306011
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306012#if defined(WLAN_FEATURE_FILS_SK)
6013#if defined(CFG80211_CONNECT_DONE) || \
6014 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
6015#if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
6016 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306017/**
6018 * hdd_populate_fils_params() - Populate FILS keys to connect response
6019 * @fils_params: connect response to supplicant
6020 * @fils_kek: FILS kek
6021 * @fils_kek_len: FILS kek length
6022 * @pmk: FILS PMK
6023 * @pmk_len: FILS PMK length
6024 * @pmkid: PMKID
6025 * @fils_seq_num: FILS Seq number
6026 *
6027 * Return: None
6028 */
6029static void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6030 *fils_params, const uint8_t *fils_kek,
6031 size_t fils_kek_len, const uint8_t *pmk,
6032 size_t pmk_len, const uint8_t *pmkid,
6033 uint16_t fils_seq_num)
6034{
6035 /* Increament seq number to be used for next FILS */
6036 fils_params->fils_erp_next_seq_num = fils_seq_num + 1;
6037 fils_params->update_erp_next_seq_num = true;
6038 fils_params->fils_kek = fils_kek;
6039 fils_params->fils_kek_len = fils_kek_len;
6040 fils_params->pmk = pmk;
6041 fils_params->pmk_len = pmk_len;
6042 fils_params->pmkid = pmkid;
6043}
6044#else
6045static inline void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6046 *fils_params, const uint8_t
6047 *fils_kek, size_t fils_kek_len,
6048 const uint8_t *pmk, size_t pmk_len,
6049 const uint8_t *pmkid,
6050 uint16_t fils_seq_num)
6051{ }
6052#endif
6053
Jeff Johnson172237b2017-11-07 15:32:59 -08006054void hdd_update_hlp_info(struct net_device *dev,
6055 struct csr_roam_info *roam_info)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306056{
6057 struct sk_buff *skb;
6058 uint16_t skb_len;
6059 struct llc_snap_hdr_t *llc_hdr;
6060 QDF_STATUS status;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306061 uint8_t *hlp_data;
6062 uint16_t hlp_data_len;
6063 struct fils_join_rsp_params *roam_fils_params
6064 = roam_info->fils_join_rsp;
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306065 struct hdd_adapter *padapter = WLAN_HDD_GET_PRIV_PTR(dev);
6066
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306067 if (!roam_fils_params) {
6068 hdd_err("FILS Roam Param NULL");
6069 return;
6070 }
6071
Srinivas Girigowda3cc8e912017-11-28 18:11:57 -08006072 if (!roam_fils_params->hlp_data_len) {
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306073 hdd_err("FILS HLP Data NULL, len %d",
6074 roam_fils_params->hlp_data_len);
6075 return;
6076 }
6077
6078 hlp_data = roam_fils_params->hlp_data;
6079 hlp_data_len = roam_fils_params->hlp_data_len;
6080
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306081 /* Calculate skb length */
6082 skb_len = (2 * ETH_ALEN) + hlp_data_len;
6083 skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false);
6084 if (skb == NULL) {
6085 hdd_err("HLP packet nbuf alloc fails");
6086 return;
6087 }
6088
6089 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->dst_mac.bytes,
6090 QDF_MAC_ADDR_SIZE);
6091 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->src_mac.bytes,
6092 QDF_MAC_ADDR_SIZE);
6093
6094 llc_hdr = (struct llc_snap_hdr_t *) hlp_data;
6095 if (IS_SNAP(llc_hdr)) {
6096 hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
6097 hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
6098 }
6099
6100 qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len);
6101
6102 /*
6103 * This HLP packet is formed from HLP info encapsulated
6104 * in assoc response frame which is AEAD encrypted.
6105 * Hence, this checksum validation can be set unnecessary.
6106 * i.e. network layer need not worry about checksum.
6107 */
6108 skb->ip_summed = CHECKSUM_UNNECESSARY;
6109
6110 status = hdd_rx_packet_cbk(padapter, skb);
6111 if (QDF_IS_STATUS_ERROR(status)) {
6112 hdd_err("Sending HLP packet fails");
6113 return;
6114 }
6115 hdd_debug("send HLP packet to netif successfully");
6116}
6117
6118/**
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306119 * hdd_connect_done() - Wrapper API to call cfg80211_connect_done
6120 * @dev: network device
6121 * @bssid: bssid to which we want to associate
6122 * @bss: cfg80211 bss info
6123 * @roam_info: information about connected bss
6124 * @req_ie: Request Information Element
6125 * @req_ie_len: len of the req IE
6126 * @resp_ie: Response IE
6127 * @resp_ie_len: len of ht response IE
6128 * @status: status
6129 * @gfp: allocation flags
6130 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
6131 * @timeout_reason: reason for connect timeout
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306132 *
6133 * This API is used as wrapper to send FILS key/sequence number
6134 * params etc. to supplicant in case of FILS connection
6135 *
6136 * Return: None
6137 */
6138static void hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006139 struct cfg80211_bss *bss,
6140 struct csr_roam_info *roam_info,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306141 const u8 *req_ie, size_t req_ie_len,
6142 const u8 *resp_ie, size_t resp_ie_len, u16 status,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006143 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306144 tSirResultCodes timeout_reason)
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306145{
6146 struct cfg80211_connect_resp_params fils_params;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306147 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6148 struct fils_join_rsp_params *roam_fils_params =
6149 roam_info->fils_join_rsp;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006150
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306151 qdf_mem_zero(&fils_params, sizeof(fils_params));
6152
6153 if (!roam_fils_params) {
6154 fils_params.status = WLAN_STATUS_UNSPECIFIED_FAILURE;
6155 } else {
6156 fils_params.status = status;
6157 fils_params.bssid = bssid;
Srinivas Girigowdae975f532018-01-05 14:03:05 -08006158 fils_params.timeout_reason =
6159 hdd_convert_timeout_reason(timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306160 fils_params.req_ie = req_ie;
6161 fils_params.req_ie_len = req_ie_len;
6162 fils_params.resp_ie = resp_ie;
6163 fils_params.resp_ie_len = resp_ie_len;
6164 fils_params.bss = bss;
6165 hdd_populate_fils_params(&fils_params, roam_fils_params->kek,
6166 roam_fils_params->kek_len,
6167 roam_fils_params->fils_pmk,
6168 roam_fils_params->fils_pmk_len,
6169 roam_fils_params->fils_pmkid,
6170 roam_info->fils_seq_num);
Sridhar Selvaraje5260442017-08-19 10:12:03 +05306171 hdd_save_gtk_params(adapter, roam_info, false);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306172 }
6173 hdd_debug("FILS indicate connect status %d seq no %d",
6174 fils_params.status,
6175 fils_params.fils_erp_next_seq_num);
6176
6177 cfg80211_connect_done(dev, &fils_params, gfp);
6178
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306179 if (roam_fils_params && roam_fils_params->hlp_data_len)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306180 hdd_update_hlp_info(dev, roam_info);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306181
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306182 /* Clear all the FILS key info */
6183 if (roam_fils_params && roam_fils_params->fils_pmk)
6184 qdf_mem_free(roam_fils_params->fils_pmk);
6185 if (roam_fils_params)
6186 qdf_mem_free(roam_fils_params);
6187 roam_info->fils_join_rsp = NULL;
6188}
6189#else
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006190static inline void
6191hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006192 struct cfg80211_bss *bss, struct csr_roam_info *roam_info,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006193 const u8 *req_ie, size_t req_ie_len,
6194 const u8 *resp_ie, size_t resp_ie_len, u16 status,
6195 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306196 tSirResultCodes timeout_reason)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306197{ }
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306198#endif
6199#endif
6200
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306201#if defined(WLAN_FEATURE_FILS_SK) && \
6202 (defined(CFG80211_CONNECT_DONE) || \
6203 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306204/**
6205 * hdd_fils_update_connect_results() - API to send fils connection status to
6206 * supplicant.
6207 * @dev: network device
6208 * @bssid: bssid to which we want to associate
6209 * @bss: cfg80211 bss info
6210 * @roam_info: information about connected bss
6211 * @req_ie: Request Information Element
6212 * @req_ie_len: len of the req IE
6213 * @resp_ie: Response IE
6214 * @resp_ie_len: len of ht response IE
6215 * @status: status
6216 * @gfp: allocation flags
6217 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
6218 * @timeout_reason: reason for connect timeout
6219 *
6220 * The API is a wrapper to send connection status to supplicant
6221 *
6222 * Return: 0 if success else failure
6223 */
6224static int hdd_fils_update_connect_results(struct net_device *dev,
6225 const u8 *bssid,
6226 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08006227 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306228 size_t req_ie_len, const u8 *resp_ie,
6229 size_t resp_ie_len, u16 status, gfp_t gfp,
6230 bool connect_timeout,
6231 tSirResultCodes timeout_reason)
6232{
Dustin Brown491d54b2018-03-14 12:39:11 -07006233 hdd_enter();
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306234 if (!roam_info || !roam_info->is_fils_connection)
6235 return -EINVAL;
6236
6237 hdd_connect_done(dev, bssid, bss, roam_info, req_ie, req_ie_len,
6238 resp_ie, resp_ie_len, status, gfp, connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306239 timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306240 return 0;
6241}
6242#else
6243static inline int hdd_fils_update_connect_results(struct net_device *dev,
6244 const u8 *bssid,
6245 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08006246 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306247 size_t req_ie_len, const u8 *resp_ie,
6248 size_t resp_ie_len, u16 status, gfp_t gfp,
6249 bool connect_timeout,
6250 tSirResultCodes timeout_reason)
6251{
6252 return -EINVAL;
6253}
6254#endif
6255
Anurag Chouhanc4092922016-09-08 15:56:11 +05306256/**
6257 * hdd_connect_result() - API to send connection status to supplicant
6258 * @dev: network device
6259 * @bssid: bssid to which we want to associate
6260 * @roam_info: information about connected bss
6261 * @req_ie: Request Information Element
6262 * @req_ie_len: len of the req IE
6263 * @resp_ie: Response IE
6264 * @resp_ie_len: len of ht response IE
6265 * @status: status
6266 * @gfp: Kernel Flag
Abhishek Singha84d3952016-09-13 13:45:05 +05306267 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306268 * @timeout_reason: reason for connect timeout
Anurag Chouhanc4092922016-09-08 15:56:11 +05306269 *
6270 * The API is a wrapper to send connection status to supplicant
6271 * and allow runtime suspend
6272 *
6273 * Return: Void
6274 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05306275void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006276 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306277 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05306278 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306279 bool connect_timeout,
6280 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05306281{
Jeff Johnson9d295242017-08-29 14:39:48 -07006282 struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306283 struct cfg80211_bss *bss = NULL;
Jingxiang Ge929c7932018-01-24 14:01:12 +08006284 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(padapter);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306285
6286 if (WLAN_STATUS_SUCCESS == status) {
6287 struct ieee80211_channel *chan;
6288 int freq;
6289 int chan_no = roam_info->pBssDesc->channelId;
6290
6291 if (chan_no <= 14)
6292 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07006293 HDD_NL80211_BAND_2GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306294 else
6295 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07006296 HDD_NL80211_BAND_5GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306297
6298 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
6299 bss = hdd_cfg80211_get_bss(padapter->wdev.wiphy, chan, bssid,
6300 roam_info->u.pConnectedProfile->SSID.ssId,
6301 roam_info->u.pConnectedProfile->SSID.length);
6302 }
Komal Seelama89be8d2016-09-29 11:09:26 +05306303
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306304 if (hdd_fils_update_connect_results(dev, bssid, bss,
6305 roam_info, req_ie, req_ie_len, resp_ie,
6306 resp_ie_len, status, gfp, connect_timeout,
6307 timeout_reason) != 0) {
6308 hdd_connect_bss(dev, bssid, bss, req_ie,
6309 req_ie_len, resp_ie, resp_ie_len,
6310 status, gfp, connect_timeout, timeout_reason);
6311 }
Komal Seelama89be8d2016-09-29 11:09:26 +05306312
Jingxiang Geb49aa302018-01-17 20:54:15 +08006313 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07006314 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306315}
6316#else
6317void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006318 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306319 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05306320 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306321 bool connect_timeout,
6322 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05306323{
Jeff Johnson9d295242017-08-29 14:39:48 -07006324 struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev);
Jingxiang Ge929c7932018-01-24 14:01:12 +08006325 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(padapter);
Komal Seelama89be8d2016-09-29 11:09:26 +05306326
Anurag Chouhanc4092922016-09-08 15:56:11 +05306327 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
6328 resp_ie, resp_ie_len, status, gfp);
Prashanth Bhatta87b6dc02017-01-19 15:17:58 -08006329
Jingxiang Geb49aa302018-01-17 20:54:15 +08006330 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07006331 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306332}
6333#endif
6334
Nirav Shah73713f72018-05-17 14:50:41 +05306335#ifdef FEATURE_MONITOR_MODE_SUPPORT
Jeff Johnsond9952752018-04-18 12:15:35 -07006336int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
6337 uint32_t bandwidth)
6338{
6339 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6340 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
6341 struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info;
6342 QDF_STATUS status;
Jeff Johnson43837af2018-10-17 12:44:05 -07006343 mac_handle_t mac_handle = hdd_ctx->mac_handle;
Jeff Johnsond9952752018-04-18 12:15:35 -07006344 struct qdf_mac_addr bssid;
6345 struct csr_roam_profile roam_profile;
6346 struct ch_params ch_params;
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006347 eConnectionState connstate;
Jeff Johnsond9952752018-04-18 12:15:35 -07006348
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006349 if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
6350 adapter->device_mode != QDF_STA_MODE) {
6351 hdd_err("Not supported, device is not in monitor mode or sta mission mode");
Jeff Johnsond9952752018-04-18 12:15:35 -07006352 return -EINVAL;
6353 }
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006354 if (adapter->device_mode == QDF_STA_MODE &&
6355 hdd_ctx->config->enable_change_channel_bandwidth) {
6356 connstate = sta_ctx->conn_info.connState;
6357 if (eConnectionState_Associated == connstate ||
6358 eConnectionState_Connecting == connstate) {
6359 return -EINVAL;
6360 }
6361 }
Jeff Johnsond9952752018-04-18 12:15:35 -07006362
Visweswara Tanuku006313a2018-04-12 12:26:34 +05306363 /* Validate Channel */
6364 if (!WLAN_REG_IS_24GHZ_CH(chan) && !WLAN_REG_IS_5GHZ_CH(chan)) {
6365 hdd_err("Channel %d Not supported", chan);
6366 return -EINVAL;
6367 }
6368
6369 if (WLAN_REG_IS_24GHZ_CH(chan)) {
6370 if (bandwidth == CH_WIDTH_80MHZ) {
6371 hdd_err("BW80 not possible in 2.4GHz band");
6372 return -EINVAL;
6373 }
6374 if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 14) &&
6375 (bandwidth != CH_WIDTH_MAX)) {
6376 hdd_err("Only BW20 possible on channel 14");
6377 return -EINVAL;
6378 }
6379 }
6380
6381 if (WLAN_REG_IS_5GHZ_CH(chan)) {
6382 if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 165) &&
6383 (bandwidth != CH_WIDTH_MAX)) {
6384 hdd_err("Only BW20 possible on channel 165");
6385 return -EINVAL;
6386 }
6387 }
6388
Jeff Johnsond9952752018-04-18 12:15:35 -07006389 hdd_debug("Set monitor mode Channel %d", chan);
6390 qdf_mem_zero(&roam_profile, sizeof(roam_profile));
6391 roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
6392 roam_profile.ChannelInfo.numOfChannels = 1;
6393 roam_profile.phyMode = ch_info->phy_mode;
6394 roam_profile.ch_params.ch_width = bandwidth;
6395 hdd_select_cbmode(adapter, chan, &roam_profile.ch_params);
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006396 if (hdd_ctx->config->enable_change_channel_bandwidth &&
Jeff Johnson43837af2018-10-17 12:44:05 -07006397 (!sme_find_session_by_bssid(mac_handle, adapter->mac_addr.bytes))) {
6398 status = sme_create_mon_session(mac_handle,
Rajeev Kumar Sirasanagandlae3b59912018-08-24 15:53:31 +05306399 adapter->mac_addr.bytes,
6400 adapter->session_id);
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006401 if (status != QDF_STATUS_SUCCESS) {
6402 hdd_err("Status: %d Failed to create session.",
6403 status);
6404 return qdf_status_to_os_return(status);
6405 }
6406 }
Jeff Johnsond9952752018-04-18 12:15:35 -07006407 qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
6408 QDF_MAC_ADDR_SIZE);
6409
6410 ch_params.ch_width = bandwidth;
Dustin Brown07901ec2018-09-07 11:02:41 -07006411 wlan_reg_set_channel_params(hdd_ctx->pdev, chan, 0, &ch_params);
Jeff Johnsond9952752018-04-18 12:15:35 -07006412 if (ch_params.ch_width == CH_WIDTH_INVALID) {
6413 hdd_err("Invalid capture channel or bandwidth for a country");
6414 return -EINVAL;
6415 }
6416 if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan,
6417 POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
6418 hdd_err("Failed to change hw mode");
6419 return -EINVAL;
6420 }
6421
Jeff Johnson16528362018-06-14 12:34:16 -07006422 status = sme_roam_channel_change_req(hdd_ctx->mac_handle,
6423 bssid, &ch_params,
Jeff Johnsond9952752018-04-18 12:15:35 -07006424 &roam_profile);
6425 if (status) {
6426 hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
6427 status);
6428 }
6429
6430 adapter->mon_chan = chan;
6431 adapter->mon_bandwidth = bandwidth;
6432 return qdf_status_to_os_return(status);
6433}
Nirav Shah73713f72018-05-17 14:50:41 +05306434#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05306435
Wu Gaodf929f12018-05-25 18:12:25 +08006436#ifdef MSM_PLATFORM
6437/**
6438 * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO
6439 * @adapter: pointer to adapter
6440 *
6441 * This function calls cfg80211 API to stop P2P GO
6442 *
6443 * Return: None
6444 */
6445static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
6446{
6447 hdd_debug("[SSR] send stop ap to supplicant");
6448 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
6449}
6450
6451static inline void hdd_delete_sta(struct hdd_adapter *adapter)
6452{
6453}
6454#else
6455static inline void hdd_stop_p2p_go(struct hdd_adapter *adapter)
6456{
6457}
6458
6459/**
6460 * hdd_delete_sta() - call cfg80211 API to delete STA
6461 * @adapter: pointer to adapter
6462 *
6463 * This function calls cfg80211 API to delete STA
6464 *
6465 * Return: None
6466 */
6467static void hdd_delete_sta(struct hdd_adapter *adapter)
6468{
6469 struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
6470
6471 hdd_debug("[SSR] send restart supplicant");
6472 /* event supplicant to restart */
6473 cfg80211_del_sta(adapter->dev,
6474 (const u8 *)&bcast_mac.bytes[0],
6475 GFP_KERNEL);
6476}
6477#endif
6478
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006479QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006480{
Jeff Johnson9d295242017-08-29 14:39:48 -07006481 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006482 eConnectionState connState;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05306483 bool value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006484
Dustin Brown491d54b2018-03-14 12:39:11 -07006485 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006486
Dustin Brown920397d2017-12-13 16:27:50 -08006487 hdd_for_each_adapter(hdd_ctx, adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05306488 if (!hdd_is_interface_up(adapter))
Dustin Brown920397d2017-12-13 16:27:50 -08006489 continue;
Arun Khandavallifae92942016-08-01 13:31:08 +05306490
Yue Ma42654682018-01-11 16:55:24 -08006491 hdd_debug("[SSR] start adapter with device mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07006492 qdf_opmode_str(adapter->device_mode),
Yue Ma42654682018-01-11 16:55:24 -08006493 adapter->device_mode);
6494
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006495 hdd_wmm_init(adapter);
6496
6497 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006498 case QDF_STA_MODE:
6499 case QDF_P2P_CLIENT_MODE:
6500 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006501
6502 connState = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
6503 ->conn_info.connState;
6504
Krunal Sonib51eec72017-11-20 21:53:01 -08006505 hdd_start_station_adapter(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006506 /* Open the gates for HDD to receive Wext commands */
Jeff Johnsonc72c5732017-10-28 12:49:37 -07006507 adapter->is_link_up_service_needed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006508
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006509 /* Indicate disconnect event to supplicant
6510 * if associated previously
6511 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006512 if (eConnectionState_Associated == connState ||
Yue Macd961442015-10-20 16:15:31 -07006513 eConnectionState_IbssConnected == connState ||
6514 eConnectionState_NotConnected == connState ||
6515 eConnectionState_IbssDisconnected == connState ||
6516 eConnectionState_Disconnecting == connState) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006517 union iwreq_data wrqu;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006518
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006519 memset(&wrqu, '\0', sizeof(wrqu));
6520 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6521 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
6522 wireless_send_event(adapter->dev, SIOCGIWAP,
6523 &wrqu, NULL);
Jeff Johnsonb9424862017-10-30 08:49:35 -07006524 adapter->session.station.
Jeff Johnson690fe952017-10-25 11:48:39 -07006525 hdd_reassoc_scenario = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006526
6527 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05306528 wlan_hdd_cfg80211_indicate_disconnect(
6529 adapter->dev, false,
6530 WLAN_REASON_UNSPECIFIED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006531 } else if (eConnectionState_Connecting == connState) {
6532 /*
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006533 * Indicate connect failure to supplicant if we
6534 * were in the process of connecting
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006535 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05306536 hdd_connect_result(adapter->dev, NULL, NULL,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306537 NULL, 0, NULL, 0,
6538 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006539 GFP_KERNEL, false, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006540 }
6541
6542 hdd_register_tx_flow_control(adapter,
6543 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08006544 hdd_tx_resume_cb,
6545 hdd_tx_flow_control_is_pause);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006546
Arunk Khandavalli40943af2017-05-15 19:25:34 +05306547 hdd_lpass_notify_start(hdd_ctx, adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05306548 hdd_nud_ignore_tracking(adapter, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006549 break;
6550
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006551 case QDF_SAP_MODE:
Dustin Brown05d81302018-09-11 16:49:22 -07006552 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05306553 &value);
6554 if (value)
Krunal Sonib51eec72017-11-20 21:53:01 -08006555 hdd_start_ap_adapter(adapter);
Arun Khandavallicc544b32017-01-30 19:52:16 +05306556
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006557 break;
6558
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006559 case QDF_P2P_GO_MODE:
Wu Gaodf929f12018-05-25 18:12:25 +08006560 hdd_delete_sta(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006561 break;
Arunk Khandavalli062fb032017-10-04 12:18:15 +05306562 case QDF_MONITOR_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08006563 hdd_start_station_adapter(adapter);
Arunk Khandavalli062fb032017-10-04 12:18:15 +05306564 hdd_set_mon_rx_cb(adapter->dev);
6565 wlan_hdd_set_mon_chan(adapter, adapter->mon_chan,
6566 adapter->mon_bandwidth);
6567 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006568 default:
6569 break;
6570 }
Krunal Soni9c2ee032017-07-18 13:49:54 -07006571 /*
6572 * Action frame registered in one adapter which will
6573 * applicable to all interfaces
6574 */
6575 wlan_hdd_cfg80211_register_frames(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006576 }
6577
Wu Gaodf929f12018-05-25 18:12:25 +08006578 hdd_for_each_adapter(hdd_ctx, adapter) {
6579 if (!hdd_is_interface_up(adapter))
6580 continue;
6581
6582 if (adapter->device_mode == QDF_P2P_GO_MODE)
6583 hdd_stop_p2p_go(adapter);
6584 }
6585
Dustin Browne74003f2018-03-14 12:51:58 -07006586 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006587
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306588 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006589}
6590
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006591QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006592 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006593{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306594 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006595 qdf_list_node_t *node;
6596
6597 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006598
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006599 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006600 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006601 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006602
6603 if (QDF_IS_STATUS_ERROR(status))
6604 return status;
6605
6606 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6607
6608 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006609}
6610
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006611QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006612 struct hdd_adapter *current_adapter,
6613 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006614{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306615 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006616 qdf_list_node_t *node;
6617
6618 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006619
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006620 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Jeff Johnson19fc8e42017-10-30 19:53:49 -07006621 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
Dustin Brown920397d2017-12-13 16:27:50 -08006622 &current_adapter->node,
6623 &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006624 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006625
6626 if (QDF_IS_STATUS_ERROR(status))
6627 return status;
6628
6629 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6630
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006631 return status;
6632}
6633
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006634QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006635 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006636{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306637 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006638
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006639 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006640 status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006641 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006642
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006643 return status;
6644}
6645
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006646QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006647 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006648{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306649 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006650 qdf_list_node_t *node;
6651
6652 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006653
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006654 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006655 status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006656 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006657
6658 if (QDF_IS_STATUS_ERROR(status))
6659 return status;
6660
6661 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6662
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006663 return status;
6664}
6665
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006666QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006667 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006668{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306669 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006670
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006671 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006672 status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006673 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006674
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006675 return status;
6676}
6677
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006678QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006679 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006680{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306681 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006682
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006683 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006684 status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006685 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006686
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006687 return status;
6688}
6689
Liangwei Dong3abfe8f2018-09-20 02:25:44 -04006690struct hdd_adapter *hdd_get_adapter_by_rand_macaddr(
6691 struct hdd_context *hdd_ctx, tSirMacAddr mac_addr)
6692{
6693 struct hdd_adapter *adapter;
6694
6695 hdd_for_each_adapter(hdd_ctx, adapter) {
6696 if ((adapter->device_mode == QDF_STA_MODE ||
6697 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6698 adapter->device_mode == QDF_P2P_DEVICE_MODE) &&
6699 ucfg_p2p_check_random_mac(hdd_ctx->psoc,
6700 adapter->session_id, mac_addr))
6701 return adapter;
6702 }
6703
6704 return NULL;
6705}
6706
Jeff Johnson9d295242017-08-29 14:39:48 -07006707struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006708 tSirMacAddr macAddr)
6709{
Jeff Johnson9d295242017-08-29 14:39:48 -07006710 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006711
Dustin Brown920397d2017-12-13 16:27:50 -08006712 hdd_for_each_adapter(hdd_ctx, adapter) {
6713 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
6714 macAddr, sizeof(tSirMacAddr)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006715 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006716 }
6717
6718 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006719}
6720
Jeff Johnson9d295242017-08-29 14:39:48 -07006721struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006722 uint32_t vdev_id)
6723{
Jeff Johnson9d295242017-08-29 14:39:48 -07006724 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006725
Dustin Brown920397d2017-12-13 16:27:50 -08006726 hdd_for_each_adapter(hdd_ctx, adapter) {
Jeff Johnson1b780e42017-10-31 14:11:45 -07006727 if (adapter->session_id == vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006728 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006729 }
6730
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006731 return NULL;
6732}
6733
Abhishek Singh7996eb72015-12-30 17:24:02 +05306734/**
6735 * hdd_get_adapter_by_sme_session_id() - Return adapter with
6736 * the sessionid
6737 * @hdd_ctx: hdd context.
6738 * @sme_session_id: sme session is for the adapter to get.
6739 *
6740 * This function is used to get the adapter with provided session id
6741 *
6742 * Return: adapter pointer if found
6743 *
6744 */
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07006745struct hdd_adapter *
6746hdd_get_adapter_by_sme_session_id(struct hdd_context *hdd_ctx,
6747 uint32_t sme_session_id)
Abhishek Singh7996eb72015-12-30 17:24:02 +05306748{
Jeff Johnson9d295242017-08-29 14:39:48 -07006749 struct hdd_adapter *adapter;
Abhishek Singh7996eb72015-12-30 17:24:02 +05306750
Dustin Brown920397d2017-12-13 16:27:50 -08006751 hdd_for_each_adapter(hdd_ctx, adapter) {
6752 if (adapter->session_id == sme_session_id)
Abhishek Singh7996eb72015-12-30 17:24:02 +05306753 return adapter;
Abhishek Singh7996eb72015-12-30 17:24:02 +05306754 }
Dustin Brown920397d2017-12-13 16:27:50 -08006755
Abhishek Singh7996eb72015-12-30 17:24:02 +05306756 return NULL;
6757}
6758
Jeff Johnson9d295242017-08-29 14:39:48 -07006759struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
Naveen Rawat4edb6822017-04-12 10:09:17 -07006760 const char *iface_name)
6761{
Jeff Johnson9d295242017-08-29 14:39:48 -07006762 struct hdd_adapter *adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07006763
Dustin Brown920397d2017-12-13 16:27:50 -08006764 hdd_for_each_adapter(hdd_ctx, adapter) {
6765 if (!qdf_str_cmp(adapter->dev->name, iface_name))
Naveen Rawat4edb6822017-04-12 10:09:17 -07006766 return adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07006767 }
Dustin Brown920397d2017-12-13 16:27:50 -08006768
Naveen Rawat4edb6822017-04-12 10:09:17 -07006769 return NULL;
6770}
6771
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006772/**
6773 * hdd_get_adapter() - to get adapter matching the mode
6774 * @hdd_ctx: hdd context
6775 * @mode: adapter mode
6776 *
6777 * This routine will return the pointer to adapter matching
6778 * with the passed mode.
6779 *
6780 * Return: pointer to adapter or null
6781 */
Jeff Johnson9d295242017-08-29 14:39:48 -07006782struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08006783 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006784{
Jeff Johnson9d295242017-08-29 14:39:48 -07006785 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006786
Dustin Brown920397d2017-12-13 16:27:50 -08006787 hdd_for_each_adapter(hdd_ctx, adapter) {
6788 if (adapter->device_mode == mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006789 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006790 }
6791
6792 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006793}
6794
Jeff Johnson36a0abf2018-05-20 11:24:25 -07006795enum QDF_OPMODE hdd_get_device_mode(uint32_t session_id)
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05306796{
6797 struct hdd_context *hdd_ctx;
6798 struct hdd_adapter *adapter;
6799
6800 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6801 if (!hdd_ctx) {
6802 hdd_err("Invalid HDD context");
6803 return QDF_MAX_NO_OF_MODE;
6804 }
6805
6806 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
6807 if (!adapter) {
6808 hdd_err("Invalid HDD adapter");
6809 return QDF_MAX_NO_OF_MODE;
6810 }
6811
6812 return adapter->device_mode;
6813}
6814
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006815/**
6816 * hdd_get_operating_channel() - return operating channel of the device mode
6817 * @hdd_ctx: Pointer to the HDD context.
6818 * @mode: Device mode for which operating channel is required.
Jeff Johnson77f89bb2018-05-06 16:21:36 -07006819 * Supported modes:
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006820 * QDF_STA_MODE,
6821 * QDF_P2P_CLIENT_MODE,
6822 * QDF_SAP_MODE,
6823 * QDF_P2P_GO_MODE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006824 *
6825 * This API returns the operating channel of the requested device mode
6826 *
6827 * Return: channel number. "0" id the requested device is not found OR it is
6828 * not connected.
6829 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006830uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08006831 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006832{
Jeff Johnson9d295242017-08-29 14:39:48 -07006833 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006834 uint8_t operatingChannel = 0;
6835
Dustin Brown920397d2017-12-13 16:27:50 -08006836 hdd_for_each_adapter(hdd_ctx, adapter) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006837 if (mode == adapter->device_mode) {
6838 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006839 case QDF_STA_MODE:
6840 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006841 if (hdd_conn_is_connected
6842 (WLAN_HDD_GET_STATION_CTX_PTR
6843 (adapter))) {
6844 operatingChannel =
6845 (WLAN_HDD_GET_STATION_CTX_PTR
6846 (adapter))->conn_info.
6847 operationChannel;
6848 }
6849 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006850 case QDF_SAP_MODE:
6851 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006852 /* softap connection info */
6853 if (test_bit
6854 (SOFTAP_BSS_STARTED,
6855 &adapter->event_flags))
6856 operatingChannel =
6857 (WLAN_HDD_GET_AP_CTX_PTR
Jeff Johnson01206862017-10-27 20:55:59 -07006858 (adapter))->operating_channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006859 break;
6860 default:
6861 break;
6862 }
6863
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006864 /* Found the device of interest. break the loop */
6865 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006866 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006867 }
Dustin Brown920397d2017-12-13 16:27:50 -08006868
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006869 return operatingChannel;
6870}
6871
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006872static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006873 hdd_ctx)
6874{
Jeff Johnson9d295242017-08-29 14:39:48 -07006875 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006876
Dustin Brown491d54b2018-03-14 12:39:11 -07006877 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006878
Dustin Brown920397d2017-12-13 16:27:50 -08006879 hdd_for_each_adapter(hdd_ctx, adapter) {
6880 if (adapter->device_mode == QDF_STA_MODE ||
6881 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6882 adapter->device_mode == QDF_IBSS_MODE ||
6883 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
6884 adapter->device_mode == QDF_SAP_MODE ||
6885 adapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006886 hdd_unregister_wext(adapter->dev);
6887 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006888 }
6889
Dustin Browne74003f2018-03-14 12:51:58 -07006890 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006891
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306892 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006893}
6894
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006895QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006896{
Jeff Johnson9d295242017-08-29 14:39:48 -07006897 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006898
Dustin Brown491d54b2018-03-14 12:39:11 -07006899 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006900
Dustin Brown920397d2017-12-13 16:27:50 -08006901 hdd_for_each_adapter(hdd_ctx, adapter) {
6902 if (adapter->device_mode == QDF_STA_MODE ||
6903 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6904 adapter->device_mode == QDF_IBSS_MODE ||
6905 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
6906 adapter->device_mode == QDF_SAP_MODE ||
6907 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brown07901ec2018-09-07 11:02:41 -07006908 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
Jeff Johnson1b780e42017-10-31 14:11:45 -07006909 adapter->session_id, INVALID_SCAN_ID,
Vignesh Viswanathan19611c82018-01-16 16:20:40 +05306910 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006911 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006912 }
6913
Dustin Browne74003f2018-03-14 12:51:58 -07006914 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006915
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306916 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006917}
6918
Dustin Brownf27bce82016-11-03 12:52:27 -07006919/**
6920 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
6921 * adapters
6922 * @hdd_ctx: The HDD context containing the adapters to operate on
6923 *
6924 * return: QDF_STATUS_SUCCESS
6925 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006926static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
Dustin Brownf27bce82016-11-03 12:52:27 -07006927{
Jeff Johnson9d295242017-08-29 14:39:48 -07006928 struct hdd_adapter *adapter;
Dustin Brownf27bce82016-11-03 12:52:27 -07006929 int err;
6930
Dustin Brown491d54b2018-03-14 12:39:11 -07006931 hdd_enter();
Dustin Brownf27bce82016-11-03 12:52:27 -07006932
Dustin Brown920397d2017-12-13 16:27:50 -08006933 hdd_for_each_adapter(hdd_ctx, adapter) {
6934 if (adapter->device_mode == QDF_STA_MODE ||
6935 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6936 adapter->device_mode == QDF_IBSS_MODE ||
6937 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
6938 adapter->device_mode == QDF_SAP_MODE ||
6939 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brownf27bce82016-11-03 12:52:27 -07006940 err = wlan_hdd_sched_scan_stop(adapter->dev);
6941 if (err)
6942 hdd_err("Unable to stop scheduled scan");
6943 }
Dustin Brownf27bce82016-11-03 12:52:27 -07006944 }
6945
Dustin Browne74003f2018-03-14 12:51:58 -07006946 hdd_exit();
Dustin Brownf27bce82016-11-03 12:52:27 -07006947
6948 return QDF_STATUS_SUCCESS;
6949}
6950
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006951#ifdef WLAN_NS_OFFLOAD
6952/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006953 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006954 * @hdd_ctx: Pointer to hdd context
6955 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006956 * Unregister for IPv6 address change notifications.
6957 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006958 * Return: None
6959 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006960static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006961{
6962 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006963}
6964
6965/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006966 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006967 * @hdd_ctx: Pointer to hdd context
6968 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006969 * Register for IPv6 address change notifications.
6970 *
6971 * Return: 0 on success and errno on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006972 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006973static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006974{
6975 int ret;
6976
6977 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
6978 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006979 if (ret) {
6980 hdd_err("Failed to register IPv6 notifier: %d", ret);
6981 goto out;
6982 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006983
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006984 hdd_debug("Registered IPv6 notifier");
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006985out:
6986 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006987}
6988#else
6989/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006990 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006991 * @hdd_ctx: Pointer to hdd context
6992 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006993 * Unregister for IPv6 address change notifications.
6994 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006995 * Return: None
6996 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006997static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006998{
6999}
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007000
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007001/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007002 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007003 * @hdd_ctx: Pointer to hdd context
7004 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007005 * Register for IPv6 address change notifications.
7006 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007007 * Return: None
7008 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007009static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007010{
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007011 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007012}
7013#endif
7014
Alok Kumarb64650c2018-03-23 17:05:11 +05307015void hdd_set_disconnect_status(struct hdd_adapter *adapter, bool status)
7016{
7017 qdf_mutex_acquire(&adapter->disconnection_status_lock);
7018 adapter->disconnection_in_progress = status;
7019 qdf_mutex_release(&adapter->disconnection_status_lock);
7020 hdd_debug("setting disconnection status: %d", status);
7021}
7022
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007023/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007024 * hdd_register_notifiers - Register netdev notifiers.
7025 * @hdd_ctx: HDD context
7026 *
7027 * Register netdev notifiers like IPv4 and IPv6.
7028 *
7029 * Return: 0 on success and errno on failure
7030 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007031static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007032{
7033 int ret;
7034
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007035 ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
7036 if (ret)
Arun Khandavalli08479ba2017-08-07 19:56:23 +05307037 goto out;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007038
7039 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
7040 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
7041 if (ret) {
7042 hdd_err("Failed to register IPv4 notifier: %d", ret);
7043 goto unregister_ip6_notifier;
7044 }
7045
Alok Kumarb64650c2018-03-23 17:05:11 +05307046 ret = hdd_nud_register_netevent_notifier(hdd_ctx);
7047 if (ret) {
7048 hdd_err("Failed to register netevent notifier: %d",
7049 ret);
7050 goto unregister_inetaddr_notifier;
7051 }
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007052 return 0;
7053
Alok Kumarb64650c2018-03-23 17:05:11 +05307054unregister_inetaddr_notifier:
7055 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007056unregister_ip6_notifier:
7057 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007058out:
7059 return ret;
7060
7061}
7062
7063/**
7064 * hdd_unregister_notifiers - Unregister netdev notifiers.
7065 * @hdd_ctx: HDD context
7066 *
7067 * Unregister netdev notifiers like IPv4 and IPv6.
7068 *
7069 * Return: None.
7070 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007071void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007072{
Alok Kumarb64650c2018-03-23 17:05:11 +05307073 hdd_nud_unregister_netevent_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007074 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
7075
7076 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007077}
7078
7079/**
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007080 * hdd_exit_netlink_services - Exit netlink services
7081 * @hdd_ctx: HDD context
7082 *
7083 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
7084 * nl service.
7085 *
7086 * Return: None.
7087 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007088static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007089{
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307090 spectral_scan_deactivate_service();
7091 cnss_diag_deactivate_service();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007092 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007093 ptt_sock_deactivate_svc();
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307094 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007095
7096 nl_srv_exit();
7097}
7098
7099/**
7100 * hdd_init_netlink_services- Init netlink services
7101 * @hdd_ctx: HDD context
7102 *
7103 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
7104 * nl service.
7105 *
7106 * Return: 0 on success and errno on failure.
7107 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007108static int hdd_init_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007109{
7110 int ret;
7111
Ryan Hsuceddceb2016-04-28 10:20:14 -07007112 ret = wlan_hdd_nl_init(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007113 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007114 hdd_err("nl_srv_init failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007115 goto out;
7116 }
Ryan Hsuceddceb2016-04-28 10:20:14 -07007117 cds_set_radio_index(hdd_ctx->radio_index);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007118
Naveen Rawat910726a2017-03-06 11:42:51 -08007119 ret = hdd_activate_wifi_pos(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007120 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007121 hdd_err("hdd_activate_wifi_pos failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007122 goto err_nl_srv;
7123 }
7124
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307125 ptt_sock_activate_svc();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007126
7127 ret = hdd_open_cesium_nl_sock();
Ryan Hsu5e2e2052016-04-28 10:19:38 -07007128 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007129 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007130
7131 ret = cnss_diag_activate_service();
7132 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007133 hdd_err("cnss_diag_activate_service failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007134 goto err_close_cesium;
7135 }
7136
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307137 spectral_scan_activate_service();
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -08007138
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007139 return 0;
7140
7141err_close_cesium:
7142 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007143 ptt_sock_deactivate_svc();
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307144 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007145err_nl_srv:
7146 nl_srv_exit();
7147out:
7148 return ret;
7149}
7150
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007151/**
7152 * hdd_rx_wake_lock_destroy() - Destroy RX wakelock
7153 * @hdd_ctx: HDD context.
7154 *
7155 * Destroy RX wakelock.
7156 *
7157 * Return: None.
7158 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007159static void hdd_rx_wake_lock_destroy(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007160{
7161 qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
7162}
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007163
7164/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007165 * hdd_rx_wake_lock_create() - Create RX wakelock
7166 * @hdd_ctx: HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007167 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007168 * Create RX wakelock.
7169 *
7170 * Return: None.
7171 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007172static void hdd_rx_wake_lock_create(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007173{
7174 qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
7175}
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007176
7177/**
Houston Hoffman160db392016-10-10 17:37:51 -07007178 * hdd_context_deinit() - Deinitialize HDD context
7179 * @hdd_ctx: HDD context.
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007180 *
Houston Hoffman160db392016-10-10 17:37:51 -07007181 * Deinitialize HDD context along with all the feature specific contexts but
7182 * do not free hdd context itself. Caller of this API is supposed to free
7183 * HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007184 *
Houston Hoffman160db392016-10-10 17:37:51 -07007185 * return: 0 on success and errno on failure.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007186 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007187static int hdd_context_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007188{
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05307189 qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock);
7190
Houston Hoffman160db392016-10-10 17:37:51 -07007191 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007192
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007193 hdd_sap_context_destroy(hdd_ctx);
7194
7195 hdd_rx_wake_lock_destroy(hdd_ctx);
7196
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007197 hdd_scan_context_destroy(hdd_ctx);
7198
Jeff Johnson19fc8e42017-10-30 19:53:49 -07007199 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007200
Houston Hoffman160db392016-10-10 17:37:51 -07007201 return 0;
7202}
7203
Dustin Brown623e7e32018-09-05 14:27:50 -07007204void hdd_context_destroy(struct hdd_context *hdd_ctx)
Houston Hoffman160db392016-10-10 17:37:51 -07007205{
Rajeev Kumar493a31b2017-09-29 14:01:24 -07007206 cds_set_context(QDF_MODULE_ID_HDD, NULL);
Arunk Khandavalli3d267b42017-05-02 18:58:59 +05307207
Dustin Brown623e7e32018-09-05 14:27:50 -07007208 hdd_exit_netlink_services(hdd_ctx);
Hanumantha Reddy Pothula00c74f62016-11-24 20:13:32 +05307209 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
7210
Houston Hoffman160db392016-10-10 17:37:51 -07007211 hdd_context_deinit(hdd_ctx);
7212
Dustin Browndb2df2e2018-10-31 15:29:24 -07007213 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
7214
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307215 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007216 hdd_ctx->config = NULL;
Dustin Brown84f46ea2018-02-15 11:57:36 -08007217 cfg_release();
7218
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007219 wiphy_free(hdd_ctx->wiphy);
7220}
7221
7222/**
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05307223 * wlan_destroy_bug_report_lock() - Destroy bug report lock
7224 *
7225 * This function is used to destroy bug report lock
7226 *
7227 * Return: None
7228 */
7229static void wlan_destroy_bug_report_lock(void)
7230{
Jeff Johnson2b6982c2018-05-29 14:56:11 -07007231 struct cds_context *p_cds_context;
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05307232
7233 p_cds_context = cds_get_global_context();
7234 if (!p_cds_context) {
7235 hdd_err("cds context is NULL");
7236 return;
7237 }
7238
7239 qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
7240}
7241
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +05307242#ifdef DISABLE_CHANNEL_LIST
7243static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
7244{
7245 qdf_mutex_destroy(&hdd_ctx->cache_channel_lock);
7246}
7247#else
7248static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
7249{
7250}
7251#endif
7252
Dustin Brown92bd8382018-10-31 15:49:46 -07007253void hdd_wlan_exit(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007254{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007255 struct wiphy *wiphy = hdd_ctx->wiphy;
Arun Khandavallifae92942016-08-01 13:31:08 +05307256 int driver_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007257
Dustin Brown491d54b2018-03-14 12:39:11 -07007258 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007259
Dustin Brown4c663222018-10-23 14:19:36 -07007260 hdd_psoc_idle_timer_stop(hdd_ctx);
Dustin Brown6470aba2018-09-05 09:49:58 -07007261
Arun Khandavallifae92942016-08-01 13:31:08 +05307262 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007263
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007264#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +05307265 if (QDF_TIMER_STATE_RUNNING ==
7266 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
7267 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007268 }
7269
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307270 if (!QDF_IS_STATUS_SUCCESS
Anurag Chouhan210db072016-02-22 18:42:15 +05307271 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
Jeff Johnson5880d792016-08-15 13:32:30 -07007272 hdd_err("Cannot deallocate ACS Skip timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007273 }
Liangwei Dongaef84342016-10-21 05:28:00 -04007274 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
7275 qdf_mem_free(hdd_ctx->last_acs_channel_list);
7276 hdd_ctx->last_acs_channel_list = NULL;
7277 hdd_ctx->num_of_channels = 0;
7278 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007279#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007280
Arun Khandavallifae92942016-08-01 13:31:08 +05307281 mutex_lock(&hdd_ctx->iface_change_lock);
7282 driver_status = hdd_ctx->driver_status;
7283 mutex_unlock(&hdd_ctx->iface_change_lock);
7284
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007285 /*
7286 * Powersave Offload Case
7287 * Disable Idle Power Save Mode
7288 */
7289 hdd_set_idle_ps_config(hdd_ctx, false);
Sandeep Puligilla8fa28fd2017-11-02 12:19:33 -07007290 /* clear the scan queue in all the scenarios */
Dustin Brown07901ec2018-09-07 11:02:41 -07007291 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007292
Arun Khandavallifae92942016-08-01 13:31:08 +05307293 if (driver_status != DRIVER_MODULES_CLOSED) {
7294 hdd_unregister_wext_all_adapters(hdd_ctx);
7295 /*
7296 * Cancel any outstanding scan requests. We are about to close
7297 * all of our adapters, but an adapter structure is what SME
7298 * passes back to our callback function. Hence if there
7299 * are any outstanding scan requests then there is a
7300 * race condition between when the adapter is closed and
7301 * when the callback is invoked. We try to resolve that
7302 * race condition here by canceling any outstanding scans
7303 * before we close the adapters.
7304 * Note that the scans may be cancelled in an asynchronous
7305 * manner, so ideally there needs to be some kind of
7306 * synchronization. Rather than introduce a new
7307 * synchronization here, we will utilize the fact that we are
7308 * about to Request Full Power, and since that is synchronized,
7309 * the expectation is that by the time Request Full Power has
7310 * completed, all scans will be cancelled
7311 */
7312 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Dustin Brownf27bce82016-11-03 12:52:27 -07007313 hdd_abort_sched_scan_all_adapters(hdd_ctx);
Dustin Browndb2a8be2017-12-20 11:49:56 -08007314 hdd_stop_all_adapters(hdd_ctx);
bings29c99862017-11-01 13:54:13 +08007315 hdd_deinit_all_adapters(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007316 }
7317
Arunk Khandavalli830c9692018-03-22 12:17:40 +05307318 unregister_reboot_notifier(&system_reboot_notifier);
Arun Khandavalli08479ba2017-08-07 19:56:23 +05307319 unregister_netdevice_notifier(&hdd_netdev_notifier);
7320
Rachit Kankane30807332018-06-27 18:39:36 +05307321 qdf_dp_trace_deinit();
7322
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07007323 hdd_wlan_stop_modules(hdd_ctx, false);
Hanumanth Reddy Pothula709a6362016-10-18 18:19:44 +05307324
Visweswara Tanukuc029a202018-11-27 10:42:10 +05307325 hdd_bus_bw_compute_timer_stop(hdd_ctx);
Dustin Brown86d196b2018-08-02 11:51:49 -07007326 hdd_bus_bandwidth_deinit(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -08007327 hdd_driver_memdump_deinit();
7328
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +05307329 qdf_nbuf_deinit_replenish_timer();
7330
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05307331 if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) {
7332 hdd_info("Release wakelock for monitor mode!");
7333 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
7334 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
7335 }
7336
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307337 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307338 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +05307339 wlan_hdd_cache_chann_mutex_destroy(hdd_ctx);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307340
Naveen Rawate02f8f52018-04-05 11:58:04 -07007341 osif_request_manager_deinit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007342
Dustin Brownd005ad82018-01-19 10:32:13 -08007343 hdd_close_all_adapters(hdd_ctx, false);
7344
Manishekar Chandrasekaranf7a1dad2016-06-23 06:43:47 +05307345 wlansap_global_deinit();
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05307346 /*
7347 * If there is re_init failure wiphy would have already de-registered
7348 * check the wiphy status before un-registering again
7349 */
Ashish Kumar Dhanotiyae16feb72017-03-31 19:39:37 +05307350 if (wiphy && wiphy->registered) {
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05307351 wiphy_unregister(wiphy);
7352 wlan_hdd_cfg80211_deinit(wiphy);
7353 hdd_lpass_notify_stop(hdd_ctx);
7354 }
Yuanyuan Liu3e918e52016-08-17 15:41:35 -07007355
Arun Khandavallifae92942016-08-01 13:31:08 +05307356 hdd_exit_netlink_services(hdd_ctx);
7357 mutex_destroy(&hdd_ctx->iface_change_lock);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05307358#ifdef FEATURE_WLAN_CH_AVOID
7359 mutex_destroy(&hdd_ctx->avoid_freq_lock);
7360#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007361}
7362
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007363#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Liangwei Dongaef84342016-10-21 05:28:00 -04007364/**
7365 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007366 * @data: pointer to struct hdd_context
Liangwei Dongaef84342016-10-21 05:28:00 -04007367 *
7368 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
7369 * Then new ACS request will do a fresh scan without reusing the cached
7370 * scan information.
7371 *
7372 * Return: void
7373 */
Tang Yingying523322d2017-01-17 23:28:43 +08007374static void hdd_skip_acs_scan_timer_handler(void *data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007375{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007376 struct hdd_context *hdd_ctx = (struct hdd_context *) data;
Jeff Johnson16528362018-06-14 12:34:16 -07007377 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007378
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007379 hdd_debug("ACS Scan result expired. Reset ACS scan skip");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007380 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
Liangwei Dongaef84342016-10-21 05:28:00 -04007381 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
7382 qdf_mem_free(hdd_ctx->last_acs_channel_list);
7383 hdd_ctx->last_acs_channel_list = NULL;
7384 hdd_ctx->num_of_channels = 0;
7385 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007386
Jeff Johnson16528362018-06-14 12:34:16 -07007387 mac_handle = hdd_ctx->mac_handle;
7388 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007389 return;
Jeff Johnson16528362018-06-14 12:34:16 -07007390 sme_scan_flush_result(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007391}
7392#endif
7393
7394#ifdef QCA_HT_2040_COEX
Jeff Johnsone7672e72017-10-21 15:10:04 -07007395int hdd_wlan_set_ht2040_mode(struct hdd_adapter *adapter, uint16_t sta_id,
7396 struct qdf_mac_addr sta_mac, int channel_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007397{
7398 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307399 QDF_STATUS qdf_status;
Jeff Johnsone7672e72017-10-21 15:10:04 -07007400 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -07007401 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007402
7403 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7404
7405 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307406 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007407 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307408
Jeff Johnson16528362018-06-14 12:34:16 -07007409 mac_handle = hdd_ctx->mac_handle;
7410 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007411 return -EINVAL;
7412
Jeff Johnson16528362018-06-14 12:34:16 -07007413 qdf_status = sme_notify_ht2040_mode(mac_handle, sta_id, sta_mac,
Jeff Johnson1b780e42017-10-31 14:11:45 -07007414 adapter->session_id, channel_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307415 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007416 hdd_err("Fail to send notification with ht2040 mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007417 return -EINVAL;
7418 }
7419
7420 return 0;
7421}
7422#endif
7423
7424/**
7425 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
7426 * @state: state
7427 *
7428 * This function notifies FW with modem power status
7429 *
7430 * Return: 0 if successful, error number otherwise
7431 */
7432int hdd_wlan_notify_modem_power_state(int state)
7433{
7434 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307435 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007436 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -07007437 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007438
Anurag Chouhan6d760662016-02-20 16:05:43 +05307439 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007440 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307441 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007442 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307443
Jeff Johnson16528362018-06-14 12:34:16 -07007444 mac_handle = hdd_ctx->mac_handle;
7445 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007446 return -EINVAL;
7447
Jeff Johnson16528362018-06-14 12:34:16 -07007448 qdf_status = sme_notify_modem_power_state(mac_handle, state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307449 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007450 hdd_err("Fail to send notification with modem power state %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007451 state);
7452 return -EINVAL;
7453 }
7454 return 0;
7455}
7456
7457/**
7458 *
7459 * hdd_post_cds_enable_config() - HDD post cds start config helper
7460 * @adapter - Pointer to the HDD
7461 *
7462 * Return: None
7463 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007464QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007465{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307466 QDF_STATUS qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007467
7468 /*
7469 * Send ready indication to the HDD. This will kick off the MAC
7470 * into a 'running' state and should kick off an initial scan.
7471 */
Jeff Johnson16528362018-06-14 12:34:16 -07007472 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307473 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007474 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
7475 qdf_ret_status, qdf_ret_status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307476 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007477 }
7478
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307479 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007480}
7481
Sourav Mohapatra92ea8d62018-02-05 10:03:10 +05307482struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx)
7483{
7484 struct hdd_adapter *adapter;
7485
7486 hdd_for_each_adapter(hdd_ctx, adapter) {
7487 if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC)
7488 return adapter;
7489 }
7490
7491 return NULL;
7492}
7493
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007494/* wake lock APIs for HDD */
7495void hdd_prevent_suspend(uint32_t reason)
7496{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05307497 qdf_wake_lock_acquire(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007498}
7499
7500void hdd_allow_suspend(uint32_t reason)
7501{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05307502 qdf_wake_lock_release(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007503}
7504
7505void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
7506{
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05307507 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
7508 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007509}
7510
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007511/* Initialize channel list in sme based on the country code */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007512QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007513{
Jeff Johnson16528362018-06-14 12:34:16 -07007514 return sme_init_chan_list(hdd_ctx->mac_handle,
Amar Singhal6f8592b2017-04-26 14:31:58 -07007515 hdd_ctx->reg.alpha2,
7516 hdd_ctx->reg.cc_src);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007517}
7518
7519/**
7520 * hdd_is_5g_supported() - check if hardware supports 5GHz
7521 * @hdd_ctx: Pointer to the hdd context
7522 *
7523 * HDD function to know if hardware supports 5GHz
7524 *
7525 * Return: true if hardware supports 5GHz
7526 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007527bool hdd_is_5g_supported(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007528{
Amar Singhal58b45ef2017-08-01 13:43:54 -07007529 if (!hdd_ctx)
zdingf54169a2016-10-12 17:08:45 +08007530 return true;
7531
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08007532 if (hdd_ctx->curr_band != BAND_2G)
zdingf54169a2016-10-12 17:08:45 +08007533 return true;
7534 else
7535 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007536}
7537
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007538static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007539{
7540 struct wiphy *wiphy;
Amar Singhale4f28ee2015-10-21 14:36:56 -07007541 int ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007542
7543 wiphy = hdd_ctx->wiphy;
7544
7545 /*
7546 * The channel information in
7547 * wiphy needs to be initialized before wiphy registration
7548 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07007549 ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
7550 if (ret_val) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007551 hdd_err("regulatory init failed");
Amar Singhale4f28ee2015-10-21 14:36:56 -07007552 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007553 }
7554
7555#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
7556 wiphy->wowlan = &wowlan_support_reg_init;
7557#else
7558 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
7559 WIPHY_WOWLAN_MAGIC_PKT |
7560 WIPHY_WOWLAN_DISCONNECT |
7561 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
7562 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
7563 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
7564 WIPHY_WOWLAN_4WAY_HANDSHAKE |
7565 WIPHY_WOWLAN_RFKILL_RELEASE;
7566
7567 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
7568 WOW_MAX_FILTERS_PER_LIST);
7569 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
7570 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
7571#endif
Liangwei Dong0da14262018-07-03 03:30:23 -04007572 if (hdd_ctx->obss_scan_offload) {
7573 hdd_debug("wmi_service_obss_scan supported");
7574 } else if (hdd_ctx->config->nChannelBondingMode24GHz) {
7575 hdd_debug("enable wpa_supp obss_scan");
7576 wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN;
7577 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007578
7579 /* registration of wiphy dev with cfg80211 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07007580 ret_val = wlan_hdd_cfg80211_register(wiphy);
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05307581 if (0 > ret_val) {
Amar Singhale4f28ee2015-10-21 14:36:56 -07007582 hdd_err("wiphy registration failed");
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05307583 return ret_val;
7584 }
Amar Singhalac26de22018-06-22 12:53:06 -07007585
Kiran Kumar Lokere0508af92018-04-23 18:38:32 -07007586 /* Check the kernel version for upstream commit aced43ce780dc5 that
7587 * has support for processing user cell_base hints when wiphy is
7588 * self managed or check the backport flag for the same.
7589 */
Amar Singhalac26de22018-06-22 12:53:06 -07007590#if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
7591 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
Kiran Kumar Lokere0508af92018-04-23 18:38:32 -07007592 hdd_send_wiphy_regd_sync_event(hdd_ctx);
7593#endif
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05307594
Amar Singhal2d812012018-02-03 15:06:47 +08007595 pld_increment_driver_load_cnt(hdd_ctx->parent_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007596
Amar Singhale4f28ee2015-10-21 14:36:56 -07007597 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007598}
7599
Mohit Khannaca4173b2017-09-12 21:52:19 -07007600#ifdef MSM_PLATFORM
7601/**
7602 * hdd_display_periodic_stats() - Function to display periodic stats
7603 * @hdd_ctx - handle to hdd context
7604 * @bool data_in_interval - true, if data detected in bw time interval
7605 *
7606 * The periodicity is determined by hdd_ctx->config->periodic_stats_disp_time.
7607 * Stats show up in wlan driver logs.
7608 *
7609 * Returns: None
7610 */
Mohit Khanna70322002018-05-15 19:21:32 -07007611static void hdd_display_periodic_stats(struct hdd_context *hdd_ctx,
7612 bool data_in_interval)
Mohit Khannaca4173b2017-09-12 21:52:19 -07007613{
Mohit Khanna70322002018-05-15 19:21:32 -07007614 static uint32_t counter;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007615 static bool data_in_time_period;
7616 ol_txrx_pdev_handle pdev;
7617
7618 if (hdd_ctx->config->periodic_stats_disp_time == 0)
7619 return;
7620
7621 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
7622 if (!pdev) {
7623 hdd_err("pdev is NULL");
7624 return;
7625 }
7626
7627 counter++;
7628 if (data_in_interval)
7629 data_in_time_period = data_in_interval;
7630
jitiphil869b9f72018-09-25 17:14:01 +05307631 if (counter * hdd_ctx->config->bus_bw_compute_interval >=
Mohit Khannaca4173b2017-09-12 21:52:19 -07007632 hdd_ctx->config->periodic_stats_disp_time * 1000) {
7633 if (data_in_time_period) {
Mohit Khanna70322002018-05-15 19:21:32 -07007634 wlan_hdd_display_txrx_stats(hdd_ctx);
7635 dp_txrx_dump_stats(cds_get_context(QDF_MODULE_ID_SOC));
7636 cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
7637 CDP_RX_RING_STATS,
7638 QDF_STATS_VERBOSITY_LEVEL_LOW);
Mohit Khannaca4173b2017-09-12 21:52:19 -07007639 cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
7640 CDP_TXRX_PATH_STATS,
7641 QDF_STATS_VERBOSITY_LEVEL_LOW);
7642 wlan_hdd_display_netif_queue_history
7643 (hdd_ctx, QDF_STATS_VERBOSITY_LEVEL_LOW);
7644 qdf_dp_trace_dump_stats();
7645 }
7646 counter = 0;
7647 data_in_time_period = false;
7648 }
7649}
7650
Ravi Joshie2331e82015-07-01 18:18:54 -07007651/**
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007652 * hdd_clear_rps_cpu_mask - clear RPS CPU mask for interfaces
7653 * @hdd_ctx: pointer to struct hdd_context
7654 *
7655 * Return: none
7656 */
7657static void hdd_clear_rps_cpu_mask(struct hdd_context *hdd_ctx)
7658{
7659 struct hdd_adapter *adapter;
7660
7661 hdd_for_each_adapter(hdd_ctx, adapter)
7662 hdd_send_rps_disable_ind(adapter);
7663}
7664
7665/**
Yuanyuan Liu13738502016-04-06 17:41:37 -07007666 * hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
Ravi Joshie2331e82015-07-01 18:18:54 -07007667 * @hdd_ctx - handle to hdd context
7668 * @tx_packets - transmit packet count
7669 * @rx_packets - receive packet count
7670 *
7671 * The function controls the bus bandwidth and dynamic control of
7672 * tcp delayed ack configuration
7673 *
7674 * Returns: None
7675 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07007676
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007677static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07007678 const uint64_t tx_packets,
7679 const uint64_t rx_packets)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007680{
Mohit Khannaca4173b2017-09-12 21:52:19 -07007681 u64 total_pkts = tx_packets + rx_packets;
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007682 uint64_t temp_tx = 0, avg_rx = 0;
7683 uint64_t no_rx_offload_pkts = 0, avg_no_rx_offload_pkts = 0;
7684 uint64_t rx_offload_pkts = 0, avg_rx_offload_pkts = 0;
Yuanyuan Liu13738502016-04-06 17:41:37 -07007685 enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_NONE;
Mohit Khannac3da7062017-02-08 21:08:56 -08007686 static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
Mohit Khannae71e2262015-11-10 09:37:24 -08007687 enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
Ravi Joshib89e7f72016-09-07 13:43:15 -07007688 uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007689 uint16_t index = 0;
7690 bool vote_level_change = false;
7691 bool rx_level_change = false;
7692 bool tx_level_change = false;
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007693 bool rxthread_high_tput_req = false;
Mohit Khannaf7562c32018-07-05 17:42:36 -07007694 bool dptrace_high_tput_req;
Srinivas Girigowda50335342018-09-07 15:21:01 -07007695
jitiphil869b9f72018-09-25 17:14:01 +05307696 if (total_pkts > hdd_ctx->config->bus_bw_high_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007697 next_vote_level = PLD_BUS_WIDTH_HIGH;
jitiphil869b9f72018-09-25 17:14:01 +05307698 else if (total_pkts > hdd_ctx->config->bus_bw_medium_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007699 next_vote_level = PLD_BUS_WIDTH_MEDIUM;
jitiphil869b9f72018-09-25 17:14:01 +05307700 else if (total_pkts > hdd_ctx->config->bus_bw_low_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007701 next_vote_level = PLD_BUS_WIDTH_LOW;
Yue Mad6478e42015-10-20 18:49:24 -07007702 else
Yuanyuan Liu13738502016-04-06 17:41:37 -07007703 next_vote_level = PLD_BUS_WIDTH_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007704
Mohit Khannaf7562c32018-07-05 17:42:36 -07007705 dptrace_high_tput_req =
7706 next_vote_level > PLD_BUS_WIDTH_NONE ? true : false;
7707
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007708 if (hdd_ctx->cur_vote_level != next_vote_level) {
Ravi Joshie2331e82015-07-01 18:18:54 -07007709 hdd_debug("trigger level %d, tx_packets: %lld, rx_packets: %lld",
7710 next_vote_level, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007711 hdd_ctx->cur_vote_level = next_vote_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007712 vote_level_change = true;
Yuanyuan Liu13738502016-04-06 17:41:37 -07007713 pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level);
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007714 if ((next_vote_level == PLD_BUS_WIDTH_LOW) ||
7715 (next_vote_level == PLD_BUS_WIDTH_NONE)) {
Nirav Shahffc6a092016-06-09 16:09:08 +05307716 if (hdd_ctx->hbw_requested) {
7717 pld_remove_pm_qos(hdd_ctx->parent_dev);
7718 hdd_ctx->hbw_requested = false;
7719 }
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007720 if (hdd_ctx->dynamic_rps)
7721 hdd_clear_rps_cpu_mask(hdd_ctx);
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07007722 } else {
Nirav Shahffc6a092016-06-09 16:09:08 +05307723 if (!hdd_ctx->hbw_requested) {
7724 pld_request_pm_qos(hdd_ctx->parent_dev, 1);
7725 hdd_ctx->hbw_requested = true;
7726 }
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007727 if (hdd_ctx->dynamic_rps)
7728 hdd_set_rps_cpu_mask(hdd_ctx);
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07007729 }
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007730
Manjunathappa Prakashcb6df762018-05-29 18:54:58 -07007731 if (hdd_ctx->config->napi_cpu_affinity_mask)
7732 hdd_napi_apply_throughput_policy(hdd_ctx,
7733 tx_packets,
7734 rx_packets);
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007735
jitiphil869b9f72018-09-25 17:14:01 +05307736 if (rx_packets < hdd_ctx->config->bus_bw_low_threshold)
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007737 hdd_disable_rx_ol_for_low_tput(hdd_ctx, true);
7738 else
7739 hdd_disable_rx_ol_for_low_tput(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007740 }
Mohit Khannae71e2262015-11-10 09:37:24 -08007741
Mohit Khannaf7562c32018-07-05 17:42:36 -07007742 qdf_dp_trace_apply_tput_policy(dptrace_high_tput_req);
7743
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007744 /*
7745 * Includes tcp+udp, if perf core is required for tcp, then
7746 * perf core is also required for udp.
7747 */
7748 no_rx_offload_pkts = hdd_ctx->no_rx_offload_pkt_cnt;
7749 hdd_ctx->no_rx_offload_pkt_cnt = 0;
7750 rx_offload_pkts = rx_packets - no_rx_offload_pkts;
Mohit Khannae71e2262015-11-10 09:37:24 -08007751
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007752 avg_no_rx_offload_pkts = (no_rx_offload_pkts +
7753 hdd_ctx->prev_no_rx_offload_pkts) / 2;
7754 hdd_ctx->prev_no_rx_offload_pkts = no_rx_offload_pkts;
Mohit Khannab1dd1e82017-02-04 15:14:38 -08007755
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007756 avg_rx_offload_pkts = (rx_offload_pkts +
7757 hdd_ctx->prev_rx_offload_pkts) / 2;
7758 hdd_ctx->prev_rx_offload_pkts = rx_offload_pkts;
7759
7760 avg_rx = avg_no_rx_offload_pkts + avg_rx_offload_pkts;
7761 /*
7762 * Takes care to set Rx_thread affinity for below case
7763 * 1)LRO/GRO not supported ROME case
7764 * 2)when rx_ol is disabled in cases like concurrency etc
7765 * 3)For UDP cases
7766 */
7767 if (avg_no_rx_offload_pkts >
jitiphil869b9f72018-09-25 17:14:01 +05307768 hdd_ctx->config->bus_bw_high_threshold)
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007769 rxthread_high_tput_req = true;
Poddar, Siddarth47c23402017-10-25 12:17:39 +05307770 else
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007771 rxthread_high_tput_req = false;
Poddar, Siddarth47c23402017-10-25 12:17:39 +05307772
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007773 if (cds_sched_handle_throughput_req(rxthread_high_tput_req))
7774 hdd_warn("Rx thread high_tput(%d) affinity request failed",
7775 rxthread_high_tput_req);
7776
7777 /* fine-tuning parameters for RX Flows */
jitiphil869b9f72018-09-25 17:14:01 +05307778 if (avg_rx > hdd_ctx->config->tcp_delack_thres_high) {
Ravi Joshifed83572016-10-07 16:20:37 -07007779 if ((hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH) &&
7780 (++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt)) {
7781 next_rx_level = WLAN_SVC_TP_HIGH;
7782 }
Ravi Joshib89e7f72016-09-07 13:43:15 -07007783 } else {
Ravi Joshib89e7f72016-09-07 13:43:15 -07007784 hdd_ctx->rx_high_ind_cnt = 0;
Mohit Khannac3da7062017-02-08 21:08:56 -08007785 next_rx_level = WLAN_SVC_TP_LOW;
Ravi Joshib89e7f72016-09-07 13:43:15 -07007786 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007787
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007788 if (hdd_ctx->cur_rx_level != next_rx_level) {
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007789 struct wlan_rx_tp_data rx_tp_data = {0};
7790
Ravi Joshie2331e82015-07-01 18:18:54 -07007791 hdd_debug("TCP DELACK trigger level %d, average_rx: %llu",
Jeff Johnsonb9feee42018-07-08 10:34:48 -07007792 next_rx_level, avg_rx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007793 hdd_ctx->cur_rx_level = next_rx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007794 rx_level_change = true;
Ravi Joshie2331e82015-07-01 18:18:54 -07007795 /* Send throughput indication only if it is enabled.
7796 * Disabling tcp_del_ack will revert the tcp stack behavior
7797 * to default delayed ack. Note that this will disable the
7798 * dynamic delayed ack mechanism across the system
7799 */
Manjunathappa Prakashbfd12762018-04-29 22:44:52 -07007800 if (hdd_ctx->en_tcp_delack_no_lro)
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007801 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
7802
Mohit Khanna6272fb682017-04-13 09:34:36 -07007803 if (hdd_ctx->config->enable_tcp_adv_win_scale)
7804 rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
7805
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007806 rx_tp_data.level = next_rx_level;
Alok Kumar2fad6442018-11-08 19:19:28 +05307807 wlan_hdd_update_tcp_rx_param(hdd_ctx, &rx_tp_data);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007808 }
7809
Mohit Khannae71e2262015-11-10 09:37:24 -08007810 /* fine-tuning parameters for TX Flows */
7811 temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2;
7812 hdd_ctx->prev_tx = tx_packets;
7813 if (temp_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
7814 next_tx_level = WLAN_SVC_TP_HIGH;
7815 else
7816 next_tx_level = WLAN_SVC_TP_LOW;
7817
Prakash Manjunathappae73e3b52018-02-27 18:56:22 -08007818 if ((hdd_ctx->config->enable_tcp_limit_output) &&
7819 (hdd_ctx->cur_tx_level != next_tx_level)) {
Alok Kumar2fad6442018-11-08 19:19:28 +05307820 struct wlan_tx_tp_data tx_tp_data = {0};
7821
Mohit Khannae71e2262015-11-10 09:37:24 -08007822 hdd_debug("change TCP TX trigger level %d, average_tx: %llu",
7823 next_tx_level, temp_tx);
7824 hdd_ctx->cur_tx_level = next_tx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007825 tx_level_change = true;
Alok Kumar2fad6442018-11-08 19:19:28 +05307826 tx_tp_data.level = next_tx_level;
7827 tx_tp_data.tcp_limit_output = true;
7828 wlan_hdd_update_tcp_tx_param(hdd_ctx, &tx_tp_data);
Mohit Khannae71e2262015-11-10 09:37:24 -08007829 }
7830
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007831 index = hdd_ctx->hdd_txrx_hist_idx;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007832 if (vote_level_change || tx_level_change || rx_level_change) {
7833 hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level;
7834 hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level;
7835 hdd_ctx->hdd_txrx_hist[index].next_vote_level = next_vote_level;
7836 hdd_ctx->hdd_txrx_hist[index].interval_rx = rx_packets;
7837 hdd_ctx->hdd_txrx_hist[index].interval_tx = tx_packets;
7838 hdd_ctx->hdd_txrx_hist[index].qtime = qdf_get_log_timestamp();
7839 hdd_ctx->hdd_txrx_hist_idx++;
7840 hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
7841 }
Mohit Khannaca4173b2017-09-12 21:52:19 -07007842
7843 hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007844}
7845
7846#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
Rajeev Kumarb2b5e692018-08-31 15:12:40 -07007847static void __hdd_bus_bw_work_handler(struct work_struct *work)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007848{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007849 struct hdd_context *hdd_ctx = container_of(work, struct hdd_context,
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307850 bus_bw_work);
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05307851 struct hdd_adapter *adapter = NULL, *con_sap_adapter = NULL;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307852 uint64_t tx_packets = 0, rx_packets = 0;
Himanshu Agarwala6cedee2016-06-08 14:50:00 +05307853 uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
7854 uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007855 uint64_t total_tx = 0, total_rx = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307856 A_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007857 bool connected = false;
7858 uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
7859
Prashanth Bhattaab004382016-10-11 16:08:11 -07007860 if (wlan_hdd_validate_context(hdd_ctx))
7861 return;
7862
Jeff Johnson214671b2017-10-30 19:45:23 -07007863 if (hdd_ctx->is_wiphy_suspended)
Jingxiang Gec64e1932017-08-22 14:38:59 +08007864 goto restart_timer;
7865
Dustin Brown920397d2017-12-13 16:27:50 -08007866 hdd_for_each_adapter(hdd_ctx, adapter) {
Manjeet Singh01327cc2016-09-03 12:14:25 +05307867 /*
7868 * Validate magic so we don't end up accessing
7869 * an invalid adapter.
7870 */
7871 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
7872 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007873
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007874 if ((adapter->device_mode == QDF_STA_MODE ||
7875 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007876 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.connState
7877 != eConnectionState_Associated) {
7878
7879 continue;
7880 }
7881
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007882 if ((adapter->device_mode == QDF_SAP_MODE ||
7883 adapter->device_mode == QDF_P2P_GO_MODE) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -07007884 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007885
7886 continue;
7887 }
7888
7889 tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets,
7890 adapter->prev_tx_packets);
7891 rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets,
7892 adapter->prev_rx_packets);
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307893
7894 if (adapter->device_mode == QDF_SAP_MODE ||
7895 adapter->device_mode == QDF_P2P_GO_MODE ||
7896 adapter->device_mode == QDF_IBSS_MODE) {
7897
Dhanashri Atrea8f82f22017-01-23 12:58:24 -08007898 ret = cdp_get_intra_bss_fwd_pkts_count(
7899 cds_get_context(QDF_MODULE_ID_SOC),
Jeff Johnson1b780e42017-10-31 14:11:45 -07007900 adapter->session_id,
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307901 &fwd_tx_packets, &fwd_rx_packets);
7902 if (ret == A_OK) {
7903 fwd_tx_packets_diff += HDD_BW_GET_DIFF(
7904 fwd_tx_packets,
7905 adapter->prev_fwd_tx_packets);
7906 fwd_rx_packets_diff += HDD_BW_GET_DIFF(
7907 fwd_tx_packets,
7908 adapter->prev_fwd_rx_packets);
7909 }
7910 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007911
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05307912 if (adapter->device_mode == QDF_SAP_MODE)
7913 con_sap_adapter = adapter;
7914
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007915 total_rx += adapter->stats.rx_packets;
7916 total_tx += adapter->stats.tx_packets;
7917
7918 spin_lock_bh(&hdd_ctx->bus_bw_lock);
7919 adapter->prev_tx_packets = adapter->stats.tx_packets;
7920 adapter->prev_rx_packets = adapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307921 adapter->prev_fwd_tx_packets = fwd_tx_packets;
7922 adapter->prev_fwd_rx_packets = fwd_rx_packets;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007923 spin_unlock_bh(&hdd_ctx->bus_bw_lock);
7924 connected = true;
7925 }
7926
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007927 if (!connected) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007928 hdd_err("bus bandwidth timer running in disconnected state");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007929 return;
7930 }
7931
Yun Parka29974a2018-04-09 12:05:49 -07007932 /* add intra bss forwarded tx and rx packets */
7933 tx_packets += fwd_tx_packets_diff;
7934 rx_packets += fwd_rx_packets_diff;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007935
Dustin Brown07901ec2018-09-07 11:02:41 -07007936 if (ucfg_ipa_is_fw_wdi_activated(hdd_ctx->pdev)) {
7937 ucfg_ipa_uc_stat_query(hdd_ctx->pdev, &ipa_tx_packets,
7938 &ipa_rx_packets);
Yun Parka29974a2018-04-09 12:05:49 -07007939 tx_packets += (uint64_t)ipa_tx_packets;
7940 rx_packets += (uint64_t)ipa_rx_packets;
7941
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05307942 if (con_sap_adapter) {
7943 con_sap_adapter->stats.tx_packets += ipa_tx_packets;
7944 con_sap_adapter->stats.rx_packets += ipa_rx_packets;
7945 }
7946
Dustin Brown07901ec2018-09-07 11:02:41 -07007947 ucfg_ipa_set_perf_level(hdd_ctx->pdev, tx_packets, rx_packets);
7948 ucfg_ipa_uc_stat_request(hdd_ctx->pdev, 2);
Yun Parka29974a2018-04-09 12:05:49 -07007949 }
7950
7951 hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007952
Jingxiang Gec64e1932017-08-22 14:38:59 +08007953restart_timer:
Dustin Brown2ed60362017-01-18 12:25:50 -08007954 /* ensure periodic timer should still be running before restarting it */
Dustin Brownfce08d12017-01-17 16:29:38 -08007955 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown2ed60362017-01-18 12:25:50 -08007956 if (hdd_ctx->bus_bw_timer_running)
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +05307957 qdf_timer_mod(&hdd_ctx->bus_bw_timer,
jitiphil869b9f72018-09-25 17:14:01 +05307958 hdd_ctx->config->bus_bw_compute_interval);
Dustin Brownfce08d12017-01-17 16:29:38 -08007959 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007960}
Prashanth Bhattaab004382016-10-11 16:08:11 -07007961
Rajeev Kumarb2b5e692018-08-31 15:12:40 -07007962static void hdd_bus_bw_work_handler(struct work_struct *work)
7963{
7964 cds_ssr_protect(__func__);
7965 __hdd_bus_bw_work_handler(work);
7966 cds_ssr_unprotect(__func__);
7967}
7968
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307969/**
7970 * __hdd_bus_bw_cbk() - Bus bandwidth data structure callback.
7971 * @arg: Argument of timer function
7972 *
7973 * Schedule a workqueue in this function where all the processing is done.
7974 *
7975 * Return: None.
7976 */
7977static void __hdd_bus_bw_cbk(void *arg)
7978{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007979 struct hdd_context *hdd_ctx = (struct hdd_context *) arg;
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307980
7981 if (wlan_hdd_validate_context(hdd_ctx))
7982 return;
7983
7984 schedule_work(&hdd_ctx->bus_bw_work);
7985}
7986
7987/**
7988 * hdd_bus_bw_cbk() - Wrapper for bus bw callback for SSR protection.
7989 * @arg: Argument of timer function
7990 *
7991 * Return: None.
7992 */
7993static void hdd_bus_bw_cbk(void *arg)
7994{
7995 cds_ssr_protect(__func__);
7996 __hdd_bus_bw_cbk(arg);
7997 cds_ssr_unprotect(__func__);
7998}
7999
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008000int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07008001{
Dustin Brown35008ba2018-08-23 14:34:21 -07008002 hdd_enter();
8003
Prashanth Bhattaab004382016-10-11 16:08:11 -07008004 spin_lock_init(&hdd_ctx->bus_bw_lock);
Dustin Brown35008ba2018-08-23 14:34:21 -07008005 INIT_WORK(&hdd_ctx->bus_bw_work, hdd_bus_bw_work_handler);
Dustin Brownfce08d12017-01-17 16:29:38 -08008006 hdd_ctx->bus_bw_timer_running = false;
8007 qdf_spinlock_create(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown35008ba2018-08-23 14:34:21 -07008008 qdf_timer_init(NULL, &hdd_ctx->bus_bw_timer, hdd_bus_bw_cbk,
8009 (void *)hdd_ctx, QDF_TIMER_TYPE_SW);
8010
8011 hdd_exit();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008012
8013 return 0;
8014}
8015
Dustin Brown86d196b2018-08-02 11:51:49 -07008016void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07008017{
Dustin Brown35008ba2018-08-23 14:34:21 -07008018 hdd_enter();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008019
Rajeev Kumarc27efb62018-08-31 14:21:22 -07008020 QDF_BUG(!hdd_ctx->bus_bw_timer_running);
Dustin Brown35008ba2018-08-23 14:34:21 -07008021
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05308022 qdf_timer_free(&hdd_ctx->bus_bw_timer);
Dustin Brownfce08d12017-01-17 16:29:38 -08008023 qdf_spinlock_destroy(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown35008ba2018-08-23 14:34:21 -07008024
8025 hdd_exit();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008026}
Lin Baic5c06882017-09-21 13:58:43 +08008027
Dustin Brown35008ba2018-08-23 14:34:21 -07008028#endif /* MSM_PLATFORM */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008029
8030/**
Nirav Shahed34b212016-04-25 10:59:16 +05308031 * wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
8032 * @hdd_ctx: hdd context
8033 *
8034 * Return: 0 for success or error code
8035 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008036static int wlan_hdd_init_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05308037{
8038 hdd_ctx->hdd_txrx_hist = qdf_mem_malloc(
8039 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Min Liu74a1a502018-10-10 19:59:07 +08008040 if (!hdd_ctx->hdd_txrx_hist)
Nirav Shahed34b212016-04-25 10:59:16 +05308041 return -ENOMEM;
Nirav Shahed34b212016-04-25 10:59:16 +05308042 return 0;
8043}
8044
8045/**
8046 * wlan_hdd_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
8047 * @hdd_ctx: hdd context
8048 *
8049 * Return: none
8050 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008051void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05308052{
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05308053 if (!hdd_ctx || hdd_ctx->hdd_txrx_hist == NULL)
8054 return;
8055
8056 qdf_mem_free(hdd_ctx->hdd_txrx_hist);
8057 hdd_ctx->hdd_txrx_hist = NULL;
Nirav Shahed34b212016-04-25 10:59:16 +05308058}
8059
Nirav Shahda008342016-05-17 18:50:40 +05308060static uint8_t *convert_level_to_string(uint32_t level)
8061{
8062 switch (level) {
8063 /* initialize the wlan sub system */
8064 case WLAN_SVC_TP_NONE:
8065 return "NONE";
8066 case WLAN_SVC_TP_LOW:
8067 return "LOW";
8068 case WLAN_SVC_TP_MEDIUM:
8069 return "MED";
8070 case WLAN_SVC_TP_HIGH:
8071 return "HIGH";
8072 default:
8073 return "INVAL";
8074 }
8075}
8076
Nirav Shahed34b212016-04-25 10:59:16 +05308077
8078/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008079 * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram
8080 * @hdd_ctx: hdd context
8081 *
8082 * Return: none
8083 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008084void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008085{
8086 int i;
8087
8088#ifdef MSM_PLATFORM
Nirav Shahe6194ac2018-07-13 11:04:41 +05308089 hdd_nofl_info("BW compute Interval: %dms",
jitiphil869b9f72018-09-25 17:14:01 +05308090 hdd_ctx->config->bus_bw_compute_interval);
Nirav Shahe6194ac2018-07-13 11:04:41 +05308091 hdd_nofl_info("BW High TH: %d BW Med TH: %d BW Low TH: %d",
jitiphil869b9f72018-09-25 17:14:01 +05308092 hdd_ctx->config->bus_bw_high_threshold,
8093 hdd_ctx->config->bus_bw_medium_threshold,
8094 hdd_ctx->config->bus_bw_low_threshold);
Nirav Shahe6194ac2018-07-13 11:04:41 +05308095 hdd_nofl_info("Enable TCP DEL ACK: %d",
8096 hdd_ctx->en_tcp_delack_no_lro);
8097 hdd_nofl_info("TCP DEL High TH: %d TCP DEL Low TH: %d",
jitiphil869b9f72018-09-25 17:14:01 +05308098 hdd_ctx->config->tcp_delack_thres_high,
8099 hdd_ctx->config->tcp_delack_thres_low);
Nirav Shahe6194ac2018-07-13 11:04:41 +05308100 hdd_nofl_info("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_limit)",
8101 hdd_ctx->config->tcp_tx_high_tput_thres);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008102#endif
8103
Nirav Shahe6194ac2018-07-13 11:04:41 +05308104 hdd_nofl_info("Total entries: %d Current index: %d",
8105 NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
Nirav Shahda008342016-05-17 18:50:40 +05308106
Nirav Shahe6194ac2018-07-13 11:04:41 +05308107 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 -08008108
8109 for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008110 /* using hdd_log to avoid printing function name */
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008111 if (hdd_ctx->hdd_txrx_hist[i].qtime > 0)
Nirav Shahe6194ac2018-07-13 11:04:41 +05308112 hdd_nofl_info("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s",
8113 i, hdd_ctx->hdd_txrx_hist[i].qtime,
8114 hdd_ctx->hdd_txrx_hist[i].interval_rx,
8115 hdd_ctx->hdd_txrx_hist[i].interval_tx,
8116 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008117 hdd_ctx->hdd_txrx_hist[i].
8118 next_vote_level),
Nirav Shahe6194ac2018-07-13 11:04:41 +05308119 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008120 hdd_ctx->hdd_txrx_hist[i].
8121 next_rx_level),
Nirav Shahe6194ac2018-07-13 11:04:41 +05308122 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008123 hdd_ctx->hdd_txrx_hist[i].
8124 next_tx_level));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008125 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008126}
8127
8128/**
8129 * wlan_hdd_clear_tx_rx_histogram() - clear tx rx histogram
8130 * @hdd_ctx: hdd context
8131 *
8132 * Return: none
8133 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008134void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008135{
8136 hdd_ctx->hdd_txrx_hist_idx = 0;
Nirav Shahed34b212016-04-25 10:59:16 +05308137 qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
8138 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008139}
8140
Mohit Khannaca4173b2017-09-12 21:52:19 -07008141/* length of the netif queue log needed per adapter */
8142#define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
8143
8144/**
8145 *
8146 * hdd_display_netif_queue_history_compact() - display compact netifq history
8147 * @hdd_ctx: hdd context
8148 *
8149 * Return: none
8150 */
8151static void
8152hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
8153{
8154 int adapter_num = 0;
8155 int i;
8156 int bytes_written;
8157 u32 tbytes;
8158 qdf_time_t total, pause, unpause, curr_time, delta;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008159 char temp_str[20 * WLAN_REASON_TYPE_MAX];
jiadbdefb252018-01-03 14:27:06 +08008160 char *comb_log_str;
8161 uint32_t comb_log_str_size;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008162 struct hdd_adapter *adapter = NULL;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008163
Dustin Brownbee82832018-07-23 10:10:51 -07008164 comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * CSR_ROAM_SESSION_MAX) + 1;
jiadbdefb252018-01-03 14:27:06 +08008165 comb_log_str = qdf_mem_malloc(comb_log_str_size);
Min Liu74a1a502018-10-10 19:59:07 +08008166 if (!comb_log_str)
jiadbdefb252018-01-03 14:27:06 +08008167 return;
jiadbdefb252018-01-03 14:27:06 +08008168
Mohit Khannaca4173b2017-09-12 21:52:19 -07008169 bytes_written = 0;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008170
Dustin Brown920397d2017-12-13 16:27:50 -08008171 hdd_for_each_adapter(hdd_ctx, adapter) {
Mohit Khannaca4173b2017-09-12 21:52:19 -07008172 curr_time = qdf_system_ticks();
8173 total = curr_time - adapter->start_time;
8174 delta = curr_time - adapter->last_time;
8175
8176 if (adapter->pause_map) {
8177 pause = adapter->total_pause_time + delta;
8178 unpause = adapter->total_unpause_time;
8179 } else {
8180 unpause = adapter->total_unpause_time + delta;
8181 pause = adapter->total_pause_time;
8182 }
8183
8184 tbytes = 0;
8185 qdf_mem_set(temp_str, 0, sizeof(temp_str));
8186 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
8187 if (adapter->queue_oper_stats[i].pause_count == 0)
8188 continue;
8189 tbytes +=
8190 snprintf(
8191 &temp_str[tbytes],
8192 (tbytes >= sizeof(temp_str) ?
8193 0 : sizeof(temp_str) - tbytes),
8194 "%d(%d,%d) ",
8195 i,
8196 adapter->queue_oper_stats[i].
8197 pause_count,
8198 adapter->queue_oper_stats[i].
8199 unpause_count);
8200 }
8201 if (tbytes >= sizeof(temp_str))
8202 hdd_warn("log truncated");
8203
8204 bytes_written += snprintf(&comb_log_str[bytes_written],
jiadbdefb252018-01-03 14:27:06 +08008205 bytes_written >= comb_log_str_size ? 0 :
8206 comb_log_str_size - bytes_written,
Mohit Khannaca4173b2017-09-12 21:52:19 -07008207 "[%d %d] (%d) %u/%ums %s|",
8208 adapter->session_id, adapter->device_mode,
8209 adapter->pause_map,
8210 qdf_system_ticks_to_msecs(pause),
8211 qdf_system_ticks_to_msecs(total),
8212 temp_str);
8213
Mohit Khannaca4173b2017-09-12 21:52:19 -07008214 adapter_num++;
8215 }
8216
8217 /* using QDF_TRACE to avoid printing function name */
8218 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
8219 "STATS |%s", comb_log_str);
8220
jiadbdefb252018-01-03 14:27:06 +08008221 if (bytes_written >= comb_log_str_size)
Mohit Khannaca4173b2017-09-12 21:52:19 -07008222 hdd_warn("log string truncated");
jiadbdefb252018-01-03 14:27:06 +08008223
8224 qdf_mem_free(comb_log_str);
Mohit Khannaca4173b2017-09-12 21:52:19 -07008225}
8226
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008227/**
Srinivas Girigowdab841da72017-03-25 18:04:39 -07008228 * wlan_hdd_display_netif_queue_history() - display netif queue history
Jeff Johnson58adbcf2017-09-03 08:53:31 -07008229 * @hdd_ctx: hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008230 *
8231 * Return: none
8232 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07008233void
8234wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
8235 enum qdf_stats_verbosity_level verb_lvl)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008236{
8237
Jeff Johnson9d295242017-08-29 14:39:48 -07008238 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008239 int i;
Nirav Shahda008342016-05-17 18:50:40 +05308240 qdf_time_t total, pause, unpause, curr_time, delta;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008241
Mohit Khannaca4173b2017-09-12 21:52:19 -07008242 if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
8243 hdd_display_netif_queue_history_compact(hdd_ctx);
8244 return;
8245 }
8246
Dustin Brown920397d2017-12-13 16:27:50 -08008247 hdd_for_each_adapter(hdd_ctx, adapter) {
Nirav Shahe6194ac2018-07-13 11:04:41 +05308248 hdd_nofl_info("Netif queue operation statistics:");
8249 hdd_nofl_info("Session_id %d device mode %d",
8250 adapter->session_id, adapter->device_mode);
8251 hdd_nofl_info("Current pause_map value %x", adapter->pause_map);
Nirav Shah617cff92016-04-25 10:24:24 +05308252 curr_time = qdf_system_ticks();
8253 total = curr_time - adapter->start_time;
Nirav Shahda008342016-05-17 18:50:40 +05308254 delta = curr_time - adapter->last_time;
Nirav Shah617cff92016-04-25 10:24:24 +05308255 if (adapter->pause_map) {
Nirav Shahda008342016-05-17 18:50:40 +05308256 pause = adapter->total_pause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05308257 unpause = adapter->total_unpause_time;
8258 } else {
Nirav Shahda008342016-05-17 18:50:40 +05308259 unpause = adapter->total_unpause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05308260 pause = adapter->total_pause_time;
8261 }
Nirav Shahe6194ac2018-07-13 11:04:41 +05308262 hdd_nofl_info("Total: %ums Pause: %ums Unpause: %ums",
8263 qdf_system_ticks_to_msecs(total),
8264 qdf_system_ticks_to_msecs(pause),
8265 qdf_system_ticks_to_msecs(unpause));
8266 hdd_nofl_info("reason_type: pause_cnt: unpause_cnt: pause_time");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008267
Nirav Shahda008342016-05-17 18:50:40 +05308268 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
8269 qdf_time_t pause_delta = 0;
8270
8271 if (adapter->pause_map & (1 << i))
8272 pause_delta = delta;
8273
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008274 /* using hdd_log to avoid printing function name */
Nirav Shahe6194ac2018-07-13 11:04:41 +05308275 hdd_nofl_info("%s: %d: %d: %ums",
8276 hdd_reason_type_to_string(i),
8277 adapter->queue_oper_stats[i].pause_count,
8278 adapter->queue_oper_stats[i].
8279 unpause_count,
8280 qdf_system_ticks_to_msecs(
8281 adapter->queue_oper_stats[i].
8282 total_pause_time + pause_delta));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008283 }
8284
Nirav Shahe6194ac2018-07-13 11:04:41 +05308285 hdd_nofl_info("Netif queue operation history:");
8286 hdd_nofl_info("Total entries: %d current index %d",
8287 WLAN_HDD_MAX_HISTORY_ENTRY,
8288 adapter->history_index);
Nirav Shahda008342016-05-17 18:50:40 +05308289
Nirav Shahe6194ac2018-07-13 11:04:41 +05308290 hdd_nofl_info("index: time: action_type: reason_type: pause_map");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008291
8292 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008293 /* using hdd_log to avoid printing function name */
8294 if (adapter->queue_oper_history[i].time == 0)
8295 continue;
Nirav Shahe6194ac2018-07-13 11:04:41 +05308296 hdd_nofl_info("%d: %u: %s: %s: %x",
8297 i, qdf_system_ticks_to_msecs(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008298 adapter->queue_oper_history[i].time),
Nirav Shahe6194ac2018-07-13 11:04:41 +05308299 hdd_action_type_to_string(
8300 adapter->queue_oper_history[i].
8301 netif_action),
8302 hdd_reason_type_to_string(
8303 adapter->queue_oper_history[i].
8304 netif_reason),
8305 adapter->queue_oper_history[i].pause_map);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008306 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008307 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008308}
8309
8310/**
8311 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
8312 * @hdd_ctx: hdd context
8313 *
8314 * Return: none
8315 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008316void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008317{
Jeff Johnson9d295242017-08-29 14:39:48 -07008318 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008319
Dustin Brown920397d2017-12-13 16:27:50 -08008320 hdd_for_each_adapter(hdd_ctx, adapter) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308321 qdf_mem_zero(adapter->queue_oper_stats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008322 sizeof(adapter->queue_oper_stats));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308323 qdf_mem_zero(adapter->queue_oper_history,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008324 sizeof(adapter->queue_oper_history));
Nirav Shah617cff92016-04-25 10:24:24 +05308325 adapter->history_index = 0;
8326 adapter->start_time = adapter->last_time = qdf_system_ticks();
8327 adapter->total_pause_time = 0;
8328 adapter->total_unpause_time = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008329 }
8330}
8331
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008332#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8333/**
8334 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
8335 * @hdd_ctx: hdd global context
8336 *
8337 * Return: none
8338 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008339static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008340{
8341 uint8_t i;
8342
8343 mutex_init(&hdd_ctx->op_ctx.op_lock);
8344 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
8345 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
8346 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
8347 }
8348}
8349#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008350static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008351{
8352}
8353#endif
8354
Yingying Tang95409972016-10-20 15:16:15 +08008355#ifdef WLAN_FEATURE_WOW_PULSE
8356/**
8357 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008358 * @phddctx: struct hdd_context structure pointer
Yingying Tang95409972016-10-20 15:16:15 +08008359 * @enable: enable or disable this behaviour
8360 *
8361 * Return: int
8362 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008363static int wlan_hdd_set_wow_pulse(struct hdd_context *phddctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08008364{
Yingying Tang95409972016-10-20 15:16:15 +08008365 struct wow_pulse_mode wow_pulse_set_info;
8366 QDF_STATUS status;
8367
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008368 hdd_debug("wow pulse enable flag is %d", enable);
Yingying Tang95409972016-10-20 15:16:15 +08008369
Wu Gao66454f12018-09-26 19:55:41 +08008370 if (!ucfg_pmo_is_wow_pulse_enabled(phddctx->psoc))
Yingying Tang95409972016-10-20 15:16:15 +08008371 return 0;
8372
8373 /* prepare the request to send to SME */
8374 if (enable == true) {
8375 wow_pulse_set_info.wow_pulse_enable = true;
8376 wow_pulse_set_info.wow_pulse_pin =
Wu Gao66454f12018-09-26 19:55:41 +08008377 ucfg_pmo_get_wow_pulse_pin(phddctx->psoc);
8378
Yingying Tang95409972016-10-20 15:16:15 +08008379 wow_pulse_set_info.wow_pulse_interval_high =
Wu Gao66454f12018-09-26 19:55:41 +08008380 ucfg_pmo_get_wow_pulse_interval_high(phddctx->psoc);
8381
8382 wow_pulse_set_info.wow_pulse_interval_low =
8383 ucfg_pmo_get_wow_pulse_interval_low(phddctx->psoc);
Yingying Tang95409972016-10-20 15:16:15 +08008384 } else {
8385 wow_pulse_set_info.wow_pulse_enable = false;
8386 wow_pulse_set_info.wow_pulse_pin = 0;
8387 wow_pulse_set_info.wow_pulse_interval_low = 0;
8388 wow_pulse_set_info.wow_pulse_interval_high = 0;
8389 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008390 hdd_debug("enable %d pin %d low %d high %d",
Yingying Tang95409972016-10-20 15:16:15 +08008391 wow_pulse_set_info.wow_pulse_enable,
8392 wow_pulse_set_info.wow_pulse_pin,
8393 wow_pulse_set_info.wow_pulse_interval_low,
8394 wow_pulse_set_info.wow_pulse_interval_high);
8395
8396 status = sme_set_wow_pulse(&wow_pulse_set_info);
8397 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008398 hdd_debug("sme_set_wow_pulse failure!");
Yingying Tang95409972016-10-20 15:16:15 +08008399 return -EIO;
8400 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008401 hdd_debug("sme_set_wow_pulse success!");
Yingying Tang95409972016-10-20 15:16:15 +08008402 return 0;
8403}
8404#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008405static inline int wlan_hdd_set_wow_pulse(struct hdd_context *phddctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08008406{
8407 return 0;
8408}
8409#endif
8410
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008411#ifdef WLAN_FEATURE_FASTPATH
jitiphil377bcc12018-10-05 19:46:08 +05308412
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008413/**
8414 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
8415 * @hdd_cfg: hdd config
8416 * @context: lower layer context
8417 *
8418 * Return: none
8419 */
jitiphil377bcc12018-10-05 19:46:08 +05308420void hdd_enable_fastpath(struct hdd_context *hdd_ctx,
8421 void *context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008422{
jitiphil377bcc12018-10-05 19:46:08 +05308423 if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008424 hif_enable_fastpath(context);
8425}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008426#endif
8427
Yuanyuan Liu13738502016-04-06 17:41:37 -07008428#if defined(FEATURE_WLAN_CH_AVOID)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008429/**
8430 * hdd_set_thermal_level_cb() - set thermal level callback function
Jeff Johnson0e963082018-07-04 19:39:20 -07008431 * @hdd_handle: opaque handle for the hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008432 * @level: thermal level
8433 *
8434 * Change IPA data path to SW path when the thermal throttle level greater
8435 * than 0, and restore the original data path when throttle level is 0
8436 *
8437 * Return: none
8438 */
Jeff Johnson0e963082018-07-04 19:39:20 -07008439static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008440{
Jeff Johnson0e963082018-07-04 19:39:20 -07008441 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008442
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008443 /* Change IPA to SW path when throttle level greater than 0 */
8444 if (level > THROTTLE_LEVEL_0)
Dustin Brown07901ec2018-09-07 11:02:41 -07008445 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008446 else
8447 /* restore original concurrency mode */
Dustin Brown07901ec2018-09-07 11:02:41 -07008448 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008449}
8450
8451/**
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05308452 * hdd_get_safe_channel() - Get safe channel from current regulatory
8453 * @hdd_ctx: pointer to hdd context
8454 * @adapter: pointer to softap adapter
8455 *
8456 * This function is used to get safe channel from current regulatory valid
8457 * channels to restart SAP if failed to get safe channel from PCL.
8458 *
8459 * Return: Channel number to restart SAP in case of success. In case of any
8460 * failure, the channel number returned is zero.
8461 */
8462static uint8_t
8463hdd_get_safe_channel(struct hdd_context *hdd_ctx,
8464 struct hdd_adapter *adapter)
8465{
8466 struct sir_pcl_list pcl = {0};
8467 uint32_t i, j;
8468 bool found = false;
8469 int ret;
8470
8471 /* Try for safe channel from all valid channel */
8472 pcl.pcl_len = MAX_NUM_CHAN;
8473 ret = hdd_get_valid_chan(hdd_ctx, pcl.pcl_list,
8474 &pcl.pcl_len);
8475 if (ret) {
8476 hdd_err("error %d in getting valid channel list", ret);
8477 return INVALID_CHANNEL_ID;
8478 }
8479
8480 for (i = 0; i < pcl.pcl_len; i++) {
8481 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
8482 found = false;
8483 for (j = 0; j < hdd_ctx->unsafe_channel_count; j++) {
8484 if (pcl.pcl_list[i] ==
8485 hdd_ctx->unsafe_channel_list[j]) {
8486 hdd_debug("unsafe chan:%d", pcl.pcl_list[i]);
8487 found = true;
8488 break;
8489 }
8490 }
8491
8492 if (found)
8493 continue;
8494
8495 if ((pcl.pcl_list[i] >=
8496 adapter->session.ap.sap_config.acs_cfg.start_ch) &&
8497 (pcl.pcl_list[i] <=
8498 adapter->session.ap.sap_config.acs_cfg.end_ch)) {
8499 hdd_debug("found safe chan:%d", pcl.pcl_list[i]);
8500 return pcl.pcl_list[i];
8501 }
8502 }
8503
8504 return INVALID_CHANNEL_ID;
8505}
8506
8507#else
8508/**
8509 * hdd_set_thermal_level_cb() - set thermal level callback function
8510 * @hdd_handle: opaque handle for the hdd context
8511 * @level: thermal level
8512 *
8513 * Change IPA data path to SW path when the thermal throttle level greater
8514 * than 0, and restore the original data path when throttle level is 0
8515 *
8516 * Return: none
8517 */
8518static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
8519{
8520}
8521
8522/**
8523 * hdd_get_safe_channel() - Get safe channel from current regulatory
8524 * @hdd_ctx: pointer to hdd context
8525 * @adapter: pointer to softap adapter
8526 *
8527 * This function is used to get safe channel from current regulatory valid
8528 * channels to restart SAP if failed to get safe channel from PCL.
8529 *
8530 * Return: Channel number to restart SAP in case of success. In case of any
8531 * failure, the channel number returned is zero.
8532 */
8533static uint8_t
8534hdd_get_safe_channel(struct hdd_context *hdd_ctx,
8535 struct hdd_adapter *adapter)
8536{
8537 return 0;
8538}
8539#endif
8540
8541/**
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308542 * hdd_get_safe_channel_from_pcl_and_acs_range() - Get safe channel for SAP
8543 * restart
Manishekar Chandrasekarandb9b8672016-06-10 23:31:19 +05308544 * @adapter: AP adapter, which should be checked for NULL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008545 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308546 * Get a safe channel to restart SAP. PCL already takes into account the
8547 * unsafe channels. So, the PCL is validated with the ACS range to provide
8548 * a safe channel for the SAP to restart.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008549 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308550 * Return: Channel number to restart SAP in case of success. In case of any
8551 * failure, the channel number returned is zero.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008552 */
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05308553static uint8_t
8554hdd_get_safe_channel_from_pcl_and_acs_range(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008555{
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308556 struct sir_pcl_list pcl;
8557 QDF_STATUS status;
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05308558 uint32_t i;
Jeff Johnson16528362018-06-14 12:34:16 -07008559 mac_handle_t mac_handle;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008560 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008561
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308562 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8563 if (!hdd_ctx) {
8564 hdd_err("invalid HDD context");
8565 return INVALID_CHANNEL_ID;
8566 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008567
Jeff Johnson16528362018-06-14 12:34:16 -07008568 mac_handle = hdd_ctx->mac_handle;
8569 if (!mac_handle) {
8570 hdd_err("invalid MAC handle");
Manishekar Chandrasekaran79746ac2016-06-24 04:45:33 +05308571 return INVALID_CHANNEL_ID;
8572 }
8573
Dustin Brown1dbefe62018-09-11 16:32:03 -07008574 status = policy_mgr_get_pcl_for_existing_conn(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08008575 PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len,
bings37bd58f2017-07-20 16:49:26 +08008576 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list),
8577 false);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308578 if (QDF_IS_STATUS_ERROR(status)) {
8579 hdd_err("Get PCL failed");
8580 return INVALID_CHANNEL_ID;
8581 }
8582
Frank Liudc2cefb2017-06-21 15:38:18 +08008583 /*
8584 * In some scenarios, like hw dbs disabled, sap+sap case, if operating
8585 * channel is unsafe channel, the pcl may be empty, instead of return,
8586 * try to choose a safe channel from acs range.
8587 */
8588 if (!pcl.pcl_len)
8589 hdd_debug("pcl length is zero!");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308590
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008591 hdd_debug("start:%d end:%d",
Jeff Johnsonb9424862017-10-30 08:49:35 -07008592 adapter->session.ap.sap_config.acs_cfg.start_ch,
8593 adapter->session.ap.sap_config.acs_cfg.end_ch);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308594
8595 /* PCL already takes unsafe channel into account */
8596 for (i = 0; i < pcl.pcl_len; i++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008597 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308598 if ((pcl.pcl_list[i] >=
Jeff Johnsonb9424862017-10-30 08:49:35 -07008599 adapter->session.ap.sap_config.acs_cfg.start_ch) &&
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308600 (pcl.pcl_list[i] <=
Jeff Johnsonb9424862017-10-30 08:49:35 -07008601 adapter->session.ap.sap_config.acs_cfg.end_ch)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008602 hdd_debug("found PCL safe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308603 return pcl.pcl_list[i];
8604 }
8605 }
8606
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008607 hdd_debug("no safe channel from PCL found in ACS range");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308608
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05308609 return hdd_get_safe_channel(hdd_ctx, adapter);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308610}
8611
8612/**
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08008613 * hdd_switch_sap_channel() - Move SAP to the given channel
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308614 * @adapter: AP adapter
8615 * @channel: Channel
Min Liu2fef5792018-01-19 17:59:42 +08008616 * @forced: Force to switch channel, ignore SCC/MCC check
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308617 *
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08008618 * Moves the SAP interface by invoking the function which
8619 * executes the callback to perform channel switch using (E)CSA.
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308620 *
8621 * Return: None
8622 */
Min Liu2fef5792018-01-19 17:59:42 +08008623void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel,
8624 bool forced)
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308625{
Jeff Johnson87251032017-08-29 13:31:11 -07008626 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008627 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -07008628 mac_handle_t mac_handle;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308629
8630 if (!adapter) {
8631 hdd_err("invalid adapter");
8632 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008633 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308634
8635 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
8636
Jeff Johnson16528362018-06-14 12:34:16 -07008637 mac_handle = hdd_adapter_get_mac_handle(adapter);
8638 if (!mac_handle) {
8639 hdd_err("invalid MAC handle");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308640 return;
8641 }
8642
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08008643 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8644
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008645 hdd_debug("chan:%d width:%d",
Jeff Johnson91df29d2017-10-27 19:29:50 -07008646 channel, hdd_ap_ctx->sap_config.ch_width_orig);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308647
Dustin Brown1dbefe62018-09-11 16:32:03 -07008648 policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -07008649 adapter->session_id, channel,
Min Liu2fef5792018-01-19 17:59:42 +08008650 hdd_ap_ctx->sap_config.ch_width_orig, forced);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008651}
Kapil Gupta8878ad92017-02-13 11:56:04 +05308652
Jeff Johnson9d295242017-08-29 14:39:48 -07008653int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
Kapil Gupta8878ad92017-02-13 11:56:04 +05308654{
8655 struct hdd_external_acs_timer_context *timer_context;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308656 int status;
8657 QDF_STATUS qdf_status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308658
8659 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
8660
8661 if (QDF_TIMER_STATE_RUNNING ==
Jeff Johnsonb9424862017-10-30 08:49:35 -07008662 qdf_mc_timer_get_current_state(&adapter->session.
Kapil Gupta8878ad92017-02-13 11:56:04 +05308663 ap.vendor_acs_timer)) {
Jeff Johnsonb9424862017-10-30 08:49:35 -07008664 qdf_mc_timer_stop(&adapter->session.ap.vendor_acs_timer);
Kapil Gupta8878ad92017-02-13 11:56:04 +05308665 }
8666 timer_context = (struct hdd_external_acs_timer_context *)
Jeff Johnsonb9424862017-10-30 08:49:35 -07008667 adapter->session.ap.vendor_acs_timer.user_data;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308668 timer_context->reason = reason;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308669 qdf_status =
Jeff Johnsonb9424862017-10-30 08:49:35 -07008670 qdf_mc_timer_start(&adapter->session.ap.vendor_acs_timer,
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308671 WLAN_VENDOR_ACS_WAIT_TIME);
8672 if (qdf_status != QDF_STATUS_SUCCESS) {
8673 hdd_err("failed to start external acs timer");
8674 return -ENOSPC;
8675 }
8676 /* Update config to application */
8677 status = hdd_cfg80211_update_acs_config(adapter, reason);
Dustin Brown5e89ef82018-03-14 11:50:23 -07008678 hdd_info("Updated ACS config to nl with reason %d", reason);
Kapil Gupta8878ad92017-02-13 11:56:04 +05308679
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308680 return status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308681}
8682
Nirav Shaheb017be2018-02-15 11:20:58 +05308683#if defined(FEATURE_WLAN_CH_AVOID)
Agrawal Ashish467dde42016-09-08 18:44:22 +05308684/**
8685 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
8686 * @hdd_ctx: hdd context pointer
8687 *
8688 * hdd_unsafe_channel_restart_sap check all unsafe channel list
8689 * and if ACS is enabled, driver will ask userspace to restart the
8690 * sap. User space on LTE coex indication restart driver.
8691 *
8692 * Return - none
8693 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008694void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
Agrawal Ashish467dde42016-09-08 18:44:22 +05308695{
Dustin Brown920397d2017-12-13 16:27:50 -08008696 struct hdd_adapter *adapter;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308697 uint32_t i;
8698 bool found = false;
8699 uint8_t restart_chan;
Krunal Sonidf29bc42018-11-15 13:26:29 -08008700 uint8_t scc_on_lte_coex = 0;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05308701 bool value;
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07008702 QDF_STATUS status;
8703 bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE);
8704 bool is_vendor_acs_support =
8705 cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008706
Dustin Brown920397d2017-12-13 16:27:50 -08008707 hdd_for_each_adapter(hdd_ctxt, adapter) {
8708 if (!(adapter->device_mode == QDF_SAP_MODE &&
8709 adapter->session.ap.sap_config.acs_cfg.acs_mode)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008710 hdd_debug("skip device mode:%d acs:%d",
Dustin Brown920397d2017-12-13 16:27:50 -08008711 adapter->device_mode,
8712 adapter->session.ap.sap_config.
8713 acs_cfg.acs_mode);
8714 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308715 }
8716
8717 found = false;
Krunal Sonidf29bc42018-11-15 13:26:29 -08008718 status =
8719 ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctxt->psoc,
8720 &scc_on_lte_coex);
8721 if (!QDF_IS_STATUS_SUCCESS(status))
8722 hdd_err("can't get scc on lte coex chnl, use def");
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07008723 /*
8724 * If STA+SAP is doing SCC & g_sta_sap_scc_on_lte_coex_chan
8725 * is set, no need to move SAP.
8726 */
Dustin Brown1dbefe62018-09-11 16:32:03 -07008727 if (policy_mgr_is_sta_sap_scc(hdd_ctxt->psoc,
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07008728 adapter->session.ap.operating_channel) &&
Krunal Sonidf29bc42018-11-15 13:26:29 -08008729 scc_on_lte_coex)
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07008730 hdd_debug("SAP is allowed on SCC channel, no need to move SAP");
8731 else {
8732 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
8733 if (adapter->session.ap.operating_channel ==
8734 hdd_ctxt->unsafe_channel_list[i]) {
8735 found = true;
8736 hdd_debug("operating ch:%d is unsafe",
8737 adapter->session.ap.operating_channel);
8738 break;
8739 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05308740 }
8741 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05308742 if (!found) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008743 hdd_debug("ch:%d is safe. no need to change channel",
Dustin Brown920397d2017-12-13 16:27:50 -08008744 adapter->session.ap.operating_channel);
8745 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308746 }
8747
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07008748 status = ucfg_mlme_get_acs_support_for_dfs_ltecoex(
8749 hdd_ctxt->psoc,
8750 &is_acs_support_for_dfs_ltecoex);
8751 if (!QDF_IS_STATUS_SUCCESS(status))
8752 hdd_err("get_acs_support_for_dfs_ltecoex failed,set def");
8753
8754 status = ucfg_mlme_get_vendor_acs_support(
8755 hdd_ctxt->psoc,
8756 &is_vendor_acs_support);
8757 if (!QDF_IS_STATUS_SUCCESS(status))
8758 hdd_err("get_vendor_acs_support failed, set default");
8759
8760 if (is_vendor_acs_support && is_acs_support_for_dfs_ltecoex) {
Dustin Brown920397d2017-12-13 16:27:50 -08008761 hdd_update_acs_timer_reason(adapter,
Kapil Gupta8878ad92017-02-13 11:56:04 +05308762 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
Dustin Brown920397d2017-12-13 16:27:50 -08008763 continue;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308764 } else
8765 restart_chan =
8766 hdd_get_safe_channel_from_pcl_and_acs_range(
Dustin Brown920397d2017-12-13 16:27:50 -08008767 adapter);
Agrawal Ashish467dde42016-09-08 18:44:22 +05308768 if (!restart_chan) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008769 hdd_err("fail to restart SAP");
Agrawal Ashish467dde42016-09-08 18:44:22 +05308770 } else {
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08008771 /*
8772 * SAP restart due to unsafe channel. While
8773 * restarting the SAP, make sure to clear
8774 * acs_channel, channel to reset to
8775 * 0. Otherwise these settings will override
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05308776 * the ACS while restart.
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08008777 */
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05308778 hdd_ctxt->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008779 hdd_debug("sending coex indication");
Agrawal Ashish467dde42016-09-08 18:44:22 +05308780 wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index,
8781 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Dustin Brown05d81302018-09-11 16:49:22 -07008782 ucfg_mlme_get_sap_internal_restart(hdd_ctxt->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05308783 &value);
8784 hdd_debug("driver to start sap: %d", value);
8785 if (value)
Min Liu2fef5792018-01-19 17:59:42 +08008786 hdd_switch_sap_channel(adapter, restart_chan,
8787 true);
Liangwei Dong6663d162017-07-10 03:29:36 -04008788 else
8789 return;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308790 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05308791 }
8792}
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05308793
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008794/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008795 * hdd_init_channel_avoidance() - Initialize channel avoidance
8796 * @hdd_ctx: HDD global context
8797 *
8798 * Initialize the channel avoidance logic by retrieving the unsafe
Yuanyuan Liu13738502016-04-06 17:41:37 -07008799 * channel list from the platform driver and plumbing the data
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008800 * down to the lower layers. Then subscribe to subsequent channel
8801 * avoidance events.
8802 *
8803 * Return: None
8804 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008805static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008806{
8807 uint16_t unsafe_channel_count;
8808 int index;
8809
Yuanyuan Liu13738502016-04-06 17:41:37 -07008810 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
8811 hdd_ctx->unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008812 &(hdd_ctx->unsafe_channel_count),
Amar Singhalb8d4f152016-02-10 10:21:43 -08008813 sizeof(uint16_t) * NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008814
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008815 hdd_debug("num of unsafe channels is %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008816 hdd_ctx->unsafe_channel_count);
8817
Anurag Chouhan6d760662016-02-20 16:05:43 +05308818 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
Amar Singhalb8d4f152016-02-10 10:21:43 -08008819 (uint16_t)NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008820
8821 for (index = 0; index < unsafe_channel_count; index++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008822 hdd_debug("channel %d is not safe",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008823 hdd_ctx->unsafe_channel_list[index]);
8824
8825 }
8826
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008827}
Dustin Brown676a2322017-08-15 13:16:13 -07008828
Jeff Johnson9d295242017-08-29 14:39:48 -07008829static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008830 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07008831{
8832 uint8_t restart_chan;
8833
8834 restart_chan = hdd_get_safe_channel_from_pcl_and_acs_range(adapter);
8835 if (!restart_chan) {
8836 hdd_alert("fail to restart SAP");
8837 return;
8838 }
8839
8840 /* SAP restart due to unsafe channel. While restarting
8841 * the SAP, make sure to clear acs_channel, channel to
8842 * reset to 0. Otherwise these settings will override
8843 * the ACS while restart.
8844 */
8845 hdd_ctx->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Dustin Brown676a2322017-08-15 13:16:13 -07008846
8847 hdd_debug("sending coex indication");
8848
8849 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
8850 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Min Liu2fef5792018-01-19 17:59:42 +08008851 hdd_switch_sap_channel(adapter, restart_chan, true);
Dustin Brown676a2322017-08-15 13:16:13 -07008852}
Liangwei Dong6e1a2092017-08-30 16:29:06 +08008853
8854int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
8855 uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count)
8856{
8857 uint32_t size;
8858 uint16_t *unsafe_list;
8859 uint16_t chan_count;
8860
8861 if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count)
8862 return -EINVAL;
8863
8864 chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count,
8865 NUM_CHANNELS);
8866 if (chan_count) {
8867 size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]);
8868 unsafe_list = qdf_mem_malloc(size);
Min Liu74a1a502018-10-10 19:59:07 +08008869 if (!unsafe_list)
Liangwei Dong6e1a2092017-08-30 16:29:06 +08008870 return -ENOMEM;
Liangwei Dong6e1a2092017-08-30 16:29:06 +08008871 qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size);
8872 } else {
8873 unsafe_list = NULL;
8874 }
8875
8876 *local_unsafe_list = unsafe_list;
8877 *local_unsafe_list_count = chan_count;
8878
8879 return 0;
8880}
8881
8882bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
8883 uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count)
8884{
8885 int i, j;
8886
8887 if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count)
8888 return true;
8889 if (local_unsafe_list_count == 0)
8890 return false;
8891 for (i = 0; i < local_unsafe_list_count; i++) {
8892 for (j = 0; j < local_unsafe_list_count; j++)
8893 if (local_unsafe_list[i] ==
8894 hdd_ctx->unsafe_channel_list[j])
8895 break;
8896 if (j >= local_unsafe_list_count)
8897 break;
8898 }
8899 if (i >= local_unsafe_list_count) {
8900 hdd_info("unsafe chan list same");
8901 return false;
8902 }
8903
8904 return true;
8905}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008906#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008907static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008908{
8909}
Dustin Brown676a2322017-08-15 13:16:13 -07008910
Jeff Johnson9d295242017-08-29 14:39:48 -07008911static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008912 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07008913{
8914 hdd_debug("Channel avoidance is not enabled; Abort SAP restart");
8915}
Yuanyuan Liu13738502016-04-06 17:41:37 -07008916#endif /* defined(FEATURE_WLAN_CH_AVOID) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008917
8918/**
Rajeev Kumard004abc2016-02-17 12:09:56 -08008919 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
8920 * user space
8921 * @frame_ind: Management frame data to be informed.
8922 *
8923 * This function is used to indicate management frame to
8924 * user space
8925 *
8926 * Return: None
8927 *
8928 */
8929void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
8930{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008931 struct hdd_context *hdd_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07008932 struct hdd_adapter *adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08008933 int i;
Pragaspathi Thilagaraj28ffc042018-07-18 15:19:36 +05308934 struct ieee80211_mgmt *mgmt =
8935 (struct ieee80211_mgmt *)frame_ind->frameBuf;
Rajeev Kumard004abc2016-02-17 12:09:56 -08008936
Dustin Browne7e71d32018-05-11 16:00:08 -07008937 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
8938 if (wlan_hdd_validate_context(hdd_ctx))
Rajeev Kumard004abc2016-02-17 12:09:56 -08008939 return;
8940
Pragaspathi Thilagaraj28ffc042018-07-18 15:19:36 +05308941 if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) {
8942 hdd_err(" Invalid frame length");
8943 return;
8944 }
8945
Rajeev Kumard004abc2016-02-17 12:09:56 -08008946 if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
8947 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
8948 adapter =
8949 hdd_get_adapter_by_sme_session_id(hdd_ctx, i);
8950 if (adapter)
8951 break;
8952 }
Wu Gaoa0230a62018-01-04 20:56:57 +08008953 } else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) {
8954 hdd_for_each_adapter(hdd_ctx, adapter) {
8955 if ((NULL != adapter) &&
8956 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)) {
8957 __hdd_indicate_mgmt_frame(adapter,
8958 frame_ind->frame_len,
8959 frame_ind->frameBuf,
8960 frame_ind->frameType,
8961 frame_ind->rxChan,
8962 frame_ind->rxRssi);
8963 }
8964 }
8965 adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08008966 } else {
8967 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
8968 frame_ind->sessionId);
8969 }
8970
8971 if ((NULL != adapter) &&
8972 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
8973 __hdd_indicate_mgmt_frame(adapter,
8974 frame_ind->frame_len,
8975 frame_ind->frameBuf,
8976 frame_ind->frameType,
8977 frame_ind->rxChan,
8978 frame_ind->rxRssi);
Rajeev Kumard004abc2016-02-17 12:09:56 -08008979}
8980
Kapil Gupta8878ad92017-02-13 11:56:04 +05308981void hdd_acs_response_timeout_handler(void *context)
8982{
8983 struct hdd_external_acs_timer_context *timer_context =
8984 (struct hdd_external_acs_timer_context *)context;
Jeff Johnson9d295242017-08-29 14:39:48 -07008985 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008986 struct hdd_context *hdd_ctx;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308987 uint8_t reason;
8988
Dustin Brown491d54b2018-03-14 12:39:11 -07008989 hdd_enter();
Kapil Gupta8878ad92017-02-13 11:56:04 +05308990 if (!timer_context) {
8991 hdd_err("invlaid timer context");
8992 return;
8993 }
8994 adapter = timer_context->adapter;
8995 reason = timer_context->reason;
8996
8997
8998 if ((!adapter) ||
8999 (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
9000 hdd_err("invalid adapter or adapter has invalid magic");
9001 return;
9002 }
9003 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9004 if (wlan_hdd_validate_context(hdd_ctx))
9005 return;
9006
9007 if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags))
9008 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
9009 else
9010 return;
9011
9012 hdd_err("ACS timeout happened for %s reason %d",
9013 adapter->dev->name, reason);
Jeff Johnson16528362018-06-14 12:34:16 -07009014
Kapil Gupta8878ad92017-02-13 11:56:04 +05309015 switch (reason) {
9016 /* SAP init case */
9017 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
9018 wlan_sap_set_vendor_acs(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
9019 false);
9020 wlan_hdd_cfg80211_start_acs(adapter);
9021 break;
9022 /* DFS detected on current channel */
9023 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
9024 wlan_sap_update_next_channel(
9025 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 0, 0);
Jeff Johnson16528362018-06-14 12:34:16 -07009026 sme_update_new_channel_event(hdd_ctx->mac_handle,
Jeff Johnson1b780e42017-10-31 14:11:45 -07009027 adapter->session_id);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309028 break;
9029 /* LTE coex event on current channel */
9030 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
9031 hdd_lte_coex_restart_sap(adapter, hdd_ctx);
9032 break;
9033 default:
9034 hdd_info("invalid reason for timer invoke");
9035
9036 }
9037}
9038
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009039/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009040 * hdd_override_ini_config - Override INI config
9041 * @hdd_ctx: HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009042 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009043 * Override INI config based on module parameter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009044 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009045 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009046 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009047static void hdd_override_ini_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009048{
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309049 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009050
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009051 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
9052 hdd_ctx->config->enableDFSChnlScan = enable_dfs_chan_scan;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009053 hdd_debug("Module enable_dfs_chan_scan set to %d",
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009054 enable_dfs_chan_scan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009055 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009056 if (0 == enable_11d || 1 == enable_11d) {
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309057 status = ucfg_mlme_set_11d_enabled(hdd_ctx->psoc, enable_11d);
9058 if (!QDF_IS_STATUS_SUCCESS(status))
9059 hdd_err("Failed to set 11d_enable flag");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009060 }
Leo Chang11545d62016-10-17 14:53:50 -07009061
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +05309062 if (hdd_ctx->config->action_oui_enable && !ucfg_action_oui_enabled()) {
9063 hdd_ctx->config->action_oui_enable = 0;
Sourav Mohapatra58841062018-11-19 16:33:27 +05309064 hdd_err("Ignore action oui ini, since no action_oui component");
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +05309065 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009066}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009067
Ashish Kumar Dhanotiya12f68212018-09-04 22:00:14 +05309068#ifdef ENABLE_MTRACE_LOG
9069static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
9070{
9071 uint8_t module_id = 0;
9072 int qdf_print_idx = -1;
9073
9074 qdf_print_idx = qdf_get_pidx();
9075 for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++)
9076 qdf_print_set_category_verbose(
9077 qdf_print_idx,
9078 module_id, QDF_TRACE_LEVEL_TRACE,
9079 hdd_ctx->config->enable_mtrace);
9080}
9081#else
9082static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
9083{
9084}
9085
9086#endif
9087
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009088/**
9089 * hdd_set_trace_level_for_each - Set trace level for each INI config
9090 * @hdd_ctx - HDD context
9091 *
9092 * Set trace level for each module based on INI config.
9093 *
9094 * Return: None
9095 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009096static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009097{
Wu Gaobc6eaa12018-11-30 14:17:45 +08009098 hdd_qdf_trace_enable(QDF_MODULE_ID_DP, 0x7f);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05309099 hdd_qdf_trace_enable(QDF_MODULE_ID_MLME, 0xffff);
Sourav Mohapatra113685f2018-08-29 14:21:55 +05309100 hdd_qdf_trace_enable(QDF_MODULE_ID_FWOL, 0xffff);
Kiran Kumar Lokere4ce40482018-08-30 16:31:00 -07009101 hdd_qdf_trace_enable(QDF_MODULE_ID_CRYPTO, 0xffff);
Kiran Kumar Lokere798de7e2017-03-30 14:01:12 -07009102
Ashish Kumar Dhanotiya12f68212018-09-04 22:00:14 +05309103 hdd_set_mtrace_for_each(hdd_ctx);
9104
Nirav Shah5c083da2018-08-03 13:46:02 +05309105 hdd_cfg_print_global_config(hdd_ctx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009106}
9107
9108/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009109 * hdd_context_init() - Initialize HDD context
9110 * @hdd_ctx: HDD context.
9111 *
9112 * Initialize HDD context along with all the feature specific contexts.
9113 *
9114 * return: 0 on success and errno on failure.
9115 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009116static int hdd_context_init(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009117{
9118 int ret;
9119
9120 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
9121 hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
9122
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009123 init_completion(&hdd_ctx->mc_sus_event_var);
9124 init_completion(&hdd_ctx->ready_to_suspend);
9125
9126 qdf_spinlock_create(&hdd_ctx->connection_status_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009127 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05309128
Dustin Brownbee82832018-07-23 10:10:51 -07009129 qdf_list_create(&hdd_ctx->hdd_adapters, 0);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009130
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009131 ret = hdd_scan_context_init(hdd_ctx);
9132 if (ret)
9133 goto list_destroy;
9134
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009135 hdd_rx_wake_lock_create(hdd_ctx);
9136
9137 ret = hdd_sap_context_init(hdd_ctx);
9138 if (ret)
9139 goto scan_destroy;
9140
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009141 wlan_hdd_cfg80211_extscan_init(hdd_ctx);
9142
9143 hdd_init_offloaded_packets_ctx(hdd_ctx);
9144
9145 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
9146 hdd_ctx->config);
9147 if (ret)
Wu Gao02bd75b2017-10-13 18:34:02 +08009148 goto sap_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009149
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05309150 qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock,
9151 "monitor_mode_wakelock");
9152
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009153 return 0;
9154
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009155sap_destroy:
9156 hdd_sap_context_destroy(hdd_ctx);
9157
9158scan_destroy:
9159 hdd_scan_context_destroy(hdd_ctx);
9160 hdd_rx_wake_lock_destroy(hdd_ctx);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009161list_destroy:
Jeff Johnson19fc8e42017-10-30 19:53:49 -07009162 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Sandeep Puligillad0004212017-02-26 18:34:56 -08009163
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009164 return ret;
9165}
9166
Dustin Brown4c663222018-10-23 14:19:36 -07009167void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx)
9168{
9169 uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time;
9170 enum wake_lock_reason reason =
9171 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER;
9172
9173 hdd_debug("Starting psoc idle timer");
9174 qdf_sched_delayed_work(&hdd_ctx->psoc_idle_timeout_work, timeout_ms);
9175 hdd_prevent_suspend_timeout(timeout_ms, reason);
9176}
9177
9178void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx)
9179{
9180 qdf_cancel_delayed_work(&hdd_ctx->psoc_idle_timeout_work);
9181 hdd_debug("Stopped psoc idle timer");
9182}
9183
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009184/**
Dustin Brown3ecc8782018-09-19 16:37:13 -07009185 * hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc
9186 * @hdd_ctx: the hdd context which should be shutdown
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309187 *
Dustin Brown3ecc8782018-09-19 16:37:13 -07009188 * When no interfaces are "up" on a psoc, an idle shutdown timer is started.
9189 * If no interfaces are brought up before the timer expires, we do an
9190 * "idle shutdown," cutting power to the physical SoC to save power. This is
9191 * done completely transparently from the perspective of userspace.
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309192 *
Dustin Brown3ecc8782018-09-19 16:37:13 -07009193 * Return: None
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309194 */
Dustin Brown3ecc8782018-09-19 16:37:13 -07009195static void hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309196{
Dustin Brown3ecc8782018-09-19 16:37:13 -07009197 struct hdd_psoc *hdd_psoc = hdd_ctx->hdd_psoc;
9198 QDF_STATUS status;
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309199
Dustin Brown491d54b2018-03-14 12:39:11 -07009200 hdd_enter();
Dustin Brown3ecc8782018-09-19 16:37:13 -07009201
9202 status = dsc_psoc_trans_start(hdd_psoc->dsc_psoc, "idle shutdown");
9203 if (QDF_IS_STATUS_ERROR(status)) {
9204 hdd_info("psoc busy, abort idle shutdown; status:%u", status);
9205 return;
9206 }
9207
9208 QDF_BUG(!hdd_wlan_stop_modules(hdd_ctx, false));
9209
9210 hdd_psoc->state = psoc_state_idle;
9211 dsc_psoc_trans_stop(hdd_psoc->dsc_psoc);
9212
Dustin Browne74003f2018-03-14 12:51:58 -07009213 hdd_exit();
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309214}
9215
Dustin Brown3ecc8782018-09-19 16:37:13 -07009216int hdd_psoc_idle_restart(struct hdd_context *hdd_ctx)
9217{
9218 struct hdd_psoc *hdd_psoc = hdd_ctx->hdd_psoc;
9219 QDF_STATUS status;
9220 int errno;
9221
9222 status = dsc_psoc_trans_start_wait(hdd_psoc->dsc_psoc, "idle restart");
9223 if (QDF_IS_STATUS_ERROR(status)) {
9224 hdd_info("unable to start 'idle restart'; status:%u", status);
9225 return qdf_status_to_os_return(status);
9226 }
9227
9228 errno = hdd_wlan_start_modules(hdd_ctx, false);
9229 if (!errno)
9230 hdd_psoc->state = psoc_state_active;
9231
9232 dsc_psoc_trans_stop(hdd_psoc->dsc_psoc);
9233
9234 return errno;
9235}
9236
9237/**
9238 * hdd_psoc_idle_timeout_callback() - Handler for psoc idle timeout
9239 * @priv: pointer to hdd context
9240 *
9241 * Return: None
9242 */
9243static void hdd_psoc_idle_timeout_callback(void *priv)
9244{
9245 struct hdd_context *hdd_ctx = priv;
9246
9247 if (wlan_hdd_validate_context(hdd_ctx))
9248 return;
9249
9250 hdd_debug("Psoc idle timeout elapsed; starting psoc shutdown");
9251 hdd_psoc_idle_shutdown(hdd_ctx);
9252}
9253
Nirav Shaheb017be2018-02-15 11:20:58 +05309254#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9255static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
9256{
9257 wlan_logging_set_log_to_console(hdd_ctx->config->
9258 wlan_logging_to_console);
9259 wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable);
9260}
9261#else
9262static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
9263{ }
9264#endif
9265
Dundi Raviteja8e338282018-09-25 17:16:04 +05309266#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9267static void hdd_init_wlan_logging_params(struct hdd_config *config,
9268 struct wlan_objmgr_psoc *psoc)
9269{
9270 config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT);
9271
9272 config->wlan_logging_to_console =
9273 cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT);
9274}
9275#else
9276static void hdd_init_wlan_logging_params(struct hdd_config *config,
9277 struct wlan_objmgr_psoc *psoc)
9278{
9279}
9280#endif
9281
9282#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
9283static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
9284 struct wlan_objmgr_psoc *psoc)
9285{
9286 config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN);
9287}
9288#else
9289static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
9290 struct wlan_objmgr_psoc *psoc)
9291{
9292}
9293#endif
9294
9295#ifndef REMOVE_PKT_LOG
9296static void hdd_init_packet_log(struct hdd_config *config,
9297 struct wlan_objmgr_psoc *psoc)
9298{
9299 config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG);
9300}
9301#else
9302static void hdd_init_packet_log(struct hdd_config *config,
9303 struct wlan_objmgr_psoc *psoc)
9304{
9305}
9306#endif
9307
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +05309308#ifdef FEATURE_RUNTIME_PM
9309static void hdd_init_runtime_pm(struct hdd_config *config,
9310 struct wlan_objmgr_psoc *psoc)
9311{
9312 config->runtime_pm = cfg_get(psoc, CFG_ENABLE_RUNTIME_PM);
9313}
9314#else
9315static void hdd_init_runtime_pm(struct hdd_config *config,
9316 struct wlan_objmgr_psoc *psoc)
9317
9318{
9319}
9320#endif
9321
9322#ifdef FEATURE_WLAN_DYNAMIC_CVM
9323static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
9324 struct wlan_objmgr_psoc *psoc)
9325{
9326 config->vc_mode_cfg_bitmap = cfg_get(psoc, CFG_VC_MODE_BITMAP);
9327}
9328#else
9329static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
9330 struct wlan_objmgr_psoc *psoc)
9331{
9332}
9333#endif
9334
Dundi Raviteja8e338282018-09-25 17:16:04 +05309335/**
9336 * hdd_cfg_params_init() - Initialize hdd params in hdd_config strucuture
9337 * @hdd_ctx - Pointer to HDD context
9338 *
9339 * Return: None
9340 */
9341static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
9342{
9343 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
9344 struct hdd_config *config = hdd_ctx->config;
9345
9346 if (!psoc) {
9347 hdd_err("Invalid psoc");
9348 return;
9349 }
9350
9351 if (!config) {
9352 hdd_err("Invalid hdd config");
9353 return;
9354 }
9355
9356 config->bug_on_reinit_failure = cfg_get(psoc,
9357 CFG_BUG_ON_REINIT_FAILURE);
9358
9359 config->is_ramdump_enabled = cfg_get(psoc,
9360 CFG_ENABLE_RAMDUMP_COLLECTION);
9361
9362 config->iface_change_wait_time = cfg_get(psoc,
9363 CFG_INTERFACE_CHANGE_WAIT);
9364
9365 config->multicast_host_fw_msgs = cfg_get(psoc,
9366 CFG_MULTICAST_HOST_FW_MSGS);
9367
9368 config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL);
9369 config->timer_multiplier = cfg_get(psoc, CFG_TIMER_MULTIPLIER);
9370 config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT);
9371 config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG);
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +05309372 config->operating_channel = cfg_get(psoc, CFG_OPERATING_CHANNEL);
9373 config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE);
9374
9375 qdf_str_lcopy(config->enable_concurrent_sta,
9376 cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA),
9377 CFG_CONCURRENT_IFACE_MAX_LEN);
9378 qdf_str_lcopy(config->dbs_scan_selection,
9379 cfg_get(psoc, CFG_DBS_SCAN_SELECTION),
9380 CFG_DBS_SCAN_PARAM_LENGTH);
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +05309381 config->inform_bss_rssi_raw = cfg_get(psoc, CFG_INFORM_BSS_RSSI_RAW);
Sourav Mohapatra58841062018-11-19 16:33:27 +05309382 config->intfMacAddr[0] = cfg_get(psoc, CFG_INTF0_MAC_ADDR);
9383 config->intfMacAddr[1] = cfg_get(psoc, CFG_INTF1_MAC_ADDR);
9384 config->intfMacAddr[2] = cfg_get(psoc, CFG_INTF2_MAC_ADDR);
9385 config->intfMacAddr[3] = cfg_get(psoc, CFG_INTF3_MAC_ADDR);
9386 config->action_oui_enable = cfg_get(psoc, CFG_ENABLE_ACTION_OUI);
9387
9388 qdf_str_lcopy(config->action_oui_str[0],
9389 cfg_get(psoc, CFG_ACTION_OUI_CONNECT_1X1),
9390 ACTION_OUI_MAX_STR_LEN);
9391 qdf_str_lcopy(config->action_oui_str[1],
9392 cfg_get(psoc, CFG_ACTION_OUI_ITO_EXTENSION),
9393 ACTION_OUI_MAX_STR_LEN);
9394 qdf_str_lcopy(config->action_oui_str[2],
9395 cfg_get(psoc, CFG_ACTION_OUI_CCKM_1X1),
9396 ACTION_OUI_MAX_STR_LEN);
9397 qdf_str_lcopy(config->action_oui_str[3],
9398 cfg_get(psoc, CFG_ACTION_OUI_ITO_ALTERNATE),
9399 ACTION_OUI_MAX_STR_LEN);
9400 qdf_str_lcopy(config->action_oui_str[4],
9401 cfg_get(psoc, CFG_ACTION_OUI_SWITCH_TO_11N_MODE),
9402 ACTION_OUI_MAX_STR_LEN);
9403 qdf_str_lcopy(config->action_oui_str[5],
9404 cfg_get(psoc,
9405 CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN),
9406 ACTION_OUI_MAX_STR_LEN);
Dundi Raviteja8e338282018-09-25 17:16:04 +05309407
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +05309408 hdd_init_vc_mode_cfg_bitmap(config, psoc);
9409 hdd_init_runtime_pm(config, psoc);
Dundi Raviteja8e338282018-09-25 17:16:04 +05309410 hdd_init_wlan_auto_shutdown(config, psoc);
9411 hdd_init_wlan_logging_params(config, psoc);
9412 hdd_init_packet_log(config, psoc);
jitiphil869b9f72018-09-25 17:14:01 +05309413 hdd_dp_cfg_update(psoc, hdd_ctx);
Dundi Raviteja8e338282018-09-25 17:16:04 +05309414}
9415
Dustin Brown623e7e32018-09-05 14:27:50 -07009416struct hdd_context *hdd_context_create(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009417{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309418 QDF_STATUS status;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009419 int ret = 0;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009420 struct hdd_context *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009421
Dustin Brown491d54b2018-03-14 12:39:11 -07009422 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009423
Dustin Brown92bd8382018-10-31 15:49:46 -07009424 hdd_ctx = hdd_cfg80211_wiphy_alloc();
9425 if (!hdd_ctx) {
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009426 ret = -ENOMEM;
9427 goto err_out;
9428 }
9429
Dustin Brown4c663222018-10-23 14:19:36 -07009430 qdf_create_delayed_work(&hdd_ctx->psoc_idle_timeout_work,
Dustin Brown3ecc8782018-09-19 16:37:13 -07009431 hdd_psoc_idle_timeout_callback,
Dustin Brown4c663222018-10-23 14:19:36 -07009432 hdd_ctx);
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309433
9434 mutex_init(&hdd_ctx->iface_change_lock);
9435
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009436 hdd_ctx->parent_dev = dev;
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +05309437 hdd_ctx->last_scan_reject_session_id = 0xFF;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009438
Anurag Chouhan600c3a02016-03-01 10:33:54 +05309439 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
Min Liu74a1a502018-10-10 19:59:07 +08009440 if (!hdd_ctx->config) {
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009441 ret = -ENOMEM;
9442 goto err_free_hdd_context;
9443 }
9444
9445 /* Read and parse the qcom_cfg.ini file */
9446 status = hdd_parse_config_ini(hdd_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309447 if (QDF_STATUS_SUCCESS != status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05309448 hdd_err("Error (status: %d) parsing INI file: %s", status,
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009449 WLAN_INI_FILE);
9450 ret = -EINVAL;
9451 goto err_free_config;
9452 }
9453
Dustin Brown84f46ea2018-02-15 11:57:36 -08009454 status = cfg_parse(WLAN_INI_FILE);
9455 if (QDF_IS_STATUS_ERROR(status))
9456 hdd_err("Failed to parse cfg %s; status:%d\n",
9457 WLAN_INI_FILE, status);
9458
Dundi Ravitejafb9357a2018-09-25 12:16:03 +05309459 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID);
9460 if (ret) {
Dundi Raviteja8e338282018-09-25 17:16:04 +05309461 QDF_DEBUG_PANIC("Psoc creation fails!");
Dundi Ravitejafb9357a2018-09-25 12:16:03 +05309462 goto err_free_config;
9463 }
9464
Dundi Raviteja8e338282018-09-25 17:16:04 +05309465 hdd_cfg_params_init(hdd_ctx);
9466
Dustin Brown7f939932017-05-18 15:02:17 -07009467 hdd_debug("setting timer multiplier: %u",
9468 hdd_ctx->config->timer_multiplier);
9469 qdf_timer_set_multiplier(hdd_ctx->config->timer_multiplier);
9470
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309471 cds_set_fatal_event(cfg_get(hdd_ctx->psoc,
9472 CFG_ENABLE_FATAL_EVENT_TRIGGER));
Abhishek Singh5ea86532016-04-27 14:10:53 +05309473
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009474 hdd_override_ini_config(hdd_ctx);
9475
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009476 ret = hdd_context_init(hdd_ctx);
9477
9478 if (ret)
Dundi Ravitejafb9357a2018-09-25 12:16:03 +05309479 goto err_hdd_objmgr_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009480
Anurag Chouhan6d760662016-02-20 16:05:43 +05309481 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009482 goto skip_multicast_logging;
9483
9484 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
9485
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07009486 ret = wlan_hdd_init_tx_rx_histogram(hdd_ctx);
9487 if (ret)
9488 goto err_deinit_hdd_context;
Nirav Shahed34b212016-04-25 10:59:16 +05309489
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -07009490 ret = hdd_init_netlink_services(hdd_ctx);
9491 if (ret)
9492 goto err_deinit_txrx_histogram;
9493
Nirav Shaheb017be2018-02-15 11:20:58 +05309494 hdd_set_wlan_logging(hdd_ctx);
Nirav Shahed34b212016-04-25 10:59:16 +05309495
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009496skip_multicast_logging:
9497 hdd_set_trace_level_for_each(hdd_ctx);
9498
Rajeev Kumar493a31b2017-09-29 14:01:24 -07009499 cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx);
9500
Dustin Browne74003f2018-03-14 12:51:58 -07009501 hdd_exit();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -07009502
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009503 return hdd_ctx;
9504
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -07009505err_deinit_txrx_histogram:
9506 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
9507
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07009508err_deinit_hdd_context:
9509 hdd_context_deinit(hdd_ctx);
9510
Dundi Ravitejafb9357a2018-09-25 12:16:03 +05309511err_hdd_objmgr_destroy:
9512 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
9513
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009514err_free_config:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05309515 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009516
9517err_free_hdd_context:
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309518 mutex_destroy(&hdd_ctx->iface_change_lock);
Rajeev Kumarfa55a692018-01-09 14:12:41 -08009519 wiphy_free(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009520
9521err_out:
9522 return ERR_PTR(ret);
9523}
9524
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009525#ifdef WLAN_OPEN_P2P_INTERFACE
9526/**
9527 * hdd_open_p2p_interface - Open P2P interface
Dustin Brown61cc3932018-10-18 16:12:13 -07009528 * @hdd_ctx: HDD context
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009529 *
Dustin Brown61cc3932018-10-18 16:12:13 -07009530 * Return: QDF_STATUS
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009531 */
Dustin Brown61cc3932018-10-18 16:12:13 -07009532static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009533{
Jeff Johnson9d295242017-08-29 14:39:48 -07009534 struct hdd_adapter *adapter;
Dustin Brown61cc3932018-10-18 16:12:13 -07009535 bool p2p_dev_addr_admin;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009536
Dustin Brown1dbefe62018-09-11 16:32:03 -07009537 cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
Dustin Brown61cc3932018-10-18 16:12:13 -07009538
Wu Gaoe5689792018-07-05 19:20:13 +08009539 if (p2p_dev_addr_admin &&
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009540 !(hdd_ctx->config->intfMacAddr[0].bytes[0] & 0x02)) {
Dustin Brown61cc3932018-10-18 16:12:13 -07009541 hdd_ctx->p2p_device_address = hdd_ctx->config->intfMacAddr[0];
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009542
9543 /*
Dustin Brown61cc3932018-10-18 16:12:13 -07009544 * Generate the P2P Device Address. This consists of
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009545 * the device's primary MAC address with the locally
9546 * administered bit set.
9547 */
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07009548 hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009549 } else {
Dustin Brown61cc3932018-10-18 16:12:13 -07009550 uint8_t *p2p_dev_addr;
9551
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009552 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx);
Dustin Brown61cc3932018-10-18 16:12:13 -07009553 if (!p2p_dev_addr) {
9554 hdd_err("Failed to get MAC address for new p2p device");
9555 return QDF_STATUS_E_INVAL;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009556 }
9557
Dustin Brown61cc3932018-10-18 16:12:13 -07009558 qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07009559 p2p_dev_addr, QDF_MAC_ADDR_SIZE);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009560 }
9561
Krunal Soni9b04c9b2016-03-10 13:08:05 -08009562 adapter = hdd_open_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE, "p2p%d",
Dustin Brown61cc3932018-10-18 16:12:13 -07009563 hdd_ctx->p2p_device_address.bytes,
9564 NET_NAME_UNKNOWN, true);
9565 if (!adapter) {
9566 hdd_err("Failed to open p2p interface");
9567 return QDF_STATUS_E_INVAL;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009568 }
9569
Dustin Brown61cc3932018-10-18 16:12:13 -07009570 return QDF_STATUS_SUCCESS;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009571}
9572#else
Dustin Brown61cc3932018-10-18 16:12:13 -07009573static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009574{
Dustin Brown61cc3932018-10-18 16:12:13 -07009575 return QDF_STATUS_SUCCESS;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009576}
9577#endif
9578
Dustin Brown61cc3932018-10-18 16:12:13 -07009579static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
Jeff Johnson957bc272017-02-02 08:54:48 -08009580{
Jeff Johnson9d295242017-08-29 14:39:48 -07009581 struct hdd_adapter *adapter;
Jeff Johnson957bc272017-02-02 08:54:48 -08009582
9583 adapter = hdd_open_adapter(hdd_ctx, QDF_OCB_MODE, "wlanocb%d",
9584 wlan_hdd_get_intf_addr(hdd_ctx),
Dustin Brown61cc3932018-10-18 16:12:13 -07009585 NET_NAME_UNKNOWN, true);
9586 if (!adapter) {
Jeff Johnson957bc272017-02-02 08:54:48 -08009587 hdd_err("Failed to open 802.11p interface");
Dustin Brown61cc3932018-10-18 16:12:13 -07009588 return QDF_STATUS_E_INVAL;
Jeff Johnson957bc272017-02-02 08:54:48 -08009589 }
9590
Dustin Brown61cc3932018-10-18 16:12:13 -07009591 return QDF_STATUS_SUCCESS;
9592}
9593
9594static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
9595{
9596 struct hdd_adapter *adapter;
9597
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +05309598 if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, ""))
Dustin Brown61cc3932018-10-18 16:12:13 -07009599 return QDF_STATUS_SUCCESS;
9600
9601 adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE,
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +05309602 hdd_ctx->config->enable_concurrent_sta,
Dustin Brown61cc3932018-10-18 16:12:13 -07009603 wlan_hdd_get_intf_addr(hdd_ctx),
9604 NET_NAME_UNKNOWN, true);
9605 if (!adapter) {
9606 hdd_err("Failed to open concurrent station interface");
9607 return QDF_STATUS_E_INVAL;
9608 }
9609
9610 return QDF_STATUS_SUCCESS;
Jeff Johnson957bc272017-02-02 08:54:48 -08009611}
9612
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009613/**
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309614 * hdd_start_station_adapter()- Start the Station Adapter
9615 * @adapter: HDD adapter
9616 *
9617 * This function initializes the adapter for the station mode.
9618 *
9619 * Return: 0 on success or errno on failure.
9620 */
Jeff Johnson9d295242017-08-29 14:39:48 -07009621int hdd_start_station_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309622{
9623 QDF_STATUS status;
Krunal Sonib51eec72017-11-20 21:53:01 -08009624 int ret;
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309625
Dustin Brownfdf17c12018-03-14 12:55:34 -07009626 hdd_enter_dev(adapter->dev);
Krunal Sonib51eec72017-11-20 21:53:01 -08009627 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
9628 hdd_err("session is already opened, %d",
9629 adapter->session_id);
9630 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
9631 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309632
Krunal Sonib51eec72017-11-20 21:53:01 -08009633 ret = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
9634 if (ret) {
9635 hdd_err("failed to create vdev: %d", ret);
9636 return ret;
9637 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309638 status = hdd_init_station_mode(adapter);
9639
9640 if (QDF_STATUS_SUCCESS != status) {
9641 hdd_err("Error Initializing station mode: %d", status);
9642 return qdf_status_to_os_return(status);
9643 }
9644
Arun Khandavallifae92942016-08-01 13:31:08 +05309645 hdd_register_tx_flow_control(adapter,
9646 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08009647 hdd_tx_resume_cb,
9648 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +05309649
Dustin Browne74003f2018-03-14 12:51:58 -07009650 hdd_exit();
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05309651
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309652 return 0;
9653}
9654
9655/**
9656 * hdd_start_ap_adapter()- Start AP Adapter
9657 * @adapter: HDD adapter
9658 *
9659 * This function initializes the adapter for the AP mode.
9660 *
9661 * Return: 0 on success errno on failure.
9662 */
Jeff Johnson9d295242017-08-29 14:39:48 -07009663int hdd_start_ap_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309664{
9665 QDF_STATUS status;
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08009666 bool is_ssr = false;
Krunal Sonib51eec72017-11-20 21:53:01 -08009667 int ret;
Naveen Rawat1af09392018-01-03 17:28:21 -08009668 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Arif Hussainbd5194c2018-11-27 19:01:15 -08009669 uint32_t fine_time_meas_cap = 0;
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309670
Dustin Brown491d54b2018-03-14 12:39:11 -07009671 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309672
Krunal Sonib51eec72017-11-20 21:53:01 -08009673 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
9674 hdd_err("session is already opened, %d",
9675 adapter->session_id);
9676 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
9677 }
9678 /*
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08009679 * In SSR case no need to create new sap context.
9680 * Otherwise create sap context first and then create
9681 * vdev as while creating the vdev, driver needs to
9682 * register SAP callback and that callback uses sap context
Krunal Sonib51eec72017-11-20 21:53:01 -08009683 */
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08009684 if (adapter->session.ap.sap_context) {
9685 is_ssr = true;
9686 } else if (!hdd_sap_create_ctx(adapter)) {
Krunal Sonib51eec72017-11-20 21:53:01 -08009687 hdd_err("sap creation failed");
9688 return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
9689 }
9690
9691 ret = hdd_vdev_create(adapter, wlansap_roam_callback,
9692 adapter->session.ap.sap_context);
9693 if (ret) {
9694 hdd_err("failed to create vdev, status:%d", ret);
9695 hdd_sap_destroy_ctx(adapter);
9696 return ret;
9697 }
Naveen Rawat1af09392018-01-03 17:28:21 -08009698
Arif Hussainbd5194c2018-11-27 19:01:15 -08009699 if (adapter->device_mode == QDF_SAP_MODE) {
9700 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
9701 &fine_time_meas_cap);
Naveen Rawat1af09392018-01-03 17:28:21 -08009702 sme_cli_set_command(adapter->session_id,
9703 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE,
Arif Hussainbd5194c2018-11-27 19:01:15 -08009704 (bool)(fine_time_meas_cap & WMI_FW_AP_RTT_RESPR),
Naveen Rawat1af09392018-01-03 17:28:21 -08009705 VDEV_CMD);
Arif Hussainbd5194c2018-11-27 19:01:15 -08009706 }
Naveen Rawat1af09392018-01-03 17:28:21 -08009707
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08009708 status = hdd_init_ap_mode(adapter, is_ssr);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309709
9710 if (QDF_STATUS_SUCCESS != status) {
9711 hdd_err("Error Initializing the AP mode: %d", status);
9712 return qdf_status_to_os_return(status);
9713 }
9714
Arun Khandavallifae92942016-08-01 13:31:08 +05309715 hdd_register_tx_flow_control(adapter,
9716 hdd_softap_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08009717 hdd_softap_tx_resume_cb,
9718 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +05309719
Dustin Browne74003f2018-03-14 12:51:58 -07009720 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309721 return 0;
9722}
9723
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309724#ifdef QCA_LL_TX_FLOW_CONTROL_V2
9725/**
9726 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
9727 * @cds_cfg: CDS Configuration
9728 * @hdd_ctx: Pointer to hdd context
9729 *
9730 * Return: none
9731 */
9732static inline void hdd_txrx_populate_cds_config(struct cds_config_info
9733 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009734 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309735{
9736 cds_cfg->tx_flow_stop_queue_th =
jitiphil47c3d9a2018-11-08 18:30:55 +05309737 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309738 cds_cfg->tx_flow_start_queue_offset =
jitiphil47c3d9a2018-11-08 18:30:55 +05309739 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
Mohit Khanna70322002018-05-15 19:21:32 -07009740 /* configuration for DP RX Threads */
9741 cds_cfg->enable_dp_rx_threads = hdd_ctx->enable_dp_rx_threads;
9742 cds_cfg->num_dp_rx_threads = hdd_ctx->config->num_dp_rx_threads;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309743}
9744#else
9745static inline void hdd_txrx_populate_cds_config(struct cds_config_info
9746 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009747 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309748{
9749}
9750#endif
9751
9752#ifdef FEATURE_WLAN_RA_FILTERING
9753/**
9754 * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
9755 * @cds_cfg: CDS Configuration
9756 * @hdd_ctx: Pointer to hdd context
9757 *
9758 * Return: none
9759 */
Anand Kumar3b92a912016-12-05 12:01:26 +05309760static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009761 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309762{
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05309763 bool is_rate_limit_enabled;
9764 QDF_STATUS status;
9765
9766 status = ucfg_fwol_get_is_rate_limit_enabled(hdd_ctx->psoc,
9767 &is_rate_limit_enabled);
9768 if (QDF_IS_STATUS_ERROR(status))
9769 return;
9770
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309771 cds_cfg->ra_ratelimit_interval =
9772 hdd_ctx->config->RArateLimitInterval;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05309773 cds_cfg->is_ra_ratelimit_enabled = is_rate_limit_enabled;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309774}
9775#else
Anand Kumar3b92a912016-12-05 12:01:26 +05309776static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009777 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309778{
9779}
9780#endif
9781
9782/**
9783 * hdd_update_cds_config() - API to update cds configuration parameters
9784 * @hdd_ctx: HDD Context
9785 *
9786 * Return: 0 for Success, errno on failure
9787 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009788static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309789{
9790 struct cds_config_info *cds_cfg;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309791 int value;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309792 uint8_t band_capability;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309793 uint8_t ito_repeat_count;
Vignesh Viswanathana851d752018-10-03 19:44:38 +05309794 bool crash_inject;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309795 bool self_recovery;
9796 bool fw_timeout_crash;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309797 QDF_STATUS status;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309798
Min Liu74a1a502018-10-10 19:59:07 +08009799 cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg));
9800 if (!cds_cfg)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309801 return -ENOMEM;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309802
Srinivas Girigowda35b00312017-06-27 21:52:03 -07009803 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
Bala Venkatesh46e29032018-11-14 18:24:55 +05309804 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
9805 &cds_cfg->sta_maxlimod_dtim);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309806
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309807 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
Vignesh Viswanathana851d752018-10-03 19:44:38 +05309808 if (QDF_IS_STATUS_ERROR(status)) {
9809 hdd_err("Failed to get crash inject ini config");
9810 goto exit;
9811 }
9812
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309813 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
9814 if (QDF_IS_STATUS_ERROR(status)) {
9815 hdd_err("Failed to get self recovery ini config");
9816 goto exit;
9817 }
9818
9819 status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc,
9820 &fw_timeout_crash);
9821 if (QDF_IS_STATUS_ERROR(status)) {
9822 hdd_err("Failed to get fw timeout crash ini config");
9823 goto exit;
9824 }
9825
9826 status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc,
9827 &ito_repeat_count);
9828 if (QDF_IS_STATUS_ERROR(status)) {
9829 hdd_err("Failed to get ITO repeat count ini config");
9830 goto exit;
9831 }
9832
Vignesh Viswanathana851d752018-10-03 19:44:38 +05309833 cds_cfg->force_target_assert_enabled = crash_inject;
SaidiReddy Yenugacc733af2016-11-09 17:45:42 +05309834
Dustin Brown05d81302018-09-11 16:49:22 -07009835 ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309836 cds_cfg->ap_maxoffload_peers = value;
Dustin Brown05d81302018-09-11 16:49:22 -07009837 ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309838 &value);
9839 cds_cfg->ap_maxoffload_reorderbuffs = value;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309840
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309841 cds_cfg->reorder_offload =
jitiphil47c3d9a2018-11-08 18:30:55 +05309842 cfg_get(hdd_ctx->psoc, CFG_DP_REORDER_OFFLOAD_SUPPORT);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309843
9844 /* IPA micro controller data path offload resource config item */
Sravan Kumar Kairam5214f652018-03-13 09:52:31 +05309845 cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled();
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309846 cds_cfg->max_scan = hdd_ctx->config->max_scan_count;
9847
Jeff Johnsone2ba3cd2017-10-30 20:02:09 -07009848 cds_cfg->enable_rxthread = hdd_ctx->enable_rxthread;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309849 cds_cfg->self_gen_frm_pwr = hdd_ctx->config->self_gen_frm_pwr;
Dustin Brown05d81302018-09-11 16:49:22 -07009850 ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309851 cds_cfg->max_station = value;
Naveen Rawat64e477e2016-05-20 10:34:56 -07009852 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
Orhan K AKYILDIZ30e8cbc2017-08-11 18:00:28 -07009853 cds_cfg->max_msdus_per_rxinorderind =
jitiphil8e15ea62018-11-16 18:05:34 +05309854 cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND);
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309855 cds_cfg->self_recovery_enabled = self_recovery;
9856 cds_cfg->fw_timeout_crash = fw_timeout_crash;
Nachiket Kukadee547a482018-05-22 16:43:30 +05309857 cds_cfg->active_uc_apf_mode = hdd_ctx->config->active_uc_apf_mode;
9858 cds_cfg->active_mc_bc_apf_mode = hdd_ctx->config->active_mc_bc_apf_mode;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309859
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309860 cds_cfg->ito_repeat_count = ito_repeat_count;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309861
9862 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
9863 if (QDF_IS_STATUS_ERROR(status))
9864 goto exit;
9865
9866 cds_cfg->bandcapability = band_capability;
Rachit Kankane0106e382018-05-16 18:59:28 +05309867 cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs;
Ashish Kumar Dhanotiya9335d812017-06-30 16:57:20 +05309868
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309869 hdd_ra_populate_cds_config(cds_cfg, hdd_ctx);
9870 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
Jeff Johnson9078bdc2016-09-23 17:18:11 -07009871 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309872 cds_init_ini_config(cds_cfg);
9873 return 0;
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05309874
9875exit:
9876 qdf_mem_free(cds_cfg);
9877 return -EINVAL;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309878}
9879
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009880/**
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009881 * hdd_update_user_config() - API to update user configuration
9882 * parameters to obj mgr which are used by multiple components
9883 * @hdd_ctx: HDD Context
9884 *
9885 * Return: 0 for Success, errno on failure
9886 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009887static int hdd_update_user_config(struct hdd_context *hdd_ctx)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009888{
9889 struct wlan_objmgr_psoc_user_config *user_config;
Wu Gaoe5689792018-07-05 19:20:13 +08009890 bool skip_dfs_in_p2p_search = false;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309891 uint8_t band_capability;
Krunal Sonidf29bc42018-11-15 13:26:29 -08009892 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309893 QDF_STATUS status;
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309894 bool value = false;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309895
9896 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
9897 if (QDF_IS_STATUS_ERROR(status))
9898 return -EIO;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009899
Krunal Sonidf29bc42018-11-15 13:26:29 -08009900 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
9901 &dual_mac_feature);
9902 if (QDF_IS_STATUS_ERROR(status))
9903 return -EIO;
9904
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009905 user_config = qdf_mem_malloc(sizeof(*user_config));
Min Liu74a1a502018-10-10 19:59:07 +08009906 if (!user_config)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009907 return -ENOMEM;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009908
9909 user_config->dot11_mode = hdd_ctx->config->dot11Mode;
Krunal Sonidf29bc42018-11-15 13:26:29 -08009910 user_config->dual_mac_feature_disable = dual_mac_feature;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009911 user_config->indoor_channel_support =
9912 hdd_ctx->config->indoor_channel_support;
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309913
9914 status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value);
9915 if (!QDF_IS_STATUS_SUCCESS(status))
9916 hdd_err("Invalid 11d_enable flag");
9917 user_config->is_11d_support_enabled = value;
9918
9919 value = false;
9920 status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value);
9921 if (!QDF_IS_STATUS_SUCCESS(status))
9922 hdd_err("Invalid 11h_enable flag");
9923 user_config->is_11h_support_enabled = value;
9924
Dustin Brown1dbefe62018-09-11 16:32:03 -07009925 cfg_p2p_get_skip_dfs_channel_p2p_search(hdd_ctx->psoc,
Wu Gaoe5689792018-07-05 19:20:13 +08009926 &skip_dfs_in_p2p_search);
9927 user_config->skip_dfs_chnl_in_p2p_search = skip_dfs_in_p2p_search;
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{
9946 tSmeThermalParams thermal_param;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309947 QDF_STATUS status;
Jeff Johnson16528362018-06-14 12:34:16 -07009948 mac_handle_t mac_handle;
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309949 struct wlan_fwol_thermal_temp thermal_temp = {0};
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009950
9951 thermal_param.smeThermalMgmtEnabled =
9952 hdd_ctx->config->thermalMitigationEnable;
9953 thermal_param.smeThrottlePeriod = hdd_ctx->config->throttlePeriod;
9954
Poddar, Siddarth83905022016-04-16 17:56:08 -07009955 thermal_param.sme_throttle_duty_cycle_tbl[0] =
9956 hdd_ctx->config->throttle_dutycycle_level0;
9957 thermal_param.sme_throttle_duty_cycle_tbl[1] =
9958 hdd_ctx->config->throttle_dutycycle_level1;
9959 thermal_param.sme_throttle_duty_cycle_tbl[2] =
9960 hdd_ctx->config->throttle_dutycycle_level2;
9961 thermal_param.sme_throttle_duty_cycle_tbl[3] =
9962 hdd_ctx->config->throttle_dutycycle_level3;
9963
Dustin Brown05d81302018-09-11 16:49:22 -07009964 status = ucfg_fwol_get_thermal_temp(hdd_ctx->psoc, &thermal_temp);
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309965 if (QDF_IS_STATUS_ERROR(status))
9966 return qdf_status_to_os_return(status);
9967
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009968 thermal_param.smeThermalLevels[0].smeMinTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309969 thermal_temp.thermal_temp_min_level0;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009970 thermal_param.smeThermalLevels[0].smeMaxTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309971 thermal_temp.thermal_temp_max_level0;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009972 thermal_param.smeThermalLevels[1].smeMinTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309973 thermal_temp.thermal_temp_min_level1;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009974 thermal_param.smeThermalLevels[1].smeMaxTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309975 thermal_temp.thermal_temp_max_level1;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009976 thermal_param.smeThermalLevels[2].smeMinTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309977 thermal_temp.thermal_temp_min_level2;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009978 thermal_param.smeThermalLevels[2].smeMaxTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309979 thermal_temp.thermal_temp_max_level2;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009980 thermal_param.smeThermalLevels[3].smeMinTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309981 thermal_temp.thermal_temp_min_level3;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009982 thermal_param.smeThermalLevels[3].smeMaxTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309983 thermal_temp.thermal_temp_max_level3;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009984
Jeff Johnson16528362018-06-14 12:34:16 -07009985 mac_handle = hdd_ctx->mac_handle;
9986 status = sme_init_thermal_info(mac_handle, thermal_param);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009987
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309988 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanc5548422016-02-24 18:33:27 +05309989 return qdf_status_to_os_return(status);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009990
Jeff Johnson16528362018-06-14 12:34:16 -07009991 sme_add_set_thermal_level_callback(mac_handle,
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009992 hdd_set_thermal_level_cb);
9993
9994 return 0;
9995
9996}
9997
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009998#if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
9999/**
10000 * hdd_hold_rtnl_lock - Hold RTNL lock
10001 *
10002 * Hold RTNL lock
10003 *
10004 * Return: True if held and false otherwise
10005 */
10006static inline bool hdd_hold_rtnl_lock(void)
10007{
10008 rtnl_lock();
10009 return true;
10010}
10011
10012/**
10013 * hdd_release_rtnl_lock - Release RTNL lock
10014 *
10015 * Release RTNL lock
10016 *
10017 * Return: None
10018 */
10019static inline void hdd_release_rtnl_lock(void)
10020{
10021 rtnl_unlock();
10022}
10023#else
10024static inline bool hdd_hold_rtnl_lock(void) { return false; }
10025static inline void hdd_release_rtnl_lock(void) { }
10026#endif
10027
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010028#if !defined(REMOVE_PKT_LOG)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010029
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010030/* MAX iwpriv command support */
10031#define PKTLOG_SET_BUFF_SIZE 3
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010032#define PKTLOG_CLEAR_BUFF 4
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010033#define MAX_PKTLOG_SIZE 16
10034
10035/**
10036 * hdd_pktlog_set_buff_size() - set pktlog buffer size
10037 * @hdd_ctx: hdd context
10038 * @set_value2: pktlog buffer size value
10039 *
10040 *
10041 * Return: 0 for success or error.
10042 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010043static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010044{
10045 struct sir_wifi_start_log start_log = { 0 };
10046 QDF_STATUS status;
10047
10048 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10049 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
10050 start_log.ini_triggered = cds_is_packet_log_enabled();
10051 start_log.user_triggered = 1;
10052 start_log.size = set_value2;
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010053 start_log.is_pktlog_buff_clear = false;
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010054
Jeff Johnson16528362018-06-14 12:34:16 -070010055 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010056 if (!QDF_IS_STATUS_SUCCESS(status)) {
10057 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010058 hdd_exit();
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010059 return -EINVAL;
10060 }
10061
10062 return 0;
10063}
10064
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010065/**
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010066 * hdd_pktlog_clear_buff() - clear pktlog buffer
10067 * @hdd_ctx: hdd context
10068 *
10069 * Return: 0 for success or error.
10070 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010071static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010072{
10073 struct sir_wifi_start_log start_log;
10074 QDF_STATUS status;
10075
10076 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10077 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
10078 start_log.ini_triggered = cds_is_packet_log_enabled();
10079 start_log.user_triggered = 1;
10080 start_log.size = 0;
10081 start_log.is_pktlog_buff_clear = true;
10082
Jeff Johnson16528362018-06-14 12:34:16 -070010083 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010084 if (!QDF_IS_STATUS_SUCCESS(status)) {
10085 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010086 hdd_exit();
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010087 return -EINVAL;
10088 }
10089
10090 return 0;
10091}
10092
10093
10094/**
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010095 * hdd_process_pktlog_command() - process pktlog command
10096 * @hdd_ctx: hdd context
10097 * @set_value: value set by user
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010098 * @set_value2: pktlog buffer size value
10099 *
10100 * This function process pktlog command.
10101 * set_value2 only matters when set_value is 3 (set buff size)
10102 * otherwise we ignore it.
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010103 *
10104 * Return: 0 for success or error.
10105 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010106int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010107 int set_value2)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010108{
10109 int ret;
10110 bool enable;
10111 uint8_t user_triggered = 0;
10112
10113 ret = wlan_hdd_validate_context(hdd_ctx);
10114 if (0 != ret)
10115 return ret;
10116
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010117 hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010118
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010119 if (set_value > PKTLOG_CLEAR_BUFF) {
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010120 hdd_err("invalid pktlog value %d", set_value);
10121 return -EINVAL;
10122 }
10123
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010124 if (set_value == PKTLOG_SET_BUFF_SIZE) {
10125 if (set_value2 <= 0) {
10126 hdd_err("invalid pktlog size %d", set_value2);
10127 return -EINVAL;
10128 } else if (set_value2 > MAX_PKTLOG_SIZE) {
10129 hdd_err("Pktlog buff size is too large. max value is 16MB.\n");
10130 return -EINVAL;
10131 }
10132 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010133 } else if (set_value == PKTLOG_CLEAR_BUFF) {
10134 return hdd_pktlog_clear_buff(hdd_ctx);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010135 }
10136
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010137 /*
10138 * set_value = 0 then disable packetlog
10139 * set_value = 1 enable packetlog forcefully
10140 * set_vlaue = 2 then disable packetlog if disabled through ini or
10141 * enable packetlog with AUTO type.
10142 */
10143 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
10144 true : false;
10145
10146 if (1 == set_value) {
10147 enable = true;
10148 user_triggered = 1;
10149 }
10150
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010151 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010152}
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070010153
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010154/**
10155 * hdd_pktlog_enable_disable() - Enable/Disable packet logging
10156 * @hdd_ctx: HDD context
10157 * @enable: Flag to enable/disable
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010158 * @user_triggered: triggered through iwpriv
10159 * @size: buffer size to be used for packetlog
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010160 *
10161 * Return: 0 on success; error number otherwise
10162 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010163int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, bool enable,
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010164 uint8_t user_triggered, int size)
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010165{
10166 struct sir_wifi_start_log start_log;
10167 QDF_STATUS status;
10168
10169 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10170 start_log.verbose_level =
10171 enable ? WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010172 start_log.ini_triggered = cds_is_packet_log_enabled();
10173 start_log.user_triggered = user_triggered;
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010174 start_log.size = size;
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010175 start_log.is_pktlog_buff_clear = false;
Poddar, Siddartheefe3482016-09-21 18:12:59 +053010176 /*
10177 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
10178 * commands. Host uses this flag to decide whether to send pktlog
10179 * disable command to fw without sending pktlog enable command
10180 * previously. For eg, If vendor sends pktlog disable command without
10181 * sending pktlog enable command, then host discards the packet
10182 * but for iwpriv command, host will send it to fw.
10183 */
10184 start_log.is_iwpriv_command = 1;
Jeff Johnson16528362018-06-14 12:34:16 -070010185 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010186 if (!QDF_IS_STATUS_SUCCESS(status)) {
10187 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010188 hdd_exit();
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010189 return -EINVAL;
10190 }
10191
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053010192 if (enable == true)
10193 hdd_ctx->is_pktlog_enabled = 1;
10194 else
10195 hdd_ctx->is_pktlog_enabled = 0;
10196
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010197 return 0;
10198}
10199#endif /* REMOVE_PKT_LOG */
10200
Komal Seelam92fff912016-03-24 11:51:41 +053010201/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010202 * hdd_get_platform_wlan_mac_buff() - API to query platform driver
10203 * for MAC address
Komal Seelam92fff912016-03-24 11:51:41 +053010204 * @dev: Device Pointer
10205 * @num: Number of Valid Mac address
10206 *
10207 * Return: Pointer to MAC address buffer
10208 */
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010209static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
10210 uint32_t *num)
Komal Seelam92fff912016-03-24 11:51:41 +053010211{
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010212 return pld_get_wlan_mac_address(dev, num);
Komal Seelam92fff912016-03-24 11:51:41 +053010213}
Komal Seelam92fff912016-03-24 11:51:41 +053010214
10215/**
10216 * hdd_populate_random_mac_addr() - API to populate random mac addresses
10217 * @hdd_ctx: HDD Context
10218 * @num: Number of random mac addresses needed
10219 *
10220 * Generate random addresses using bit manipulation on the base mac address
10221 *
10222 * Return: None
10223 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010224void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
Komal Seelam92fff912016-03-24 11:51:41 +053010225{
10226 uint32_t start_idx = QDF_MAX_CONCURRENCY_PERSONA - num;
10227 uint32_t iter;
10228 struct hdd_config *ini = hdd_ctx->config;
10229 uint8_t *buf = NULL;
10230 uint8_t macaddr_b3, tmp_br3;
10231 uint8_t *src = ini->intfMacAddr[0].bytes;
10232
10233 for (iter = start_idx; iter < QDF_MAX_CONCURRENCY_PERSONA; ++iter) {
10234 buf = ini->intfMacAddr[iter].bytes;
10235 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
10236 macaddr_b3 = buf[3];
10237 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + iter) &
10238 INTF_MACADDR_MASK;
10239 macaddr_b3 += tmp_br3;
10240 macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
10241 buf[0] |= 0x02;
10242 buf[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010243 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +053010244 }
10245}
10246
10247/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010248 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
Komal Seelam92fff912016-03-24 11:51:41 +053010249 * @hdd_ctx: HDD Context
10250 *
10251 * API to get mac addresses from platform driver and update the driver
10252 * structures and configure FW with the base mac address.
10253 * Return: int
10254 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010255static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +053010256{
10257 uint32_t no_of_mac_addr, iter;
10258 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
10259 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
10260 uint8_t *addr, *buf;
10261 struct device *dev = hdd_ctx->parent_dev;
10262 struct hdd_config *ini = hdd_ctx->config;
10263 tSirMacAddr mac_addr;
10264 QDF_STATUS status;
10265
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010266 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
Komal Seelam92fff912016-03-24 11:51:41 +053010267
Dustin Brown7e761c72018-07-31 13:50:17 -070010268 if (no_of_mac_addr == 0 || !addr)
Komal Seelam92fff912016-03-24 11:51:41 +053010269 return -EINVAL;
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) {
10277 buf = ini->intfMacAddr[iter].bytes;
10278 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010279 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +053010280 }
10281
10282 status = sme_set_custom_mac_addr(mac_addr);
10283
10284 if (!QDF_IS_STATUS_SUCCESS(status))
10285 return -EAGAIN;
Srinivas Girigowdab841da72017-03-25 18:04:39 -070010286
Komal Seelam92fff912016-03-24 11:51:41 +053010287 if (no_of_mac_addr < max_mac_addr)
10288 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
10289 no_of_mac_addr);
10290 return 0;
10291}
10292
10293/**
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010294 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
10295 * @hdd_ctx: HDD Context
10296 *
10297 * Update MAC address to FW. If MAC address passed by FW is invalid, host
10298 * will generate its own MAC and update it to FW.
10299 *
10300 * Return: 0 for success
10301 * Non-zero error code for failure
10302 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010303static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010304{
10305 tSirMacAddr customMacAddr;
10306 QDF_STATUS status;
10307
10308 qdf_mem_copy(&customMacAddr,
10309 &hdd_ctx->config->intfMacAddr[0].bytes[0],
10310 sizeof(tSirMacAddr));
10311 status = sme_set_custom_mac_addr(customMacAddr);
10312 if (!QDF_IS_STATUS_SUCCESS(status))
10313 return -EAGAIN;
10314 return 0;
10315}
10316
10317/**
Komal Seelam92fff912016-03-24 11:51:41 +053010318 * hdd_initialize_mac_address() - API to get wlan mac addresses
10319 * @hdd_ctx: HDD Context
10320 *
10321 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
10322 * is provisioned with mac addresses, driver uses it, else it will use
10323 * wlan_mac.bin to update HW MAC addresses.
10324 *
10325 * Return: None
10326 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010327static void hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +053010328{
10329 QDF_STATUS status;
10330 int ret;
10331
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010332 ret = hdd_platform_wlan_mac(hdd_ctx);
Dustin Brown7e761c72018-07-31 13:50:17 -070010333 if (!ret) {
10334 hdd_info("using MAC address from platform driver");
Komal Seelam92fff912016-03-24 11:51:41 +053010335 return;
Dustin Brown7e761c72018-07-31 13:50:17 -070010336 }
Komal Seelam92fff912016-03-24 11:51:41 +053010337
10338 status = hdd_update_mac_config(hdd_ctx);
Dustin Brown7e761c72018-07-31 13:50:17 -070010339 if (QDF_IS_STATUS_SUCCESS(status)) {
10340 hdd_info("using MAC address from wlan_mac.bin");
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010341 return;
Dustin Brown7e761c72018-07-31 13:50:17 -070010342 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010343
Dustin Brown7e761c72018-07-31 13:50:17 -070010344 hdd_info("using default MAC address");
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010345
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -080010346 if (hdd_ctx->update_mac_addr_to_fw) {
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010347 ret = hdd_update_mac_addr_to_fw(hdd_ctx);
Dustin Brown7e761c72018-07-31 13:50:17 -070010348 if (ret)
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -080010349 hdd_err("MAC address out-of-sync, ret:%d", ret);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010350 }
Komal Seelam92fff912016-03-24 11:51:41 +053010351}
10352
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010353static int hdd_set_smart_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010354{
10355 int vdev_id = 0;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053010356 QDF_STATUS status;
10357 bool smart_chainmask_enabled;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010358 int param_id = WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010359 int vpdev = PDEV_CMD;
10360 int ret;
10361
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053010362 status = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc,
10363 &smart_chainmask_enabled);
10364 if (QDF_IS_STATUS_ERROR(status))
10365 return -EINVAL;
10366
10367 ret = sme_cli_set_command(vdev_id, param_id,
10368 (int)smart_chainmask_enabled, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010369 if (ret)
10370 hdd_err("WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME failed %d", ret);
10371
10372 return ret;
10373}
10374
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010375static int hdd_set_alternative_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010376{
10377 int vdev_id = 0;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010378 QDF_STATUS status;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010379 int param_id = WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010380 bool alternative_chainmask_enabled;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010381 int vpdev = PDEV_CMD;
10382 int ret;
10383
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010384 status = ucfg_get_alternative_chainmask_enabled(
10385 hdd_ctx->psoc,
10386 &alternative_chainmask_enabled);
10387 if (QDF_IS_STATUS_ERROR(status))
10388 return -EINVAL;
10389
10390 ret = sme_cli_set_command(vdev_id, param_id,
10391 (int)alternative_chainmask_enabled, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010392 if (ret)
10393 hdd_err("WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME failed %d",
10394 ret);
10395
10396 return ret;
10397}
10398
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010399static int hdd_set_ani_enabled(struct hdd_context *hdd_ctx)
Jeff Johnson12a744b2017-04-04 08:19:37 -070010400{
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010401 QDF_STATUS status;
Jeff Johnson12a744b2017-04-04 08:19:37 -070010402 int vdev_id = 0;
10403 int param_id = WMI_PDEV_PARAM_ANI_ENABLE;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010404 bool value;
Jeff Johnson12a744b2017-04-04 08:19:37 -070010405 int vpdev = PDEV_CMD;
10406 int ret;
10407
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010408 status = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &value);
10409 if (QDF_IS_STATUS_ERROR(status))
10410 return -EINVAL;
10411
10412 ret = sme_cli_set_command(vdev_id, param_id, (int)value, vpdev);
Jeff Johnson12a744b2017-04-04 08:19:37 -070010413 if (ret)
10414 hdd_err("WMI_PDEV_PARAM_ANI_ENABLE failed %d", ret);
10415
10416 return ret;
10417}
10418
Jeff Johnson89c66ff2016-04-22 15:21:37 -070010419/**
Prashanth Bhatta07998752016-04-28 12:35:33 -070010420 * hdd_pre_enable_configure() - Configurations prior to cds_enable
10421 * @hdd_ctx: HDD context
10422 *
10423 * Pre configurations to be done at lower layer before calling cds enable.
10424 *
10425 * Return: 0 on success and errno on failure.
10426 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010427static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
Prashanth Bhatta07998752016-04-28 12:35:33 -070010428{
10429 int ret;
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053010430 uint8_t val = 0;
Prashanth Bhatta07998752016-04-28 12:35:33 -070010431 QDF_STATUS status;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010432 uint32_t arp_ac_category;
Leo Changfdb45c32016-10-28 11:09:23 -070010433 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010434
Leo Changfdb45c32016-10-28 11:09:23 -070010435 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
Ajit Pal Singh5d269612018-04-19 16:29:12 +053010436 /* Register HL netdev flow control callback */
10437 cdp_hl_fc_register(soc, wlan_hdd_txrx_pause_cb);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010438
10439 /*
10440 * Note that the cds_pre_enable() sequence triggers the cfg download.
10441 * The cfg download must occur before we update the SME config
10442 * since the SME config operation must access the cfg database
10443 */
10444 status = hdd_set_sme_config(hdd_ctx);
10445
10446 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010447 hdd_err("Failed hdd_set_sme_config: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010448 ret = qdf_status_to_os_return(status);
10449 goto out;
10450 }
10451
Tushnim Bhattacharyyaba8ee932017-03-23 09:27:40 -070010452 status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
10453 if (QDF_STATUS_SUCCESS != status) {
10454 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
10455 ret = qdf_status_to_os_return(status);
10456 goto out;
10457 }
10458
Dustin Brown1dbefe62018-09-11 16:32:03 -070010459 status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val);
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053010460 if (QDF_STATUS_SUCCESS != status) {
10461 hdd_err("Get tx_chainmask_1ss from mlme failed");
10462 ret = qdf_status_to_os_return(status);
10463 goto out;
10464 }
10465 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, val,
Prashanth Bhatta07998752016-04-28 12:35:33 -070010466 PDEV_CMD);
10467 if (0 != ret) {
10468 hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret);
10469 goto out;
10470 }
10471
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010472 ret = hdd_set_smart_chainmask_enabled(hdd_ctx);
10473 if (ret)
10474 goto out;
10475
10476 ret = hdd_set_alternative_chainmask_enabled(hdd_ctx);
10477 if (ret)
10478 goto out;
10479
Jeff Johnson12a744b2017-04-04 08:19:37 -070010480 ret = hdd_set_ani_enabled(hdd_ctx);
10481 if (ret)
10482 goto out;
10483
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010484 status = ucfg_get_arp_ac_category(hdd_ctx->psoc, &arp_ac_category);
10485
10486 if (QDF_IS_STATUS_ERROR(status))
10487 return -EINVAL;
10488
Naveen Rawat247a8682017-06-05 15:00:31 -070010489 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010490 arp_ac_category,
Srinivas Girigowda70e169a2017-03-07 23:55:57 -080010491 PDEV_CMD);
10492 if (0 != ret) {
10493 hdd_err("WMI_PDEV_PARAM_ARP_AC_OVERRIDE ac: %d ret: %d",
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010494 arp_ac_category, ret);
Srinivas Girigowda70e169a2017-03-07 23:55:57 -080010495 goto out;
10496 }
10497
Prashanth Bhatta07998752016-04-28 12:35:33 -070010498 status = hdd_set_sme_chan_list(hdd_ctx);
10499 if (status != QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010500 hdd_err("Failed to init channel list: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010501 ret = qdf_status_to_os_return(status);
10502 goto out;
10503 }
10504
10505 /* Apply the cfg.ini to cfg.dat */
Krunal Sonidf0f8742016-09-26 14:56:31 -070010506 if (!hdd_update_config_cfg(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010507 hdd_err("config update failed");
Prashanth Bhatta07998752016-04-28 12:35:33 -070010508 ret = -EINVAL;
10509 goto out;
10510 }
10511
Prashanth Bhatta07998752016-04-28 12:35:33 -070010512 /*
10513 * Set the MAC Address Currently this is used by HAL to add self sta.
10514 * Remove this once self sta is added as part of session open.
10515 */
Jeff Johnson16528362018-06-14 12:34:16 -070010516 status = sme_cfg_set_str(hdd_ctx->mac_handle, WNI_CFG_STA_ID,
Jeff Johnsonbae59f92018-06-01 17:05:43 -070010517 hdd_ctx->config->intfMacAddr[0].bytes,
10518 sizeof(hdd_ctx->config->intfMacAddr[0]));
Prashanth Bhatta07998752016-04-28 12:35:33 -070010519
Jeff Johnsonbae59f92018-06-01 17:05:43 -070010520 if (QDF_IS_STATUS_ERROR(status)) {
10521 hdd_err("Failed to set MAC Address, status %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010522 ret = -EINVAL;
10523 goto out;
10524 }
10525
10526 hdd_init_channel_avoidance(hdd_ctx);
10527
10528out:
10529 return ret;
10530}
10531
Rachit Kankane026e77a2018-07-31 16:21:09 +053010532#ifdef FEATURE_P2P_LISTEN_OFFLOAD
Prashanth Bhatta07998752016-04-28 12:35:33 -070010533/**
Peng Xu8fdaa492016-06-22 10:20:47 -070010534 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070010535 * @context: context registered with sme_register_p2p_lo_event(). HDD
10536 * always registers a hdd context pointer
10537 * @evt:event structure pointer
Peng Xu8fdaa492016-06-22 10:20:47 -070010538 *
10539 * This is the p2p listen offload stop event handler, it sends vendor
10540 * event back to supplicant to notify the stop reason.
10541 *
10542 * Return: None
10543 */
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070010544static void wlan_hdd_p2p_lo_event_callback(void *context,
10545 struct sir_p2p_lo_event *evt)
Peng Xu8fdaa492016-06-22 10:20:47 -070010546{
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070010547 struct hdd_context *hdd_ctx = context;
Peng Xu8fdaa492016-06-22 10:20:47 -070010548 struct sk_buff *vendor_event;
Jeff Johnson9d295242017-08-29 14:39:48 -070010549 struct hdd_adapter *adapter;
Peng Xu8fdaa492016-06-22 10:20:47 -070010550
Dustin Brown491d54b2018-03-14 12:39:11 -070010551 hdd_enter();
Peng Xu8fdaa492016-06-22 10:20:47 -070010552
10553 if (hdd_ctx == NULL) {
10554 hdd_err("Invalid HDD context pointer");
10555 return;
10556 }
10557
Peng Xu5c682812017-08-06 07:39:13 -070010558 adapter = hdd_get_adapter_by_vdev(hdd_ctx, evt->vdev_id);
10559 if (!adapter) {
10560 hdd_err("Cannot find adapter by vdev_id = %d",
10561 evt->vdev_id);
10562 return;
10563 }
10564
Peng Xu8fdaa492016-06-22 10:20:47 -070010565 vendor_event =
10566 cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
Peng Xu5c682812017-08-06 07:39:13 -070010567 &(adapter->wdev), sizeof(uint32_t) + NLMSG_HDRLEN,
Peng Xu8fdaa492016-06-22 10:20:47 -070010568 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX,
10569 GFP_KERNEL);
10570
10571 if (!vendor_event) {
10572 hdd_err("cfg80211_vendor_event_alloc failed");
10573 return;
10574 }
10575
10576 if (nla_put_u32(vendor_event,
10577 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
10578 evt->reason_code)) {
10579 hdd_err("nla put failed");
10580 kfree_skb(vendor_event);
10581 return;
10582 }
10583
10584 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Peng Xu5c682812017-08-06 07:39:13 -070010585 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
10586 evt->vdev_id);
Peng Xu8fdaa492016-06-22 10:20:47 -070010587}
Rachit Kankane026e77a2018-07-31 16:21:09 +053010588#else
10589static void wlan_hdd_p2p_lo_event_callback(void *context,
10590 struct sir_p2p_lo_event *evt)
10591{
10592}
10593#endif
Peng Xu8fdaa492016-06-22 10:20:47 -070010594
Rachit Kankanef6834c42018-08-02 18:47:50 +053010595#ifdef FEATURE_WLAN_DYNAMIC_CVM
10596static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
10597{
10598 return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap);
10599}
10600#else
10601static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
10602{
10603 return QDF_STATUS_SUCCESS;
10604}
10605#endif
10606
Peng Xu8fdaa492016-06-22 10:20:47 -070010607/**
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010608 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
10609 * @hdd_ctx: HDD context
10610 *
10611 * This function sends the adaptive dwell time config configuration to the
10612 * firmware via WMA
10613 *
10614 * Return: 0 - success, < 0 - failure
10615 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010616static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010617{
10618 QDF_STATUS status;
10619 struct adaptive_dwelltime_params dwelltime_params;
10620
10621 dwelltime_params.is_enabled =
10622 hdd_ctx->config->adaptive_dwell_mode_enabled;
10623 dwelltime_params.dwelltime_mode =
10624 hdd_ctx->config->global_adapt_dwelltime_mode;
10625 dwelltime_params.lpf_weight =
10626 hdd_ctx->config->adapt_dwell_lpf_weight;
10627 dwelltime_params.passive_mon_intval =
10628 hdd_ctx->config->adapt_dwell_passive_mon_intval;
10629 dwelltime_params.wifi_act_threshold =
10630 hdd_ctx->config->adapt_dwell_wifi_act_threshold;
10631
Jeff Johnson16528362018-06-14 12:34:16 -070010632 status = sme_set_adaptive_dwelltime_config(hdd_ctx->mac_handle,
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010633 &dwelltime_params);
10634
10635 hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
10636 if (!QDF_IS_STATUS_SUCCESS(status)) {
10637 hdd_err("Failed to send Adaptive Dwelltime configuration!");
10638 return -EAGAIN;
10639 }
10640 return 0;
10641}
10642
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010643int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010644{
10645 QDF_STATUS status;
10646 struct wmi_dbs_scan_sel_params dbs_scan_params;
10647 uint32_t i = 0;
10648 uint8_t count = 0, numentries = 0;
Krunal Sonidf29bc42018-11-15 13:26:29 -080010649 uint8_t dual_mac_feature;
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010650 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
10651 * CDS_DBS_SCAN_CLIENTS_MAX];
10652
Krunal Sonidf29bc42018-11-15 13:26:29 -080010653 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
10654 &dual_mac_feature);
10655
10656 if (status != QDF_STATUS_SUCCESS) {
10657 hdd_err("can't get dual mac feature flag");
10658 return -EINVAL;
10659 }
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010660 /* check if DBS is enabled or supported */
Krunal Sonidf29bc42018-11-15 13:26:29 -080010661 if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) ||
10662 (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN))
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010663 return -EINVAL;
10664
10665 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
10666 dbs_scan_config, &numentries,
10667 (CDS_DBS_SCAN_PARAM_PER_CLIENT
10668 * CDS_DBS_SCAN_CLIENTS_MAX));
10669
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010670 if (!numentries) {
Dustin Brown6a8d39b2018-08-14 15:27:26 -070010671 hdd_debug("Do not send scan_selection_config");
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010672 return 0;
10673 }
10674
10675 /* hdd_set_fw_log_params */
10676 dbs_scan_params.num_clients = 0;
10677 while (count < (numentries - 2)) {
10678 dbs_scan_params.module_id[i] = dbs_scan_config[count];
10679 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
10680 dbs_scan_params.num_non_dbs_scans[i] =
10681 dbs_scan_config[count + 2];
10682 dbs_scan_params.num_clients++;
10683 hdd_debug("module:%d NDS:%d NNDS:%d",
10684 dbs_scan_params.module_id[i],
10685 dbs_scan_params.num_dbs_scans[i],
10686 dbs_scan_params.num_non_dbs_scans[i]);
10687 count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
10688 i++;
10689 }
10690
10691 dbs_scan_params.pdev_id = 0;
10692
10693 hdd_debug("clients:%d pdev:%d",
10694 dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
10695
Jeff Johnson16528362018-06-14 12:34:16 -070010696 status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle,
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010697 &dbs_scan_params);
10698 hdd_debug("Sending DBS Scan Selection Configuration to fw");
10699 if (!QDF_IS_STATUS_SUCCESS(status)) {
10700 hdd_err("Failed to send DBS Scan selection configuration!");
10701 return -EAGAIN;
10702 }
10703 return 0;
10704}
10705
Arun Khandavallid4349a92016-07-25 11:10:43 +053010706#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
10707/**
10708 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
10709 * @hdd_ctx: HDD context
10710 *
10711 * Set auto shutdown callback to get indications from firmware to indicate
10712 * userspace to shutdown WLAN after a configured amount of inactivity.
10713 *
10714 * Return: 0 on success and errno on failure.
10715 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010716static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010717{
10718 QDF_STATUS status;
10719
Dundi Raviteja8e338282018-09-25 17:16:04 +053010720 if (!hdd_ctx->config->wlan_auto_shutdown)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010721 return 0;
10722
Jeff Johnson16528362018-06-14 12:34:16 -070010723 status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle,
Arun Khandavallid4349a92016-07-25 11:10:43 +053010724 wlan_hdd_auto_shutdown_cb);
10725 if (status != QDF_STATUS_SUCCESS)
10726 hdd_err("Auto shutdown feature could not be enabled: %d",
10727 status);
10728
10729 return qdf_status_to_os_return(status);
10730}
10731#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010732static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010733{
10734 return 0;
10735}
10736#endif
10737
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053010738#ifdef MWS_COEX
10739/**
10740 * hdd_set_mws_coex() - Set MWS coex configurations
10741 * @hdd_ctx: HDD context
10742 *
10743 * This function sends MWS-COEX 4G quick FTDM and
10744 * MWS-COEX 5G-NR power limit to FW
10745 *
10746 * Return: 0 on success and errno on failure.
10747 */
10748static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
10749{
10750 int ret = 0;
10751
10752 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM,
10753 hdd_ctx->config->mws_coex_4g_quick_tdm,
10754 PDEV_CMD);
10755 if (ret) {
10756 hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy");
10757 return ret;
10758 }
10759
10760 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT,
10761 hdd_ctx->config->mws_coex_5g_nr_pwr_limit,
10762 PDEV_CMD);
10763 if (ret) {
10764 hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy");
10765 return ret;
10766 }
10767 return ret;
10768}
10769#else
10770static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
10771{
10772 return 0;
10773}
10774#endif
10775
Arun Khandavallid4349a92016-07-25 11:10:43 +053010776/**
10777 * hdd_features_init() - Init features
10778 * @hdd_ctx: HDD context
Arun Khandavallid4349a92016-07-25 11:10:43 +053010779 *
10780 * Initialize features and their feature context after WLAN firmware is up.
10781 *
10782 * Return: 0 on success and errno on failure.
10783 */
Dustin Browne7e71d32018-05-11 16:00:08 -070010784static int hdd_features_init(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010785{
10786 tSirTxPowerLimit hddtxlimit;
10787 QDF_STATUS status;
10788 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -070010789 mac_handle_t mac_handle;
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070010790 struct hdd_config *cfg;
Wu Gao93816212018-08-31 16:49:54 +080010791 bool b_cts2self;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010792
Dustin Brown491d54b2018-03-14 12:39:11 -070010793 hdd_enter();
Arun Khandavallid4349a92016-07-25 11:10:43 +053010794
Dustin Brownad698ae2018-09-05 17:19:30 -070010795 ret = hdd_update_country_code(hdd_ctx);
10796 if (ret) {
10797 hdd_err("Failed to update country code; errno:%d", ret);
10798 return -EINVAL;
10799 }
10800
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053010801 ret = hdd_init_mws_coex(hdd_ctx);
10802 if (ret)
10803 hdd_warn("Error initializing mws-coex");
10804
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070010805 cfg = hdd_ctx->config;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010806 /* FW capabilities received, Set the Dot11 mode */
Jeff Johnson16528362018-06-14 12:34:16 -070010807 mac_handle = hdd_ctx->mac_handle;
10808 sme_setdef_dot11mode(mac_handle);
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070010809 sme_set_etsi13_srd_ch_in_master_mode(mac_handle,
10810 cfg->
10811 etsi13_srd_chan_in_master_mode);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010812
10813 if (hdd_ctx->config->fIsImpsEnabled)
10814 hdd_set_idle_ps_config(hdd_ctx, true);
10815 else
10816 hdd_set_idle_ps_config(hdd_ctx, false);
10817
Poddar, Siddarth37033032017-10-11 15:47:40 +053010818 /* Send Enable/Disable data stall detection cmd to FW */
10819 sme_cli_set_command(0, WMI_PDEV_PARAM_DATA_STALL_DETECT_ENABLE,
jitiphil377bcc12018-10-05 19:46:08 +053010820 cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
10821 cfg_dp_enable_data_stall), PDEV_CMD);
Poddar, Siddarth37033032017-10-11 15:47:40 +053010822
Dustin Brown1dbefe62018-09-11 16:32:03 -070010823 ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self);
Wu Gao93816212018-08-31 16:49:54 +080010824 if (b_cts2self)
Jeff Johnson16528362018-06-14 12:34:16 -070010825 sme_set_cts2self_for_p2p_go(mac_handle);
Agrawal Ashish642ec9b2017-02-22 14:45:30 +053010826
Rachit Kankanef6834c42018-08-02 18:47:50 +053010827 if (hdd_set_vc_mode_config(hdd_ctx))
Nachiket Kukade8983cf62017-10-12 18:14:48 +053010828 hdd_warn("Error in setting Voltage Corner mode config to FW");
10829
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070010830 if (hdd_rx_ol_init(hdd_ctx))
10831 hdd_err("Unable to initialize Rx LRO/GRO in fw");
Arun Khandavallid4349a92016-07-25 11:10:43 +053010832
10833 if (hdd_adaptive_dwelltime_init(hdd_ctx))
10834 hdd_err("Unable to send adaptive dwelltime setting to FW");
10835
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010836 if (hdd_dbs_scan_selection_init(hdd_ctx))
10837 hdd_err("Unable to send DBS scan selection setting to FW");
10838
Arun Khandavallid4349a92016-07-25 11:10:43 +053010839 ret = hdd_init_thermal_info(hdd_ctx);
10840 if (ret) {
10841 hdd_err("Error while initializing thermal information");
Dustin Browne7e71d32018-05-11 16:00:08 -070010842 return ret;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010843 }
10844
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053010845 /**
10846 * In case of SSR/PDR, if pktlog was enabled manually before
10847 * SSR/PDR, Then enabled it again automatically after Wlan
10848 * device up.
10849 */
10850 if (cds_is_driver_recovering()) {
10851 if (hdd_ctx->is_pktlog_enabled)
10852 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
Alok Kumar5a75b9d2018-08-31 10:55:43 +053010853 } else if (cds_is_packet_log_enabled())
10854 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
Poddar, Siddarth66a46592017-02-22 11:44:44 +053010855
gaurank kathpalia3d2e3852018-10-03 22:03:23 +053010856 hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G);
10857 hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G);
Jeff Johnson16528362018-06-14 12:34:16 -070010858 status = sme_txpower_limit(mac_handle, &hddtxlimit);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010859 if (!QDF_IS_STATUS_SUCCESS(status))
10860 hdd_err("Error setting txlimit in sme: %d", status);
10861
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010862 wlan_hdd_tsf_init(hdd_ctx);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010863
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010864 status = sme_enable_disable_chanavoidind_event(mac_handle, 0);
10865 if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) {
10866 hdd_err("Failed to disable Chan Avoidance Indication");
Sourav Mohapatra674925f2018-04-16 11:16:58 +053010867 return -EINVAL;
Selvaraj, Sridhar371f55e2017-02-21 10:36:15 +053010868 }
Arun Khandavallid4349a92016-07-25 11:10:43 +053010869
10870 /* register P2P Listen Offload event callback */
10871 if (wma_is_p2p_lo_capable())
Jeff Johnson16528362018-06-14 12:34:16 -070010872 sme_register_p2p_lo_event(mac_handle, hdd_ctx,
10873 wlan_hdd_p2p_lo_event_callback);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010874
10875 ret = hdd_set_auto_shutdown_cb(hdd_ctx);
10876
10877 if (ret)
Sourav Mohapatra674925f2018-04-16 11:16:58 +053010878 return -EINVAL;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010879
Dustin Brown11638b72018-01-25 17:37:25 +053010880 wlan_hdd_init_chan_info(hdd_ctx);
Varun Reddy Yeturu3c9f89c2018-04-18 19:10:34 -070010881 wlan_hdd_twt_init(hdd_ctx);
Dustin Brown11638b72018-01-25 17:37:25 +053010882
Dustin Browne74003f2018-03-14 12:51:58 -070010883 hdd_exit();
Arun Khandavallid4349a92016-07-25 11:10:43 +053010884 return 0;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010885}
10886
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010887/**
10888 * hdd_features_deinit() - Deinit features
10889 * @hdd_ctx: HDD context
10890 *
10891 * De-Initialize features and their feature context.
10892 *
10893 * Return: none.
10894 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010895static void hdd_features_deinit(struct hdd_context *hdd_ctx)
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010896{
Varun Reddy Yeturu3c9f89c2018-04-18 19:10:34 -070010897 wlan_hdd_twt_deinit(hdd_ctx);
Dustin Brown11638b72018-01-25 17:37:25 +053010898 wlan_hdd_deinit_chan_info(hdd_ctx);
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010899 wlan_hdd_tsf_deinit(hdd_ctx);
jitiphil4e3bef42018-11-14 14:31:13 +053010900 if (cds_is_packet_log_enabled())
10901 hdd_pktlog_enable_disable(hdd_ctx, false, 0, 0);
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010902}
10903
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010904/**
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070010905 * hdd_register_bcn_cb() - register scan beacon callback
10906 * @hdd_ctx - Pointer to the HDD context
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010907 *
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070010908 * Return: QDF_STATUS
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010909 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010910static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010911{
10912 QDF_STATUS status;
10913
Dustin Brown1dbefe62018-09-11 16:32:03 -070010914 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010915 wlan_cfg80211_inform_bss_frame,
10916 SCAN_CB_TYPE_INFORM_BCN);
10917 if (!QDF_IS_STATUS_SUCCESS(status)) {
10918 hdd_err("failed with status code %08d [x%08x]",
10919 status, status);
10920 return status;
10921 }
10922
10923 return QDF_STATUS_SUCCESS;
10924}
Arun Khandavallid4349a92016-07-25 11:10:43 +053010925
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010926/**
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070010927 * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active
10928 * @vdev_id: vdev_id, corresponds to flow_pool
10929 *
10930 * Return: none.
10931 */
10932static void hdd_v2_flow_pool_map(int vdev_id)
10933{
10934 QDF_STATUS status;
10935
10936 status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC),
10937 cds_get_context(QDF_MODULE_ID_TXRX),
10938 vdev_id);
10939 /*
10940 * For Adrastea flow control v2 is based on FW MAP events,
10941 * so this above callback is not implemented.
10942 * Hence this is not actual failure. Dont return failure
10943 */
10944 if ((status != QDF_STATUS_SUCCESS) &&
10945 (status != QDF_STATUS_E_INVAL)) {
10946 hdd_err("vdev_id: %d, failed to create flow pool status %d",
10947 vdev_id, status);
10948 }
10949}
10950
10951/**
10952 * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active
10953 * @vdev_id: vdev_id, corresponds to flow_pool
10954 *
10955 * Return: none.
10956 */
10957static void hdd_v2_flow_pool_unmap(int vdev_id)
10958{
10959 cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC),
10960 cds_get_context(QDF_MODULE_ID_TXRX), vdev_id);
10961}
10962
10963/**
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053010964 * hdd_action_oui_config() - Configure action_oui strings
10965 * @hdd_ctx: pointer to hdd context
10966 *
10967 * This is a HDD wrapper function which invokes ucfg api
10968 * of action_oui component to parse action oui strings.
10969 *
10970 * Return: None
10971 */
10972static void hdd_action_oui_config(struct hdd_context *hdd_ctx)
10973{
10974 QDF_STATUS status;
10975 uint32_t id;
10976 uint8_t *str;
10977
10978 if (!hdd_ctx->config->action_oui_enable)
10979 return;
10980
10981 for (id = 0; id < ACTION_OUI_MAXIMUM_ID; id++) {
10982 str = hdd_ctx->config->action_oui_str[id];
10983 if (!qdf_str_len(str))
10984 continue;
10985
Dustin Brown1dbefe62018-09-11 16:32:03 -070010986 status = ucfg_action_oui_parse(hdd_ctx->psoc, str, id);
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053010987 if (!QDF_IS_STATUS_SUCCESS(status))
10988 hdd_err("Failed to parse action_oui str: %u", id);
10989 }
10990}
10991
10992/**
10993 * hdd_action_oui_send() - Send action_oui extensions to firmware
10994 * @hdd_ctx: pointer to hdd context
10995 *
10996 * This is a HDD wrapper function which invokes ucfg api
10997 * of action_oui component to send action oui extensions to firmware.
10998 *
10999 * Return: None
11000 */
11001static void hdd_action_oui_send(struct hdd_context *hdd_ctx)
11002{
11003 QDF_STATUS status;
11004
11005 if (!hdd_ctx->config->action_oui_enable)
11006 return;
11007
Dustin Brown1dbefe62018-09-11 16:32:03 -070011008 status = ucfg_action_oui_send(hdd_ctx->psoc);
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011009 if (!QDF_IS_STATUS_SUCCESS(status))
11010 hdd_err("Failed to send one or all action_ouis");
11011}
11012
11013/**
Arun Khandavallifae92942016-08-01 13:31:08 +053011014 * hdd_configure_cds() - Configure cds modules
11015 * @hdd_ctx: HDD context
11016 * @adapter: Primary adapter context
11017 *
11018 * Enable Cds modules after WLAN firmware is up.
11019 *
11020 * Return: 0 on success and errno on failure.
11021 */
Dustin Browne7e71d32018-05-11 16:00:08 -070011022int hdd_configure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053011023{
11024 int ret;
11025 QDF_STATUS status;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011026 int set_value;
Jeff Johnson16528362018-06-14 12:34:16 -070011027 mac_handle_t mac_handle;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011028 bool enable_rts_sifsbursting;
11029 uint8_t enable_phy_reg_retention;
Krunal Sonidf29bc42018-11-15 13:26:29 -080011030 uint8_t max_mpdus_inampdu, is_force_1x1 = 0;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011031 uint32_t num_abg_tx_chains = 0;
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011032 uint16_t num_11b_tx_chains = 0;
11033 uint16_t num_11ag_tx_chains = 0;
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070011034 struct policy_mgr_dp_cbacks dp_cbs = {0};
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053011035 bool value;
Wu Gao66454f12018-09-26 19:55:41 +080011036 enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053011037 bool bval = false;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011038
Jeff Johnson16528362018-06-14 12:34:16 -070011039 mac_handle = hdd_ctx->mac_handle;
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011040
11041 hdd_action_oui_send(hdd_ctx);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011042 status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1);
11043 if (status != QDF_STATUS_SUCCESS) {
11044 hdd_err("Failed to get force 1x1 value");
11045 goto out;
11046 }
11047 if (is_force_1x1)
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011048 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_SET_IOT_PATTERN,
11049 1, PDEV_CMD);
11050 /* set chip power save failure detected callback */
Jeff Johnson16528362018-06-14 12:34:16 -070011051 sme_set_chip_pwr_save_fail_cb(mac_handle,
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011052 hdd_chip_pwr_save_fail_detected_cb);
11053
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011054 status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc,
11055 &max_mpdus_inampdu);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011056 if (status) {
11057 hdd_err("Failed to get max mpdus in ampdu value");
11058 goto out;
11059 }
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011060
11061 if (max_mpdus_inampdu) {
11062 set_value = max_mpdus_inampdu;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011063 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU,
11064 set_value, PDEV_CMD);
11065 }
11066
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011067 status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc,
11068 &enable_rts_sifsbursting);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011069 if (status) {
11070 hdd_err("Failed to get rts sifs bursting value");
11071 goto out;
11072 }
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011073
11074 if (enable_rts_sifsbursting) {
11075 set_value = enable_rts_sifsbursting;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011076 sme_cli_set_command(0,
11077 (int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING,
11078 set_value, PDEV_CMD);
11079 }
11080
Dustin Brown05d81302018-09-11 16:49:22 -070011081 ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053011082 if (value) {
11083 set_value = value;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011084 sme_cli_set_command(0,
11085 (int)WMI_PDEV_PARAM_PEER_STATS_INFO_ENABLE,
11086 set_value, PDEV_CMD);
11087 }
11088
Dustin Brown1dbefe62018-09-11 16:32:03 -070011089 status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc,
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011090 &num_11b_tx_chains);
11091 if (status != QDF_STATUS_SUCCESS) {
11092 hdd_err("Failed to get num_11b_tx_chains");
11093 goto out;
11094 }
11095
Dustin Brown1dbefe62018-09-11 16:32:03 -070011096 status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc,
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011097 &num_11ag_tx_chains);
11098 if (status != QDF_STATUS_SUCCESS) {
11099 hdd_err("Failed to get num_11ag_tx_chains");
11100 goto out;
11101 }
11102
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053011103 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
11104 if (!QDF_IS_STATUS_SUCCESS(status))
11105 hdd_err("unable to get vht_enable2x2");
11106
11107 if (!bval) {
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011108 if (num_11b_tx_chains > 1)
11109 num_11b_tx_chains = 1;
11110 if (num_11ag_tx_chains > 1)
11111 num_11ag_tx_chains = 1;
11112 }
11113 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
11114 num_11b_tx_chains);
11115 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
11116 num_11ag_tx_chains);
11117 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM,
11118 num_abg_tx_chains, PDEV_CMD);
Arun Khandavallifae92942016-08-01 13:31:08 +053011119
Paul Zhang02526cd2018-09-20 17:47:46 +080011120 if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc))
11121 ucfg_reg_program_default_cc(hdd_ctx->pdev,
11122 hdd_ctx->reg.reg_domain);
11123
Arun Khandavallifae92942016-08-01 13:31:08 +053011124 ret = hdd_pre_enable_configure(hdd_ctx);
11125 if (ret) {
11126 hdd_err("Failed to pre-configure cds");
11127 goto out;
11128 }
11129
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080011130 /* Always get latest IPA resources allocated from cds_open and configure
11131 * IPA module before configuring them to FW. Sequence required as crash
11132 * observed otherwise.
11133 */
Dustin Brown07901ec2018-09-07 11:02:41 -070011134 if (ucfg_ipa_uc_ol_init(hdd_ctx->pdev,
11135 cds_get_context(QDF_MODULE_ID_QDF_DEVICE))) {
Manikandan Mohan2e803a02017-02-14 14:57:53 -080011136 hdd_err("Failed to setup pipes");
11137 goto out;
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080011138 }
11139
Arun Khandavallifae92942016-08-01 13:31:08 +053011140 /*
11141 * Start CDS which starts up the SME/MAC/HAL modules and everything
11142 * else
11143 */
Dustin Brown1dbefe62018-09-11 16:32:03 -070011144 status = cds_enable(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053011145
11146 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011147 hdd_err("cds_enable failed");
Arun Khandavallifae92942016-08-01 13:31:08 +053011148 goto out;
11149 }
11150
11151 status = hdd_post_cds_enable_config(hdd_ctx);
11152 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011153 hdd_err("hdd_post_cds_enable_config failed");
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011154 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053011155 }
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011156 status = hdd_register_bcn_cb(hdd_ctx);
11157 if (!QDF_IS_STATUS_SUCCESS(status)) {
Paul Zhange03cf4c2018-01-19 18:33:22 +080011158 hdd_err("hdd_register_bcn_cb failed");
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011159 goto cds_disable;
11160 }
Arun Khandavallifae92942016-08-01 13:31:08 +053011161
Dustin Browne7e71d32018-05-11 16:00:08 -070011162 ret = hdd_features_init(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053011163 if (ret)
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011164 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053011165
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070011166 if (hdd_ctx->ol_enable)
11167 dp_cbs.hdd_disable_rx_ol_in_concurrency =
11168 hdd_disable_rx_ol_in_concurrency;
Yun Parkff6a16a2017-09-26 16:38:18 -070011169 dp_cbs.hdd_set_rx_mode_rps_cb = hdd_set_rx_mode_rps;
jiadbb47e132018-03-30 16:28:30 +080011170 dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070011171 dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map;
11172 dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap;
Dustin Brown1dbefe62018-09-11 16:32:03 -070011173 status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs);
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011174 if (!QDF_IS_STATUS_SUCCESS(status)) {
Yun Parkff6a16a2017-09-26 16:38:18 -070011175 hdd_debug("Failed to register DP cb with Policy Manager");
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011176 goto cds_disable;
11177 }
Dustin Brown1dbefe62018-09-11 16:32:03 -070011178 status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc,
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011179 wlan_hdd_send_mode_change_event);
11180 if (!QDF_IS_STATUS_SUCCESS(status)) {
11181 hdd_debug("Failed to register mode change cb with Policy Manager");
11182 goto cds_disable;
11183 }
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011184
Jeff Johnson8bb61112018-03-31 13:33:54 -070011185 if (hdd_green_ap_enable_egap(hdd_ctx))
Nachiket Kukadefbd1afc2017-07-12 17:41:54 +053011186 hdd_debug("enhance green ap is not enabled");
11187
Nachiket Kukadedd302662017-07-13 17:31:44 +053011188 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
11189 hdd_debug("Failed to set wow pulse");
11190
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053011191 sme_cli_set_command(0, WMI_PDEV_PARAM_GCMP_SUPPORT_ENABLE,
11192 hdd_ctx->config->gcmp_enabled, PDEV_CMD);
Wu Gao66454f12018-09-26 19:55:41 +080011193
11194 auto_power_fail_mode =
11195 ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc);
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +053011196 sme_cli_set_command(0, WMI_PDEV_AUTO_DETECT_POWER_FAILURE,
Wu Gao66454f12018-09-26 19:55:41 +080011197 auto_power_fail_mode, PDEV_CMD);
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +053011198
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011199 status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc,
11200 &enable_phy_reg_retention);
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053011201
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011202 if (QDF_IS_STATUS_ERROR(status))
11203 return -EINVAL;
11204
11205 if (enable_phy_reg_retention)
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053011206 wma_cli_set_command(0, WMI_PDEV_PARAM_FAST_PWR_TRANSITION,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011207 enable_phy_reg_retention, PDEV_CMD);
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053011208
Arun Khandavallifae92942016-08-01 13:31:08 +053011209 return 0;
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011210
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011211cds_disable:
Dustin Brown1dbefe62018-09-11 16:32:03 -070011212 cds_disable(hdd_ctx->psoc);
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011213
Arun Khandavallifae92942016-08-01 13:31:08 +053011214out:
11215 return -EINVAL;
11216}
11217
11218/**
11219 * hdd_deconfigure_cds() -De-Configure cds
11220 * @hdd_ctx: HDD context
11221 *
11222 * Deconfigure Cds modules before WLAN firmware is down.
11223 *
11224 * Return: 0 on success and errno on failure.
11225 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011226static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053011227{
11228 QDF_STATUS qdf_status;
Houston Hoffman6640cf32016-10-10 16:44:29 -070011229 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053011230
Dustin Brown491d54b2018-03-14 12:39:11 -070011231 hdd_enter();
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011232
11233 /* De-init features */
11234 hdd_features_deinit(hdd_ctx);
11235
Dustin Brown1dbefe62018-09-11 16:32:03 -070011236 qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc);
Srinivas Girigowdad2412882018-09-07 15:42:04 -070011237 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011238 hdd_debug("Failed to deregister mode change cb with Policy Manager");
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011239
Dustin Brown1dbefe62018-09-11 16:32:03 -070011240 qdf_status = cds_disable(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053011241 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11242 hdd_err("Failed to Disable the CDS Modules! :%d",
11243 qdf_status);
Houston Hoffman6640cf32016-10-10 16:44:29 -070011244 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011245 }
11246
Dustin Brown07901ec2018-09-07 11:02:41 -070011247 if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) {
Sravan Kumar Kairam71121712017-04-15 00:34:42 +053011248 hdd_err("Failed to disconnect pipes");
11249 ret = -EINVAL;
11250 }
11251
Dustin Browne74003f2018-03-14 12:51:58 -070011252 hdd_exit();
Houston Hoffman6640cf32016-10-10 16:44:29 -070011253 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053011254}
11255
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070011256#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
11257static void hdd_deregister_policy_manager_callback(
11258 struct wlan_objmgr_psoc *psoc)
11259{
11260 if (QDF_STATUS_SUCCESS !=
11261 policy_mgr_deregister_hdd_cb(psoc)) {
11262 hdd_err("HDD callback deregister with policy manager failed");
11263 }
11264}
11265#else
11266static void hdd_deregister_policy_manager_callback(
11267 struct wlan_objmgr_psoc *psoc)
11268{
11269}
11270#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053011271
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011272int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
Arun Khandavallifae92942016-08-01 13:31:08 +053011273{
11274 void *hif_ctx;
11275 qdf_device_t qdf_ctx;
11276 QDF_STATUS qdf_status;
Dustin Brown4bc0a622017-12-06 15:56:50 -080011277 bool is_recovery_stop = cds_is_driver_recovering();
Sourav Mohapatra808e3d42018-07-04 09:34:23 +053011278 int ret = 0;
Dustin Brown70111822017-03-30 15:31:40 -070011279 int active_threads;
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053011280 int debugfs_threads;
Arunk Khandavallia6305a32018-01-25 11:19:18 +053011281 struct target_psoc_info *tgt_hdl;
Arun Khandavallifae92942016-08-01 13:31:08 +053011282
Dustin Brown491d54b2018-03-14 12:39:11 -070011283 hdd_enter();
Arun Khandavallifae92942016-08-01 13:31:08 +053011284
Dustin Brown1dbefe62018-09-11 16:32:03 -070011285 hdd_deregister_policy_manager_callback(hdd_ctx->psoc);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070011286
Arun Khandavallifae92942016-08-01 13:31:08 +053011287 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
11288 if (!qdf_ctx) {
11289 hdd_err("QDF device context NULL");
11290 return -EINVAL;
11291 }
11292
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011293 mutex_lock(&hdd_ctx->iface_change_lock);
11294 hdd_ctx->stop_modules_in_progress = true;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070011295 cds_set_module_stop_in_progress(true);
Arun Khandavallifae92942016-08-01 13:31:08 +053011296
Dustin Brown70111822017-03-30 15:31:40 -070011297 active_threads = cds_return_external_threads_count();
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053011298 debugfs_threads = hdd_return_debugfs_threads_count();
Dustin Brown70111822017-03-30 15:31:40 -070011299
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053011300 if (active_threads > 0 || debugfs_threads > 0 ||
11301 hdd_ctx->is_wiphy_suspended) {
11302 hdd_warn("External threads %d, Debugfs threads %d, wiphy suspend %d",
11303 active_threads, debugfs_threads,
11304 hdd_ctx->is_wiphy_suspended);
11305
11306 if (active_threads)
11307 cds_print_external_threads();
Dustin Brown70111822017-03-30 15:31:40 -070011308
Sourav Mohapatra808e3d42018-07-04 09:34:23 +053011309 if (IS_IDLE_STOP && !ftm_mode) {
Dustin Brown70111822017-03-30 15:31:40 -070011310 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown4c663222018-10-23 14:19:36 -070011311 hdd_psoc_idle_timer_start(hdd_ctx);
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070011312 hdd_ctx->stop_modules_in_progress = false;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070011313 cds_set_module_stop_in_progress(false);
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011314
Dustin Brown70111822017-03-30 15:31:40 -070011315 return 0;
11316 }
Rajeev Kumar86177c22017-03-16 19:44:39 -070011317 }
11318
Kabilan Kannan6edafeb2017-11-16 16:34:34 -080011319 /* free user wowl patterns */
11320 hdd_free_user_wowl_ptrns();
11321
Arun Khandavallifae92942016-08-01 13:31:08 +053011322 switch (hdd_ctx->driver_status) {
11323 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011324 hdd_debug("Modules not initialized just return");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011325 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053011326 case DRIVER_MODULES_CLOSED:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011327 hdd_debug("Modules already closed");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011328 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053011329 case DRIVER_MODULES_ENABLED:
Dustin Brown1a20b082018-08-03 17:27:15 -070011330 hdd_info("Wlan transitioning (CLOSED <- ENABLED)");
11331
11332 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE)
11333 break;
Dustin Brown550f6d22017-12-14 15:44:01 -080011334
Komal Seelamf2136bb2016-09-28 18:30:44 +053011335 hdd_disable_power_management();
Arun Khandavallifae92942016-08-01 13:31:08 +053011336 if (hdd_deconfigure_cds(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011337 hdd_err("Failed to de-configure CDS");
Arun Khandavallifae92942016-08-01 13:31:08 +053011338 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011339 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011340 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011341 hdd_debug("successfully Disabled the CDS modules!");
Dustin Brown550f6d22017-12-14 15:44:01 -080011342
Arun Khandavallifae92942016-08-01 13:31:08 +053011343 break;
11344 default:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011345 QDF_DEBUG_PANIC("Unknown driver state:%d",
Arun Khandavallifae92942016-08-01 13:31:08 +053011346 hdd_ctx->driver_status);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011347 ret = -EINVAL;
11348 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053011349 }
11350
Arunk Khandavalli890f6d92018-10-30 20:18:28 +053011351 hdd_sysfs_destroy_powerstats_interface();
Amar Singhal18081642018-01-26 16:04:13 -080011352 hdd_sysfs_destroy_version_interface();
Arunk Khandavalli890f6d92018-10-30 20:18:28 +053011353 hdd_sysfs_destroy_driver_root_obj();
Dustin Brown550f6d22017-12-14 15:44:01 -080011354 hdd_debug("Closing CDS modules!");
Amar Singhal18081642018-01-26 16:04:13 -080011355
Rajeev Kumarbe021242017-02-16 16:12:23 -080011356 qdf_status = cds_post_disable();
Govind Singhb048e872016-09-27 22:07:43 +053011357 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11358 hdd_err("Failed to process post CDS disable Modules! :%d",
11359 qdf_status);
11360 ret = -EINVAL;
11361 QDF_ASSERT(0);
11362 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070011363
Sourav Mohapatra674925f2018-04-16 11:16:58 +053011364 /* De-register the SME callbacks */
11365 hdd_deregister_cb(hdd_ctx);
11366
psimhadeea0a12017-12-18 14:50:02 -080011367 hdd_runtime_suspend_context_deinit(hdd_ctx);
11368
Dustin Brown1dbefe62018-09-11 16:32:03 -070011369 qdf_status = cds_dp_close(hdd_ctx->psoc);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070011370 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11371 hdd_warn("Failed to stop CDS DP: %d", qdf_status);
11372 ret = -EINVAL;
11373 QDF_ASSERT(0);
11374 }
11375
Dustin Brown1dbefe62018-09-11 16:32:03 -070011376 qdf_status = cds_close(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053011377 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011378 hdd_warn("Failed to stop CDS: %d", qdf_status);
Govind Singhb048e872016-09-27 22:07:43 +053011379 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011380 QDF_ASSERT(0);
11381 }
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053011382
11383 qdf_status = wbuff_module_deinit();
11384 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
11385 hdd_err("WBUFF de-init unsuccessful; status: %d", qdf_status);
11386
Sandeep Puligillab7beb472018-08-13 22:54:20 -070011387 hdd_component_pdev_close(hdd_ctx->pdev);
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053011388
Dustin Brown1dbefe62018-09-11 16:32:03 -070011389 hdd_component_psoc_close(hdd_ctx->psoc);
Dustin Brown07901ec2018-09-07 11:02:41 -070011390 dispatcher_pdev_close(hdd_ctx->pdev);
Liangwei Dong50a64a72018-01-11 01:17:00 -050011391 ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
11392 if (ret) {
11393 hdd_err("Failed to destroy pdev; errno:%d", ret);
11394 QDF_ASSERT(0);
11395 }
11396
11397 /*
11398 * Reset total mac phy during module stop such that during
11399 * next module start same psoc is used to populate new service
11400 * ready data
11401 */
Dustin Brown1dbefe62018-09-11 16:32:03 -070011402 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
Arunk Khandavallia6305a32018-01-25 11:19:18 +053011403 if (tgt_hdl)
11404 target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0);
11405
Liangwei Dong50a64a72018-01-11 01:17:00 -050011406
Arun Khandavallifae92942016-08-01 13:31:08 +053011407 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
11408 if (!hif_ctx) {
11409 hdd_err("Hif context is Null");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011410 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011411 }
11412
Arunk Khandavalli4b404332017-09-26 12:46:00 +053011413 if (hdd_ctx->target_hw_name) {
11414 qdf_mem_free(hdd_ctx->target_hw_name);
11415 hdd_ctx->target_hw_name = NULL;
11416 }
11417
Sravan Kumar Kairam27296782017-04-21 22:04:18 +053011418 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053011419
11420 ol_cds_free();
11421
Dustin Brownc2a156e2018-10-25 16:56:27 -070011422 if (IS_IDLE_STOP) {
Arun Khandavallifae92942016-08-01 13:31:08 +053011423 ret = pld_power_off(qdf_ctx->dev);
11424 if (ret)
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011425 hdd_err("Failed to power down device; errno:%d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053011426 }
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011427
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011428 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
11429 wlan_hdd_free_cache_channels(hdd_ctx);
Arunk Khandavalli847969d2017-09-25 15:15:36 +053011430
Dustin Brown29533f22018-07-24 13:11:56 -070011431 hdd_check_for_leaks(hdd_ctx, is_recovery_stop);
Dustin Brown26b3d042017-12-21 11:13:27 -080011432 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -080011433
Arunk Khandavalli847969d2017-09-25 15:15:36 +053011434 /* Once the firmware sequence is completed reset this flag */
11435 hdd_ctx->imps_enabled = false;
Arun Khandavallifae92942016-08-01 13:31:08 +053011436 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -080011437 hdd_info("Wlan transitioned (now CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +053011438
Kai Liueabb1df2018-11-08 14:58:54 +080011439 pld_request_bus_bandwidth(hdd_ctx->parent_dev, PLD_BUS_WIDTH_NONE);
11440
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011441done:
11442 hdd_ctx->stop_modules_in_progress = false;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070011443 cds_set_module_stop_in_progress(false);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011444 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown4bc0a622017-12-06 15:56:50 -080011445
Dustin Browne74003f2018-03-14 12:51:58 -070011446 hdd_exit();
Arun Khandavallifae92942016-08-01 13:31:08 +053011447
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011448 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053011449}
11450
Arun Khandavallifae92942016-08-01 13:31:08 +053011451
Wen Gong3f003382018-05-14 14:26:37 +080011452#ifdef WLAN_FEATURE_MEMDUMP_ENABLE
Arun Khandavallifae92942016-08-01 13:31:08 +053011453/**
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011454 * hdd_state_info_dump() - prints state information of hdd layer
11455 * @buf: buffer pointer
11456 * @size: size of buffer to be filled
11457 *
11458 * This function is used to dump state information of hdd layer
11459 *
11460 * Return: None
11461 */
11462static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
11463{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011464 struct hdd_context *hdd_ctx;
Jeff Johnson40dae4e2017-08-29 14:00:25 -070011465 struct hdd_station_ctx *hdd_sta_ctx;
Jeff Johnson9d295242017-08-29 14:39:48 -070011466 struct hdd_adapter *adapter;
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011467 uint16_t len = 0;
11468 char *buf = *buf_ptr;
11469
11470 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11471 if (!hdd_ctx) {
11472 hdd_err("Failed to get hdd context ");
11473 return;
11474 }
11475
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011476 hdd_debug("size of buffer: %d", *size);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011477
11478 len += scnprintf(buf + len, *size - len,
Jeff Johnson214671b2017-10-30 19:45:23 -070011479 "\n is_wiphy_suspended %d", hdd_ctx->is_wiphy_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011480 len += scnprintf(buf + len, *size - len,
Rajeev Kumareada0d02016-12-08 17:44:17 -080011481 "\n is_scheduler_suspended %d",
11482 hdd_ctx->is_scheduler_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011483
Dustin Brown920397d2017-12-13 16:27:50 -080011484 hdd_for_each_adapter(hdd_ctx, adapter) {
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011485 if (adapter->dev)
11486 len += scnprintf(buf + len, *size - len,
11487 "\n device name: %s", adapter->dev->name);
wadesong42968e92017-06-08 14:11:21 +080011488 len += scnprintf(buf + len, *size - len,
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011489 "\n device_mode: %d", adapter->device_mode);
11490 switch (adapter->device_mode) {
11491 case QDF_STA_MODE:
11492 case QDF_P2P_CLIENT_MODE:
11493 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
11494 len += scnprintf(buf + len, *size - len,
11495 "\n connState: %d",
11496 hdd_sta_ctx->conn_info.connState);
11497 break;
11498
11499 default:
11500 break;
11501 }
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011502 }
11503
11504 *size -= len;
11505 *buf_ptr += len;
11506}
11507
11508/**
11509 * hdd_register_debug_callback() - registration function for hdd layer
11510 * to print hdd state information
11511 *
11512 * Return: None
11513 */
11514static void hdd_register_debug_callback(void)
11515{
11516 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
11517}
Wen Gong3f003382018-05-14 14:26:37 +080011518#else /* WLAN_FEATURE_MEMDUMP_ENABLE */
Wen Gongaa6d55d2018-04-26 16:33:21 +080011519static void hdd_register_debug_callback(void)
11520{
11521}
Wen Gong3f003382018-05-14 14:26:37 +080011522#endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011523
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053011524/*
11525 * wlan_init_bug_report_lock() - Initialize bug report lock
11526 *
11527 * This function is used to create bug report lock
11528 *
11529 * Return: None
11530 */
11531static void wlan_init_bug_report_lock(void)
11532{
Jeff Johnson2b6982c2018-05-29 14:56:11 -070011533 struct cds_context *p_cds_context;
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053011534
11535 p_cds_context = cds_get_global_context();
11536 if (!p_cds_context) {
11537 hdd_err("cds context is NULL");
11538 return;
11539 }
11540
11541 qdf_spinlock_create(&p_cds_context->bug_report_lock);
11542}
11543
Nirav Shahd21a2e32018-04-20 16:34:43 +053011544#ifdef CONFIG_DP_TRACE
Mohit Khannaf8f96822017-05-17 17:11:59 -070011545void hdd_dp_trace_init(struct hdd_config *config)
11546{
Mohit Khannaf8f96822017-05-17 17:11:59 -070011547 bool live_mode = DP_TRACE_CONFIG_DEFAULT_LIVE_MODE;
11548 uint8_t thresh = DP_TRACE_CONFIG_DEFAULT_THRESH;
11549 uint16_t thresh_time_limit = DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT;
11550 uint8_t verbosity = DP_TRACE_CONFIG_DEFAULT_VERBOSTY;
11551 uint8_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP;
11552 uint8_t config_params[DP_TRACE_CONFIG_NUM_PARAMS];
11553 uint8_t num_entries = 0;
Lin Baiaa7f8d72017-10-18 17:23:45 +080011554 uint32_t bw_compute_interval;
Mohit Khannaf8f96822017-05-17 17:11:59 -070011555
Nirav Shahd21a2e32018-04-20 16:34:43 +053011556 if (!config->enable_dp_trace) {
11557 hdd_err("dp trace is disabled from ini");
11558 return;
11559 }
11560
Mohit Khannaf8f96822017-05-17 17:11:59 -070011561 hdd_string_to_u8_array(config->dp_trace_config, config_params,
11562 &num_entries, sizeof(config_params));
11563
11564 /* calculating, num bw timer intervals in a second (1000ms) */
Lin Baiaa7f8d72017-10-18 17:23:45 +080011565 bw_compute_interval = GET_BW_COMPUTE_INTV(config);
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080011566 if (bw_compute_interval <= 1000 && bw_compute_interval > 0)
Lin Baiaa7f8d72017-10-18 17:23:45 +080011567 thresh_time_limit = 1000 / bw_compute_interval;
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080011568 else if (bw_compute_interval > 1000) {
11569 hdd_err("busBandwidthComputeInterval > 1000, using 1000");
11570 thresh_time_limit = 1;
11571 } else
Mohit Khannaf8f96822017-05-17 17:11:59 -070011572 hdd_err("busBandwidthComputeInterval is 0, using defaults");
11573
11574 switch (num_entries) {
11575 case 4:
11576 proto_bitmap = config_params[3];
Alok Kumarb5a33a22018-05-07 18:09:14 +053011577 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070011578 case 3:
11579 verbosity = config_params[2];
Alok Kumarb5a33a22018-05-07 18:09:14 +053011580 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070011581 case 2:
11582 thresh = config_params[1];
Alok Kumarb5a33a22018-05-07 18:09:14 +053011583 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070011584 case 1:
11585 live_mode = config_params[0];
Alok Kumarb5a33a22018-05-07 18:09:14 +053011586 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070011587 default:
Dustin Browna7bb6ae2018-08-16 16:51:50 -070011588 hdd_debug("live_mode %u thresh %u time_limit %u verbosity %u bitmap 0x%x",
11589 live_mode, thresh, thresh_time_limit,
11590 verbosity, proto_bitmap);
Mohit Khannaf8f96822017-05-17 17:11:59 -070011591 };
11592
11593 qdf_dp_trace_init(live_mode, thresh, thresh_time_limit,
11594 verbosity, proto_bitmap);
11595
11596}
Nirav Shahd21a2e32018-04-20 16:34:43 +053011597#endif
11598
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011599#ifdef DISABLE_CHANNEL_LIST
Dustin Brown623e7e32018-09-05 14:27:50 -070011600static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011601{
11602 return qdf_mutex_create(&hdd_ctx->cache_channel_lock);
11603}
11604#else
Dustin Brown623e7e32018-09-05 14:27:50 -070011605static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011606{
Dustin Brown623e7e32018-09-05 14:27:50 -070011607 return QDF_STATUS_SUCCESS;
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011608}
11609#endif
11610
Dustin Brown61cc3932018-10-18 16:12:13 -070011611static QDF_STATUS
11612hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
Dustin Browna2deeb72018-10-18 14:19:27 -070011613{
11614 struct hdd_adapter *adapter;
11615 enum dot11p_mode dot11p_mode;
Dustin Brown61cc3932018-10-18 16:12:13 -070011616 QDF_STATUS status;
Dustin Browna2deeb72018-10-18 14:19:27 -070011617
11618 ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode);
11619
11620 /* Create only 802.11p interface? */
11621 if (dot11p_mode == CFG_11P_STANDALONE)
Dustin Brown61cc3932018-10-18 16:12:13 -070011622 return hdd_open_ocb_interface(hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070011623
11624 adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE, "wlan%d",
11625 wlan_hdd_get_intf_addr(hdd_ctx),
11626 NET_NAME_UNKNOWN, true);
11627 if (!adapter)
Dustin Brown61cc3932018-10-18 16:12:13 -070011628 return QDF_STATUS_E_INVAL;
Dustin Browna2deeb72018-10-18 14:19:27 -070011629
Dustin Brown61cc3932018-10-18 16:12:13 -070011630 /* opening concurrent STA is best effort, continue on error */
11631 hdd_open_concurrent_interface(hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070011632
Dustin Brown61cc3932018-10-18 16:12:13 -070011633 status = hdd_open_p2p_interface(hdd_ctx);
11634 if (status)
Dustin Browna2deeb72018-10-18 14:19:27 -070011635 goto err_close_adapters;
11636
11637 /* Open 802.11p Interface */
11638 if (dot11p_mode == CFG_11P_CONCURRENT) {
Dustin Brown61cc3932018-10-18 16:12:13 -070011639 status = hdd_open_ocb_interface(hdd_ctx);
11640 if (QDF_IS_STATUS_ERROR(status))
Dustin Browna2deeb72018-10-18 14:19:27 -070011641 goto err_close_adapters;
11642 }
11643
Dustin Brown61cc3932018-10-18 16:12:13 -070011644 return QDF_STATUS_SUCCESS;
Dustin Browna2deeb72018-10-18 14:19:27 -070011645
11646err_close_adapters:
11647 hdd_close_all_adapters(hdd_ctx, true);
11648
Dustin Brown61cc3932018-10-18 16:12:13 -070011649 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070011650}
11651
Dustin Brown61cc3932018-10-18 16:12:13 -070011652static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx)
Dustin Browna2deeb72018-10-18 14:19:27 -070011653{
11654 struct hdd_adapter *adapter;
Dustin Brown61cc3932018-10-18 16:12:13 -070011655
11656 adapter = hdd_open_adapter(hdd_ctx, QDF_FTM_MODE, "wlan%d",
11657 wlan_hdd_get_intf_addr(hdd_ctx),
11658 NET_NAME_UNKNOWN, true);
11659
11660 return adapter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_INVAL;
11661}
11662
11663static QDF_STATUS
11664hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx)
11665{
11666 struct hdd_adapter *adapter;
11667
11668 adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
11669 wlan_hdd_get_intf_addr(hdd_ctx),
11670 NET_NAME_UNKNOWN, true);
11671
11672 return adapter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_INVAL;
11673}
11674
11675static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx)
11676{
Dustin Browna2deeb72018-10-18 14:19:27 -070011677 QDF_STATUS status;
Dustin Brown61cc3932018-10-18 16:12:13 -070011678 qdf_device_t qdf_dev;
Dustin Browna2deeb72018-10-18 14:19:27 -070011679
11680 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
11681 QDF_BUG(qdf_dev);
11682 if (!qdf_dev)
Dustin Brown61cc3932018-10-18 16:12:13 -070011683 return QDF_STATUS_E_INVAL;
11684
11685 status = epping_open();
11686 if (QDF_IS_STATUS_ERROR(status))
11687 return status;
11688
11689 if (epping_enable(qdf_dev->dev)) {
11690 status = QDF_STATUS_E_INVAL;
11691 goto epping_close;
11692 }
11693
11694 return QDF_STATUS_SUCCESS;
11695
11696epping_close:
11697 epping_close();
11698
11699 return status;
11700}
11701
11702typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx);
11703
11704static const hdd_open_mode_handler
11705hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = {
11706 [QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode,
11707 [QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode,
11708 [QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode,
11709 [QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode,
11710};
11711
Dustin Brown92bd8382018-10-31 15:49:46 -070011712static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
11713 enum QDF_GLOBAL_MODE driver_mode)
Dustin Brown61cc3932018-10-18 16:12:13 -070011714{
11715 QDF_STATUS status;
11716
11717 if (driver_mode < 0 ||
11718 driver_mode >= QDF_GLOBAL_MAX_MODE ||
11719 !hdd_open_mode_handlers[driver_mode]) {
11720 hdd_err("Driver mode %d not supported", driver_mode);
11721 return -ENOTSUPP;
11722 }
Dustin Browna2deeb72018-10-18 14:19:27 -070011723
11724 hdd_hold_rtnl_lock();
Dustin Brown61cc3932018-10-18 16:12:13 -070011725 status = hdd_open_mode_handlers[driver_mode](hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070011726 hdd_release_rtnl_lock();
11727
Dustin Brown92bd8382018-10-31 15:49:46 -070011728 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070011729}
11730
Dustin Brown623e7e32018-09-05 14:27:50 -070011731int hdd_wlan_startup(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080011732{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011733 QDF_STATUS status;
Dustin Brown623e7e32018-09-05 14:27:50 -070011734 int errno;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080011735
Dustin Brown491d54b2018-03-14 12:39:11 -070011736 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080011737
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011738 hdd_action_oui_config(hdd_ctx);
11739
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +053011740 qdf_nbuf_init_replenish_timer();
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011741
Dustin Brown623e7e32018-09-05 14:27:50 -070011742 status = wlan_hdd_cache_chann_mutex_create(hdd_ctx);
11743 if (QDF_IS_STATUS_ERROR(status))
11744 return qdf_status_to_os_return(status);
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011745
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +053011746#ifdef FEATURE_WLAN_CH_AVOID
11747 mutex_init(&hdd_ctx->avoid_freq_lock);
11748#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053011749
Naveen Rawate02f8f52018-04-05 11:58:04 -070011750 osif_request_manager_init();
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053011751 qdf_atomic_init(&hdd_ctx->con_mode_flag);
Dustin Brown021cecd2017-12-11 13:56:43 -080011752 hdd_driver_memdump_init();
Dustin Brown86d196b2018-08-02 11:51:49 -070011753 hdd_bus_bandwidth_init(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -080011754
Dustin Brown623e7e32018-09-05 14:27:50 -070011755 errno = hdd_wlan_start_modules(hdd_ctx, false);
11756 if (errno) {
11757 hdd_err("Failed to start modules; errno:%d", errno);
11758 goto memdump_deinit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011759 }
11760
Yingying Tang80e15f32016-09-27 18:23:01 +080011761 wlan_hdd_update_wiphy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011762
Dustin Brown623e7e32018-09-05 14:27:50 -070011763 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
11764 if (!hdd_ctx->mac_handle) {
Jeff Johnson16528362018-06-14 12:34:16 -070011765 hdd_err("Mac Handle is null");
Dustin Brown623e7e32018-09-05 14:27:50 -070011766 goto stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011767 }
11768
Dustin Brown623e7e32018-09-05 14:27:50 -070011769 errno = hdd_wiphy_init(hdd_ctx);
11770 if (errno) {
11771 hdd_err("Failed to initialize wiphy; errno:%d", errno);
11772 goto stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011773 }
11774
Nirav Shahd21a2e32018-04-20 16:34:43 +053011775 hdd_dp_trace_init(hdd_ctx->config);
Nirav Shahcc1f1ae2016-04-26 11:41:29 +053011776
Yuanyuan Liuc98370e2016-10-13 11:22:13 -070011777 hdd_initialize_mac_address(hdd_ctx);
Prashanth Bhatta75fa9a12016-01-11 18:30:08 -080011778
Dustin Brown623e7e32018-09-05 14:27:50 -070011779 errno = register_netdevice_notifier(&hdd_netdev_notifier);
11780 if (errno) {
11781 hdd_err("register_netdevice_notifier failed; errno:%d", errno);
11782 goto unregister_wiphy;
Paul Zhangfb02f452017-12-22 11:58:43 +080011783 }
Arun Khandavalli08479ba2017-08-07 19:56:23 +053011784
Dustin Brown623e7e32018-09-05 14:27:50 -070011785 errno = register_reboot_notifier(&system_reboot_notifier);
11786 if (errno) {
11787 hdd_err("Failed to register reboot notifier; errno:%d", errno);
11788 goto unregister_netdev;
Arunk Khandavalli830c9692018-03-22 12:17:40 +053011789 }
11790
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080011791 wlan_hdd_update_11n_mode(hdd_ctx->config);
11792
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011793#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +053011794 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
Anurag Chouhan6d760662016-02-20 16:05:43 +053011795 QDF_TIMER_TYPE_SW,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011796 hdd_skip_acs_scan_timer_handler,
Dustin Browna2deeb72018-10-18 14:19:27 -070011797 hdd_ctx);
Dustin Brown92bd8382018-10-31 15:49:46 -070011798 if (QDF_IS_STATUS_ERROR(status))
Jeff Johnson34c88b72016-08-15 14:27:11 -070011799 hdd_err("Failed to init ACS Skip timer");
Dustin Brown92bd8382018-10-31 15:49:46 -070011800
Liangwei Dongaef84342016-10-21 05:28:00 -040011801 qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011802#endif
11803
Arunk Khandavalli40943af2017-05-15 19:25:34 +053011804 hdd_lpass_notify_wlan_version(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011805
Dustin Brown623e7e32018-09-05 14:27:50 -070011806 errno = hdd_register_notifiers(hdd_ctx);
11807 if (errno)
11808 goto unregister_reboot;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -070011809
Paul Zhangfb02f452017-12-22 11:58:43 +080011810 status = wlansap_global_init();
Dustin Brown92bd8382018-10-31 15:49:46 -070011811 if (QDF_IS_STATUS_ERROR(status))
11812 goto unregister_notifiers;
Paul Zhangfb02f452017-12-22 11:58:43 +080011813
Dustin Brown92bd8382018-10-31 15:49:46 -070011814 hdd_set_idle_ps_config(hdd_ctx, hdd_ctx->config->fIsImpsEnabled);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011815
Dustin Brown92bd8382018-10-31 15:49:46 -070011816 hdd_exit();
11817
11818 return 0;
11819
11820unregister_notifiers:
11821 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011822
Dustin Brown623e7e32018-09-05 14:27:50 -070011823unregister_reboot:
Arunk Khandavalli830c9692018-03-22 12:17:40 +053011824 unregister_reboot_notifier(&system_reboot_notifier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011825
Dustin Brown623e7e32018-09-05 14:27:50 -070011826unregister_netdev:
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011827 unregister_netdevice_notifier(&hdd_netdev_notifier);
11828
Dustin Brown623e7e32018-09-05 14:27:50 -070011829unregister_wiphy:
Rachit Kankane30807332018-06-27 18:39:36 +053011830 qdf_dp_trace_deinit();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080011831 wiphy_unregister(hdd_ctx->wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011832
Dustin Brown623e7e32018-09-05 14:27:50 -070011833stop_modules:
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070011834 hdd_wlan_stop_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +053011835
Dustin Brown623e7e32018-09-05 14:27:50 -070011836memdump_deinit:
Dustin Brown86d196b2018-08-02 11:51:49 -070011837 hdd_bus_bandwidth_deinit(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -080011838 hdd_driver_memdump_deinit();
Naveen Rawate02f8f52018-04-05 11:58:04 -070011839 osif_request_manager_deinit();
Dustin Brown623e7e32018-09-05 14:27:50 -070011840 qdf_nbuf_deinit_replenish_timer();
Ryan Hsucfef0ae2016-04-28 10:20:46 -070011841
Nachiket Kukade8003d252017-03-30 15:55:58 +053011842 if (cds_is_fw_down())
11843 hdd_err("Not setting the complete event as fw is down");
11844 else
Dustin Brown623e7e32018-09-05 14:27:50 -070011845 hdd_start_complete(errno);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011846
Dustin Browne74003f2018-03-14 12:51:58 -070011847 hdd_exit();
Dustin Brown92bd8382018-10-31 15:49:46 -070011848
Dustin Brown623e7e32018-09-05 14:27:50 -070011849 return errno;
Dustin Brown92bd8382018-10-31 15:49:46 -070011850}
11851
11852QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx)
11853{
11854 enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam();
11855 QDF_STATUS status;
11856
11857 status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode);
11858 if (QDF_IS_STATUS_ERROR(status)) {
11859 hdd_err("Failed to create vdevs; status:%d", status);
11860 return status;
11861 }
11862
11863 if (hdd_ctx->rps)
11864 hdd_set_rps_cpu_mask(hdd_ctx);
11865
11866 if (driver_mode != QDF_GLOBAL_FTM_MODE)
11867 hdd_psoc_idle_timer_start(hdd_ctx);
11868
11869 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011870}
11871
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011872/**
Arun Khandavallifae92942016-08-01 13:31:08 +053011873 * hdd_wlan_update_target_info() - update target type info
11874 * @hdd_ctx: HDD context
11875 * @context: hif context
11876 *
11877 * Update target info received from firmware in hdd context
11878 * Return:None
11879 */
11880
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011881void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
Arun Khandavallifae92942016-08-01 13:31:08 +053011882{
11883 struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
11884
11885 if (!tgt_info) {
11886 hdd_err("Target info is Null");
11887 return;
11888 }
11889
11890 hdd_ctx->target_type = tgt_info->target_type;
11891}
11892
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011893void hdd_get_nud_stats_cb(void *data, struct rsp_stats *rsp, void *context)
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011894{
11895 struct hdd_context *hdd_ctx = (struct hdd_context *)data;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011896 int status;
11897 struct hdd_adapter *adapter = NULL;
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011898 struct osif_request *request = NULL;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011899
Dustin Brown491d54b2018-03-14 12:39:11 -070011900 hdd_enter();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011901
11902 if (!rsp) {
11903 hdd_err("data is null");
11904 return;
11905 }
11906
11907 status = wlan_hdd_validate_context(hdd_ctx);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011908 if (status != 0)
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011909 return;
11910
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011911 request = osif_request_get(context);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011912 if (!request) {
11913 hdd_err("obselete request");
11914 return;
11915 }
11916
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011917 adapter = hdd_get_adapter_by_vdev(hdd_ctx, rsp->vdev_id);
11918 if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
11919 hdd_err("Invalid adapter or adapter has invalid magic");
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011920 osif_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011921 return;
11922 }
11923
Alok Kumarce2c29a2018-10-12 15:44:02 +053011924 hdd_debug("rsp->arp_req_enqueue :%x", rsp->arp_req_enqueue);
11925 hdd_debug("rsp->arp_req_tx_success :%x", rsp->arp_req_tx_success);
11926 hdd_debug("rsp->arp_req_tx_failure :%x", rsp->arp_req_tx_failure);
11927 hdd_debug("rsp->arp_rsp_recvd :%x", rsp->arp_rsp_recvd);
11928 hdd_debug("rsp->out_of_order_arp_rsp_drop_cnt :%x",
11929 rsp->out_of_order_arp_rsp_drop_cnt);
11930 hdd_debug("rsp->dad_detected :%x", rsp->dad_detected);
11931 hdd_debug("rsp->connect_status :%x", rsp->connect_status);
11932 hdd_debug("rsp->ba_session_establishment_status :%x",
11933 rsp->ba_session_establishment_status);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011934
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011935 adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011936 adapter->dad |= rsp->dad_detected;
11937 adapter->con_status = rsp->connect_status;
11938
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011939 /* Flag true indicates connectivity check stats present. */
11940 if (rsp->connect_stats_present) {
Alok Kumarce2c29a2018-10-12 15:44:02 +053011941 hdd_debug("rsp->tcp_ack_recvd :%x", rsp->tcp_ack_recvd);
11942 hdd_debug("rsp->icmpv4_rsp_recvd :%x", rsp->icmpv4_rsp_recvd);
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011943 adapter->hdd_stats.hdd_tcp_stats.rx_fw_cnt = rsp->tcp_ack_recvd;
11944 adapter->hdd_stats.hdd_icmpv4_stats.rx_fw_cnt =
11945 rsp->icmpv4_rsp_recvd;
11946 }
11947
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011948 osif_request_complete(request);
11949 osif_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011950
Dustin Browne74003f2018-03-14 12:51:58 -070011951 hdd_exit();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011952}
11953
11954/**
Arun Khandavallifae92942016-08-01 13:31:08 +053011955 * hdd_register_cb - Register HDD callbacks.
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011956 * @hdd_ctx: HDD context
11957 *
11958 * Register the HDD callbacks to CDS/SME.
11959 *
11960 * Return: 0 for success or Error code for failure
11961 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011962int hdd_register_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011963{
11964 QDF_STATUS status;
11965 int ret = 0;
Jeff Johnson16528362018-06-14 12:34:16 -070011966 mac_handle_t mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011967
Dustin Brown491d54b2018-03-14 12:39:11 -070011968 hdd_enter();
Sourav Mohapatra674925f2018-04-16 11:16:58 +053011969 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
11970 hdd_err("in ftm mode, no need to register callbacks");
11971 return ret;
11972 }
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011973
Jeff Johnson16528362018-06-14 12:34:16 -070011974 mac_handle = hdd_ctx->mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011975
Jeff Johnson16528362018-06-14 12:34:16 -070011976 sme_register_oem_data_rsp_callback(mac_handle,
11977 hdd_send_oem_data_rsp_msg);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011978
Jeff Johnson16528362018-06-14 12:34:16 -070011979 sme_register_mgmt_frame_ind_callback(mac_handle,
Deepthi Gowrid5a58fe2016-09-03 16:01:28 +053011980 hdd_indicate_mgmt_frame);
Jeff Johnson16528362018-06-14 12:34:16 -070011981 sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx);
11982 sme_nan_register_callback(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011983 wlan_hdd_cfg80211_nan_callback);
Jeff Johnson16528362018-06-14 12:34:16 -070011984 sme_stats_ext_register_callback(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011985 wlan_hdd_cfg80211_stats_ext_callback);
11986
Jeff Johnson16528362018-06-14 12:34:16 -070011987 sme_ext_scan_register_callback(mac_handle,
11988 wlan_hdd_cfg80211_extscan_callback);
11989 sme_stats_ext2_register_callback(mac_handle,
lifeng66831662017-05-19 16:01:35 +080011990 wlan_hdd_cfg80211_stats_ext2_callback);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011991
Jeff Johnson16528362018-06-14 12:34:16 -070011992 sme_set_rssi_threshold_breached_cb(mac_handle,
11993 hdd_rssi_threshold_breached);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011994
Jeff Johnson16528362018-06-14 12:34:16 -070011995 sme_set_link_layer_stats_ind_cb(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011996 wlan_hdd_cfg80211_link_layer_stats_callback);
11997
Jeff Johnson16528362018-06-14 12:34:16 -070011998 sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb);
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +053011999
Jeff Johnson16528362018-06-14 12:34:16 -070012000 sme_set_link_layer_ext_cb(mac_handle,
Zhang Qianca38fb12016-12-23 11:10:48 +080012001 wlan_hdd_cfg80211_link_layer_stats_ext_callback);
12002
Jeff Johnson16528362018-06-14 12:34:16 -070012003 status = sme_set_lost_link_info_cb(mac_handle,
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +053012004 hdd_lost_link_info_cb);
12005 /* print error and not block the startup process */
12006 if (!QDF_IS_STATUS_SUCCESS(status))
12007 hdd_err("set lost link info callback failed");
12008
Poddar, Siddarth34872782017-08-10 14:08:51 +053012009 ret = hdd_register_data_stall_detect_cb();
12010 if (ret) {
12011 hdd_err("Register data stall detect detect callback failed.");
12012 return ret;
12013 }
12014
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012015 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
12016
Jeff Johnson16528362018-06-14 12:34:16 -070012017 sme_register_set_connection_info_cb(mac_handle,
12018 hdd_set_connection_in_progress,
12019 hdd_is_connection_in_progress);
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +053012020
Jeff Johnson16528362018-06-14 12:34:16 -070012021 status = sme_congestion_register_callback(mac_handle,
12022 hdd_update_cca_info_cb);
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +053012023 if (!QDF_IS_STATUS_SUCCESS(status))
12024 hdd_err("set congestion callback failed");
12025
Jeff Johnson16528362018-06-14 12:34:16 -070012026 status = sme_set_bt_activity_info_cb(mac_handle,
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053012027 hdd_bt_activity_cb);
12028 if (!QDF_IS_STATUS_SUCCESS(status))
12029 hdd_err("set bt activity info callback failed");
12030
Jeff Johnson16528362018-06-14 12:34:16 -070012031 status = sme_register_tx_queue_cb(mac_handle,
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -080012032 hdd_tx_queue_cb);
12033 if (!QDF_IS_STATUS_SUCCESS(status))
12034 hdd_err("Register tx queue callback failed");
12035
Dustin Browne74003f2018-03-14 12:51:58 -070012036 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012037
12038 return ret;
12039}
12040
12041/**
12042 * hdd_deregister_cb() - De-Register HDD callbacks.
12043 * @hdd_ctx: HDD context
12044 *
12045 * De-Register the HDD callbacks to CDS/SME.
12046 *
12047 * Return: void
12048 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012049void hdd_deregister_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012050{
12051 QDF_STATUS status;
Poddar, Siddarth34872782017-08-10 14:08:51 +053012052 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -070012053 mac_handle_t mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012054
Dustin Brown491d54b2018-03-14 12:39:11 -070012055 hdd_enter();
Sourav Mohapatra674925f2018-04-16 11:16:58 +053012056 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
12057 hdd_err("in ftm mode, no need to deregister callbacks");
12058 return;
12059 }
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012060
Jeff Johnson16528362018-06-14 12:34:16 -070012061 mac_handle = hdd_ctx->mac_handle;
12062 sme_deregister_tx_queue_cb(mac_handle);
12063 status = sme_deregister_for_dcc_stats_event(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012064 if (!QDF_IS_STATUS_SUCCESS(status))
12065 hdd_err("De-register of dcc stats callback failed: %d",
12066 status);
12067
Jeff Johnson16528362018-06-14 12:34:16 -070012068 sme_reset_link_layer_stats_ind_cb(mac_handle);
12069 sme_reset_rssi_threshold_breached_cb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012070
Jeff Johnson16528362018-06-14 12:34:16 -070012071 sme_stats_ext_register_callback(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012072 wlan_hdd_cfg80211_stats_ext_callback);
12073
Jeff Johnson16528362018-06-14 12:34:16 -070012074 sme_nan_deregister_callback(mac_handle);
12075 status = sme_reset_tsfcb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012076 if (!QDF_IS_STATUS_SUCCESS(status))
12077 hdd_err("Failed to de-register tsfcb the callback:%d",
12078 status);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012079
Poddar, Siddarth34872782017-08-10 14:08:51 +053012080 ret = hdd_deregister_data_stall_detect_cb();
12081 if (ret)
12082 hdd_err("Failed to de-register data stall detect event callback");
12083
Jeff Johnson16528362018-06-14 12:34:16 -070012084 sme_deregister_oem_data_rsp_callback(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012085
Dustin Browne74003f2018-03-14 12:51:58 -070012086 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012087}
12088
12089/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012090 * hdd_softap_sta_deauth() - handle deauth req from HDD
12091 * @adapter: Pointer to the HDD
12092 * @enable: bool value
12093 *
12094 * This to take counter measure to handle deauth req from HDD
12095 *
12096 * Return: None
12097 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012098QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
Jeff Johnsone6bf7192017-11-07 15:16:09 -080012099 struct csr_del_sta_params *pDelStaParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012100{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012101 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012102
Dustin Brown491d54b2018-03-14 12:39:11 -070012103 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012104
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012105 /* Ignore request to deauth bcmc station */
12106 if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012107 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012108
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012109 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012110 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
12111 pDelStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012112
Dustin Browne74003f2018-03-14 12:51:58 -070012113 hdd_exit();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012114 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012115}
12116
12117/**
12118 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
12119 * @adapter: Pointer to the HDD
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053012120 * @p_del_sta_params: pointer to station deletion parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012121 *
12122 * This to take counter measure to handle deauth req from HDD
12123 *
12124 * Return: None
12125 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012126void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
Jeff Johnsone6bf7192017-11-07 15:16:09 -080012127 struct csr_del_sta_params *pDelStaParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012128{
Dustin Brown491d54b2018-03-14 12:39:11 -070012129 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012130
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012131 /* Ignore request to disassoc bcmc station */
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053012132 if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012133 return;
12134
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012135 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053012136 pDelStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012137}
12138
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012139/**
12140 * hdd_issta_p2p_clientconnected() - check if sta or p2p client is connected
12141 * @hdd_ctx: HDD Context
12142 *
12143 * API to find if there is any STA or P2P-Client is connected
12144 *
12145 * Return: true if connected; false otherwise
12146 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012147QDF_STATUS hdd_issta_p2p_clientconnected(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012148{
Jeff Johnson16528362018-06-14 12:34:16 -070012149 return sme_is_sta_p2p_client_connected(hdd_ctx->mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012150}
12151
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012152void wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012153{
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012154 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
12155 struct hdd_adapter *adapter = NULL;
12156 struct csr_roam_profile *roam_profile;
12157 struct hdd_station_ctx *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012158
Dustin Brown1dbefe62018-09-11 16:32:03 -070012159 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012160 hdd_debug("No active sta session");
12161 return;
12162 }
12163
12164 hdd_for_each_adapter(hdd_ctx, adapter) {
12165 roam_profile = hdd_roam_profile(adapter);
12166 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
12167
12168 if (cur_adapter->session_id != adapter->session_id &&
12169 adapter->device_mode == QDF_STA_MODE &&
12170 hdd_conn_is_connected(sta_ctx)) {
12171 hdd_debug("%d Disable roaming", adapter->session_id);
Jeff Johnson16528362018-06-14 12:34:16 -070012172 sme_stop_roaming(hdd_ctx->mac_handle,
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012173 adapter->session_id,
12174 ecsr_driver_disabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012175 }
12176 }
12177}
12178
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012179void wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012180{
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012181 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
12182 struct hdd_adapter *adapter = NULL;
12183 struct csr_roam_profile *roam_profile;
12184 struct hdd_station_ctx *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012185
Dustin Brown1dbefe62018-09-11 16:32:03 -070012186 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012187 hdd_debug("No active sta session");
12188 return;
12189 }
12190
12191 hdd_for_each_adapter(hdd_ctx, adapter) {
12192 roam_profile = hdd_roam_profile(adapter);
12193 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
12194
12195 if (cur_adapter->session_id != adapter->session_id &&
12196 adapter->device_mode == QDF_STA_MODE &&
12197 hdd_conn_is_connected(sta_ctx)) {
12198 hdd_debug("%d Enable roaming", adapter->session_id);
Jeff Johnson16528362018-06-14 12:34:16 -070012199 sme_start_roaming(hdd_ctx->mac_handle,
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012200 adapter->session_id,
12201 REASON_DRIVER_ENABLED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012202 }
12203 }
12204}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012205
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053012206/**
12207 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
12208 * @skb: sk buffer pointer
12209 *
12210 * Sends the bcast message to SVC multicast group with generic nl socket
12211 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
12212 *
12213 * Return: None
12214 */
12215static void nl_srv_bcast_svc(struct sk_buff *skb)
12216{
12217#ifdef CNSS_GENL
12218 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
12219#else
12220 nl_srv_bcast(skb);
12221#endif
12222}
12223
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012224void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012225{
12226 struct sk_buff *skb;
12227 struct nlmsghdr *nlh;
12228 tAniMsgHdr *ani_hdr;
12229 void *nl_data = NULL;
12230 int flags = GFP_KERNEL;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012231 struct radio_index_tlv *radio_info;
12232 int tlv_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012233
12234 if (in_interrupt() || irqs_disabled() || in_atomic())
12235 flags = GFP_ATOMIC;
12236
12237 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
12238
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012239 if (skb == NULL)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012240 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012241
12242 nlh = (struct nlmsghdr *)skb->data;
12243 nlh->nlmsg_pid = 0; /* from kernel */
12244 nlh->nlmsg_flags = 0;
12245 nlh->nlmsg_seq = 0;
12246 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12247
12248 ani_hdr = NLMSG_DATA(nlh);
12249 ani_hdr->type = type;
12250
12251 switch (type) {
12252 case WLAN_SVC_FW_CRASHED_IND:
Komal Seelam78ff65a2016-08-18 15:25:24 +053012253 case WLAN_SVC_FW_SHUTDOWN_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012254 case WLAN_SVC_LTE_COEX_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012255 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070012256 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012257 ani_hdr->length = 0;
12258 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012259 break;
12260 case WLAN_SVC_WLAN_STATUS_IND:
12261 case WLAN_SVC_WLAN_VERSION_IND:
12262 case WLAN_SVC_DFS_CAC_START_IND:
12263 case WLAN_SVC_DFS_CAC_END_IND:
12264 case WLAN_SVC_DFS_RADAR_DETECT_IND:
12265 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
12266 case WLAN_SVC_WLAN_TP_IND:
Mohit Khannae71e2262015-11-10 09:37:24 -080012267 case WLAN_SVC_WLAN_TP_TX_IND:
Nirav Shahbd36b062016-07-18 11:12:59 +053012268 case WLAN_SVC_RPS_ENABLE_IND:
Orhan K AKYILDIZe7445a22017-01-19 21:21:47 -080012269 case WLAN_SVC_CORE_MINFREQ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012270 ani_hdr->length = len;
12271 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12272 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12273 memcpy(nl_data, data, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012274 break;
12275
12276 default:
Jeff Johnson34c88b72016-08-15 14:27:11 -070012277 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012278 type);
12279 kfree_skb(skb);
12280 return;
12281 }
12282
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012283 /*
Jeff Johnson0d52c7a2017-01-12 08:46:55 -080012284 * Add radio index at the end of the svc event in TLV format
12285 * to maintain the backward compatibility with userspace
12286 * applications.
12287 */
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012288
12289 tlv_len = 0;
12290
12291 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
12292 < WLAN_NL_MAX_PAYLOAD) {
12293 radio_info = (struct radio_index_tlv *)((char *) ani_hdr +
12294 sizeof(*ani_hdr) + len);
12295 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
12296 radio_info->length = (unsigned short) sizeof(radio_info->radio);
12297 radio_info->radio = radio;
12298 tlv_len = sizeof(*radio_info);
Dustin Browna2868622018-03-20 11:38:14 -070012299 hdd_debug("Added radio index tlv - radio index %d",
12300 radio_info->radio);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012301 }
12302
12303 nlh->nlmsg_len += tlv_len;
12304 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
12305
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053012306 nl_srv_bcast_svc(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012307}
12308
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012309#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
12310void wlan_hdd_auto_shutdown_cb(void)
12311{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012312 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012313
12314 if (!hdd_ctx)
12315 return;
12316
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012317 hdd_debug("Wlan Idle. Sending Shutdown event..");
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012318 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
12319 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012320}
12321
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012322void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012323{
Jeff Johnson9d295242017-08-29 14:39:48 -070012324 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012325 bool ap_connected = false, sta_connected = false;
Jeff Johnson16528362018-06-14 12:34:16 -070012326 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012327
Jeff Johnson16528362018-06-14 12:34:16 -070012328 mac_handle = hdd_ctx->mac_handle;
12329 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012330 return;
12331
Dundi Raviteja8e338282018-09-25 17:16:04 +053012332 if (hdd_ctx->config->wlan_auto_shutdown == 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012333 return;
12334
12335 if (enable == false) {
Jeff Johnson16528362018-06-14 12:34:16 -070012336 if (sme_set_auto_shutdown_timer(mac_handle, 0) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012337 QDF_STATUS_SUCCESS) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012338 hdd_err("Failed to stop wlan auto shutdown timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012339 }
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012340 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070012341 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012342 return;
12343 }
12344
12345 /* To enable shutdown timer check conncurrency */
Dustin Brown1dbefe62018-09-11 16:32:03 -070012346 if (policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc)) {
Dustin Brown920397d2017-12-13 16:27:50 -080012347 hdd_for_each_adapter(hdd_ctx, adapter) {
12348 if (adapter->device_mode == QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012349 if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
12350 conn_info.connState ==
12351 eConnectionState_Associated) {
12352 sta_connected = true;
12353 break;
12354 }
12355 }
Dustin Brown920397d2017-12-13 16:27:50 -080012356
12357 if (adapter->device_mode == QDF_SAP_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012358 if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
Jeff Johnson136c51b2017-10-27 20:02:41 -070012359 ap_active == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012360 ap_connected = true;
12361 break;
12362 }
12363 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012364 }
12365 }
12366
12367 if (ap_connected == true || sta_connected == true) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012368 hdd_debug("CC Session active. Shutdown timer not enabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012369 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012370 }
Jeff Johnson68755312017-02-10 11:46:55 -080012371
Jeff Johnson16528362018-06-14 12:34:16 -070012372 if (sme_set_auto_shutdown_timer(mac_handle,
Dundi Raviteja8e338282018-09-25 17:16:04 +053012373 hdd_ctx->config->wlan_auto_shutdown)
Jeff Johnson68755312017-02-10 11:46:55 -080012374 != QDF_STATUS_SUCCESS)
12375 hdd_err("Failed to start wlan auto shutdown timer");
12376 else
Dustin Brown5e89ef82018-03-14 11:50:23 -070012377 hdd_info("Auto Shutdown timer for %d seconds enabled",
Dundi Raviteja8e338282018-09-25 17:16:04 +053012378 hdd_ctx->config->wlan_auto_shutdown);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012379}
12380#endif
12381
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070012382struct hdd_adapter *
12383hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
12384 bool check_start_bss)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012385{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012386 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070012387 struct hdd_adapter *adapter, *con_sap_adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012388
12389 con_sap_adapter = NULL;
12390
Dustin Brown920397d2017-12-13 16:27:50 -080012391 hdd_for_each_adapter(hdd_ctx, adapter) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080012392 if (adapter && ((adapter->device_mode == QDF_SAP_MODE) ||
12393 (adapter->device_mode == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012394 adapter != this_sap_adapter) {
12395 if (check_start_bss) {
12396 if (test_bit(SOFTAP_BSS_STARTED,
12397 &adapter->event_flags)) {
12398 con_sap_adapter = adapter;
12399 break;
12400 }
12401 } else {
12402 con_sap_adapter = adapter;
12403 break;
12404 }
12405 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012406 }
12407
12408 return con_sap_adapter;
12409}
12410
12411#ifdef MSM_PLATFORM
Jeff Johnson9d295242017-08-29 14:39:48 -070012412static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012413{
Dustin Brown5ec6b552017-03-31 12:11:40 -070012414 return adapter->device_mode == QDF_STA_MODE ||
12415 adapter->device_mode == QDF_P2P_CLIENT_MODE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012416}
12417
Jeff Johnson9d295242017-08-29 14:39:48 -070012418static inline bool hdd_adapter_is_ap(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012419{
Dustin Brown5ec6b552017-03-31 12:11:40 -070012420 return adapter->device_mode == QDF_SAP_MODE ||
12421 adapter->device_mode == QDF_P2P_GO_MODE;
12422}
12423
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012424static bool hdd_any_adapter_is_assoc(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012425{
Dustin Brown920397d2017-12-13 16:27:50 -080012426 struct hdd_adapter *adapter;
Dustin Brown5ec6b552017-03-31 12:11:40 -070012427
Dustin Brown920397d2017-12-13 16:27:50 -080012428 hdd_for_each_adapter(hdd_ctx, adapter) {
12429 if (hdd_adapter_is_sta(adapter) &&
Dustin Brown5ec6b552017-03-31 12:11:40 -070012430 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
12431 conn_info.connState == eConnectionState_Associated) {
12432 return true;
12433 }
12434
Dustin Brown920397d2017-12-13 16:27:50 -080012435 if (hdd_adapter_is_ap(adapter) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -070012436 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active) {
Dustin Brown5ec6b552017-03-31 12:11:40 -070012437 return true;
12438 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070012439 }
12440
12441 return false;
12442}
12443
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012444static bool hdd_bus_bw_compute_timer_is_running(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012445{
12446 bool is_running;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012447
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +053012448 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012449 is_running = hdd_ctx->bus_bw_timer_running;
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +053012450 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012451
Dustin Brown5ec6b552017-03-31 12:11:40 -070012452 return is_running;
12453}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012454
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012455static void __hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012456{
12457 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
12458 hdd_ctx->bus_bw_timer_running = true;
12459 qdf_timer_start(&hdd_ctx->bus_bw_timer,
jitiphil869b9f72018-09-25 17:14:01 +053012460 hdd_ctx->config->bus_bw_compute_interval);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012461 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
12462}
12463
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012464void hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012465{
Dustin Brown491d54b2018-03-14 12:39:11 -070012466 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012467
12468 if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
12469 hdd_debug("Bandwidth compute timer already started");
12470 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012471 }
12472
Dustin Brown5ec6b552017-03-31 12:11:40 -070012473 __hdd_bus_bw_compute_timer_start(hdd_ctx);
12474
Dustin Browne74003f2018-03-14 12:51:58 -070012475 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012476}
12477
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012478void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012479{
Dustin Brown491d54b2018-03-14 12:39:11 -070012480 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012481
12482 if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
12483 hdd_debug("Bandwidth compute timer already started");
12484 return;
Ravi Joshib89e7f72016-09-07 13:43:15 -070012485 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070012486
12487 if (hdd_any_adapter_is_assoc(hdd_ctx))
12488 __hdd_bus_bw_compute_timer_start(hdd_ctx);
12489
Dustin Browne74003f2018-03-14 12:51:58 -070012490 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012491}
12492
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012493static void __hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012494{
Dustin Brown07901ec2018-09-07 11:02:41 -070012495 ucfg_ipa_set_perf_level(hdd_ctx->pdev, 0, 0);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012496
12497 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012498 hdd_ctx->bus_bw_timer_running = false;
Dustin Brown35008ba2018-08-23 14:34:21 -070012499 qdf_timer_sync_cancel(&hdd_ctx->bus_bw_timer);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012500 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
12501
Dustin Brown35008ba2018-08-23 14:34:21 -070012502 /* work callback is long running; flush outside of lock */
12503 cancel_work_sync(&hdd_ctx->bus_bw_work);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012504 hdd_reset_tcp_delack(hdd_ctx);
12505}
12506
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012507void hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012508{
Dustin Brown491d54b2018-03-14 12:39:11 -070012509 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012510
12511 if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
12512 hdd_debug("Bandwidth compute timer already stopped");
12513 return;
12514 }
12515
12516 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
12517
Dustin Browne74003f2018-03-14 12:51:58 -070012518 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012519}
12520
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012521void hdd_bus_bw_compute_timer_try_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012522{
Dustin Brown491d54b2018-03-14 12:39:11 -070012523 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012524
12525 if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
12526 hdd_debug("Bandwidth compute timer already stopped");
12527 return;
12528 }
12529
12530 if (!hdd_any_adapter_is_assoc(hdd_ctx))
12531 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
12532
Dustin Browne74003f2018-03-14 12:51:58 -070012533 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012534}
12535#endif
12536
12537/**
12538 * wlan_hdd_check_custom_con_channel_rules() - This function checks the sap's
12539 * and sta's operating channel.
12540 * @sta_adapter: Describe the first argument to foobar.
12541 * @ap_adapter: Describe the second argument to foobar.
12542 * @roam_profile: Roam profile of AP to which STA wants to connect.
12543 * @concurrent_chnl_same: If both SAP and STA channels are same then
12544 * set this flag to true else false.
12545 *
12546 * This function checks the sap's operating channel and sta's operating channel.
12547 * if both are same then it will return false else it will restart the sap in
12548 * sta's channel and return true.
12549 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012550 * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012551 */
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070012552QDF_STATUS
12553wlan_hdd_check_custom_con_channel_rules(struct hdd_adapter *sta_adapter,
12554 struct hdd_adapter *ap_adapter,
Jeff Johnson61b5e982018-03-15 11:33:31 -070012555 struct csr_roam_profile *roam_profile,
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070012556 tScanResultHandle *scan_cache,
12557 bool *concurrent_chnl_same)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012558{
Jeff Johnson87251032017-08-29 13:31:11 -070012559 struct hdd_ap_ctx *hdd_ap_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012560 uint8_t channel_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012561 QDF_STATUS status;
Jeff Johnsonc1e62782017-11-09 09:50:17 -080012562 enum QDF_OPMODE device_mode = ap_adapter->device_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012563 *concurrent_chnl_same = true;
12564
12565 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
12566 status =
Archana Ramachandran2eb7a612017-03-23 22:58:42 -070012567 sme_get_ap_channel_from_scan_cache(roam_profile,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012568 scan_cache,
12569 &channel_id);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012570 if (QDF_STATUS_SUCCESS == status) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080012571 if ((QDF_SAP_MODE == device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012572 (channel_id < SIR_11A_CHANNEL_BEGIN)) {
Jeff Johnson01206862017-10-27 20:55:59 -070012573 if (hdd_ap_ctx->operating_channel != channel_id) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012574 *concurrent_chnl_same = false;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012575 hdd_debug("channels are different");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012576 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -080012577 } else if ((QDF_P2P_GO_MODE == device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012578 (channel_id >= SIR_11A_CHANNEL_BEGIN)) {
Jeff Johnson01206862017-10-27 20:55:59 -070012579 if (hdd_ap_ctx->operating_channel != channel_id) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012580 *concurrent_chnl_same = false;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012581 hdd_debug("channels are different");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012582 }
12583 }
12584 } else {
12585 /*
12586 * Lets handle worst case scenario here, Scan cache lookup is
12587 * failed so we have to stop the SAP to avoid any channel
12588 * discrepancy between SAP's channel and STA's channel.
12589 * Return the status as failure so caller function could know
12590 * that scan look up is failed.
12591 */
Jeff Johnson28f8a772016-08-15 15:30:36 -070012592 hdd_err("Finding AP from scan cache failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012593 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012594 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012595 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012596}
12597
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012598/**
12599 * wlan_hdd_stop_sap() - This function stops bss of SAP.
12600 * @ap_adapter: SAP adapter
12601 *
12602 * This function will process the stopping of sap adapter.
12603 *
12604 * Return: None
12605 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012606void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012607{
Jeff Johnson87251032017-08-29 13:31:11 -070012608 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070012609 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053012610 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012611 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012612
12613 if (NULL == ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012614 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012615 return;
12616 }
12617
12618 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
12619 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Abhishek Singh23edd1c2016-05-05 11:56:06 +053012620 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012621 return;
Abhishek Singh23edd1c2016-05-05 11:56:06 +053012622
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012623 mutex_lock(&hdd_ctx->sap_lock);
12624 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080012625 wlan_hdd_del_station(ap_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012626 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012627 hdd_debug("Now doing SAP STOPBSS");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053012628 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012629 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070012630 sap_context)) {
Nachiket Kukade0396b732017-11-14 16:35:16 +053012631 qdf_status = qdf_wait_for_event_completion(&hostapd_state->
Naveen Rawatb56880c2016-12-13 17:56:03 -080012632 qdf_stop_bss_event,
Vignesh Viswanathan865daaa2018-10-11 19:30:44 +053012633 SME_CMD_START_STOP_BSS_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +053012634 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012635 mutex_unlock(&hdd_ctx->sap_lock);
Jeff Johnson28f8a772016-08-15 15:30:36 -070012636 hdd_err("SAP Stop Failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012637 return;
12638 }
12639 }
12640 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -070012641 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012642 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070012643 ap_adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070012644 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053012645 false);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012646 hdd_debug("SAP Stop Success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012647 } else {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012648 hdd_err("Can't stop ap because its not started");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012649 }
12650 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012651}
12652
12653/**
12654 * wlan_hdd_start_sap() - this function starts bss of SAP.
12655 * @ap_adapter: SAP adapter
12656 *
12657 * This function will process the starting of sap adapter.
12658 *
12659 * Return: None
12660 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012661void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012662{
Jeff Johnson87251032017-08-29 13:31:11 -070012663 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070012664 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053012665 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012666 struct hdd_context *hdd_ctx;
Jeff Johnsone4c11db2018-05-05 23:22:32 -070012667 tsap_config_t *sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012668
12669 if (NULL == ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012670 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012671 return;
12672 }
12673
Krunal Soni9b04c9b2016-03-10 13:08:05 -080012674 if (QDF_SAP_MODE != ap_adapter->device_mode) {
Peng Xuf5d60c82015-10-02 17:17:03 -070012675 hdd_err("SoftAp role has not been enabled");
12676 return;
12677 }
12678
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012679 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
12680 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
12681 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -070012682 sap_config = &ap_adapter->session.ap.sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012683
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012684 mutex_lock(&hdd_ctx->sap_lock);
12685 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
12686 goto end;
12687
12688 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012689 hdd_err("SAP Not able to set AP IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012690 goto end;
12691 }
Dustin Brown07901ec2018-09-07 11:02:41 -070012692 wlan_reg_set_channel_params(hdd_ctx->pdev,
Abhinav Kumar6f694482018-09-04 16:07:39 +053012693 hdd_ap_ctx->sap_config.channel, 0,
12694 &hdd_ap_ctx->sap_config.ch_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012695
Wei Song2f76f642016-11-18 16:32:53 +080012696 qdf_event_reset(&hostapd_state->qdf_event);
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070012697 if (wlansap_start_bss(hdd_ap_ctx->sap_context, hdd_hostapd_sap_event_cb,
Jeff Johnson91df29d2017-10-27 19:29:50 -070012698 &hdd_ap_ctx->sap_config,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012699 ap_adapter->dev)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012700 != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012701 goto end;
12702
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012703 hdd_debug("Waiting for SAP to start");
Nachiket Kukade0396b732017-11-14 16:35:16 +053012704 qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Vignesh Viswanathan865daaa2018-10-11 19:30:44 +053012705 SME_CMD_START_STOP_BSS_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +053012706 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012707 hdd_err("SAP Start failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012708 goto end;
12709 }
Jeff Johnson28f8a772016-08-15 15:30:36 -070012710 hdd_info("SAP Start Success");
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053012711 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012712 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053012713 if (hostapd_state->bss_state == BSS_START) {
Dustin Brown1dbefe62018-09-11 16:32:03 -070012714 policy_mgr_incr_active_session(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012715 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070012716 ap_adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070012717 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053012718 true);
12719 }
Sourav Mohapatra9bc67112017-11-08 09:36:11 +053012720 mutex_unlock(&hdd_ctx->sap_lock);
12721
12722 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012723end:
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053012724 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012725 mutex_unlock(&hdd_ctx->sap_lock);
Manikandan Mohan3dad1a42017-06-14 10:50:18 -070012726 /* SAP context and beacon cleanup will happen during driver unload
12727 * in hdd_stop_adapter
12728 */
12729 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
12730
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012731}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012732
12733/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012734 * hdd_get_fw_version() - Get FW version
12735 * @hdd_ctx: pointer to HDD context.
12736 * @major_spid: FW version - major spid.
12737 * @minor_spid: FW version - minor spid
12738 * @ssid: FW version - ssid
12739 * @crmid: FW version - crmid
12740 *
12741 * This function is called to get the firmware build version stored
12742 * as part of the HDD context
12743 *
12744 * Return: None
12745 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012746void hdd_get_fw_version(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012747 uint32_t *major_spid, uint32_t *minor_spid,
12748 uint32_t *siid, uint32_t *crmid)
12749{
12750 *major_spid = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
12751 *minor_spid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
12752 *siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
12753 *crmid = hdd_ctx->target_fw_version & 0x7fff;
12754}
12755
12756#ifdef QCA_CONFIG_SMP
12757/**
12758 * wlan_hdd_get_cpu() - get cpu_index
12759 *
12760 * Return: cpu_index
12761 */
12762int wlan_hdd_get_cpu(void)
12763{
12764 int cpu_index = get_cpu();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012765
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012766 put_cpu();
12767 return cpu_index;
12768}
12769#endif
12770
12771/**
12772 * hdd_get_fwpath() - get framework path
12773 *
12774 * This function is used to get the string written by
12775 * userspace to start the wlan driver
12776 *
12777 * Return: string
12778 */
12779const char *hdd_get_fwpath(void)
12780{
12781 return fwpath.string;
12782}
12783
Dustin Brown94ce20f2018-09-04 13:11:38 -070012784static inline int hdd_state_query_cb(void)
12785{
12786 return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD));
12787}
12788
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012789/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012790 * hdd_init() - Initialize Driver
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012791 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012792 * This function initilizes CDS global context with the help of cds_init. This
12793 * has to be the first function called after probe to get a valid global
12794 * context.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012795 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012796 * Return: 0 for success, errno on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012797 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012798int hdd_init(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012799{
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070012800 QDF_STATUS status;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012801 int ret = 0;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012802
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070012803 status = cds_init();
wadesongae4ffd12017-10-24 16:45:54 +080012804 if (QDF_IS_STATUS_ERROR(status)) {
12805 hdd_err("Failed to allocate CDS context");
12806 ret = -ENOMEM;
12807 goto err_out;
12808 }
Dustin Brown94ce20f2018-09-04 13:11:38 -070012809 qdf_register_module_state_query_callback(hdd_state_query_cb);
Hanumanth Reddy Pothula788a37e2017-08-17 18:40:11 +053012810
12811 wlan_init_bug_report_lock();
12812
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012813#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12814 wlan_logging_sock_init_svc();
12815#endif
12816
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053012817 qdf_timer_init(NULL, &hdd_drv_ops_inactivity_timer,
12818 (void *)hdd_drv_ops_inactivity_handler, NULL,
12819 QDF_TIMER_TYPE_SW);
12820
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012821 hdd_trace_init();
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012822 hdd_register_debug_callback();
Qiwei Caiad9b01c2018-07-09 17:21:31 +080012823 wlan_roam_debug_init();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012824
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012825err_out:
12826 return ret;
12827}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012828
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012829/**
12830 * hdd_deinit() - Deinitialize Driver
12831 *
12832 * This function frees CDS global context with the help of cds_deinit. This
12833 * has to be the last function call in remove callback to free the global
12834 * context.
12835 */
12836void hdd_deinit(void)
12837{
Qiwei Caiad9b01c2018-07-09 17:21:31 +080012838 wlan_roam_debug_deinit();
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053012839 qdf_timer_free(&hdd_drv_ops_inactivity_timer);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012840
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012841#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12842 wlan_logging_sock_deinit_svc();
12843#endif
Qiwei Caiad9b01c2018-07-09 17:21:31 +080012844
12845 wlan_destroy_bug_report_lock();
12846 cds_deinit();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012847}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012848
Yue Ma6e7b1a02017-04-03 14:17:46 -070012849#ifdef QCA_WIFI_NAPIER_EMULATION
12850#define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
12851#else
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012852#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
Yue Ma6e7b1a02017-04-03 14:17:46 -070012853#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012854
Sachin Ahujadddd2632017-03-07 19:07:24 +053012855static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
12856 struct file *file)
12857{
12858 return 0;
12859}
12860
12861static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
12862 const char __user *user_buf,
12863 size_t count,
12864 loff_t *f_pos)
12865{
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012866 char buf[3];
Sachin Ahujadddd2632017-03-07 19:07:24 +053012867 static const char wlan_off_str[] = "OFF";
12868 static const char wlan_on_str[] = "ON";
12869 int ret;
12870 unsigned long rc;
12871
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012872 if (copy_from_user(buf, user_buf, 3)) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053012873 pr_err("Failed to read buffer\n");
12874 return -EINVAL;
12875 }
12876
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012877 if (strncmp(buf, wlan_off_str, strlen(wlan_off_str)) == 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053012878 pr_debug("Wifi turning off from UI\n");
12879 goto exit;
12880 }
12881
Srinivas Girigowdad2412882018-09-07 15:42:04 -070012882 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) == 0)
Sachin Ahuja16904db2017-12-13 19:56:57 +053012883 pr_info("Wifi Turning On from UI\n");
Sachin Ahuja16904db2017-12-13 19:56:57 +053012884
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012885 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) != 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053012886 pr_err("Invalid value received from framework");
12887 goto exit;
12888 }
12889
12890 if (!cds_is_driver_loaded()) {
Sachin Ahujaee62b542017-04-21 14:14:16 +053012891 init_completion(&wlan_start_comp);
Sachin Ahujadddd2632017-03-07 19:07:24 +053012892 rc = wait_for_completion_timeout(&wlan_start_comp,
12893 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
12894 if (!rc) {
Srinivas Girigowda09625b02018-09-10 15:28:09 -070012895 hdd_alert("Timed-out!!");
Sachin Ahujadddd2632017-03-07 19:07:24 +053012896 ret = -EINVAL;
Sachin Ahujadddd2632017-03-07 19:07:24 +053012897 return ret;
12898 }
12899
12900 hdd_start_complete(0);
12901 }
12902
12903exit:
12904 return count;
12905}
12906
12907
12908const struct file_operations wlan_hdd_state_fops = {
12909 .owner = THIS_MODULE,
12910 .open = wlan_hdd_state_ctrl_param_open,
12911 .write = wlan_hdd_state_ctrl_param_write,
12912};
12913
12914static int wlan_hdd_state_ctrl_param_create(void)
12915{
12916 unsigned int wlan_hdd_state_major = 0;
12917 int ret;
12918 struct device *dev;
12919
12920 device = MKDEV(wlan_hdd_state_major, 0);
12921
12922 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
12923 if (ret) {
12924 pr_err("Failed to register qcwlanstate");
12925 goto dev_alloc_err;
12926 }
12927 wlan_hdd_state_major = MAJOR(device);
12928
12929 class = class_create(THIS_MODULE, WLAN_MODULE_NAME);
12930 if (IS_ERR(class)) {
12931 pr_err("wlan_hdd_state class_create error");
12932 goto class_err;
12933 }
12934
12935 dev = device_create(class, NULL, device, NULL, WLAN_MODULE_NAME);
12936 if (IS_ERR(dev)) {
12937 pr_err("wlan_hdd_statedevice_create error");
12938 goto err_class_destroy;
12939 }
12940
12941 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
12942 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
12943 if (ret) {
12944 pr_err("Failed to add cdev error");
12945 goto cdev_add_err;
12946 }
12947
12948 pr_info("wlan_hdd_state %s major(%d) initialized",
12949 WLAN_MODULE_NAME, wlan_hdd_state_major);
12950
12951 return 0;
12952
12953cdev_add_err:
12954 device_destroy(class, device);
12955err_class_destroy:
12956 class_destroy(class);
12957class_err:
12958 unregister_chrdev_region(device, dev_num);
12959dev_alloc_err:
12960 return -ENODEV;
12961}
12962
12963static void wlan_hdd_state_ctrl_param_destroy(void)
12964{
12965 cdev_del(&wlan_hdd_state_cdev);
12966 device_destroy(class, device);
12967 class_destroy(class);
12968 unregister_chrdev_region(device, dev_num);
12969
12970 pr_info("Device node unregistered");
12971}
12972
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012973/**
Dustin Brownd585cb32018-09-12 17:12:23 -070012974 * hdd_component_init() - Initialize all components
Mukul Sharmad75a6672017-06-22 15:40:53 +053012975 *
Dustin Brownd585cb32018-09-12 17:12:23 -070012976 * Return: QDF_STATUS
Mukul Sharmad75a6672017-06-22 15:40:53 +053012977 */
Dustin Brownd585cb32018-09-12 17:12:23 -070012978static QDF_STATUS hdd_component_init(void)
Mukul Sharmad75a6672017-06-22 15:40:53 +053012979{
Dustin Brownd585cb32018-09-12 17:12:23 -070012980 QDF_STATUS status;
12981
12982 /* initialize converged components */
12983 status = dispatcher_init();
12984 if (QDF_IS_STATUS_ERROR(status))
12985 return status;
12986
12987 /* initialize non-converged components */
12988 status = ucfg_mlme_init();
12989 if (QDF_IS_STATUS_ERROR(status))
12990 goto dispatcher_deinit;
12991
12992 status = ucfg_fwol_init();
12993 if (QDF_IS_STATUS_ERROR(status))
12994 goto mlme_deinit;
12995
12996 status = disa_init();
12997 if (QDF_IS_STATUS_ERROR(status))
12998 goto fwol_deinit;
12999
13000 status = pmo_init();
13001 if (QDF_IS_STATUS_ERROR(status))
13002 goto disa_deinit;
13003
13004 status = ucfg_ocb_init();
13005 if (QDF_IS_STATUS_ERROR(status))
13006 goto pmo_deinit;
13007
13008 status = ipa_init();
13009 if (QDF_IS_STATUS_ERROR(status))
13010 goto ocb_deinit;
13011
13012 status = ucfg_action_oui_init();
13013 if (QDF_IS_STATUS_ERROR(status))
13014 goto ipa_deinit;
13015
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013016 status = nan_init();
13017 if (QDF_IS_STATUS_ERROR(status))
13018 goto action_oui_deinit;
13019
Wu Gao637d58a2018-12-08 10:37:34 +080013020 status = ucfg_p2p_init();
13021 if (QDF_IS_STATUS_ERROR(status))
13022 goto nan_deinit;
13023
Wu Gaod6b5e402018-12-03 22:09:24 +080013024 status = policy_mgr_init();
13025 if (QDF_IS_STATUS_ERROR(status))
13026 goto p2p_deinit;
13027
Dustin Brownd585cb32018-09-12 17:12:23 -070013028 return QDF_STATUS_SUCCESS;
13029
Wu Gaod6b5e402018-12-03 22:09:24 +080013030p2p_deinit:
13031 ucfg_p2p_deinit();
Wu Gao637d58a2018-12-08 10:37:34 +080013032nan_deinit:
13033 nan_deinit();
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013034action_oui_deinit:
13035 ucfg_action_oui_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013036ipa_deinit:
13037 ipa_deinit();
13038ocb_deinit:
13039 ucfg_ocb_deinit();
13040pmo_deinit:
13041 pmo_deinit();
13042disa_deinit:
13043 disa_deinit();
13044fwol_deinit:
13045 ucfg_fwol_deinit();
13046mlme_deinit:
13047 ucfg_mlme_deinit();
13048dispatcher_deinit:
13049 dispatcher_deinit();
13050
13051 return status;
Mukul Sharmad75a6672017-06-22 15:40:53 +053013052}
13053
13054/**
Dustin Brownd585cb32018-09-12 17:12:23 -070013055 * hdd_component_deinit() - Deinitialize all components
Mukul Sharmad75a6672017-06-22 15:40:53 +053013056 *
13057 * Return: None
13058 */
Dustin Brownd585cb32018-09-12 17:12:23 -070013059static void hdd_component_deinit(void)
Mukul Sharmad75a6672017-06-22 15:40:53 +053013060{
Dustin Brownd585cb32018-09-12 17:12:23 -070013061 /* deinitialize non-converged components */
Wu Gaod6b5e402018-12-03 22:09:24 +080013062 policy_mgr_deinit();
Wu Gao637d58a2018-12-08 10:37:34 +080013063 ucfg_p2p_deinit();
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013064 nan_deinit();
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053013065 ucfg_action_oui_deinit();
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +053013066 ipa_deinit();
Zhang Qian47e22ce2018-01-04 15:38:38 +080013067 ucfg_ocb_deinit();
Mukul Sharmad75a6672017-06-22 15:40:53 +053013068 pmo_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013069 disa_deinit();
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013070 ucfg_fwol_deinit();
Vignesh Viswanathana0921c42018-09-04 19:03:35 +053013071 ucfg_mlme_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013072
13073 /* deinitialize converged components */
13074 dispatcher_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013075}
13076
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013077QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc)
13078{
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013079 QDF_STATUS status;
13080
13081 status = ucfg_mlme_psoc_open(psoc);
13082 if (QDF_IS_STATUS_ERROR(status))
13083 return status;
13084
13085 status = ucfg_fwol_psoc_open(psoc);
13086 if (QDF_IS_STATUS_ERROR(status))
Wu Gao66454f12018-09-26 19:55:41 +080013087 goto err_fwol;
13088
13089 status = ucfg_pmo_psoc_open(psoc);
13090 if (QDF_IS_STATUS_ERROR(status))
13091 goto err_pmo;
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013092
Krunal Sonie9c12f52018-10-04 11:45:42 -070013093 status = ucfg_policy_mgr_psoc_open(psoc);
13094 if (QDF_IS_STATUS_ERROR(status))
13095 goto err_plcy_mgr;
13096
Wu Gao637d58a2018-12-08 10:37:34 +080013097 status = ucfg_p2p_psoc_open(psoc);
13098 if (QDF_IS_STATUS_ERROR(status))
13099 goto err_p2p;
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013100 return status;
13101
Wu Gao637d58a2018-12-08 10:37:34 +080013102err_p2p:
13103 ucfg_p2p_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070013104err_plcy_mgr:
13105 ucfg_pmo_psoc_close(psoc);
Wu Gao66454f12018-09-26 19:55:41 +080013106err_pmo:
13107 ucfg_fwol_psoc_close(psoc);
13108err_fwol:
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013109 ucfg_mlme_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070013110
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013111 return status;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013112}
13113
13114void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc)
13115{
Wu Gao637d58a2018-12-08 10:37:34 +080013116 ucfg_p2p_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070013117 ucfg_policy_mgr_psoc_close(psoc);
Wu Gao66454f12018-09-26 19:55:41 +080013118 ucfg_pmo_psoc_close(psoc);
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013119 ucfg_fwol_psoc_close(psoc);
Vignesh Viswanathana0921c42018-09-04 19:03:35 +053013120 ucfg_mlme_psoc_close(psoc);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013121}
13122
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013123void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc)
13124{
Zhang Qian47e22ce2018-01-04 15:38:38 +080013125 ocb_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013126 disa_psoc_enable(psoc);
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013127 nan_psoc_enable(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013128 p2p_psoc_enable(psoc);
Wu Gaod6b5e402018-12-03 22:09:24 +080013129 policy_mgr_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013130}
13131
13132void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc)
13133{
Wu Gaod6b5e402018-12-03 22:09:24 +080013134 policy_mgr_psoc_disable(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013135 p2p_psoc_disable(psoc);
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013136 nan_psoc_disable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013137 disa_psoc_disable(psoc);
Zhang Qian47e22ce2018-01-04 15:38:38 +080013138 ocb_psoc_disable(psoc);
Mukul Sharmad75a6672017-06-22 15:40:53 +053013139}
13140
Sandeep Puligillab7beb472018-08-13 22:54:20 -070013141QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev)
13142{
13143 return ucfg_mlme_pdev_open(pdev);
13144}
13145
13146void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev)
13147{
13148 ucfg_mlme_pdev_close(pdev);
13149}
13150
Dustin Brown21a1d462018-07-31 15:13:06 -070013151static struct hdd_driver __hdd_driver;
13152
13153static QDF_STATUS hdd_driver_ctx_init(struct hdd_driver *hdd_driver)
13154{
13155 QDF_BUG(hdd_driver);
13156 if (!hdd_driver)
13157 return QDF_STATUS_E_INVAL;
13158
13159 hdd_driver->state = driver_state_uninit;
13160
13161 return dsc_driver_create(&hdd_driver->dsc_driver);
13162}
13163
13164static void hdd_driver_ctx_deinit(struct hdd_driver *hdd_driver)
13165{
13166 QDF_BUG(hdd_driver);
13167 if (!hdd_driver)
13168 return;
13169
13170 dsc_driver_destroy(&hdd_driver->dsc_driver);
13171 qdf_mem_zero(hdd_driver, sizeof(*hdd_driver));
13172}
13173
13174struct hdd_driver *hdd_driver_get(void)
13175{
13176 return &__hdd_driver;
13177}
13178
Dustin Browna2a39dc2018-09-17 15:29:59 -070013179static QDF_STATUS hdd_qdf_print_init(void)
13180{
13181 QDF_STATUS status;
13182 int qdf_print_idx;
13183
13184 status = qdf_print_setup();
13185 if (QDF_IS_STATUS_ERROR(status)) {
13186 pr_err("Failed qdf_print_setup; status:%u\n", status);
13187 return status;
13188 }
13189
13190 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
13191 if (qdf_print_idx < 0) {
13192 pr_err("Failed to register for qdf_print_ctrl\n");
13193 return QDF_STATUS_E_FAILURE;
13194 }
13195
13196 qdf_set_pidx(qdf_print_idx);
13197
13198 return QDF_STATUS_SUCCESS;
13199}
13200
13201static void hdd_qdf_print_deinit(void)
13202{
13203 int qdf_pidx = qdf_get_pidx();
13204
13205 qdf_set_pidx(-1);
13206 qdf_print_ctrl_cleanup(qdf_pidx);
13207
13208 /* currently, no qdf print 'un-setup'*/
13209}
13210
13211static QDF_STATUS hdd_qdf_init(void)
13212{
13213 QDF_STATUS status;
13214
13215 status = hdd_qdf_print_init();
13216 if (QDF_IS_STATUS_ERROR(status))
13217 goto exit;
13218
13219 status = qdf_debugfs_init();
13220 if (QDF_IS_STATUS_ERROR(status)) {
13221 hdd_err("Failed to init debugfs; status:%u", status);
13222 goto print_deinit;
13223 }
13224
13225 qdf_lock_stats_init();
13226 qdf_mem_init();
13227 qdf_mc_timer_manager_init();
13228 qdf_event_list_init();
13229
13230 status = qdf_cpuhp_init();
13231 if (QDF_IS_STATUS_ERROR(status)) {
13232 hdd_err("Failed to init cpuhp; status:%u", status);
13233 goto event_deinit;
13234 }
13235
13236 status = qdf_trace_spin_lock_init();
13237 if (QDF_IS_STATUS_ERROR(status)) {
13238 hdd_err("Failed to init spinlock; status:%u", status);
13239 goto cpuhp_deinit;
13240 }
13241
13242 qdf_trace_init();
13243 qdf_register_debugcb_init();
13244
13245 return QDF_STATUS_SUCCESS;
13246
13247cpuhp_deinit:
13248 qdf_cpuhp_deinit();
13249event_deinit:
13250 qdf_event_list_destroy();
13251 qdf_mc_timer_manager_exit();
13252 qdf_mem_exit();
13253 qdf_lock_stats_deinit();
13254 qdf_debugfs_exit();
13255print_deinit:
13256 hdd_qdf_print_deinit();
13257
13258exit:
13259 return status;
13260}
13261
13262static void hdd_qdf_deinit(void)
13263{
13264 /* currently, no debugcb deinit */
13265
13266 qdf_trace_deinit();
13267
13268 /* currently, no trace spinlock deinit */
13269
13270 qdf_cpuhp_deinit();
13271 qdf_event_list_destroy();
13272 qdf_mc_timer_manager_exit();
13273 qdf_mem_exit();
13274 qdf_lock_stats_deinit();
13275 qdf_debugfs_exit();
13276 hdd_qdf_print_deinit();
13277}
Dustin Brownf0f70562018-09-14 10:29:38 -070013278
13279/**
13280 * hdd_driver_load() - Perform the driver-level load operation
13281 *
13282 * Note: this is used in both static and DLKM driver builds
13283 *
13284 * Return: Errno
13285 */
13286static int hdd_driver_load(void)
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013287{
Dustin Brown21a1d462018-07-31 15:13:06 -070013288 struct hdd_driver *hdd_driver = hdd_driver_get();
Dustin Brownd585cb32018-09-12 17:12:23 -070013289 QDF_STATUS status;
Dustin Brownf0f70562018-09-14 10:29:38 -070013290 int errno;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013291
Rajeev Kumare555e2d2018-09-17 11:52:37 -070013292 pr_err("%s: Loading driver v%s\n",
Dustin Brownab482ac2017-06-09 17:00:44 -070013293 WLAN_MODULE_NAME,
Rajeev Kumare555e2d2018-09-17 11:52:37 -070013294 g_wlan_driver_version);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013295
Dustin Browna2a39dc2018-09-17 15:29:59 -070013296 status = hdd_qdf_init();
13297 if (QDF_IS_STATUS_ERROR(status)) {
13298 errno = qdf_status_to_os_return(status);
13299 goto exit;
13300 }
13301
Dustin Brown21a1d462018-07-31 15:13:06 -070013302 status = hdd_driver_ctx_init(hdd_driver);
13303 if (QDF_IS_STATUS_ERROR(status)) {
13304 hdd_err("Failed to init driver context; status:%u", status);
13305 errno = qdf_status_to_os_return(status);
13306 goto qdf_deinit;
13307 }
13308
13309 status = dsc_driver_trans_start(hdd_driver->dsc_driver, "load");
13310 QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
13311 if (QDF_IS_STATUS_ERROR(status)) {
13312 errno = qdf_status_to_os_return(status);
13313 goto hdd_driver_deinit;
13314 }
13315
Dustin Brownf0f70562018-09-14 10:29:38 -070013316 errno = hdd_init();
13317 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013318 hdd_err("Failed to init HDD; errno:%d", errno);
Dustin Brown21a1d462018-07-31 15:13:06 -070013319 goto trans_stop;
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013320 }
13321
Dustin Brownd585cb32018-09-12 17:12:23 -070013322 status = hdd_component_init();
13323 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013324 hdd_err("Failed to init components; status:%u", status);
Dustin Brownf0f70562018-09-14 10:29:38 -070013325 errno = qdf_status_to_os_return(status);
Dustin Brownd585cb32018-09-12 17:12:23 -070013326 goto hdd_deinit;
13327 }
Mukul Sharmad75a6672017-06-22 15:40:53 +053013328
Dustin Brownf0f70562018-09-14 10:29:38 -070013329 status = qdf_wake_lock_create(&wlan_wake_lock, "wlan");
13330 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013331 hdd_err("Failed to create wake lock; status:%u", status);
Dustin Brownf0f70562018-09-14 10:29:38 -070013332 errno = qdf_status_to_os_return(status);
13333 goto comp_deinit;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013334 }
13335
Dustin Brownf0f70562018-09-14 10:29:38 -070013336 hdd_set_conparam(con_mode);
13337
Dustin Brownf0f70562018-09-14 10:29:38 -070013338 errno = wlan_hdd_state_ctrl_param_create();
13339 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013340 hdd_err("Failed to create ctrl param; errno:%d", errno);
Dustin Brown4b9dbe62018-09-14 15:41:11 -070013341 goto wakelock_destroy;
13342 }
13343
Dustin Brown25843ad2018-09-17 14:54:33 -070013344 errno = pld_init();
13345 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013346 hdd_err("Failed to init PLD; errno:%d", errno);
Dustin Brown25843ad2018-09-17 14:54:33 -070013347 goto param_destroy;
13348 }
13349
Dustin Brown21a1d462018-07-31 15:13:06 -070013350 hdd_driver->state = driver_state_loaded;
13351 dsc_driver_trans_stop(hdd_driver->dsc_driver);
13352
13353 /* psoc probe can happen in registration; do after 'load' transition */
Dustin Brown4b9dbe62018-09-14 15:41:11 -070013354 errno = wlan_hdd_register_driver();
13355 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013356 hdd_err("Failed to register driver; errno:%d", errno);
Dustin Brown25843ad2018-09-17 14:54:33 -070013357 goto pld_deinit;
Sachin Ahuja16904db2017-12-13 19:56:57 +053013358 }
13359
Dustin Browna2a39dc2018-09-17 15:29:59 -070013360 hdd_debug("%s: driver loaded", WLAN_MODULE_NAME);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013361
13362 return 0;
Dustin Brownd585cb32018-09-12 17:12:23 -070013363
Dustin Brown25843ad2018-09-17 14:54:33 -070013364pld_deinit:
Dustin Brown21a1d462018-07-31 15:13:06 -070013365 status = dsc_driver_trans_start(hdd_driver->dsc_driver, "unload");
13366 QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
13367
Dustin Brown25843ad2018-09-17 14:54:33 -070013368 pld_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070013369
Dustin Brown4b9dbe62018-09-14 15:41:11 -070013370param_destroy:
13371 wlan_hdd_state_ctrl_param_destroy();
Dustin Brownf0f70562018-09-14 10:29:38 -070013372wakelock_destroy:
Anurag Chouhana37b5b72016-02-21 14:53:42 +053013373 qdf_wake_lock_destroy(&wlan_wake_lock);
Dustin Brownf0f70562018-09-14 10:29:38 -070013374comp_deinit:
Dustin Brownd585cb32018-09-12 17:12:23 -070013375 hdd_component_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013376hdd_deinit:
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013377 hdd_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070013378trans_stop:
13379 hdd_driver->state = driver_state_deinit;
13380 dsc_driver_trans_stop(hdd_driver->dsc_driver);
13381hdd_driver_deinit:
13382 hdd_driver_ctx_deinit(hdd_driver);
Dustin Browna2a39dc2018-09-17 15:29:59 -070013383qdf_deinit:
13384 hdd_qdf_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013385
Dustin Brown25843ad2018-09-17 14:54:33 -070013386exit:
Dustin Brownf0f70562018-09-14 10:29:38 -070013387 return errno;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013388}
13389
13390/**
Dustin Brownf0f70562018-09-14 10:29:38 -070013391 * hdd_driver_unload() - Performs the driver-level unload operation
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013392 *
Dustin Brownf0f70562018-09-14 10:29:38 -070013393 * Note: this is used in both static and DLKM driver builds
13394 *
13395 * Return: None
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013396 */
Dustin Brownf0f70562018-09-14 10:29:38 -070013397static void hdd_driver_unload(void)
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013398{
Dustin Brown21a1d462018-07-31 15:13:06 -070013399 struct hdd_driver *hdd_driver = hdd_driver_get();
Will Huang36049722018-04-13 11:48:51 +080013400 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Dustin Brown21a1d462018-07-31 15:13:06 -070013401 QDF_STATUS status;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +053013402
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013403 pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
13404 QWLAN_VERSIONSTR);
13405
Dustin Brown21a1d462018-07-31 15:13:06 -070013406 status = dsc_driver_trans_start_wait(hdd_driver->dsc_driver, "unload");
13407 QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
13408 if (QDF_IS_STATUS_ERROR(status)) {
13409 hdd_err("Unable to unload wlan; status:%u", status);
Arunk Khandavalli830c9692018-03-22 12:17:40 +053013410 return;
Dustin Brown21a1d462018-07-31 15:13:06 -070013411 }
13412
13413 dsc_driver_wait_for_ops(hdd_driver->dsc_driver);
13414
13415 if (!hdd_wait_for_recovery_completion()) {
13416 dsc_driver_trans_stop(hdd_driver->dsc_driver);
13417 return;
13418 }
Arunk Khandavalli07ec8f62016-09-27 21:51:01 +053013419
Will Huangba035ec2018-07-05 11:13:30 +080013420 cds_set_driver_loaded(false);
13421 cds_set_unload_in_progress(true);
13422
13423 if (!cds_wait_for_external_threads_completion(__func__))
13424 hdd_warn("External threads are still active attempting "
13425 "driver unload anyway");
13426
Rajeev Kumar3505ae52018-05-10 18:44:45 -070013427 if (hdd_ctx)
Dustin Brown4c663222018-10-23 14:19:36 -070013428 hdd_psoc_idle_timer_stop(hdd_ctx);
Will Huang36049722018-04-13 11:48:51 +080013429
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013430 wlan_hdd_unregister_driver();
Dustin Brown25843ad2018-09-17 14:54:33 -070013431 pld_deinit();
Dustin Brown4b9dbe62018-09-14 15:41:11 -070013432 wlan_hdd_state_ctrl_param_destroy();
Dustin Brownf0f70562018-09-14 10:29:38 -070013433 hdd_set_conparam(0);
Anurag Chouhana37b5b72016-02-21 14:53:42 +053013434 qdf_wake_lock_destroy(&wlan_wake_lock);
Dustin Brownd585cb32018-09-12 17:12:23 -070013435 hdd_component_deinit();
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013436 hdd_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070013437
13438 hdd_driver->state = driver_state_deinit;
13439 dsc_driver_trans_stop(hdd_driver->dsc_driver);
Dustin Brown623e7e32018-09-05 14:27:50 -070013440
Dustin Brown21a1d462018-07-31 15:13:06 -070013441 hdd_driver_ctx_deinit(hdd_driver);
13442
Dustin Browna2a39dc2018-09-17 15:29:59 -070013443 hdd_qdf_deinit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013444}
13445
Arun Khandavallifae92942016-08-01 13:31:08 +053013446#ifndef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013447/**
Arun Khandavallifae92942016-08-01 13:31:08 +053013448 * wlan_boot_cb() - Wlan boot callback
13449 * @kobj: object whose directory we're creating the link in.
13450 * @attr: attribute the user is interacting with
13451 * @buff: the buffer containing the user data
13452 * @count: number of bytes in the buffer
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013453 *
Arun Khandavallifae92942016-08-01 13:31:08 +053013454 * This callback is invoked when the fs is ready to start the
13455 * wlan driver initialization.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013456 *
Arun Khandavallifae92942016-08-01 13:31:08 +053013457 * Return: 'count' on success or a negative error code in case of failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013458 */
Arun Khandavallifae92942016-08-01 13:31:08 +053013459static ssize_t wlan_boot_cb(struct kobject *kobj,
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013460 struct kobj_attribute *attr,
13461 const char *buf,
13462 size_t count)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013463{
Arun Khandavallifae92942016-08-01 13:31:08 +053013464
Arun Khandavallifae92942016-08-01 13:31:08 +053013465 if (wlan_loader->loaded_state) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013466 hdd_err("wlan driver already initialized");
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013467 return -EALREADY;
Arun Khandavallifae92942016-08-01 13:31:08 +053013468 }
13469
Dustin Brownf0f70562018-09-14 10:29:38 -070013470 if (hdd_driver_load())
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013471 return -EIO;
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013472
13473 wlan_loader->loaded_state = MODULE_INITIALIZED;
Arun Khandavallifae92942016-08-01 13:31:08 +053013474
13475 return count;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013476}
Arun Khandavallifae92942016-08-01 13:31:08 +053013477
13478/**
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013479 * hdd_sysfs_cleanup() - cleanup sysfs
13480 *
13481 * Return: None
13482 *
13483 */
13484static void hdd_sysfs_cleanup(void)
13485{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013486 /* remove from group */
13487 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
13488 sysfs_remove_group(wlan_loader->boot_wlan_obj,
13489 wlan_loader->attr_group);
13490
13491 /* unlink the object from parent */
13492 kobject_del(wlan_loader->boot_wlan_obj);
13493
13494 /* free the object */
13495 kobject_put(wlan_loader->boot_wlan_obj);
13496
13497 kfree(wlan_loader->attr_group);
13498 kfree(wlan_loader);
13499
13500 wlan_loader = NULL;
13501}
13502
13503/**
Arun Khandavallifae92942016-08-01 13:31:08 +053013504 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
13505 * ready
13506 *
13507 * This is creates the syfs entry boot_wlan. Which shall be invoked
13508 * when the filesystem is ready.
13509 *
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013510 * QDF API cannot be used here since this function is called even before
13511 * initializing WLAN driver.
13512 *
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070013513 * Return: 0 for success, errno on failure
Arun Khandavallifae92942016-08-01 13:31:08 +053013514 */
13515static int wlan_init_sysfs(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013516{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013517 int ret = -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053013518
13519 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070013520 if (!wlan_loader)
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013521 return -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053013522
13523 wlan_loader->boot_wlan_obj = NULL;
13524 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
13525 GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070013526 if (!wlan_loader->attr_group)
Arun Khandavallifae92942016-08-01 13:31:08 +053013527 goto error_return;
Arun Khandavallifae92942016-08-01 13:31:08 +053013528
13529 wlan_loader->loaded_state = 0;
13530 wlan_loader->attr_group->attrs = attrs;
13531
Qun Zhang4a83a462018-09-11 16:28:51 +080013532 wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME,
Arun Khandavallifae92942016-08-01 13:31:08 +053013533 kernel_kobj);
13534 if (!wlan_loader->boot_wlan_obj) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013535 hdd_err("sysfs create and add failed");
Arun Khandavallifae92942016-08-01 13:31:08 +053013536 goto error_return;
13537 }
13538
13539 ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
13540 wlan_loader->attr_group);
13541 if (ret) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013542 hdd_err("sysfs create group failed; errno:%d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053013543 goto error_return;
13544 }
13545
13546 return 0;
13547
13548error_return:
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013549 hdd_sysfs_cleanup();
Arun Khandavallifae92942016-08-01 13:31:08 +053013550
13551 return ret;
13552}
13553
13554/**
13555 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
13556 *
13557 * Return: 0 on success or errno on failure
13558 */
13559static int wlan_deinit_sysfs(void)
13560{
Arun Khandavallifae92942016-08-01 13:31:08 +053013561 if (!wlan_loader) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013562 hdd_err("wlan_loader is null");
Arun Khandavallifae92942016-08-01 13:31:08 +053013563 return -EINVAL;
13564 }
13565
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013566 hdd_sysfs_cleanup();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013567 return 0;
13568}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013569
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013570#endif /* MODULE */
Arun Khandavallifae92942016-08-01 13:31:08 +053013571
13572#ifdef MODULE
13573/**
Dustin Brownf0f70562018-09-14 10:29:38 -070013574 * hdd_module_init() - Module init helper
Arun Khandavallifae92942016-08-01 13:31:08 +053013575 *
13576 * Module init helper function used by both module and static driver.
13577 *
13578 * Return: 0 for success, errno on failure
13579 */
13580static int hdd_module_init(void)
13581{
Dustin Brownf0f70562018-09-14 10:29:38 -070013582 if (hdd_driver_load())
Dustin Brownab482ac2017-06-09 17:00:44 -070013583 return -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053013584
Dustin Brownab482ac2017-06-09 17:00:44 -070013585 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053013586}
13587#else
13588static int __init hdd_module_init(void)
13589{
13590 int ret = -EINVAL;
13591
13592 ret = wlan_init_sysfs();
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070013593 if (ret)
Dustin Browna2a39dc2018-09-17 15:29:59 -070013594 hdd_err("Failed to create sysfs entry");
Arun Khandavallifae92942016-08-01 13:31:08 +053013595
13596 return ret;
13597}
13598#endif
13599
13600
13601#ifdef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013602/**
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013603 * hdd_module_exit() - Exit function
13604 *
13605 * This is the driver exit point (invoked when module is unloaded using rmmod)
13606 *
13607 * Return: None
13608 */
13609static void __exit hdd_module_exit(void)
13610{
Dustin Brownf0f70562018-09-14 10:29:38 -070013611 hdd_driver_unload();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013612}
Arun Khandavallifae92942016-08-01 13:31:08 +053013613#else
13614static void __exit hdd_module_exit(void)
13615{
Dustin Brownf0f70562018-09-14 10:29:38 -070013616 hdd_driver_unload();
Arun Khandavallifae92942016-08-01 13:31:08 +053013617 wlan_deinit_sysfs();
13618}
13619#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013620
Srinivas Girigowda841da292018-02-21 16:33:00 -080013621static int fwpath_changed_handler(const char *kmessage,
13622 const struct kernel_param *kp)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013623{
13624 return param_set_copystring(kmessage, kp);
13625}
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013626
Nirav Shah73713f72018-05-17 14:50:41 +053013627#ifdef FEATURE_MONITOR_MODE_SUPPORT
13628static bool is_monitor_mode_supported(void)
13629{
13630 return true;
13631}
13632#else
13633static bool is_monitor_mode_supported(void)
13634{
13635 pr_err("Monitor mode not supported!");
13636 return false;
13637}
13638#endif
13639
13640#ifdef WLAN_FEATURE_EPPING
13641static bool is_epping_mode_supported(void)
13642{
13643 return true;
13644}
13645#else
13646static bool is_epping_mode_supported(void)
13647{
13648 pr_err("Epping mode not supported!");
13649 return false;
13650}
13651#endif
13652
Ryan Hsu6e9db0b2018-06-01 10:45:51 -070013653#ifdef QCA_WIFI_FTM
13654static bool is_ftm_mode_supported(void)
13655{
13656 return true;
13657}
13658#else
13659static bool is_ftm_mode_supported(void)
13660{
13661 pr_err("FTM mode not supported!");
13662 return false;
13663}
13664#endif
13665
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013666/**
13667 * is_con_mode_valid() check con mode is valid or not
13668 * @mode: global con mode
13669 *
13670 * Return: TRUE on success FALSE on failure
13671 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080013672static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013673{
13674 switch (mode) {
13675 case QDF_GLOBAL_MONITOR_MODE:
Nirav Shah73713f72018-05-17 14:50:41 +053013676 return is_monitor_mode_supported();
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013677 case QDF_GLOBAL_EPPING_MODE:
Nirav Shah73713f72018-05-17 14:50:41 +053013678 return is_epping_mode_supported();
13679 case QDF_GLOBAL_FTM_MODE:
Ryan Hsu6e9db0b2018-06-01 10:45:51 -070013680 return is_ftm_mode_supported();
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013681 case QDF_GLOBAL_MISSION_MODE:
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013682 return true;
13683 default:
13684 return false;
13685 }
13686}
13687
Dustin Brown27cd9942017-09-27 16:11:44 -070013688static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080013689 enum QDF_GLOBAL_MODE curr_mode)
Dustin Brown27cd9942017-09-27 16:11:44 -070013690{
13691 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
13692 return;
13693
13694 switch (curr_mode) {
Dustin Brown27cd9942017-09-27 16:11:44 -070013695 case QDF_GLOBAL_MONITOR_MODE:
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053013696 hdd_info("Release wakelock for monitor mode!");
13697 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
13698 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
Dundi Raviteja0a2a65b2018-04-30 12:34:11 +053013699 /* fallthrough */
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053013700 case QDF_GLOBAL_MISSION_MODE:
Dustin Brown27cd9942017-09-27 16:11:44 -070013701 case QDF_GLOBAL_FTM_MODE:
13702 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Dustin Brown07901ec2018-09-07 11:02:41 -070013703 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
Dustin Browndb2a8be2017-12-20 11:49:56 -080013704 hdd_stop_all_adapters(hdd_ctx);
Ashish Kumar Dhanotiya6ff329e2018-10-05 20:38:10 +053013705 hdd_deinit_all_adapters(hdd_ctx, false);
Dustin Brown27cd9942017-09-27 16:11:44 -070013706
Dustin Brown27cd9942017-09-27 16:11:44 -070013707 break;
13708 default:
13709 break;
13710 }
13711}
13712
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013713static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080013714 enum QDF_GLOBAL_MODE curr_mode)
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013715{
Ashish Kumar Dhanotiya00243132017-01-24 16:37:34 +053013716 int driver_status;
13717
13718 driver_status = hdd_ctx->driver_status;
13719
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013720 switch (curr_mode) {
13721 case QDF_GLOBAL_MISSION_MODE:
13722 case QDF_GLOBAL_MONITOR_MODE:
13723 case QDF_GLOBAL_FTM_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013724 hdd_close_all_adapters(hdd_ctx, false);
13725 break;
13726 case QDF_GLOBAL_EPPING_MODE:
13727 epping_disable();
13728 epping_close();
13729 break;
13730 default:
13731 return;
13732 }
13733}
13734
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013735static int
13736hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode)
13737{
13738 int mode;
13739 int errno;
13740
Dustin Brown62743f42018-10-24 14:53:18 -070013741 *out_mode = QDF_GLOBAL_MAX_MODE;
13742
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013743 errno = kstrtoint(mode_str, 0, &mode);
13744 if (!errno)
13745 *out_mode = (enum QDF_GLOBAL_MODE)mode;
13746
13747 return errno;
13748}
13749
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013750/**
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013751 * __con_mode_handler() - Handles module param con_mode change
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013752 * @kmessage: con mode name on which driver to be bring up
13753 * @kp: The associated kernel parameter
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013754 * @hdd_ctx: Pointer to the global HDD context
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013755 *
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013756 * This function is invoked when user updates con mode using sys entry,
13757 * to initialize and bring-up driver in that specific mode.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013758 *
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013759 * Return: Errno
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013760 */
Srinivas Girigowda841da292018-02-21 16:33:00 -080013761static int __con_mode_handler(const char *kmessage,
13762 const struct kernel_param *kp,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013763 struct hdd_context *hdd_ctx)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013764{
Jeff Johnson876c1a62017-12-12 10:43:07 -080013765 enum QDF_GLOBAL_MODE curr_mode;
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013766 enum QDF_GLOBAL_MODE next_mode;
13767 int errno;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013768
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013769 hdd_info("Driver mode changing to %s", kmessage);
Dustin Brownab6029b2017-05-24 13:04:19 -070013770
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013771 errno = wlan_hdd_validate_context(hdd_ctx);
13772 if (errno)
13773 return errno;
13774
13775 errno = hdd_parse_driver_mode(kmessage, &next_mode);
13776 if (errno) {
13777 hdd_err_rl("Failed to parse driver mode '%s'", kmessage);
13778 return errno;
13779 }
13780
13781 if (!is_con_mode_valid(next_mode)) {
13782 hdd_err_rl("Requested driver mode is invalid");
13783 return -EINVAL;
13784 }
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013785
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053013786 qdf_atomic_set(&hdd_ctx->con_mode_flag, 1);
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053013787 mutex_lock(&hdd_init_deinit_lock);
Arun Khandavallifae92942016-08-01 13:31:08 +053013788
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013789 curr_mode = hdd_get_conparam();
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013790 if (curr_mode == next_mode) {
13791 hdd_err_rl("Driver is already in the requested mode");
13792 errno = 0;
13793 goto unlock;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013794 }
13795
Dustin Brown27cd9942017-09-27 16:11:44 -070013796 /* ensure adapters are stopped */
13797 hdd_stop_present_mode(hdd_ctx, curr_mode);
13798
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013799 errno = hdd_wlan_stop_modules(hdd_ctx, true);
13800 if (errno) {
Arun Khandavallifae92942016-08-01 13:31:08 +053013801 hdd_err("Stop wlan modules failed");
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013802 goto unlock;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013803 }
13804
Dustin Browndd4e50f2018-05-24 15:43:42 -070013805 /* Cleanup present mode before switching to new mode */
13806 hdd_cleanup_present_mode(hdd_ctx, curr_mode);
Ashish Kumar Dhanotiyacda57662017-08-14 14:45:25 +053013807
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013808 hdd_set_conparam(next_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013809
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013810 errno = hdd_wlan_start_modules(hdd_ctx, false);
13811 if (errno) {
13812 hdd_err("Start wlan modules failed: %d", errno);
13813 goto unlock;
Arun Khandavallifae92942016-08-01 13:31:08 +053013814 }
13815
jitiphil7af5cf22018-10-26 16:06:27 +053013816 errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode);
13817 if (errno) {
13818 hdd_err("Failed to open adapters");
13819 goto unlock;
13820 }
13821
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013822 if (next_mode == QDF_GLOBAL_MONITOR_MODE) {
Dustin Browne7e71d32018-05-11 16:00:08 -070013823 struct hdd_adapter *adapter =
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013824 hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
Dustin Browne7e71d32018-05-11 16:00:08 -070013825
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013826 QDF_BUG(adapter);
Dustin Browne7e71d32018-05-11 16:00:08 -070013827 if (!adapter) {
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013828 hdd_err("Failed to get monitor adapter");
13829 goto unlock;
Dustin Browne7e71d32018-05-11 16:00:08 -070013830 }
13831
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013832 errno = hdd_start_adapter(adapter);
13833 if (errno) {
13834 hdd_err("Failed to start monitor adapter");
13835 goto unlock;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013836 }
Arun Khandavallifae92942016-08-01 13:31:08 +053013837
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013838 hdd_info("Acquire wakelock for monitor mode");
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053013839 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
13840 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
13841 }
13842
Dustin Brown20024e32018-01-03 12:34:58 -080013843 /* con_mode is a global module parameter */
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013844 con_mode = next_mode;
13845 hdd_info("Driver mode successfully changed to %s", kmessage);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013846
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013847 errno = 0;
13848
13849unlock:
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053013850 mutex_unlock(&hdd_init_deinit_lock);
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053013851 qdf_atomic_set(&hdd_ctx->con_mode_flag, 0);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013852
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013853 return errno;
13854}
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013855
Srinivas Girigowda841da292018-02-21 16:33:00 -080013856static int con_mode_handler(const char *kmessage, const struct kernel_param *kp)
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013857{
Dustin Brown67d30412018-09-20 12:10:22 -070013858 struct hdd_driver *hdd_driver = hdd_driver_get();
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013859 struct hdd_context *hdd_ctx;
Dustin Brown67d30412018-09-20 12:10:22 -070013860 QDF_STATUS status;
13861 int errno;
13862
13863 hdd_enter();
13864
Dustin Brown13fa9872018-11-13 10:57:45 -080013865 /* This handler will be invoked before module init when the wlan driver
13866 * is loaded using 'insmod wlan.ko con_mode=5' for example. Return
13867 * success in this case, as module init will bring up the correct
13868 * con_mode when it runs.
13869 */
13870 if (hdd_driver->state == driver_state_uninit)
13871 return 0;
13872
Dustin Brown67d30412018-09-20 12:10:22 -070013873 status = dsc_driver_trans_start_wait(hdd_driver->dsc_driver,
13874 "mode change");
13875 if (QDF_IS_STATUS_ERROR(status)) {
13876 hdd_err("Failed to start 'mode change'; status:%u", status);
13877 errno = qdf_status_to_os_return(status);
13878 goto exit;
13879 }
13880
13881 dsc_driver_wait_for_ops(hdd_driver->dsc_driver);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013882
13883 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Dustin Brown67d30412018-09-20 12:10:22 -070013884 errno = wlan_hdd_validate_context(hdd_ctx);
13885 if (errno)
13886 goto trans_stop;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013887
Ashish Kumar Dhanotiya759b3272018-05-18 17:49:46 +053013888 if (!cds_wait_for_external_threads_completion(__func__)) {
13889 hdd_warn("External threads are still active, can not change mode");
Dustin Brown67d30412018-09-20 12:10:22 -070013890 errno = -EAGAIN;
13891 goto trans_stop;
Ashish Kumar Dhanotiya759b3272018-05-18 17:49:46 +053013892 }
13893
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013894 cds_ssr_protect(__func__);
Dustin Brown67d30412018-09-20 12:10:22 -070013895 errno = __con_mode_handler(kmessage, kp, hdd_ctx);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013896 cds_ssr_unprotect(__func__);
13897
Dustin Brown67d30412018-09-20 12:10:22 -070013898trans_stop:
13899 dsc_driver_trans_stop(hdd_driver->dsc_driver);
13900
13901exit:
13902 hdd_exit();
13903
13904 return errno;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013905}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013906
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053013907static int con_mode_handler_ftm(const char *kmessage,
Srinivas Girigowda841da292018-02-21 16:33:00 -080013908 const struct kernel_param *kp)
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053013909{
13910 int ret;
13911
13912 ret = param_set_int(kmessage, kp);
13913
13914 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
13915 pr_err("Only FTM mode supported!");
13916 return -ENOTSUPP;
13917 }
13918
13919 hdd_set_conparam(con_mode_ftm);
13920 con_mode = con_mode_ftm;
13921
13922 return ret;
13923}
13924
Nirav Shah73713f72018-05-17 14:50:41 +053013925#ifdef FEATURE_MONITOR_MODE_SUPPORT
Ravi Joshia307f632017-07-17 23:41:41 -070013926static int con_mode_handler_monitor(const char *kmessage,
Srinivas Girigowda841da292018-02-21 16:33:00 -080013927 const struct kernel_param *kp)
Ravi Joshia307f632017-07-17 23:41:41 -070013928{
13929 int ret;
13930
13931 ret = param_set_int(kmessage, kp);
13932
13933 if (con_mode_monitor != QDF_GLOBAL_MONITOR_MODE) {
13934 pr_err("Only Monitor mode supported!");
13935 return -ENOTSUPP;
13936 }
13937
13938 hdd_set_conparam(con_mode_monitor);
13939 con_mode = con_mode_monitor;
13940
13941 return ret;
13942}
Nirav Shah73713f72018-05-17 14:50:41 +053013943#endif
Ravi Joshia307f632017-07-17 23:41:41 -070013944
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013945/**
13946 * hdd_get_conparam() - driver exit point
13947 *
13948 * This is the driver exit point (invoked when module is unloaded using rmmod)
13949 *
Jeff Johnson876c1a62017-12-12 10:43:07 -080013950 * Return: enum QDF_GLOBAL_MODE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013951 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080013952enum QDF_GLOBAL_MODE hdd_get_conparam(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013953{
Jeff Johnson876c1a62017-12-12 10:43:07 -080013954 return (enum QDF_GLOBAL_MODE) curr_con_mode;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013955}
13956
Dustin Brownf0f70562018-09-14 10:29:38 -070013957void hdd_set_conparam(int32_t con_param)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013958{
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080013959 curr_con_mode = con_param;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013960}
13961
Komal Seelamc11bb222016-01-27 18:57:10 +053013962/**
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053013963 * hdd_clean_up_pre_cac_interface() - Clean up the pre cac interface
13964 * @hdd_ctx: HDD context
13965 *
13966 * Cleans up the pre cac interface, if it exists
13967 *
13968 * Return: None
13969 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013970void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx)
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053013971{
13972 uint8_t session_id;
13973 QDF_STATUS status;
Jeff Johnson85b5c112017-08-11 15:15:23 -070013974 struct hdd_adapter *precac_adapter;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053013975
Jeff Johnson16528362018-06-14 12:34:16 -070013976 status = wlan_sap_get_pre_cac_vdev_id(hdd_ctx->mac_handle, &session_id);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053013977 if (QDF_IS_STATUS_ERROR(status)) {
13978 hdd_err("failed to get pre cac vdev id");
13979 return;
13980 }
13981
13982 precac_adapter = hdd_get_adapter_by_vdev(hdd_ctx, session_id);
13983 if (!precac_adapter) {
Jeff Johnsondd2f1fc2018-05-06 11:22:52 -070013984 hdd_err("invalid pre cac adapter");
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053013985 return;
13986 }
13987
13988 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
13989 wlan_hdd_sap_pre_cac_failure,
13990 (void *)precac_adapter);
13991 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
13992
13993}
13994
13995/**
Komal Seelamec702b02016-02-24 18:42:16 +053013996 * hdd_update_ol_config - API to update ol configuration parameters
13997 * @hdd_ctx: HDD context
Komal Seelamc11bb222016-01-27 18:57:10 +053013998 *
Komal Seelamc11bb222016-01-27 18:57:10 +053013999 * Return: void
14000 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014001static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
Komal Seelamc11bb222016-01-27 18:57:10 +053014002{
Komal Seelamec702b02016-02-24 18:42:16 +053014003 struct ol_config_info cfg;
Anurag Chouhandf2b2682016-02-29 14:15:27 +053014004 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014005 bool self_recovery = false;
14006 QDF_STATUS status;
Komal Seelamc11bb222016-01-27 18:57:10 +053014007
Komal Seelamec702b02016-02-24 18:42:16 +053014008 if (!ol_ctx)
14009 return;
14010
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014011 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
14012 if (QDF_IS_STATUS_ERROR(status))
14013 hdd_err("Failed to get self recovery ini config");
14014
14015 cfg.enable_self_recovery = self_recovery;
Komal Seelamec702b02016-02-24 18:42:16 +053014016 cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
14017 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
14018 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
Jeff Johnsonb8bf9072016-09-23 17:39:27 -070014019 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
Komal Seelamec702b02016-02-24 18:42:16 +053014020
14021 ol_init_ini_config(ol_ctx, &cfg);
14022}
14023
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014024#ifdef FEATURE_RUNTIME_PM
14025/**
14026 * hdd_populate_runtime_cfg() - populate runtime configuration
14027 * @hdd_ctx: hdd context
14028 * @cfg: pointer to the configuration memory being populated
14029 *
14030 * Return: void
14031 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014032static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014033 struct hif_config_info *cfg)
14034{
14035 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
Wu Gao66454f12018-09-26 19:55:41 +080014036 cfg->runtime_pm_delay =
14037 ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc);
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014038}
14039#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014040static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014041 struct hif_config_info *cfg)
14042{
14043}
14044#endif
14045
Komal Seelamec702b02016-02-24 18:42:16 +053014046/**
14047 * hdd_update_hif_config - API to update HIF configuration parameters
14048 * @hdd_ctx: HDD Context
14049 *
14050 * Return: void
14051 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014052static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053014053{
Anurag Chouhandf2b2682016-02-29 14:15:27 +053014054 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
Komal Seelamec702b02016-02-24 18:42:16 +053014055 struct hif_config_info cfg;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014056 bool prevent_link_down = false;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014057 bool self_recovery = false;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014058 QDF_STATUS status;
Komal Seelamec702b02016-02-24 18:42:16 +053014059
14060 if (!scn)
14061 return;
14062
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014063 status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc,
14064 &prevent_link_down);
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014065 if (QDF_IS_STATUS_ERROR(status))
14066 hdd_err("Failed to get prevent_link_down config");
14067
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014068 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
14069 if (QDF_IS_STATUS_ERROR(status))
14070 hdd_err("Failed to get self recovery ini config");
14071
14072 cfg.enable_self_recovery = self_recovery;
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014073 hdd_populate_runtime_cfg(hdd_ctx, &cfg);
Komal Seelamec702b02016-02-24 18:42:16 +053014074 hif_init_ini_config(scn, &cfg);
Dustin Brownee3e0592017-09-07 13:50:11 -070014075
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014076 if (prevent_link_down)
Dustin Brownee3e0592017-09-07 13:50:11 -070014077 hif_vote_link_up(scn);
Komal Seelamec702b02016-02-24 18:42:16 +053014078}
14079
14080/**
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014081 * hdd_update_dp_config() - Propagate config parameters to Lithium
14082 * datapath
14083 * @hdd_ctx: HDD Context
14084 *
14085 * Return: 0 for success/errno for failure
14086 */
14087static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
14088{
14089 struct cdp_config_params params;
14090 QDF_STATUS status;
jitiphil377bcc12018-10-05 19:46:08 +053014091 void *soc;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014092
jitiphil377bcc12018-10-05 19:46:08 +053014093 soc = cds_get_context(QDF_MODULE_ID_SOC);
14094 params.tso_enable = cfg_get(hdd_ctx->psoc, CFG_DP_TSO);
14095 params.lro_enable = cfg_get(hdd_ctx->psoc, CFG_DP_LRO);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014096#ifdef QCA_LL_TX_FLOW_CONTROL_V2
14097 params.tx_flow_stop_queue_threshold =
jitiphil47c3d9a2018-11-08 18:30:55 +053014098 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014099 params.tx_flow_start_queue_offset =
jitiphil47c3d9a2018-11-08 18:30:55 +053014100 cfg_get(hdd_ctx->psoc,
14101 CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014102#endif
jitiphil377bcc12018-10-05 19:46:08 +053014103 params.flow_steering_enable =
14104 cfg_get(hdd_ctx->psoc, CFG_DP_FLOW_STEERING_ENABLED);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014105 params.napi_enable = hdd_ctx->napi_enable;
14106 params.tcp_udp_checksumoffload =
jitiphil377bcc12018-10-05 19:46:08 +053014107 cfg_get(hdd_ctx->psoc,
14108 CFG_DP_TCP_UDP_CKSUM_OFFLOAD);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014109
jitiphil377bcc12018-10-05 19:46:08 +053014110 status = cdp_update_config_parameters(soc, &params);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014111 if (status) {
Dustin Browna2868622018-03-20 11:38:14 -070014112 hdd_err("Failed to attach config parameters");
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014113 return status;
14114 }
14115
14116 return 0;
14117}
14118
14119/**
Komal Seelamec702b02016-02-24 18:42:16 +053014120 * hdd_update_config() - Initialize driver per module ini parameters
14121 * @hdd_ctx: HDD Context
14122 *
14123 * API is used to initialize all driver per module configuration parameters
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014124 * Return: 0 for success, errno for failure
Komal Seelamec702b02016-02-24 18:42:16 +053014125 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014126int hdd_update_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053014127{
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014128 int ret;
14129
Wu Gao66454f12018-09-26 19:55:41 +080014130 if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc))
14131 hdd_ctx->ns_offload_enable = true;
14132
Komal Seelamec702b02016-02-24 18:42:16 +053014133 hdd_update_ol_config(hdd_ctx);
14134 hdd_update_hif_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014135 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
14136 ret = hdd_update_cds_config_ftm(hdd_ctx);
14137 else
14138 ret = hdd_update_cds_config(hdd_ctx);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080014139 ret = hdd_update_user_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014140
14141 return ret;
Komal Seelamc11bb222016-01-27 18:57:10 +053014142}
14143
Mukul Sharma9d797a02017-01-05 20:26:03 +053014144#ifdef FEATURE_WLAN_RA_FILTERING
14145/**
14146 * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
14147 * @psoc_cfg: pmo psoc Configuration
14148 * @hdd_ctx: Pointer to hdd context
14149 *
14150 * Return: none
14151 */
14152static inline void hdd_ra_populate_pmo_config(
14153 struct pmo_psoc_cfg *psoc_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014154 struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053014155{
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053014156 bool is_rate_limit_enabled;
14157 QDF_STATUS status;
14158
14159 status = ucfg_fwol_get_is_rate_limit_enabled(hdd_ctx->psoc,
14160 &is_rate_limit_enabled);
14161 if (QDF_IS_STATUS_ERROR(status))
14162 return;
14163
Mukul Sharma9d797a02017-01-05 20:26:03 +053014164 psoc_cfg->ra_ratelimit_interval =
14165 hdd_ctx->config->RArateLimitInterval;
14166 psoc_cfg->ra_ratelimit_enable =
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053014167 is_rate_limit_enabled;
Mukul Sharma9d797a02017-01-05 20:26:03 +053014168}
14169#else
14170static inline void hdd_ra_populate_pmo_config(
14171 struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014172 struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053014173{
14174}
14175#endif
Will Huang3cd2b7c2017-11-17 13:16:56 +080014176
Mukul Sharma9d797a02017-01-05 20:26:03 +053014177/**
14178 * hdd_update_pmo_config - API to update pmo configuration parameters
14179 * @hdd_ctx: HDD context
14180 *
14181 * Return: void
14182 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014183static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053014184{
Mukul Sharma9d797a02017-01-05 20:26:03 +053014185 struct pmo_psoc_cfg psoc_cfg;
14186 QDF_STATUS status;
Wu Gao66454f12018-09-26 19:55:41 +080014187 enum pmo_wow_enable_type wow_enable;
14188
14189 ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg);
Mukul Sharma9d797a02017-01-05 20:26:03 +053014190
14191 /*
14192 * Value of hdd_ctx->wowEnable can be,
14193 * 0 - Disable both magic pattern match and pattern byte match.
14194 * 1 - Enable magic pattern match on all interfaces.
14195 * 2 - Enable pattern byte match on all interfaces.
14196 * 3 - Enable both magic patter and pattern byte match on
14197 * all interfaces.
14198 */
Wu Gao66454f12018-09-26 19:55:41 +080014199 wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc);
14200 psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false;
Mukul Sharma9d797a02017-01-05 20:26:03 +053014201 psoc_cfg.ptrn_match_enable_all_vdev =
Wu Gao66454f12018-09-26 19:55:41 +080014202 (wow_enable & 0x02) ? true : false;
Dustin Brownb9987af2018-03-01 17:15:11 -080014203 psoc_cfg.packet_filter_enabled = !hdd_ctx->config->disablePacketFilter;
Mukul Sharma9d797a02017-01-05 20:26:03 +053014204 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
Will Huang3cd2b7c2017-11-17 13:16:56 +080014205 psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
Bala Venkatesh46e29032018-11-14 18:24:55 +053014206 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
14207 &psoc_cfg.sta_max_li_mod_dtim);
14208
Mukul Sharma9d797a02017-01-05 20:26:03 +053014209
14210 hdd_ra_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9223f232017-03-08 18:42:27 +053014211 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053014212
Dustin Brown1dbefe62018-09-11 16:32:03 -070014213 status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg);
Dustin Brownb9987af2018-03-01 17:15:11 -080014214 if (QDF_IS_STATUS_ERROR(status))
14215 hdd_err("failed pmo psoc configuration; status:%d", status);
14216
14217 return qdf_status_to_os_return(status);
Mukul Sharma9d797a02017-01-05 20:26:03 +053014218}
14219
Abhishek Singhb20db962017-03-03 21:28:46 +053014220#ifdef FEATURE_WLAN_SCAN_PNO
14221static inline void hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
Wu Gao1ab05582018-11-08 16:22:49 +080014222 struct hdd_context *hdd_ctx)
Abhishek Singhb20db962017-03-03 21:28:46 +053014223{
Varun Reddy Yeturubba32e92017-09-06 13:31:40 -070014224 struct nlo_mawc_params *mawc_cfg = &pno_cfg->mawc_params;
Wu Gao1ab05582018-11-08 16:22:49 +080014225 struct hdd_config *cfg = hdd_ctx->config;
14226 bool mawc_enabled;
Varun Reddy Yeturubba32e92017-09-06 13:31:40 -070014227
Abhishek Singhb20db962017-03-03 21:28:46 +053014228 pno_cfg->channel_prediction = cfg->pno_channel_prediction;
14229 pno_cfg->top_k_num_of_channels = cfg->top_k_num_of_channels;
14230 pno_cfg->stationary_thresh = cfg->stationary_thresh;
14231 pno_cfg->adaptive_dwell_mode = cfg->adaptive_dwell_mode_enabled;
14232 pno_cfg->channel_prediction_full_scan =
14233 cfg->channel_prediction_full_scan;
Wu Gao1ab05582018-11-08 16:22:49 +080014234
14235 ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled);
14236 mawc_cfg->enable = mawc_enabled && cfg->mawc_nlo_enabled;
Varun Reddy Yeturubba32e92017-09-06 13:31:40 -070014237 mawc_cfg->exp_backoff_ratio = cfg->mawc_nlo_exp_backoff_ratio;
14238 mawc_cfg->init_scan_interval = cfg->mawc_nlo_init_scan_interval;
14239 mawc_cfg->max_scan_interval = cfg->mawc_nlo_max_scan_interval;
Abhishek Singhb20db962017-03-03 21:28:46 +053014240}
14241#else
14242static inline void
14243hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
Wu Gao1ab05582018-11-08 16:22:49 +080014244 struct hdd_context *hdd_ctx)
Abhishek Singhb20db962017-03-03 21:28:46 +053014245{
Abhishek Singhb20db962017-03-03 21:28:46 +053014246}
14247#endif
14248
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014249void hdd_update_ie_whitelist_attr(struct probe_req_whitelist_attr *ie_whitelist,
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014250 struct hdd_context *hdd_ctx)
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014251{
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014252 struct wlan_fwol_ie_whitelist whitelist = {0};
14253 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014254 QDF_STATUS status;
14255 bool is_ie_whitelist_enable = false;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014256 uint8_t i = 0;
14257
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014258 status = ucfg_fwol_get_ie_whitelist(psoc, &is_ie_whitelist_enable);
14259 if (QDF_IS_STATUS_ERROR(status)) {
14260 hdd_err("Unable to get IE whitelist param");
14261 return;
14262 }
14263
14264 ie_whitelist->white_list = is_ie_whitelist_enable;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014265 if (!ie_whitelist->white_list)
14266 return;
14267
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014268 status = ucfg_fwol_get_all_whitelist_params(psoc, &whitelist);
14269 if (QDF_IS_STATUS_ERROR(status)) {
14270 hdd_err("Unable to get all whitelist params");
14271 return;
14272 }
14273
14274 ie_whitelist->ie_bitmap[0] = whitelist.ie_bitmap_0;
14275 ie_whitelist->ie_bitmap[1] = whitelist.ie_bitmap_1;
14276 ie_whitelist->ie_bitmap[2] = whitelist.ie_bitmap_2;
14277 ie_whitelist->ie_bitmap[3] = whitelist.ie_bitmap_3;
14278 ie_whitelist->ie_bitmap[4] = whitelist.ie_bitmap_4;
14279 ie_whitelist->ie_bitmap[5] = whitelist.ie_bitmap_5;
14280 ie_whitelist->ie_bitmap[6] = whitelist.ie_bitmap_6;
14281 ie_whitelist->ie_bitmap[7] = whitelist.ie_bitmap_7;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014282
Dundi Raviteja9ab4e7b2018-09-28 14:18:28 +053014283 ie_whitelist->num_vendor_oui = whitelist.no_of_probe_req_ouis;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014284 for (i = 0; i < ie_whitelist->num_vendor_oui; i++)
Dundi Raviteja9ab4e7b2018-09-28 14:18:28 +053014285 ie_whitelist->voui[i] = whitelist.probe_req_voui[i];
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014286}
14287
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014288uint32_t hdd_limit_max_per_index_score(uint32_t per_index_score)
14289{
14290 uint8_t i, score;
14291
14292 for (i = 0; i < MAX_INDEX_PER_INI; i++) {
14293 score = WLAN_GET_SCORE_PERCENTAGE(per_index_score, i);
14294 if (score > MAX_INDEX_SCORE)
14295 WLAN_SET_SCORE_PERCENTAGE(per_index_score,
14296 MAX_INDEX_SCORE, i);
14297 }
14298
14299 return per_index_score;
14300}
14301
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014302QDF_STATUS hdd_update_score_config(
14303 struct scoring_config *score_config, struct hdd_context *hdd_ctx)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014304{
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014305 struct hdd_config *cfg = hdd_ctx->config;
gaurank kathpaliaae52c982018-10-04 01:35:18 +053014306 QDF_STATUS status;
gaurank kathpalia651abcd2018-11-12 22:41:23 +053014307 struct wlan_mlme_nss_chains vdev_ini_cfg;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014308 bool bval = false;
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014309
gaurank kathpalia651abcd2018-11-12 22:41:23 +053014310 /* Populate the nss chain params from ini for this vdev type */
14311 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
14312 QDF_STA_MODE,
14313 hdd_ctx->num_rf_chains);
14314
14315 score_config->vdev_nss_24g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ];
14316 score_config->vdev_nss_24g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ];
14317
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053014318 sme_update_score_config(hdd_ctx->mac_handle, score_config);
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014319
14320 score_config->cb_mode_24G = cfg->nChannelBondingMode24GHz;
14321 score_config->cb_mode_5G = cfg->nChannelBondingMode5GHz;
gaurank kathpaliaae52c982018-10-04 01:35:18 +053014322
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014323 if (cfg->dot11Mode == eHDD_DOT11_MODE_AUTO ||
14324 cfg->dot11Mode == eHDD_DOT11_MODE_11ax ||
14325 cfg->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)
14326 score_config->he_cap = 1;
14327
14328 if (score_config->he_cap ||
14329 cfg->dot11Mode == eHDD_DOT11_MODE_11ac ||
14330 cfg->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)
14331 score_config->vht_cap = 1;
14332
14333 if (score_config->vht_cap || cfg->dot11Mode == eHDD_DOT11_MODE_11n ||
14334 cfg->dot11Mode == eHDD_DOT11_MODE_11n_ONLY)
14335 score_config->ht_cap = 1;
14336
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014337 status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &bval);
14338 if (!QDF_IS_STATUS_SUCCESS(status))
14339 hdd_err("Failed to get vht_for_24ghz");
14340 if (score_config->vht_cap && bval)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014341 score_config->vht_24G_cap = 1;
14342
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014343 status = ucfg_mlme_get_vht_enable_tx_bf(hdd_ctx->psoc,
14344 &bval);
14345 if (!QDF_IS_STATUS_SUCCESS(status))
14346 hdd_err("unable to get vht_enable_tx_bf");
14347
14348 if (bval)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014349 score_config->beamformee_cap = 1;
14350
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053014351 return QDF_STATUS_SUCCESS;
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014352}
14353
Abhishek Singh257a9482017-03-06 16:52:39 +053014354/**
bings81fe50a2017-11-27 14:33:26 +080014355 * hdd_update_dfs_config() - API to update dfs configuration parameters.
14356 * @hdd_ctx: HDD context
14357 *
14358 * Return: 0 if success else err
14359 */
14360static int hdd_update_dfs_config(struct hdd_context *hdd_ctx)
14361{
Dustin Brown1dbefe62018-09-11 16:32:03 -070014362 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
bings81fe50a2017-11-27 14:33:26 +080014363 struct dfs_user_config dfs_cfg;
14364 QDF_STATUS status;
14365
Arif Hussain224d3812018-11-16 17:58:38 -080014366 ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc,
14367 &dfs_cfg.dfs_is_phyerr_filter_offload);
bings81fe50a2017-11-27 14:33:26 +080014368 status = ucfg_dfs_update_config(psoc, &dfs_cfg);
14369 if (QDF_IS_STATUS_ERROR(status)) {
14370 hdd_err("failed dfs psoc configuration");
14371 return -EINVAL;
14372 }
14373
14374 return 0;
14375}
14376
14377/**
Abhishek Singh257a9482017-03-06 16:52:39 +053014378 * hdd_update_scan_config - API to update scan configuration parameters
14379 * @hdd_ctx: HDD context
14380 *
14381 * Return: 0 if success else err
14382 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014383static int hdd_update_scan_config(struct hdd_context *hdd_ctx)
Abhishek Singh257a9482017-03-06 16:52:39 +053014384{
Dustin Brown1dbefe62018-09-11 16:32:03 -070014385 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Abhishek Singh257a9482017-03-06 16:52:39 +053014386 struct scan_user_cfg scan_cfg;
14387 struct hdd_config *cfg = hdd_ctx->config;
14388 QDF_STATUS status;
Wu Gaoca416ff2018-09-17 11:05:07 +080014389 uint8_t scan_bucket_thre;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014390 uint8_t select_5ghz_margin;
Wu Gao1ab05582018-11-08 16:22:49 +080014391 bool roam_prefer_5ghz;
Krunal Sonid2c33e12018-12-06 15:02:37 -080014392 uint32_t mcast_mcc_rest_time = 0;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014393
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014394 status = ucfg_mlme_get_select_5ghz_margin(hdd_ctx->psoc,
14395 &select_5ghz_margin);
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014396 if (QDF_IS_STATUS_ERROR(status)) {
14397 hdd_err("Failed to get select_5ghz_margin");
14398 return -EIO;
14399 }
Abhishek Singh257a9482017-03-06 16:52:39 +053014400
14401 scan_cfg.active_dwell = cfg->nActiveMaxChnTime;
14402 scan_cfg.passive_dwell = cfg->nPassiveMaxChnTime;
14403 scan_cfg.conc_active_dwell = cfg->nActiveMaxChnTimeConc;
14404 scan_cfg.conc_passive_dwell = cfg->nPassiveMaxChnTimeConc;
14405 scan_cfg.conc_max_rest_time = cfg->nRestTimeConc;
14406 scan_cfg.conc_min_rest_time = cfg->min_rest_time_conc;
14407 scan_cfg.conc_idle_time = cfg->idle_time_conc;
Abhishek Singh158fe252017-03-23 11:09:34 +053014408 /* convert to ms */
14409 scan_cfg.scan_cache_aging_time =
14410 cfg->scanAgingTimeout * 1000;
Wu Gao1ab05582018-11-08 16:22:49 +080014411 ucfg_mlme_is_roam_prefer_5ghz(hdd_ctx->psoc, &roam_prefer_5ghz);
14412 scan_cfg.prefer_5ghz = (uint32_t)roam_prefer_5ghz;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014413 scan_cfg.select_5ghz_margin = select_5ghz_margin;
Dustin Brown1dbefe62018-09-11 16:32:03 -070014414 ucfg_mlme_get_first_scan_bucket_threshold(hdd_ctx->psoc,
Wu Gaoca416ff2018-09-17 11:05:07 +080014415 &scan_bucket_thre);
14416 scan_cfg.scan_bucket_threshold = (int32_t)scan_bucket_thre;
Abhishek Singh158fe252017-03-23 11:09:34 +053014417 scan_cfg.rssi_cat_gap = cfg->nRssiCatGap;
Abhishek Singh257a9482017-03-06 16:52:39 +053014418 scan_cfg.scan_dwell_time_mode = cfg->scan_adaptive_dwell_mode;
Kapil Guptafa9a8c62017-04-10 15:25:40 +053014419 scan_cfg.is_snr_monitoring_enabled = cfg->fEnableSNRMonitoring;
Jeff Johnson81c00d02017-11-07 12:34:36 -080014420 scan_cfg.usr_cfg_probe_rpt_time = cfg->scan_probe_repeat_time;
14421 scan_cfg.usr_cfg_num_probes = cfg->scan_num_probes;
Abhishek Singhb58164a2017-07-19 18:47:23 +053014422 scan_cfg.is_bssid_hint_priority = cfg->is_bssid_hint_priority;
Kiran Kumar Lokered547fdd2017-09-13 17:20:55 -070014423 scan_cfg.enable_mac_spoofing = cfg->enable_mac_spoofing;
Krunal Sonid2c33e12018-12-06 15:02:37 -080014424 status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc,
14425 &mcast_mcc_rest_time);
14426 if (!QDF_IS_STATUS_SUCCESS(status)) {
14427 hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def");
14428 return -EIO;
14429 }
14430 scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time;
Wu Gao1ab05582018-11-08 16:22:49 +080014431 hdd_update_pno_config(&scan_cfg.pno_cfg, hdd_ctx);
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014432 hdd_update_ie_whitelist_attr(&scan_cfg.ie_whitelist, hdd_ctx);
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053014433
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014434 status = hdd_update_score_config(&scan_cfg.score_config, hdd_ctx);
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053014435 if (QDF_IS_STATUS_ERROR(status)) {
14436 hdd_err("Failed to update scoring config");
14437 return -EINVAL;
14438 }
Abhishek Singhb20db962017-03-03 21:28:46 +053014439
Abhishek Singh257a9482017-03-06 16:52:39 +053014440 status = ucfg_scan_update_user_config(psoc, &scan_cfg);
14441 if (status != QDF_STATUS_SUCCESS) {
14442 hdd_err("failed pmo psoc configuration");
14443 return -EINVAL;
14444 }
Liangwei Dongac3ddde2018-09-10 23:25:12 -040014445 ucfg_scan_set_global_config(
14446 psoc, SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH,
14447 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH));
Abhishek Singh257a9482017-03-06 16:52:39 +053014448
14449 return 0;
14450}
Abhishek Singh257a9482017-03-06 16:52:39 +053014451
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014452int hdd_update_components_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053014453{
14454 int ret;
14455
14456 ret = hdd_update_pmo_config(hdd_ctx);
Abhishek Singh257a9482017-03-06 16:52:39 +053014457 if (ret)
14458 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014459
Abhishek Singh257a9482017-03-06 16:52:39 +053014460 ret = hdd_update_scan_config(hdd_ctx);
Frank Liud4b2fa02017-03-29 11:46:48 +080014461 if (ret)
14462 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014463
Frank Liud4b2fa02017-03-29 11:46:48 +080014464 ret = hdd_update_tdls_config(hdd_ctx);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014465 if (ret)
14466 return ret;
14467
14468 ret = hdd_update_dp_config(hdd_ctx);
bings81fe50a2017-11-27 14:33:26 +080014469 if (ret)
14470 return ret;
14471
14472 ret = hdd_update_dfs_config(hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053014473
14474 return ret;
14475}
14476
Agrawal Ashish65634612016-08-18 13:24:32 +053014477/**
14478 * wlan_hdd_get_dfs_mode() - get ACS DFS mode
14479 * @mode : cfg80211 DFS mode
14480 *
14481 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
14482 */
14483enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
14484{
14485 switch (mode) {
14486 case DFS_MODE_ENABLE:
14487 return ACS_DFS_MODE_ENABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053014488 case DFS_MODE_DISABLE:
14489 return ACS_DFS_MODE_DISABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053014490 case DFS_MODE_DEPRIORITIZE:
14491 return ACS_DFS_MODE_DEPRIORITIZE;
Agrawal Ashish65634612016-08-18 13:24:32 +053014492 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080014493 hdd_debug("ACS dfs mode is NONE");
14494 return ACS_DFS_MODE_NONE;
Agrawal Ashish65634612016-08-18 13:24:32 +053014495 }
14496}
14497
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014498/**
14499 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
14500 * @hddctx: pointer to hdd context
14501 * @set_value: enable/disable
14502 *
14503 * When Host sends vendor command enable, FW will send *ONE* CA ind to
14504 * Host(even though it is duplicate). When Host send vendor command
14505 * disable,FW doesn't perform any action. Whenever any change in
14506 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
14507 *
14508 * return - 0 on success, appropriate error values on failure.
14509 */
Jeff Johnson16528362018-06-14 12:34:16 -070014510int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value)
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014511{
14512 QDF_STATUS status;
14513
Jeff Johnson16528362018-06-14 12:34:16 -070014514 if (0 != wlan_hdd_validate_context(hdd_ctx))
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014515 return -EAGAIN;
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014516
Jeff Johnson16528362018-06-14 12:34:16 -070014517 status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle,
14518 set_value);
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014519 if (!QDF_IS_STATUS_SUCCESS(status)) {
14520 hdd_err("Failed to send chan avoid command to SME");
14521 return -EINVAL;
14522 }
14523 return 0;
14524}
Agrawal Ashish65634612016-08-18 13:24:32 +053014525
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014526/**
14527 * hdd_set_roaming_in_progress() - to set the roaming in progress flag
14528 * @value: value to set
14529 *
14530 * This function will set the passed value to roaming in progress flag.
14531 *
14532 * Return: None
14533 */
14534void hdd_set_roaming_in_progress(bool value)
14535{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014536 struct hdd_context *hdd_ctx;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014537
14538 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14539 if (!hdd_ctx) {
14540 hdd_err("HDD context is NULL");
14541 return;
14542 }
14543
14544 hdd_ctx->roaming_in_progress = value;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080014545 hdd_debug("Roaming in Progress set to %d", value);
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014546}
14547
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053014548bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx)
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014549{
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014550 if (!hdd_ctx) {
14551 hdd_err("HDD context is NULL");
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053014552 return false;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014553 }
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080014554
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053014555 hdd_debug("roaming_in_progress = %d", hdd_ctx->roaming_in_progress);
14556
14557 return hdd_ctx->roaming_in_progress;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014558}
14559
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014560/**
14561 * hdd_is_connection_in_progress() - check if connection is in
14562 * progress
14563 * @session_id: session id
14564 * @reason: scan reject reason
14565 *
14566 * Go through each adapter and check if Connection is in progress
14567 *
14568 * Return: true if connection is in progress else false
14569 */
14570bool hdd_is_connection_in_progress(uint8_t *session_id,
14571 enum scan_reject_states *reason)
14572{
Jeff Johnson40dae4e2017-08-29 14:00:25 -070014573 struct hdd_station_ctx *hdd_sta_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -070014574 struct hdd_adapter *adapter = NULL;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014575 uint8_t sta_id = 0;
14576 uint8_t *sta_mac = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014577 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -070014578 mac_handle_t mac_handle;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014579
14580 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14581 if (!hdd_ctx) {
14582 hdd_err("HDD context is NULL");
14583 return false;
14584 }
14585
Jeff Johnson16528362018-06-14 12:34:16 -070014586 mac_handle = hdd_ctx->mac_handle;
14587
Dustin Brown920397d2017-12-13 16:27:50 -080014588 hdd_for_each_adapter(hdd_ctx, adapter) {
Tushnim Bhattacharyya929afa42018-06-01 15:04:44 -070014589 hdd_debug("Adapter with device mode %s(%d) exists",
Dustin Brown458027c2018-10-19 12:26:27 -070014590 qdf_opmode_str(adapter->device_mode),
14591 adapter->device_mode);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014592 if (((QDF_STA_MODE == adapter->device_mode)
14593 || (QDF_P2P_CLIENT_MODE == adapter->device_mode)
14594 || (QDF_P2P_DEVICE_MODE == adapter->device_mode))
14595 && (eConnectionState_Connecting ==
14596 (WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
14597 conn_info.connState)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014598 hdd_debug("%pK(%d) Connection is in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014599 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070014600 adapter->session_id);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014601 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070014602 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014603 *reason = CONNECTION_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014604 }
14605 return true;
14606 }
Archana Ramachandran62886ce2017-03-24 14:46:32 -070014607 /*
14608 * sme_neighbor_middle_of_roaming is for LFR2
14609 * hdd_is_roaming_in_progress is for LFR3
14610 */
14611 if (((QDF_STA_MODE == adapter->device_mode) &&
14612 sme_neighbor_middle_of_roaming(
Jeff Johnson16528362018-06-14 12:34:16 -070014613 mac_handle,
Jeff Johnson1b780e42017-10-31 14:11:45 -070014614 adapter->session_id)) ||
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053014615 hdd_is_roaming_in_progress(hdd_ctx)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014616 hdd_debug("%pK(%d) Reassociation in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014617 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070014618 adapter->session_id);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014619 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070014620 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014621 *reason = REASSOC_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014622 }
14623 return true;
14624 }
14625 if ((QDF_STA_MODE == adapter->device_mode) ||
14626 (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
14627 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
14628 hdd_sta_ctx =
14629 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
14630 if ((eConnectionState_Associated ==
Vignesh Viswanathan0a569292018-02-14 15:34:47 +053014631 hdd_sta_ctx->conn_info.connState)
14632 && sme_is_sta_key_exchange_in_progress(
Jeff Johnson16528362018-06-14 12:34:16 -070014633 mac_handle, adapter->session_id)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014634 sta_mac = (uint8_t *)
Jeff Johnson1e851a12017-10-28 14:36:12 -070014635 &(adapter->mac_addr.bytes[0]);
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014636 hdd_debug("client " MAC_ADDRESS_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014637 " is in middle of WPS/EAPOL exchange.",
14638 MAC_ADDR_ARRAY(sta_mac));
14639 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070014640 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014641 *reason = EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014642 }
14643 return true;
14644 }
14645 } else if ((QDF_SAP_MODE == adapter->device_mode) ||
14646 (QDF_P2P_GO_MODE == adapter->device_mode)) {
14647 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
14648 sta_id++) {
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070014649 if (!((adapter->sta_info[sta_id].in_use)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014650 && (OL_TXRX_PEER_STATE_CONN ==
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070014651 adapter->sta_info[sta_id].peer_state)))
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014652 continue;
14653
14654 sta_mac = (uint8_t *)
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070014655 &(adapter->sta_info[sta_id].
Jeff Johnsonf2356512017-10-21 16:04:12 -070014656 sta_mac.bytes[0]);
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014657 hdd_debug("client " MAC_ADDRESS_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014658 " of SAP/GO is in middle of WPS/EAPOL exchange",
14659 MAC_ADDR_ARRAY(sta_mac));
14660 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070014661 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014662 *reason = SAP_EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014663 }
14664 return true;
14665 }
14666 if (hdd_ctx->connection_in_progress) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014667 hdd_debug("AP/GO: connection is in progress");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014668 return true;
14669 }
14670 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014671 }
Dustin Brown920397d2017-12-13 16:27:50 -080014672
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014673 return false;
14674}
14675
14676/**
14677 * hdd_restart_sap() - to restart SAP in driver internally
Jeff Johnson9d295242017-08-29 14:39:48 -070014678 * @ap_adapter: Pointer to SAP struct hdd_adapter structure
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014679 *
14680 * Return: None
14681 */
Jeff Johnson9d295242017-08-29 14:39:48 -070014682void hdd_restart_sap(struct hdd_adapter *ap_adapter)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014683{
Jeff Johnson87251032017-08-29 13:31:11 -070014684 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070014685 struct hdd_hostapd_state *hostapd_state;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014686 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014687 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Jeff Johnsone4c11db2018-05-05 23:22:32 -070014688 tsap_config_t *sap_config;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014689 void *sap_ctx;
14690
14691 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
Jeff Johnson91df29d2017-10-27 19:29:50 -070014692 sap_config = &hdd_ap_ctx->sap_config;
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070014693 sap_ctx = hdd_ap_ctx->sap_context;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014694
14695 mutex_lock(&hdd_ctx->sap_lock);
14696 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
14697 wlan_hdd_del_station(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014698 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
14699 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
14700 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
14701 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053014702 qdf_wait_for_event_completion(&hostapd_state->
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014703 qdf_stop_bss_event,
Vignesh Viswanathan865daaa2018-10-11 19:30:44 +053014704 SME_CMD_START_STOP_BSS_TIMEOUT);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014705
14706 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014707 hdd_err("SAP Stop Failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014708 goto end;
14709 }
14710 }
14711 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -070014712 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -070014713 ap_adapter->device_mode, ap_adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070014714 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053014715 false);
Jeff Johnson6867ec32017-09-29 20:30:20 -070014716 hdd_err("SAP Stop Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014717
14718 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014719 hdd_err("SAP Not able to set AP IEs");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014720 wlansap_reset_sap_config_add_ie(sap_config,
14721 eUPDATE_IE_ALL);
14722 goto end;
14723 }
14724
14725 qdf_event_reset(&hostapd_state->qdf_event);
14726 if (wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
14727 sap_config,
14728 ap_adapter->dev) != QDF_STATUS_SUCCESS) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014729 hdd_err("SAP Start Bss fail");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014730 wlansap_reset_sap_config_add_ie(sap_config,
14731 eUPDATE_IE_ALL);
14732 goto end;
14733 }
14734
Jeff Johnson6867ec32017-09-29 20:30:20 -070014735 hdd_info("Waiting for SAP to start");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014736 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053014737 qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Vignesh Viswanathan865daaa2018-10-11 19:30:44 +053014738 SME_CMD_START_STOP_BSS_TIMEOUT);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014739 wlansap_reset_sap_config_add_ie(sap_config,
14740 eUPDATE_IE_ALL);
14741 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014742 hdd_err("SAP Start failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014743 goto end;
14744 }
Jeff Johnson6867ec32017-09-29 20:30:20 -070014745 hdd_err("SAP Start Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014746 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053014747 if (hostapd_state->bss_state == BSS_START) {
Dustin Brown1dbefe62018-09-11 16:32:03 -070014748 policy_mgr_incr_active_session(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014749 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070014750 ap_adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070014751 hdd_green_ap_start_state_mc(hdd_ctx,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053014752 ap_adapter->device_mode,
14753 true);
14754 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014755 }
14756end:
14757 mutex_unlock(&hdd_ctx->sap_lock);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014758}
14759
14760/**
14761 * hdd_check_and_restart_sap_with_non_dfs_acs() - Restart SAP
14762 * with non dfs acs
14763 *
14764 * Restarts SAP in non-DFS ACS mode when STA-AP mode DFS is not supported
14765 *
14766 * Return: None
14767 */
14768void hdd_check_and_restart_sap_with_non_dfs_acs(void)
14769{
Jeff Johnson9d295242017-08-29 14:39:48 -070014770 struct hdd_adapter *ap_adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014771 struct hdd_context *hdd_ctx;
Jeff Johnson2b6982c2018-05-29 14:56:11 -070014772 struct cds_context *cds_ctx;
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053014773 uint8_t restart_chan;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014774
14775 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14776 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014777 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014778 return;
14779 }
14780
14781 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
14782 if (!cds_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014783 hdd_err("Invalid CDS Context");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014784 return;
14785 }
14786
Dustin Brown1dbefe62018-09-11 16:32:03 -070014787 if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc)
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014788 != (QDF_STA_MASK | QDF_SAP_MASK)) {
Dustin Brown7e761c72018-07-31 13:50:17 -070014789 hdd_debug("Concurrency mode is not SAP");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014790 return;
14791 }
14792
14793 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
Dustin Brown07901ec2018-09-07 11:02:41 -070014794 if (ap_adapter &&
14795 test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags) &&
14796 wlan_reg_is_dfs_ch(hdd_ctx->pdev,
14797 ap_adapter->session.ap.operating_channel)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014798
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053014799 hdd_warn("STA-AP Mode DFS not supported, Switch SAP channel to Non DFS");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014800
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053014801 restart_chan =
14802 hdd_get_safe_channel_from_pcl_and_acs_range(ap_adapter);
14803 if (!restart_chan ||
Dustin Brown07901ec2018-09-07 11:02:41 -070014804 wlan_reg_is_dfs_ch(hdd_ctx->pdev, restart_chan))
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053014805 restart_chan = SAP_DEFAULT_5GHZ_CHANNEL;
14806
14807 hdd_switch_sap_channel(ap_adapter, restart_chan, true);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014808 }
14809}
14810
14811/**
14812 * hdd_set_connection_in_progress() - to set the connection in
14813 * progress flag
14814 * @value: value to set
14815 *
14816 * This function will set the passed value to connection in progress flag.
14817 * If value is previously being set to true then no need to set it again.
14818 *
14819 * Return: true if value is being set correctly and false otherwise.
14820 */
14821bool hdd_set_connection_in_progress(bool value)
14822{
14823 bool status = true;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014824 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014825
14826 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14827 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014828 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014829 return false;
14830 }
14831
14832 qdf_spin_lock(&hdd_ctx->connection_status_lock);
14833 /*
14834 * if the value is set to true previously and if someone is
14835 * trying to make it true again then it could be some race
14836 * condition being triggered. Avoid this situation by returning
14837 * false
14838 */
14839 if (hdd_ctx->connection_in_progress && value)
14840 status = false;
14841 else
14842 hdd_ctx->connection_in_progress = value;
14843 qdf_spin_unlock(&hdd_ctx->connection_status_lock);
14844 return status;
14845}
14846
Jeff Johnson9d295242017-08-29 14:39:48 -070014847int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070014848{
14849 if (!adapter) {
14850 hdd_err("Invalid adapter");
14851 return -EINVAL;
14852 }
14853 hdd_info("Send MCC P2P QUOTA to WMA: %d", set_value);
Jeff Johnson1b780e42017-10-31 14:11:45 -070014854 sme_cli_set_command(adapter->session_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070014855 WMA_VDEV_MCC_SET_TIME_QUOTA,
14856 set_value, VDEV_CMD);
14857 return 0;
14858
14859}
14860
Jeff Johnson9d295242017-08-29 14:39:48 -070014861int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070014862{
14863 if (!adapter) {
14864 hdd_err("Invalid adapter");
14865 return -EINVAL;
14866 }
14867
14868 hdd_info("Send MCC latency WMA: %d", set_value);
Jeff Johnson1b780e42017-10-31 14:11:45 -070014869 sme_cli_set_command(adapter->session_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070014870 WMA_VDEV_MCC_SET_TIME_LATENCY,
14871 set_value, VDEV_CMD);
14872 return 0;
14873}
14874
Jeff Johnson9d295242017-08-29 14:39:48 -070014875struct hdd_adapter *wlan_hdd_get_adapter_from_vdev(struct wlan_objmgr_psoc
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070014876 *psoc, uint8_t vdev_id)
14877{
Jeff Johnson9d295242017-08-29 14:39:48 -070014878 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014879 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070014880
14881 /*
14882 * Currently PSOC is not being used. But this logic will
14883 * change once we have the converged implementation of
14884 * HDD context per PSOC in place. This would break if
14885 * multiple vdev objects reuse the vdev id.
14886 */
14887 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
14888 if (!adapter)
14889 hdd_err("Get adapter by vdev id failed");
14890
14891 return adapter;
14892}
14893
Jeff Johnson9d295242017-08-29 14:39:48 -070014894int hdd_get_rssi_snr_by_bssid(struct hdd_adapter *adapter, const uint8_t *bssid,
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053014895 int8_t *rssi, int8_t *snr)
14896{
14897 QDF_STATUS status;
Jeff Johnson16528362018-06-14 12:34:16 -070014898 mac_handle_t mac_handle;
Jeff Johnson025618c2018-03-18 14:41:00 -070014899 struct csr_roam_profile *roam_profile;
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053014900
Jeff Johnson025618c2018-03-18 14:41:00 -070014901 roam_profile = hdd_roam_profile(adapter);
Jeff Johnson16528362018-06-14 12:34:16 -070014902 mac_handle = hdd_adapter_get_mac_handle(adapter);
14903 status = sme_get_rssi_snr_by_bssid(mac_handle,
Jeff Johnson025618c2018-03-18 14:41:00 -070014904 roam_profile, bssid, rssi, snr);
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053014905 if (QDF_STATUS_SUCCESS != status) {
14906 hdd_warn("sme_get_rssi_snr_by_bssid failed");
14907 return -EINVAL;
14908 }
14909
14910 return 0;
14911}
14912
Ganesh Kondabattini35739572017-06-21 16:26:39 +053014913/**
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014914 * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
14915 * @adapter - HDD adapter
14916 *
14917 * Return: 0 on success and non zero value on failure
14918 */
14919int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
14920{
14921 struct hdd_context *hdd_ctx;
14922 int ret;
14923 QDF_STATUS status;
Krunal Sonie71838d2018-09-27 10:45:05 -070014924 uint8_t sys_pref = 0;
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014925
14926 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14927 ret = wlan_hdd_validate_context(hdd_ctx);
14928 if (ret < 0)
14929 return ret;
14930
Krunal Sonie71838d2018-09-27 10:45:05 -070014931 ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc,
14932 &sys_pref);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014933 /* set the system preferece to default */
Krunal Sonie71838d2018-09-27 10:45:05 -070014934 policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014935
14936 /* clear the bitmap */
14937 adapter->active_ac = 0;
14938
14939 hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
Jeff Johnson16528362018-06-14 12:34:16 -070014940 adapter->session_id, adapter->active_ac);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014941
Jeff Johnson16528362018-06-14 12:34:16 -070014942 status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
14943 adapter->session_id,
14944 false, 0, 0, false);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014945 if (!QDF_IS_STATUS_SUCCESS(status)) {
14946 hdd_err("failed to reset limit off chan params");
14947 ret = -EINVAL;
14948 }
Ganesh Kondabattini35739572017-06-21 16:26:39 +053014949
14950 return ret;
14951}
14952
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014953/**
14954 * hdd_start_driver_ops_timer() - Starts driver ops inactivity timer
14955 * @drv_op: Enum indicating driver op
14956 *
14957 * Return: none
14958 */
14959void hdd_start_driver_ops_timer(int drv_op)
14960{
14961 memset(drv_ops_string, 0, MAX_OPS_NAME_STRING_SIZE);
14962 switch (drv_op) {
Jeff Johnson5794d4f2018-12-04 11:57:09 -080014963 case HDD_DRV_OP_PROBE:
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014964 memcpy(drv_ops_string, "probe", sizeof("probe"));
14965 break;
Jeff Johnson5794d4f2018-12-04 11:57:09 -080014966 case HDD_DRV_OP_REMOVE:
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014967 memcpy(drv_ops_string, "remove", sizeof("remove"));
14968 break;
Jeff Johnson5794d4f2018-12-04 11:57:09 -080014969 case HDD_DRV_OP_SHUTDOWN:
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014970 memcpy(drv_ops_string, "shutdown", sizeof("shutdown"));
14971 break;
Jeff Johnson5794d4f2018-12-04 11:57:09 -080014972 case HDD_DRV_OP_REINIT:
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014973 memcpy(drv_ops_string, "reinit", sizeof("reinit"));
14974 break;
Jeff Johnson5794d4f2018-12-04 11:57:09 -080014975 case HDD_DRV_OP_IFF_UP:
Arunk Khandavallie9ef42a2017-10-04 14:49:51 +053014976 memcpy(drv_ops_string, "iff_up", sizeof("iff_up"));
14977 break;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014978 }
14979
Dustin Brown45ed4bb2017-12-18 12:00:13 -080014980 hdd_drv_ops_task = current;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014981 qdf_timer_start(&hdd_drv_ops_inactivity_timer,
Dustin Browncfc54fe2018-06-18 16:17:41 -070014982 HDD_OPS_INACTIVITY_TIMEOUT * qdf_timer_get_multiplier());
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014983}
14984
14985/**
14986 * hdd_stop_driver_ops_timer() - Stops driver ops inactivity timer
14987 *
14988 * Return: none
14989 */
14990void hdd_stop_driver_ops_timer(void)
14991{
14992 qdf_timer_sync_cancel(&hdd_drv_ops_inactivity_timer);
14993}
14994
14995/**
14996 * hdd_drv_ops_inactivity_handler() - Timeout handler for driver ops
14997 * inactivity timer
14998 *
14999 * Return: None
15000 */
15001void hdd_drv_ops_inactivity_handler(void)
15002{
Rajeev Kumar4471f1b2018-06-08 14:18:28 -070015003 hdd_err("WLAN_BUG_RCA %s: %d Sec timer expired while in .%s",
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053015004 __func__, HDD_OPS_INACTIVITY_TIMEOUT/1000, drv_ops_string);
15005
Dustin Brown45ed4bb2017-12-18 12:00:13 -080015006 if (hdd_drv_ops_task) {
15007 printk("Call stack for \"%s\"\n", hdd_drv_ops_task->comm);
15008 qdf_print_thread_trace(hdd_drv_ops_task);
15009 } else {
15010 hdd_err("hdd_drv_ops_task is null");
15011 }
15012
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053015013 /* Driver shutdown is stuck, no recovery possible at this point */
15014 if (0 == qdf_mem_cmp(&drv_ops_string[0], "shutdown",
15015 sizeof("shutdown")))
15016 QDF_BUG(0);
15017
Rajeev Kumar1e57b9c2018-01-04 16:17:10 -080015018 if (cds_is_fw_down()) {
15019 hdd_err("FW is down");
15020 return;
15021 }
15022
Dustin Brown83044c22018-08-13 15:00:44 -070015023 cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053015024}
15025
Yun Parkff6a16a2017-09-26 16:38:18 -070015026/**
15027 * hdd_set_rx_mode_rps() - Enable/disable RPS in SAP mode
15028 * @struct hdd_context *hdd_ctx
15029 * @struct hdd_adapter *padapter
15030 * @bool enble
15031 *
15032 * Return: none
15033 */
15034void hdd_set_rx_mode_rps(bool enable)
15035{
15036 struct cds_config_info *cds_cfg = cds_get_ini_config();
Ryan Hsu0e878fa2018-05-04 15:22:09 -070015037 struct hdd_context *hdd_ctx;
15038 struct hdd_adapter *adapter;
Yun Parkff6a16a2017-09-26 16:38:18 -070015039
Ryan Hsu0e878fa2018-05-04 15:22:09 -070015040 if (!cds_cfg)
15041 return;
15042
15043 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15044 if (!hdd_ctx)
15045 return;
15046
15047 adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
15048 if (!adapter)
15049 return;
15050
15051 if (!hdd_ctx->rps && cds_cfg->uc_offload_enabled) {
Yun Parkff6a16a2017-09-26 16:38:18 -070015052 if (enable && !cds_cfg->rps_enabled)
15053 hdd_send_rps_ind(adapter);
15054 else if (!enable && cds_cfg->rps_enabled)
15055 hdd_send_rps_disable_ind(adapter);
15056 }
15057}
15058
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015059/* Register the module init/exit functions */
15060module_init(hdd_module_init);
15061module_exit(hdd_module_exit);
15062
15063MODULE_LICENSE("Dual BSD/GPL");
15064MODULE_AUTHOR("Qualcomm Atheros, Inc.");
15065MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
15066
Srinivas Girigowda841da292018-02-21 16:33:00 -080015067static const struct kernel_param_ops con_mode_ops = {
15068 .set = con_mode_handler,
15069 .get = param_get_int,
15070};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015071
Srinivas Girigowda841da292018-02-21 16:33:00 -080015072static const struct kernel_param_ops con_mode_ftm_ops = {
15073 .set = con_mode_handler_ftm,
15074 .get = param_get_int,
15075};
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053015076
Nirav Shah73713f72018-05-17 14:50:41 +053015077#ifdef FEATURE_MONITOR_MODE_SUPPORT
Srinivas Girigowda841da292018-02-21 16:33:00 -080015078static const struct kernel_param_ops con_mode_monitor_ops = {
15079 .set = con_mode_handler_monitor,
15080 .get = param_get_int,
15081};
Nirav Shah73713f72018-05-17 14:50:41 +053015082#endif
Ravi Joshia307f632017-07-17 23:41:41 -070015083
Srinivas Girigowda841da292018-02-21 16:33:00 -080015084static const struct kernel_param_ops fwpath_ops = {
15085 .set = fwpath_changed_handler,
15086 .get = param_get_string,
15087};
15088
15089module_param_cb(con_mode, &con_mode_ops, &con_mode,
15090 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
15091
15092module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm,
15093 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
15094
Nirav Shah73713f72018-05-17 14:50:41 +053015095#ifdef FEATURE_MONITOR_MODE_SUPPORT
Srinivas Girigowda841da292018-02-21 16:33:00 -080015096module_param_cb(con_mode_monitor, &con_mode_monitor_ops, &con_mode_monitor,
15097 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Nirav Shah73713f72018-05-17 14:50:41 +053015098#endif
Srinivas Girigowda841da292018-02-21 16:33:00 -080015099
15100module_param_cb(fwpath, &fwpath_ops, &fwpath,
15101 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015102
15103module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
15104
15105module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
15106
15107module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);