blob: 14f528ff5d52be86d07cd8dca8c938e36de02243 [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"
Dustin Brownd315c452018-11-27 11:28:48 -080058#include "qdf_talloc.h"
Dustin Brownd4241942018-02-26 12:51:37 -080059#include "qdf_trace.h"
60#include "qdf_types.h"
Manjunathappa Prakash3454fd62016-04-01 08:52:06 -070061#include <cdp_txrx_peer_ops.h>
Dhanashri Atrea8f82f22017-01-23 12:58:24 -080062#include <cdp_txrx_misc.h>
Mohit Khannaca4173b2017-09-12 21:52:19 -070063#include <cdp_txrx_stats.h>
bings0e03a982018-05-09 08:40:59 +080064#include "cdp_txrx_flow_ctrl_legacy.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080065
66#include <net/addrconf.h>
67#include <linux/wireless.h>
68#include <net/cfg80211.h>
69#include <linux/inetdevice.h>
70#include <net/addrconf.h>
71#include "wlan_hdd_cfg80211.h"
72#include "wlan_hdd_ext_scan.h"
73#include "wlan_hdd_p2p.h"
74#include <linux/rtnetlink.h>
75#include "sap_api.h"
76#include <linux/semaphore.h>
77#include <linux/ctype.h>
78#include <linux/compat.h>
Arunk Khandavalli830c9692018-03-22 12:17:40 +053079#include <linux/reboot.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080080#ifdef MSM_PLATFORM
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080081#include <soc/qcom/subsystem_restart.h>
82#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080083#include <wlan_hdd_hostapd.h>
84#include <wlan_hdd_softap_tx_rx.h>
Jeff Johnson8bb61112018-03-31 13:33:54 -070085#include <wlan_hdd_green_ap.h>
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080086#include "cfg_api.h"
87#include "qwlan_version.h"
88#include "wma_types.h"
89#include "wlan_hdd_tdls.h"
90#ifdef FEATURE_WLAN_CH_AVOID
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +053091#include "cds_regdomain.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080092#endif /* FEATURE_WLAN_CH_AVOID */
Dustin Brownce46d1d2017-08-15 13:34:24 -070093#include "cdp_txrx_flow_ctrl_v2.h"
Yuanyuan Liu1d8045c2016-04-06 16:40:49 -070094#include "pld_common.h"
Tushnim Bhattacharyya15596cf2016-02-12 11:57:02 -080095#include "wlan_hdd_ocb.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080096#include "wlan_hdd_nan.h"
97#include "wlan_hdd_debugfs.h"
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053098#include "wlan_hdd_debugfs_csr.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080099#include "wlan_hdd_driver_ops.h"
100#include "epping_main.h"
Poddar, Siddarth34872782017-08-10 14:08:51 +0530101#include "wlan_hdd_data_stall_detection.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800102
103#include <wlan_hdd_ipa.h>
104#include "hif.h"
105#include "wma.h"
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -0800106#include "wlan_policy_mgr_api.h"
Manikandan Mohandcc21ba2016-03-15 14:31:56 -0700107#include "wlan_hdd_tsf.h"
Komal Seelamec702b02016-02-24 18:42:16 +0530108#include "bmi.h"
Amar Singhale4f28ee2015-10-21 14:36:56 -0700109#include <wlan_hdd_regulatory.h>
Jeff Johnson2b0a7b82016-05-18 15:08:02 -0700110#include "wlan_hdd_lpass.h"
Arun Khandavalli4b55da72016-07-19 19:55:01 +0530111#include "nan_api.h"
Nachiket Kukade63bb63d2018-11-21 14:42:14 +0530112#include "wlan_nan_api.h"
Orhan K AKYILDIZ1481aff2016-05-16 12:40:13 -0700113#include <wlan_hdd_napi.h>
Padma, Santhosh Kumard7cc0792016-06-28 18:54:12 +0530114#include "wlan_hdd_disa.h"
Rajeev Kumar97767a02016-11-30 11:20:40 -0800115#include <dispatcher_init_deinit.h>
Rajeev Kumar699debf2017-01-06 14:17:00 -0800116#include "wlan_hdd_object_manager.h"
yeshwanth sriram guntuka310b3ac2016-11-15 23:25:26 +0530117#include "cds_utils.h"
Venkata Sharath Chandra Manchala0d44d452016-11-23 17:48:15 -0800118#include <cdp_txrx_handle.h>
Sandeep Puligillafdd201e2017-02-02 18:43:46 -0800119#include <qca_vendor.h>
Mukul Sharma9d797a02017-01-05 20:26:03 +0530120#include "wlan_pmo_ucfg_api.h"
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +0530121#include "sir_api.h"
Naveen Rawat910726a2017-03-06 11:42:51 -0800122#include "os_if_wifi_pos.h"
123#include "wifi_pos_api.h"
124#include "wlan_hdd_oemdata.h"
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -0800125#include "wlan_hdd_he.h"
Naveen Rawatcb5c5402017-03-22 10:12:19 -0700126#include "os_if_nan.h"
127#include "nan_public_structs.h"
Kiran Kumar Lokere3beeb952017-05-02 18:40:24 -0700128#include "wlan_reg_ucfg_api.h"
bings81fe50a2017-11-27 14:33:26 +0800129#include "wlan_dfs_ucfg_api.h"
Ravi Joshi4f095952017-06-29 15:39:19 -0700130#include "wlan_hdd_rx_monitor.h"
Mukul Sharmad16c2022017-07-25 18:56:12 +0530131#include "sme_power_save_api.h"
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +0530132#include "enet.h"
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -0700133#include <cdp_txrx_cmn_struct.h>
Mohit Khanna70322002018-05-15 19:21:32 -0700134#include <dp_txrx.h>
Amar Singhal0928b192017-12-01 10:50:54 -0800135#include "wlan_hdd_sysfs.h"
Nachiket Kukade98f562a2017-12-15 12:18:07 +0530136#include "wlan_disa_ucfg_api.h"
Wu Gao52084c12018-05-17 20:47:11 +0800137#include "wlan_disa_obj_mgmt_api.h"
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +0530138#include "wlan_action_oui_ucfg_api.h"
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +0530139#include "wlan_ipa_ucfg_api.h"
Arunk Khandavallia6305a32018-01-25 11:19:18 +0530140#include <target_if.h>
Alok Kumarb64650c2018-03-23 17:05:11 +0530141#include "wlan_hdd_nud_tracking.h"
Nachiket Kukaded0dd62e2018-05-21 18:39:22 +0530142#include "wlan_hdd_apf.h"
Varun Reddy Yeturue93d2462018-05-22 13:54:52 -0700143#include "wlan_hdd_twt.h"
Rachit Kankane0dc3e852018-05-07 17:33:42 +0530144#include "qc_sap_ioctl.h"
Sandeep Puligillac5609d52018-05-17 19:23:41 -0700145#include "wlan_mlme_main.h"
Wu Gaoe5689792018-07-05 19:20:13 +0800146#include "wlan_p2p_cfg_api.h"
Wu Gao637d58a2018-12-08 10:37:34 +0800147#include "wlan_cfg80211_p2p.h"
Wu Gaobdb7f272018-07-05 19:33:26 +0800148#include "wlan_tdls_cfg_api.h"
Qiwei Caie689a262018-07-26 15:50:22 +0800149#include <wlan_hdd_rssi_monitor.h>
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +0530150#include "wlan_mlme_ucfg_api.h"
Sourav Mohapatra113685f2018-08-29 14:21:55 +0530151#include "wlan_fwol_ucfg_api.h"
Krunal Sonie71838d2018-09-27 10:45:05 -0700152#include "wlan_policy_mgr_ucfg.h"
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +0530153#ifdef CNSS_GENL
154#include <net/cnss_nl.h>
155#endif
Amar Singhal5cccafe2017-02-15 12:42:58 -0800156#include "wlan_reg_ucfg_api.h"
Zhang Qian47e22ce2018-01-04 15:38:38 +0800157#include "wlan_ocb_ucfg_api.h"
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -0800158#include <wlan_hdd_spectralscan.h>
gaurank kathpalia4a205fc2018-09-15 00:59:15 +0530159#include "wlan_green_ap_ucfg_api.h"
Liangwei Dong3abfe8f2018-09-20 02:25:44 -0400160#include <wlan_p2p_ucfg_api.h>
161
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800162#ifdef MODULE
163#define WLAN_MODULE_NAME module_name(THIS_MODULE)
164#else
165#define WLAN_MODULE_NAME "wlan"
166#endif
167
168#ifdef TIMER_MANAGER
169#define TIMER_MANAGER_STR " +TIMER_MANAGER"
170#else
171#define TIMER_MANAGER_STR ""
172#endif
173
174#ifdef MEMORY_DEBUG
175#define MEMORY_DEBUG_STR " +MEMORY_DEBUG"
176#else
177#define MEMORY_DEBUG_STR ""
178#endif
179
Dustin Brownc1034df2018-02-07 14:51:32 -0800180#ifdef PANIC_ON_BUG
181#define PANIC_ON_BUG_STR " +PANIC_ON_BUG"
182#else
183#define PANIC_ON_BUG_STR ""
184#endif
185
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530186bool g_is_system_reboot_triggered;
Sachin Ahujadddd2632017-03-07 19:07:24 +0530187int wlan_start_ret_val;
188static DECLARE_COMPLETION(wlan_start_comp);
189static unsigned int dev_num = 1;
190static struct cdev wlan_hdd_state_cdev;
191static struct class *class;
192static dev_t device;
Arun Khandavallifae92942016-08-01 13:31:08 +0530193#ifndef MODULE
194static struct gwlan_loader *wlan_loader;
195static ssize_t wlan_boot_cb(struct kobject *kobj,
196 struct kobj_attribute *attr,
197 const char *buf, size_t count);
198struct gwlan_loader {
199 bool loaded_state;
200 struct kobject *boot_wlan_obj;
201 struct attribute_group *attr_group;
202};
203
204static struct kobj_attribute wlan_boot_attribute =
205 __ATTR(boot_wlan, 0220, NULL, wlan_boot_cb);
206
207static struct attribute *attrs[] = {
208 &wlan_boot_attribute.attr,
209 NULL,
210};
211
212#define MODULE_INITIALIZED 1
Qun Zhang4a83a462018-09-11 16:28:51 +0800213
214#ifdef MULTI_IF_NAME
215#define WLAN_LOADER_NAME "boot_" MULTI_IF_NAME
216#else
217#define WLAN_LOADER_NAME "boot_wlan"
218#endif
Arun Khandavallifae92942016-08-01 13:31:08 +0530219#endif
220
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530221#define HDD_OPS_INACTIVITY_TIMEOUT (120000)
222#define MAX_OPS_NAME_STRING_SIZE 20
Rajeev Kumar6d0b2ea2017-12-26 17:55:33 -0800223#define RATE_LIMIT_ERROR_LOG (256)
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530224
225static qdf_timer_t hdd_drv_ops_inactivity_timer;
Dustin Brown45ed4bb2017-12-18 12:00:13 -0800226static struct task_struct *hdd_drv_ops_task;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +0530227static char drv_ops_string[MAX_OPS_NAME_STRING_SIZE];
228
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800229/* the Android framework expects this param even though we don't use it */
230#define BUF_LEN 20
231static char fwpath_buffer[BUF_LEN];
232static struct kparam_string fwpath = {
233 .string = fwpath_buffer,
234 .maxlen = BUF_LEN,
235};
236
237static char *country_code;
238static int enable_11d = -1;
239static int enable_dfs_chan_scan = -1;
240
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800241/*
242 * spinlock for synchronizing asynchronous request/response
243 * (full description of use in wlan_hdd_main.h)
244 */
245DEFINE_SPINLOCK(hdd_context_lock);
Arunk Khandavalli16d84252017-06-21 15:26:29 +0530246DEFINE_MUTEX(hdd_init_deinit_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800247
Rajeev Kumar8e3e2832015-11-06 16:02:54 -0800248#define WLAN_NLINK_CESIUM 30
249
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530250static qdf_wake_lock_t wlan_wake_lock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800251
252#define WOW_MAX_FILTER_LISTS 1
253#define WOW_MAX_FILTERS_PER_LIST 4
254#define WOW_MIN_PATTERN_SIZE 6
255#define WOW_MAX_PATTERN_SIZE 64
256
Bala Venkatesh110b03e2018-07-10 16:02:08 +0530257/* max peer can be tdls peers + self peer + bss peer */
258#define HDD_MAX_VDEV_PEER_COUNT (HDD_MAX_NUM_TDLS_STA + 2)
Sourav Mohapatra808e3d42018-07-04 09:34:23 +0530259#define IS_IDLE_STOP (!cds_is_driver_unloading() && \
260 !cds_is_driver_recovering() && !cds_is_driver_loading())
Bala Venkatesh110b03e2018-07-10 16:02:08 +0530261
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800262#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
263static const struct wiphy_wowlan_support wowlan_support_reg_init = {
264 .flags = WIPHY_WOWLAN_ANY |
265 WIPHY_WOWLAN_MAGIC_PKT |
266 WIPHY_WOWLAN_DISCONNECT |
267 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
268 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
269 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
270 WIPHY_WOWLAN_4WAY_HANDSHAKE |
271 WIPHY_WOWLAN_RFKILL_RELEASE,
272 .n_patterns = WOW_MAX_FILTER_LISTS * WOW_MAX_FILTERS_PER_LIST,
273 .pattern_min_len = WOW_MIN_PATTERN_SIZE,
274 .pattern_max_len = WOW_MAX_PATTERN_SIZE,
275};
276#endif
277
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700278static const struct category_info cinfo[MAX_SUPPORTED_CATEGORY] = {
279 [QDF_MODULE_ID_TLSHIM] = {QDF_TRACE_LEVEL_ALL},
280 [QDF_MODULE_ID_WMI] = {QDF_TRACE_LEVEL_ALL},
281 [QDF_MODULE_ID_HTT] = {QDF_TRACE_LEVEL_ALL},
282 [QDF_MODULE_ID_HDD] = {QDF_TRACE_LEVEL_ALL},
283 [QDF_MODULE_ID_SME] = {QDF_TRACE_LEVEL_ALL},
284 [QDF_MODULE_ID_PE] = {QDF_TRACE_LEVEL_ALL},
285 [QDF_MODULE_ID_WMA] = {QDF_TRACE_LEVEL_ALL},
286 [QDF_MODULE_ID_SYS] = {QDF_TRACE_LEVEL_ALL},
287 [QDF_MODULE_ID_QDF] = {QDF_TRACE_LEVEL_ALL},
288 [QDF_MODULE_ID_SAP] = {QDF_TRACE_LEVEL_ALL},
289 [QDF_MODULE_ID_HDD_SOFTAP] = {QDF_TRACE_LEVEL_ALL},
290 [QDF_MODULE_ID_HDD_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
291 [QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DATA_PATH_TRACE_LEVEL},
292 [QDF_MODULE_ID_HIF] = {QDF_DATA_PATH_TRACE_LEVEL},
293 [QDF_MODULE_ID_HTC] = {QDF_DATA_PATH_TRACE_LEVEL},
294 [QDF_MODULE_ID_TXRX] = {QDF_DATA_PATH_TRACE_LEVEL},
295 [QDF_MODULE_ID_QDF_DEVICE] = {QDF_TRACE_LEVEL_ALL},
296 [QDF_MODULE_ID_CFG] = {QDF_TRACE_LEVEL_ALL},
297 [QDF_MODULE_ID_BMI] = {QDF_TRACE_LEVEL_ALL},
298 [QDF_MODULE_ID_EPPING] = {QDF_TRACE_LEVEL_ALL},
299 [QDF_MODULE_ID_QVIT] = {QDF_TRACE_LEVEL_ALL},
300 [QDF_MODULE_ID_DP] = {QDF_TRACE_LEVEL_ALL},
301 [QDF_MODULE_ID_SOC] = {QDF_TRACE_LEVEL_ALL},
302 [QDF_MODULE_ID_OS_IF] = {QDF_TRACE_LEVEL_ALL},
303 [QDF_MODULE_ID_TARGET_IF] = {QDF_TRACE_LEVEL_ALL},
304 [QDF_MODULE_ID_SCHEDULER] = {QDF_TRACE_LEVEL_ALL},
305 [QDF_MODULE_ID_MGMT_TXRX] = {QDF_TRACE_LEVEL_ALL},
306 [QDF_MODULE_ID_PMO] = {QDF_TRACE_LEVEL_ALL},
307 [QDF_MODULE_ID_SCAN] = {QDF_TRACE_LEVEL_ALL},
308 [QDF_MODULE_ID_POLICY_MGR] = {QDF_TRACE_LEVEL_ALL},
309 [QDF_MODULE_ID_P2P] = {QDF_TRACE_LEVEL_ALL},
310 [QDF_MODULE_ID_TDLS] = {QDF_TRACE_LEVEL_ALL},
311 [QDF_MODULE_ID_REGULATORY] = {QDF_TRACE_LEVEL_ALL},
312 [QDF_MODULE_ID_SERIALIZATION] = {QDF_TRACE_LEVEL_ALL},
Arif Hussainfde76e72017-09-05 16:58:23 -0700313 [QDF_MODULE_ID_DFS] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumarca8ef9d2017-10-06 10:43:21 -0700314 [QDF_MODULE_ID_OBJ_MGR] = {QDF_TRACE_LEVEL_ALL},
Deepak Dhamdheref918d422017-07-06 12:56:29 -0700315 [QDF_MODULE_ID_ROAM_DEBUG] = {QDF_TRACE_LEVEL_ALL},
Himanshu Agarwalb229a142017-12-21 10:16:45 +0530316 [QDF_MODULE_ID_GREEN_AP] = {QDF_TRACE_LEVEL_ALL},
Zhang Qian47e22ce2018-01-04 15:38:38 +0800317 [QDF_MODULE_ID_OCB] = {QDF_TRACE_LEVEL_ALL},
Sravan Kumar Kairam1309e7e2018-03-13 09:29:52 +0530318 [QDF_MODULE_ID_IPA] = {QDF_TRACE_LEVEL_ALL},
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +0530319 [QDF_MODULE_ID_ACTION_OUI] = {QDF_TRACE_LEVEL_ALL},
Dustin Brown84f46ea2018-02-15 11:57:36 -0800320 [QDF_MODULE_ID_CONFIG] = {QDF_TRACE_LEVEL_ALL},
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +0530321 [QDF_MODULE_ID_MLME] = {QDF_TRACE_LEVEL_ALL},
Ashish Kumar Dhanotiya8d039c82018-07-11 20:41:14 +0530322 [QDF_MODULE_ID_TARGET] = {QDF_TRACE_LEVEL_ALL},
Kiran Kumar Lokere4ce40482018-08-30 16:31:00 -0700323 [QDF_MODULE_ID_CRYPTO] = {QDF_TRACE_LEVEL_ALL},
Sourav Mohapatra113685f2018-08-29 14:21:55 +0530324 [QDF_MODULE_ID_FWOL] = {QDF_TRACE_LEVEL_ALL},
Abhishek Singh0b0105f2018-09-25 10:44:16 +0530325 [QDF_MODULE_ID_SM_ENGINE] = {QDF_TRACE_LEVEL_ALL},
326 [QDF_MODULE_ID_CMN_MLME] = {QDF_TRACE_LEVEL_ALL},
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -0700327};
328
Ashish Kumar Dhanotiyacf11bae2017-04-04 03:29:47 +0530329struct notifier_block hdd_netdev_notifier;
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530330struct notifier_block system_reboot_notifier;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800331
332struct sock *cesium_nl_srv_sock;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800333#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700334static void wlan_hdd_auto_shutdown_cb(void);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800335#endif
336
Sachin Ahujadddd2632017-03-07 19:07:24 +0530337void hdd_start_complete(int ret)
338{
339 wlan_start_ret_val = ret;
340
341 complete(&wlan_start_comp);
342}
343
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800344/**
Nirav Shahbd36b062016-07-18 11:12:59 +0530345 * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700346 * @hdd_ctx: pointer to struct hdd_context
Nirav Shahbd36b062016-07-18 11:12:59 +0530347 *
348 * Return: none
349 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700350static void hdd_set_rps_cpu_mask(struct hdd_context *hdd_ctx)
Nirav Shahbd36b062016-07-18 11:12:59 +0530351{
Jeff Johnson9d295242017-08-29 14:39:48 -0700352 struct hdd_adapter *adapter;
Nirav Shahbd36b062016-07-18 11:12:59 +0530353
Dustin Brown920397d2017-12-13 16:27:50 -0800354 hdd_for_each_adapter(hdd_ctx, adapter)
355 hdd_send_rps_ind(adapter);
Nirav Shahbd36b062016-07-18 11:12:59 +0530356}
357
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530358#ifdef QCA_HL_NETDEV_FLOW_CONTROL
359void wlan_hdd_mod_fc_timer(struct hdd_adapter *adapter,
360 enum netif_action_type action)
361{
362 if (!adapter->tx_flow_timer_initialized)
363 return;
364
365 if (action == WLAN_WAKE_NON_PRIORITY_QUEUE) {
366 qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
367 } else if (action == WLAN_STOP_NON_PRIORITY_QUEUE) {
368 QDF_STATUS status =
369 qdf_mc_timer_start(&adapter->tx_flow_control_timer,
370 WLAN_HDD_TX_FLOW_CONTROL_OS_Q_BLOCK_TIME);
371
372 if (!QDF_IS_STATUS_SUCCESS(status))
373 hdd_err("Failed to start tx_flow_control_timer");
374 else
375 adapter->
376 hdd_stats.tx_rx_stats.txflow_timer_cnt++;
377
378 adapter->hdd_stats.tx_rx_stats.txflow_pause_cnt++;
379 adapter->hdd_stats.tx_rx_stats.is_txflow_paused = true;
380 }
381}
382#endif /* QCA_HL_NETDEV_FLOW_CONTROL */
383
Alok Kumar2fad6442018-11-08 19:19:28 +0530384#ifdef MSM_PLATFORM
385void wlan_hdd_update_tcp_rx_param(struct hdd_context *hdd_ctx, void *data)
386{
387 if (!hdd_ctx) {
388 hdd_err("HDD context is null");
389 return;
390 }
391
392 if (!data) {
393 hdd_err("Data is null");
394 return;
395 }
396 if (hdd_ctx->config->enable_tcp_param_update)
397 wlan_hdd_send_tcp_param_update_event(hdd_ctx, data, 1);
398 else
399 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
400 WLAN_SVC_WLAN_TP_IND,
401 data,
402 sizeof(struct wlan_rx_tp_data));
403}
404
405void wlan_hdd_update_tcp_tx_param(struct hdd_context *hdd_ctx, void *data)
406{
407 enum wlan_tp_level next_tx_level;
408 struct wlan_tx_tp_data *tx_tp_data;
409
410 if (!hdd_ctx) {
411 hdd_err("HDD context is null");
412 return;
413 }
414
415 if (!data) {
416 hdd_err("Data is null");
417 return;
418 }
419
420 tx_tp_data = (struct wlan_tx_tp_data *)data;
421 next_tx_level = tx_tp_data->level;
422
423 if (hdd_ctx->config->enable_tcp_param_update)
424 wlan_hdd_send_tcp_param_update_event(hdd_ctx, data, 0);
425 else
426 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
427 WLAN_SVC_WLAN_TP_TX_IND,
428 &next_tx_level,
429 sizeof(next_tx_level));
430}
431
432/**
433 * wlan_hdd_send_tcp_param_update_event() - Send vendor event to update
434 * TCP parameter through Wi-Fi HAL
435 * @hdd_ctx: Pointer to HDD context
436 * @data: Parameters to update
437 * @dir: Direction(tx/rx) to update
438 *
439 * Return: None
440 */
441void wlan_hdd_send_tcp_param_update_event(struct hdd_context *hdd_ctx,
442 void *data,
443 uint8_t dir)
444{
445 struct sk_buff *vendor_event;
446 uint32_t event_len;
447 bool tcp_limit_output = false;
448 bool tcp_del_ack_ind_enabled = false;
449 bool tcp_adv_win_scl_enabled = false;
450 enum wlan_tp_level next_tp_level = WLAN_SVC_TP_NONE;
451
452 event_len = sizeof(uint8_t) + sizeof(uint8_t) + NLMSG_HDRLEN;
453
454 if (dir == 0) /*TX Flow */ {
455 struct wlan_tx_tp_data *tx_tp_data =
456 (struct wlan_tx_tp_data *)data;
457
458 next_tp_level = tx_tp_data->level;
459
460 if (tx_tp_data->tcp_limit_output) {
461 /* TCP_LIMIT_OUTPUT_BYTES */
462 event_len += sizeof(uint32_t);
463 tcp_limit_output = true;
464 }
465 } else if (dir == 1) /* RX Flow */ {
466 struct wlan_rx_tp_data *rx_tp_data =
467 (struct wlan_rx_tp_data *)data;
468
469 next_tp_level = rx_tp_data->level;
470
471 if (rx_tp_data->rx_tp_flags & TCP_DEL_ACK_IND_MASK) {
472 event_len += sizeof(uint32_t); /* TCP_DELACK_SEG */
473 tcp_del_ack_ind_enabled = true;
474 }
475 if (rx_tp_data->rx_tp_flags & TCP_ADV_WIN_SCL_MASK) {
476 event_len += sizeof(uint32_t); /* TCP_ADV_WIN_SCALE */
477 tcp_adv_win_scl_enabled = true;
478 }
479 } else {
480 hdd_err("Invalid Direction [%d]", dir);
481 return;
482 }
483
484 vendor_event =
485 cfg80211_vendor_event_alloc(
486 hdd_ctx->wiphy,
487 NULL, event_len,
488 QCA_NL80211_VENDOR_SUBCMD_THROUGHPUT_CHANGE_EVENT_INDEX,
489 GFP_KERNEL);
490
491 if (!vendor_event) {
492 hdd_err("cfg80211_vendor_event_alloc failed");
493 return;
494 }
495
496 if (nla_put_u8(
497 vendor_event,
498 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_DIRECTION,
499 dir))
500 goto tcp_param_change_nla_failed;
501
502 if (nla_put_u8(
503 vendor_event,
504 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_THROUGHPUT_LEVEL,
505 (next_tp_level == WLAN_SVC_TP_LOW ?
506 QCA_WLAN_THROUGHPUT_LEVEL_LOW :
507 QCA_WLAN_THROUGHPUT_LEVEL_HIGH)))
508 goto tcp_param_change_nla_failed;
509
510 if (tcp_limit_output &&
511 nla_put_u32(
512 vendor_event,
513 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_LIMIT_OUTPUT_BYTES,
514 (next_tp_level == WLAN_SVC_TP_LOW ?
515 TCP_LIMIT_OUTPUT_BYTES_LOW :
516 TCP_LIMIT_OUTPUT_BYTES_HI)))
517 goto tcp_param_change_nla_failed;
518
519 if (tcp_del_ack_ind_enabled &&
520 (nla_put_u32(
521 vendor_event,
522 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_DELACK_SEG,
523 (next_tp_level == WLAN_SVC_TP_LOW ?
524 TCP_DEL_ACK_LOW : TCP_DEL_ACK_HI))))
525 goto tcp_param_change_nla_failed;
526
527 if (tcp_adv_win_scl_enabled &&
528 (nla_put_u32(
529 vendor_event,
530 QCA_WLAN_VENDOR_ATTR_THROUGHPUT_CHANGE_TCP_ADV_WIN_SCALE,
531 (next_tp_level == WLAN_SVC_TP_LOW ?
532 WIN_SCALE_LOW : WIN_SCALE_HI))))
533 goto tcp_param_change_nla_failed;
534
535 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
536 return;
537
538tcp_param_change_nla_failed:
539 hdd_err("nla_put api failed");
540 kfree_skb(vendor_event);
541}
542#endif /* MSM_PLATFORM */
543
Nirav Shahbd36b062016-07-18 11:12:59 +0530544/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800545 * wlan_hdd_txrx_pause_cb() - pause callback from txrx layer
546 * @vdev_id: vdev_id
547 * @action: action type
548 * @reason: reason type
549 *
550 * Return: none
551 */
552void wlan_hdd_txrx_pause_cb(uint8_t vdev_id,
553 enum netif_action_type action, enum netif_reason_type reason)
554{
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700555 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Jeff Johnson9d295242017-08-29 14:39:48 -0700556 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800557
558 if (!hdd_ctx) {
559 hdd_err("hdd ctx is NULL");
560 return;
561 }
562 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
Ajit Pal Singh106c1412018-04-18 18:08:49 +0530563 wlan_hdd_mod_fc_timer(adapter, action);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800564 wlan_hdd_netif_queue_control(adapter, action, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800565}
566
567/*
Dustin Brownab482ac2017-06-09 17:00:44 -0700568 * Store WLAN driver version and timestamp info in global variables such that
569 * crash debugger can extract them from driver debug symbol and crashdump for
570 * post processing
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800571 */
Dustin Brown96cd9632017-11-13 12:45:04 -0800572#ifdef BUILD_TAG
Rajeev Kumare555e2d2018-09-17 11:52:37 -0700573uint8_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 -0800574#else
Rajeev Kumare555e2d2018-09-17 11:52:37 -0700575uint8_t g_wlan_driver_version[] = QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR PANIC_ON_BUG_STR;
Naveen Rawat93836252017-06-20 16:30:59 -0700576#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800577
578/**
Liangwei Dong17bf2662018-01-05 02:02:05 -0500579 * hdd_get_valid_chan() - return current chan list from regulatory.
580 * @hdd_ctx: HDD context
581 * @chan_list: buf hold returned chan list
582 * @chan_num: input buf size and output returned chan num
583 *
584 * This function helps get current available chan list from regulatory
585 * module. It excludes the "disabled" and "invalid" channels.
586 *
587 * Return: 0 for success.
588 */
589static int hdd_get_valid_chan(struct hdd_context *hdd_ctx,
590 uint8_t *chan_list,
591 uint32_t *chan_num)
592{
593 int i = 0, j = 0;
594 struct regulatory_channel *cur_chan_list;
595 struct wlan_objmgr_pdev *pdev;
596
Dustin Brown07901ec2018-09-07 11:02:41 -0700597 if (!hdd_ctx || !hdd_ctx->pdev || !chan_list || !chan_num)
Liangwei Dong17bf2662018-01-05 02:02:05 -0500598 return -EINVAL;
599
Dustin Brown07901ec2018-09-07 11:02:41 -0700600 pdev = hdd_ctx->pdev;
Liangwei Dong17bf2662018-01-05 02:02:05 -0500601 cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
602 sizeof(struct regulatory_channel));
603 if (!cur_chan_list)
604 return -ENOMEM;
605
606 if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) !=
607 QDF_STATUS_SUCCESS) {
608 qdf_mem_free(cur_chan_list);
609 return -EINVAL;
610 }
611
612 for (i = 0; i < NUM_CHANNELS; i++) {
613 uint32_t ch = cur_chan_list[i].chan_num;
614 enum channel_state state = wlan_reg_get_channel_state(pdev,
615 ch);
616
617 if (state != CHANNEL_STATE_DISABLE &&
618 state != CHANNEL_STATE_INVALID &&
619 j < *chan_num) {
620 chan_list[j] = (uint8_t)ch;
621 j++;
622 }
623 }
624 *chan_num = j;
625 qdf_mem_free(cur_chan_list);
626 return 0;
627}
628
629/**
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530630 * hdd_validate_channel_and_bandwidth() - Validate the channel-bandwidth combo
631 * @adapter: HDD adapter
632 * @chan_number: Channel number
633 * @chan_bw: Bandwidth
634 *
635 * Checks if the given bandwidth is valid for the given channel number.
636 *
637 * Return: 0 for success, non-zero for failure
638 */
Jeff Johnson9d295242017-08-29 14:39:48 -0700639int hdd_validate_channel_and_bandwidth(struct hdd_adapter *adapter,
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530640 uint32_t chan_number,
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800641 enum phy_ch_width chan_bw)
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530642{
Liangwei Dong17bf2662018-01-05 02:02:05 -0500643 uint8_t chan[NUM_CHANNELS];
644 uint32_t len = NUM_CHANNELS, i;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530645 bool found = false;
Jeff Johnson16528362018-06-14 12:34:16 -0700646 mac_handle_t mac_handle;
Liangwei Dong17bf2662018-01-05 02:02:05 -0500647 int ret;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530648
Jeff Johnson16528362018-06-14 12:34:16 -0700649 mac_handle = hdd_adapter_get_mac_handle(adapter);
650 if (!mac_handle) {
651 hdd_err("Invalid MAC handle");
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530652 return -EINVAL;
653 }
654
Liangwei Dong17bf2662018-01-05 02:02:05 -0500655 ret = hdd_get_valid_chan(adapter->hdd_ctx, chan,
656 &len);
657 if (ret) {
658 hdd_err("error %d in getting valid channel list", ret);
659 return ret;
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530660 }
661
662 for (i = 0; i < len; i++) {
663 if (chan[i] == chan_number) {
664 found = true;
665 break;
666 }
667 }
668
669 if (found == false) {
670 hdd_err("Channel not in driver's valid channel list");
671 return -EOPNOTSUPP;
672 }
673
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700674 if ((!WLAN_REG_IS_24GHZ_CH(chan_number)) &&
675 (!WLAN_REG_IS_5GHZ_CH(chan_number))) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530676 hdd_err("CH %d is not in 2.4GHz or 5GHz", chan_number);
677 return -EINVAL;
678 }
679
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700680 if (WLAN_REG_IS_24GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530681 if (chan_bw == CH_WIDTH_80MHZ) {
682 hdd_err("BW80 not possible in 2.4GHz band");
683 return -EINVAL;
684 }
685 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 14) &&
686 (chan_bw != CH_WIDTH_MAX)) {
687 hdd_err("Only BW20 possible on channel 14");
688 return -EINVAL;
689 }
690 }
691
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -0700692 if (WLAN_REG_IS_5GHZ_CH(chan_number)) {
Chandrasekaran, Manishekar794a0982016-01-12 19:42:20 +0530693 if ((chan_bw != CH_WIDTH_20MHZ) && (chan_number == 165) &&
694 (chan_bw != CH_WIDTH_MAX)) {
695 hdd_err("Only BW20 possible on channel 165");
696 return -EINVAL;
697 }
698 }
699
700 return 0;
701}
702
Arunk Khandavallie1b3a382017-09-26 12:01:26 +0530703/**
704 * hdd_wait_for_recovery_completion() - Wait for cds recovery completion
705 *
706 * Block the unloading of the driver (or) interface up until the
707 * cds recovery is completed
708 *
709 * Return: true for recovery completion else false
710 */
711static bool hdd_wait_for_recovery_completion(void)
712{
713 int retry = 0;
714
715 /* Wait for recovery to complete */
716 while (cds_is_driver_recovering()) {
717 if (retry == HDD_MOD_EXIT_SSR_MAX_RETRIES/2)
718 hdd_err("Recovery in progress; wait here!!!");
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530719
720 if (g_is_system_reboot_triggered) {
721 hdd_info("System Reboot happening ignore unload!!");
722 return false;
723 }
724
Arunk Khandavallie1b3a382017-09-26 12:01:26 +0530725 msleep(1000);
726 if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
727 hdd_err("SSR never completed, error");
728 /*
729 * Trigger the bug_on in the internal builds, in the
730 * customer builds self-recovery will be enabled
731 * in those cases just return error.
732 */
733 if (cds_is_self_recovery_enabled())
734 return false;
735 QDF_BUG(0);
736 }
737 }
738
739 hdd_info("Recovery completed successfully!");
740 return true;
741}
742
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530743
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800744static int __hdd_netdev_notifier_call(struct notifier_block *nb,
745 unsigned long state, void *data)
746{
747#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
748 struct netdev_notifier_info *dev_notif_info = data;
749 struct net_device *dev = dev_notif_info->dev;
750#else
751 struct net_device *dev = data;
752#endif
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530753 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -0700754 struct hdd_context *hdd_ctx;
Min Liu8c5d99e2018-09-10 17:18:44 +0800755 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800756
Dustin Brownfdf17c12018-03-14 12:55:34 -0700757 hdd_enter_dev(dev);
Jeff Johnson3c3994a2016-02-11 08:12:30 -0800758
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800759 if (!dev->ieee80211_ptr) {
Dustin Brownaeb55642018-07-30 17:20:32 -0700760 hdd_debug("ieee80211_ptr is null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800761 return NOTIFY_DONE;
762 }
763
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530764 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
765 if (!hdd_ctx) {
766 hdd_err("HDD Context is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800767 return NOTIFY_DONE;
768 }
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800769
770 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -0700771 hdd_debug("%s: Driver module is closed", __func__);
Jingxiang Ge9db9d232017-10-14 17:22:15 +0800772 return NOTIFY_DONE;
773 }
774
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530775 /* Make sure that this callback corresponds to our device. */
776 adapter = hdd_get_adapter_by_iface_name(hdd_ctx, dev->name);
777 if (!adapter) {
Dustin Brownaeb55642018-07-30 17:20:32 -0700778 hdd_debug("failed to look up adapter for '%s'", dev->name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800779 return NOTIFY_DONE;
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530780 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800781
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530782 if (adapter != WLAN_HDD_GET_PRIV_PTR(dev)) {
783 hdd_err("HDD adapter mismatch!");
784 return NOTIFY_DONE;
785 }
786
Dustin Brownaeb55642018-07-30 17:20:32 -0700787 if (cds_is_driver_recovering()) {
788 hdd_debug("Driver is recovering");
789 return NOTIFY_DONE;
790 }
791
792 if (cds_is_driver_in_bad_state()) {
793 hdd_debug("Driver is in failed recovery state");
Visweswara Tanuku6bc52de2018-04-09 18:38:30 +0530794 return NOTIFY_DONE;
795 }
796
797 hdd_debug("%s New Net Device State = %lu", dev->name, state);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800798
799 switch (state) {
800 case NETDEV_REGISTER:
801 break;
802
803 case NETDEV_UNREGISTER:
804 break;
805
806 case NETDEV_UP:
Jeff Johnson16528362018-06-14 12:34:16 -0700807 sme_ch_avoid_update_req(hdd_ctx->mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800808 break;
809
810 case NETDEV_DOWN:
811 break;
812
813 case NETDEV_CHANGE:
Jeff Johnsonc72c5732017-10-28 12:49:37 -0700814 if (adapter->is_link_up_service_needed)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800815 complete(&adapter->linkup_event_var);
816 break;
817
818 case NETDEV_GOING_DOWN:
Min Liu8c5d99e2018-09-10 17:18:44 +0800819 vdev = hdd_objmgr_get_vdev(adapter);
820 if (!vdev)
821 break;
822 if (ucfg_scan_get_vdev_status(vdev) !=
Sandeep Puligilla5f86d992017-10-29 14:58:53 -0700823 SCAN_NOT_IN_PROGRESS) {
Dustin Brown07901ec2018-09-07 11:02:41 -0700824 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
825 adapter->session_id, INVALID_SCAN_ID,
826 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800827 }
Min Liu8c5d99e2018-09-10 17:18:44 +0800828 hdd_objmgr_put_vdev(adapter);
Min Liu9be5d4a2018-05-17 11:51:53 +0800829 cds_flush_work(&adapter->scan_block_work);
830 /* Need to clean up blocked scan request */
831 wlan_hdd_cfg80211_scan_block_cb(&adapter->scan_block_work);
Min Liu9be5d4a2018-05-17 11:51:53 +0800832 hdd_debug("Scan is not Pending from user");
Arunk Khandavallif0c0d762017-12-07 10:18:50 +0530833 /*
834 * After NETDEV_GOING_DOWN, kernel calls hdd_stop.Irrespective
835 * of return status of hdd_stop call, kernel resets the IFF_UP
836 * flag after which driver does not send the cfg80211_scan_done.
837 * Ensure to cleanup the scan queue in NETDEV_GOING_DOWN
838 */
Dustin Brown07901ec2018-09-07 11:02:41 -0700839 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800840 break;
841
842 default:
843 break;
844 }
845
846 return NOTIFY_DONE;
847}
848
849/**
850 * hdd_netdev_notifier_call() - netdev notifier callback function
851 * @nb: pointer to notifier block
852 * @state: state
853 * @ndev: ndev pointer
854 *
855 * Return: 0 on success, error number otherwise.
856 */
857static int hdd_netdev_notifier_call(struct notifier_block *nb,
858 unsigned long state,
859 void *ndev)
860{
861 int ret;
862
863 cds_ssr_protect(__func__);
864 ret = __hdd_netdev_notifier_call(nb, state, ndev);
865 cds_ssr_unprotect(__func__);
866
867 return ret;
868}
869
870struct notifier_block hdd_netdev_notifier = {
871 .notifier_call = hdd_netdev_notifier_call,
872};
873
Arunk Khandavalli830c9692018-03-22 12:17:40 +0530874static int system_reboot_notifier_call(struct notifier_block *nb,
875 unsigned long msg_type, void *_unused)
876{
877 switch (msg_type) {
878 case SYS_DOWN:
879 case SYS_HALT:
880 case SYS_POWER_OFF:
881 g_is_system_reboot_triggered = true;
882 hdd_info("reboot, reason: %ld", msg_type);
883 break;
884 default:
885 break;
886 }
887
888 return NOTIFY_OK;
889}
890
891struct notifier_block system_reboot_notifier = {
892 .notifier_call = system_reboot_notifier_call,
893};
894
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800895/* variable to hold the insmod parameters */
896static int con_mode;
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800897
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530898static int con_mode_ftm;
Ravi Joshia307f632017-07-17 23:41:41 -0700899int con_mode_monitor;
Arunk Khandavalliba3d5582017-07-11 19:48:32 +0530900
Prashanth Bhatta05aaf012015-12-10 17:34:24 -0800901/* Variable to hold connection mode including module parameter con_mode */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800902static int curr_con_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800903
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530904/**
905 * hdd_map_nl_chan_width() - Map NL channel width to internal representation
906 * @ch_width: NL channel width
907 *
908 * Converts the NL channel width to the driver's internal representation
909 *
910 * Return: Converted channel width. In case of non matching NL channel width,
911 * CH_WIDTH_MAX will be returned.
912 */
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800913enum phy_ch_width hdd_map_nl_chan_width(enum nl80211_chan_width ch_width)
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530914{
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800915 uint8_t fw_ch_bw;
Srinivas Girigowdab841da72017-03-25 18:04:39 -0700916
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800917 fw_ch_bw = wma_get_vht_ch_width();
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530918 switch (ch_width) {
919 case NL80211_CHAN_WIDTH_20_NOHT:
920 case NL80211_CHAN_WIDTH_20:
921 return CH_WIDTH_20MHZ;
922 case NL80211_CHAN_WIDTH_40:
923 return CH_WIDTH_40MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530924 case NL80211_CHAN_WIDTH_80:
925 return CH_WIDTH_80MHZ;
926 case NL80211_CHAN_WIDTH_80P80:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800927 if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_80_PLUS_80MHZ)
928 return CH_WIDTH_80P80MHZ;
929 else if (fw_ch_bw == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
930 return CH_WIDTH_160MHZ;
931 else
932 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530933 case NL80211_CHAN_WIDTH_160:
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -0800934 if (fw_ch_bw >= WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
935 return CH_WIDTH_160MHZ;
936 else
937 return CH_WIDTH_80MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530938 case NL80211_CHAN_WIDTH_5:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800939 return CH_WIDTH_5MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530940 case NL80211_CHAN_WIDTH_10:
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800941 return CH_WIDTH_10MHZ;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530942 default:
943 hdd_err("Invalid channel width %d, setting to default",
944 ch_width);
Kiran Kumar Lokere13644672016-02-29 15:40:10 -0800945 return CH_WIDTH_INVALID;
Chandrasekaran, Manishekara74bb022016-01-12 18:37:43 +0530946 }
947}
948
Dustin Brown56377e12018-10-10 17:04:04 -0700949QDF_STATUS hdd_nl_to_qdf_iface_type(enum nl80211_iftype nl_type,
950 enum QDF_OPMODE *out_qdf_type)
951{
952 switch (nl_type) {
953 case NL80211_IFTYPE_ADHOC:
954 *out_qdf_type = QDF_IBSS_MODE;
955 break;
956 case NL80211_IFTYPE_AP:
957 *out_qdf_type = QDF_SAP_MODE;
958 break;
959 case NL80211_IFTYPE_MONITOR:
960 *out_qdf_type = QDF_MONITOR_MODE;
961 break;
962 case NL80211_IFTYPE_OCB:
963 *out_qdf_type = QDF_OCB_MODE;
964 break;
965 case NL80211_IFTYPE_P2P_CLIENT:
966 *out_qdf_type = QDF_P2P_CLIENT_MODE;
967 break;
968 case NL80211_IFTYPE_P2P_DEVICE:
969 *out_qdf_type = QDF_P2P_DEVICE_MODE;
970 break;
971 case NL80211_IFTYPE_P2P_GO:
972 *out_qdf_type = QDF_P2P_GO_MODE;
973 break;
974 case NL80211_IFTYPE_STATION:
975 *out_qdf_type = QDF_STA_MODE;
976 break;
977 case NL80211_IFTYPE_WDS:
978 *out_qdf_type = QDF_WDS_MODE;
979 break;
980 default:
981 hdd_err("Invalid nl80211 interface type %d", nl_type);
982 return QDF_STATUS_E_INVAL;
983 }
984
985 return QDF_STATUS_SUCCESS;
986}
987
Jeff Johnson16528362018-06-14 12:34:16 -0700988uint8_t wlan_hdd_find_opclass(mac_handle_t mac_handle, uint8_t channel,
989 uint8_t bw_offset)
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +0530990{
991 uint8_t opclass = 0;
992
Jeff Johnson16528362018-06-14 12:34:16 -0700993 sme_get_opclass(mac_handle, channel, bw_offset, &opclass);
Masti, Narayanraddic4a7ab82015-11-25 15:41:10 +0530994 return opclass;
995}
996
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800997/**
Anurag Chouhanf04e84f2016-03-03 10:12:12 +0530998 * hdd_qdf_trace_enable() - configure initial QDF Trace enable
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +0530999 * @module_id: Module whose trace level is being configured
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001000 * @bitmask: Bitmask of log levels to be enabled
1001 *
1002 * Called immediately after the cfg.ini is read in order to configure
1003 * the desired trace levels.
1004 *
1005 * Return: None
1006 */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301007int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001008{
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301009 QDF_TRACE_LEVEL level;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301010 int qdf_print_idx = -1;
1011 int status = -1;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001012 /*
1013 * if the bitmask is the default value, then a bitmask was not
1014 * specified in cfg.ini, so leave the logging level alone (it
1015 * will remain at the "compiled in" default value)
1016 */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001017 if (CFG_QDF_TRACE_ENABLE_DEFAULT == bitmask)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301018 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001019
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301020 qdf_print_idx = qdf_get_pidx();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001021
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301022 /* a mask was specified. start by disabling all logging */
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301023 status = qdf_print_set_category_verbose(qdf_print_idx, module_id,
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301024 QDF_TRACE_LEVEL_NONE, 0);
1025
1026 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301027 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001028 /* now cycle through the bitmask until all "set" bits are serviced */
Ashish Kumar Dhanotiya83f286b2017-09-15 19:52:58 +05301029 level = QDF_TRACE_LEVEL_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001030 while (0 != bitmask) {
1031 if (bitmask & 1) {
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301032 status = qdf_print_set_category_verbose(qdf_print_idx,
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301033 module_id, level, 1);
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +05301034 if (QDF_STATUS_SUCCESS != status)
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301035 return -EINVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001036 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001037
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001038 level++;
1039 bitmask >>= 1;
1040 }
Ashish Kumar Dhanotiya53c2f692017-02-08 00:25:11 +05301041 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001042}
1043
Dustin Brownda351e32018-07-23 15:48:22 -07001044int __wlan_hdd_validate_context(struct hdd_context *hdd_ctx, const char *func)
Chris Guo1751acf2017-07-03 14:09:01 +08001045{
Dustin Brownda351e32018-07-23 15:48:22 -07001046 if (!hdd_ctx) {
1047 hdd_err("HDD context is null (via %s)", func);
1048 return -ENODEV;
1049 }
1050
1051 if (!hdd_ctx->config) {
1052 hdd_err("HDD config is null (via %s)", func);
Chris Guo1751acf2017-07-03 14:09:01 +08001053 return -ENODEV;
1054 }
1055
1056 if (cds_is_driver_recovering()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001057 hdd_debug("Recovery in progress (via %s); state:0x%x",
1058 func, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001059 return -EAGAIN;
1060 }
1061
Yue Ma9f275d92017-09-14 16:58:41 -07001062 if (cds_is_load_or_unload_in_progress()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001063 hdd_debug("Load/unload in progress (via %s); state:0x%x",
1064 func, cds_get_driver_state());
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001065 return -EAGAIN;
Yue Ma9f275d92017-09-14 16:58:41 -07001066 }
Arun Khandavallia172c3e2016-08-26 17:33:13 +05301067
Dustin Brownda351e32018-07-23 15:48:22 -07001068 if (hdd_ctx->start_modules_in_progress) {
1069 hdd_debug("Start modules in progress (via %s)", func);
1070 return -EAGAIN;
1071 }
1072
1073 if (hdd_ctx->stop_modules_in_progress) {
1074 hdd_debug("Stop modules in progress (via %s)", func);
Arun Khandavallia172c3e2016-08-26 17:33:13 +05301075 return -EAGAIN;
1076 }
1077
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301078 if (cds_is_driver_in_bad_state()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001079 hdd_debug("Driver in bad state (via %s); state:0x%x",
1080 func, cds_get_driver_state());
Sourav Mohapatra21b3c982018-04-03 17:33:03 +05301081 return -EAGAIN;
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301082 }
1083
Arunk Khandavalli2859fa12018-02-14 10:46:26 +05301084 if (cds_is_fw_down()) {
Dustin Brownda351e32018-07-23 15:48:22 -07001085 hdd_debug("FW is down (via %s); state:0x%x",
1086 func, cds_get_driver_state());
Sourav Mohapatra21b3c982018-04-03 17:33:03 +05301087 return -EAGAIN;
Arunk Khandavalli2859fa12018-02-14 10:46:26 +05301088 }
1089
Liangwei Dong858feb12018-05-21 01:52:46 -04001090 if (qdf_atomic_read(&hdd_ctx->con_mode_flag)) {
Dustin Brownda351e32018-07-23 15:48:22 -07001091 hdd_debug("Driver mode change in progress (via %s)", func);
Liangwei Dong858feb12018-05-21 01:52:46 -04001092 return -EAGAIN;
1093 }
1094
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001095 return 0;
1096}
1097
Dustin Browna8700cc2018-08-07 12:04:47 -07001098int __hdd_validate_adapter(struct hdd_adapter *adapter, const char *func)
Dustin Brownf13b8c32017-05-19 17:23:08 -07001099{
1100 if (!adapter) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001101 hdd_err("adapter is null (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001102 return -EINVAL;
1103 }
1104
1105 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001106 hdd_err("bad adapter magic (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001107 return -EINVAL;
1108 }
1109
1110 if (!adapter->dev) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001111 hdd_err("adapter net_device is null (via %s)", func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001112 return -EINVAL;
1113 }
1114
1115 if (!(adapter->dev->flags & IFF_UP)) {
Dustin Browna8700cc2018-08-07 12:04:47 -07001116 hdd_debug_rl("adapter '%s' is not up (via %s)",
1117 adapter->dev->name, func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001118 return -EAGAIN;
1119 }
1120
Dustin Browna8700cc2018-08-07 12:04:47 -07001121 return __wlan_hdd_validate_session_id(adapter->session_id, func);
Dustin Brownf13b8c32017-05-19 17:23:08 -07001122}
1123
Dustin Brown63500612018-08-07 11:36:09 -07001124int __wlan_hdd_validate_session_id(uint8_t session_id, const char *func)
1125{
1126 if (session_id == CSR_SESSION_ID_INVALID) {
1127 hdd_debug_rl("adapter is not up (via %s)", func);
1128 return -EINVAL;
1129 }
1130
1131 if (session_id >= CSR_ROAM_SESSION_MAX) {
1132 hdd_err("bad session Id:%u (via %s)", session_id, func);
1133 return -EINVAL;
1134 }
1135
1136 return 0;
1137}
1138
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05301139QDF_STATUS __wlan_hdd_validate_mac_address(struct qdf_mac_addr *mac_addr,
1140 const char *func)
1141{
1142 if (!mac_addr) {
1143 hdd_err("Received NULL mac address (via %s)", func);
1144 return QDF_STATUS_E_INVAL;
1145 }
1146
1147 if (qdf_is_macaddr_zero(mac_addr)) {
1148 hdd_err("MAC is all zero (via %s)", func);
1149 return QDF_STATUS_E_INVAL;
1150 }
1151
1152 if (qdf_is_macaddr_broadcast(mac_addr)) {
1153 hdd_err("MAC is Broadcast (via %s)", func);
1154 return QDF_STATUS_E_INVAL;
1155 }
1156
1157 if (QDF_NET_IS_MAC_MULTICAST(mac_addr->bytes)) {
1158 hdd_err("MAC is Multicast (via %s)", func);
1159 return QDF_STATUS_E_INVAL;
1160 }
1161
1162 return QDF_STATUS_SUCCESS;
1163}
1164
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001165/**
Arun Khandavallica892f62017-05-26 14:25:50 +05301166 * wlan_hdd_validate_modules_state() - Check modules status
1167 * @hdd_ctx: HDD context pointer
1168 *
1169 * Check's the driver module's state and returns true if the
1170 * modules are enabled returns false if modules are closed.
1171 *
1172 * Return: True if modules are enabled or false.
1173 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001174bool wlan_hdd_validate_modules_state(struct hdd_context *hdd_ctx)
Arun Khandavallica892f62017-05-26 14:25:50 +05301175{
1176 mutex_lock(&hdd_ctx->iface_change_lock);
1177 if (hdd_ctx->driver_status != DRIVER_MODULES_ENABLED) {
1178 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown5e89ef82018-03-14 11:50:23 -07001179 hdd_info("Modules not enabled, Present status: %d",
1180 hdd_ctx->driver_status);
Arun Khandavallica892f62017-05-26 14:25:50 +05301181 return false;
1182 }
1183 mutex_unlock(&hdd_ctx->iface_change_lock);
1184 return true;
1185}
1186
1187/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001188 * hdd_set_ibss_power_save_params() - update IBSS Power Save params to WMA.
Jeff Johnson9d295242017-08-29 14:39:48 -07001189 * @struct hdd_adapter Hdd adapter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001190 *
1191 * This function sets the IBSS power save config parameters to WMA
1192 * which will send it to firmware if FW supports IBSS power save
1193 * before vdev start.
1194 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301195 * Return: QDF_STATUS QDF_STATUS_SUCCESS on Success and QDF_STATUS_E_FAILURE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001196 * on failure.
1197 */
Jeff Johnson9d295242017-08-29 14:39:48 -07001198QDF_STATUS hdd_set_ibss_power_save_params(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001199{
1200 int ret;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001201 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001202
1203 if (hdd_ctx == NULL) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001204 hdd_err("HDD context is null");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301205 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001206 }
1207
Jeff Johnson1b780e42017-10-31 14:11:45 -07001208 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001209 WMA_VDEV_IBSS_SET_ATIM_WINDOW_SIZE,
1210 hdd_ctx->config->ibssATIMWinSize,
1211 VDEV_CMD);
1212 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001213 hdd_err("atim window set failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301214 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001215 }
1216
Jeff Johnson1b780e42017-10-31 14:11:45 -07001217 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001218 WMA_VDEV_IBSS_SET_POWER_SAVE_ALLOWED,
1219 hdd_ctx->config->isIbssPowerSaveAllowed,
1220 VDEV_CMD);
1221 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001222 hdd_err("power save allow failed %d",
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001223 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301224 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001225 }
1226
Jeff Johnson1b780e42017-10-31 14:11:45 -07001227 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001228 WMA_VDEV_IBSS_SET_POWER_COLLAPSE_ALLOWED,
1229 hdd_ctx->config->
1230 isIbssPowerCollapseAllowed, VDEV_CMD);
1231 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001232 hdd_err("power collapse allow failed %d",
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001233 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301234 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001235 }
1236
Jeff Johnson1b780e42017-10-31 14:11:45 -07001237 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001238 WMA_VDEV_IBSS_SET_AWAKE_ON_TX_RX,
1239 hdd_ctx->config->isIbssAwakeOnTxRx,
1240 VDEV_CMD);
1241 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001242 hdd_err("set awake on tx/rx failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301243 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001244 }
1245
Jeff Johnson1b780e42017-10-31 14:11:45 -07001246 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001247 WMA_VDEV_IBSS_SET_INACTIVITY_TIME,
1248 hdd_ctx->config->ibssInactivityCount,
1249 VDEV_CMD);
1250 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001251 hdd_err("set inactivity time failed %d", ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301252 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001253 }
1254
Jeff Johnson1b780e42017-10-31 14:11:45 -07001255 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001256 WMA_VDEV_IBSS_SET_TXSP_END_INACTIVITY_TIME,
1257 hdd_ctx->config->ibssTxSpEndInactivityTime,
1258 VDEV_CMD);
1259 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001260 hdd_err("set txsp end failed %d",
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001261 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301262 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001263 }
1264
Jeff Johnson1b780e42017-10-31 14:11:45 -07001265 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001266 WMA_VDEV_IBSS_PS_SET_WARMUP_TIME_SECS,
1267 hdd_ctx->config->ibssPsWarmupTime,
1268 VDEV_CMD);
1269 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001270 hdd_err("set ps warmup failed %d",
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001271 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301272 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001273 }
1274
Jeff Johnson1b780e42017-10-31 14:11:45 -07001275 ret = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001276 WMA_VDEV_IBSS_PS_SET_1RX_CHAIN_IN_ATIM_WINDOW,
1277 hdd_ctx->config->ibssPs1RxChainInAtimEnable,
1278 VDEV_CMD);
1279 if (0 != ret) {
Rajeev Kumareeeb6f22018-07-12 11:10:27 -07001280 hdd_err("set 1rx chain atim failed %d",
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001281 ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301282 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001283 }
1284
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301285 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001286}
1287
Yue Macd359b72017-10-03 15:21:00 -07001288#ifdef FEATURE_RUNTIME_PM
1289/**
1290 * hdd_runtime_suspend_context_init() - API to initialize HDD Runtime Contexts
1291 * @hdd_ctx: HDD context
1292 *
1293 * Return: None
1294 */
1295static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx)
1296{
1297 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1298
Yue Macd359b72017-10-03 15:21:00 -07001299 qdf_runtime_lock_init(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001300 qdf_runtime_lock_init(&ctx->connect);
Yue Macd359b72017-10-03 15:21:00 -07001301
Dustin Brown07901ec2018-09-07 11:02:41 -07001302 wlan_scan_runtime_pm_init(hdd_ctx->pdev);
Yue Macd359b72017-10-03 15:21:00 -07001303}
1304
1305/**
1306 * hdd_runtime_suspend_context_deinit() - API to deinit HDD runtime context
1307 * @hdd_ctx: HDD Context
1308 *
1309 * Return: None
1310 */
1311static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx)
1312{
1313 struct hdd_runtime_pm_context *ctx = &hdd_ctx->runtime_context;
1314
Yue Macd359b72017-10-03 15:21:00 -07001315 qdf_runtime_lock_deinit(&ctx->dfs);
Jingxiang Geb49aa302018-01-17 20:54:15 +08001316 qdf_runtime_lock_deinit(&ctx->connect);
Yue Macd359b72017-10-03 15:21:00 -07001317
Dustin Brown07901ec2018-09-07 11:02:41 -07001318 wlan_scan_runtime_pm_deinit(hdd_ctx->pdev);
Yue Macd359b72017-10-03 15:21:00 -07001319}
1320
Yue Macd359b72017-10-03 15:21:00 -07001321#else /* FEATURE_RUNTIME_PM */
1322static void hdd_runtime_suspend_context_init(struct hdd_context *hdd_ctx) {}
1323static void hdd_runtime_suspend_context_deinit(struct hdd_context *hdd_ctx) {}
Yue Macd359b72017-10-03 15:21:00 -07001324#endif /* FEATURE_RUNTIME_PM */
1325
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001326#define INTF_MACADDR_MASK 0x7
1327
1328/**
1329 * hdd_update_macaddr() - update mac address
1330 * @config: hdd configuration
1331 * @hw_macaddr: mac address
1332 *
1333 * Mac address for multiple virtual interface is found as following
1334 * i) The mac address of the first interface is just the actual hw mac address.
1335 * ii) MSM 3 or 4 bits of byte5 of the actual mac address are used to
1336 * define the mac address for the remaining interfaces and locally
1337 * admistered bit is set. INTF_MACADDR_MASK is based on the number of
1338 * supported virtual interfaces, right now this is 0x07 (meaning 8
1339 * interface).
1340 * Byte[3] of second interface will be hw_macaddr[3](bit5..7) + 1,
1341 * for third interface it will be hw_macaddr[3](bit5..7) + 2, etc.
1342 *
1343 * Return: None
1344 */
1345void hdd_update_macaddr(struct hdd_config *config,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301346 struct qdf_mac_addr hw_macaddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001347{
1348 int8_t i;
1349 uint8_t macaddr_b3, tmp_br3;
1350
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301351 qdf_mem_copy(config->intfMacAddr[0].bytes, hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301352 QDF_MAC_ADDR_SIZE);
1353 for (i = 1; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301354 qdf_mem_copy(config->intfMacAddr[i].bytes, hw_macaddr.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301355 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001356 macaddr_b3 = config->intfMacAddr[i].bytes[3];
1357 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + i) &
1358 INTF_MACADDR_MASK;
1359 macaddr_b3 += tmp_br3;
1360
1361 /* XOR-ing bit-24 of the mac address. This will give enough
1362 * mac address range before collision
1363 */
1364 macaddr_b3 ^= (1 << 7);
1365
1366 /* Set locally administered bit */
1367 config->intfMacAddr[i].bytes[0] |= 0x02;
1368 config->intfMacAddr[i].bytes[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001369 hdd_debug("config->intfMacAddr[%d]: "
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001370 MAC_ADDRESS_STR, i,
1371 MAC_ADDR_ARRAY(config->intfMacAddr[i].bytes));
1372 }
1373}
1374
Kabilan Kannan44a58372017-12-06 18:16:11 -08001375static int hdd_update_tdls_config(struct hdd_context *hdd_ctx)
1376{
Dustin Brown1dbefe62018-09-11 16:32:03 -07001377 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001378 struct tdls_start_params tdls_cfg;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001379 QDF_STATUS status;
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301380 struct wlan_mlme_nss_chains vdev_ini_cfg;
1381
1382 /* Populate the nss chain params from ini for this vdev type */
1383 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
1384 QDF_TDLS_MODE,
1385 hdd_ctx->num_rf_chains);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001386
Dustin Brown1dbefe62018-09-11 16:32:03 -07001387 cfg_tdls_set_vdev_nss_2g(hdd_ctx->psoc,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301388 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ]);
Dustin Brown1dbefe62018-09-11 16:32:03 -07001389 cfg_tdls_set_vdev_nss_5g(hdd_ctx->psoc,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301390 vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ]);
jiad7b8a5e02018-11-26 16:37:57 +08001391 hdd_init_tdls_config(&tdls_cfg);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001392 tdls_cfg.tdls_del_all_peers = eWNI_SME_DEL_ALL_TDLS_PEERS;
1393 tdls_cfg.tdls_update_dp_vdev_flags = CDP_UPDATE_TDLS_FLAGS;
1394 tdls_cfg.tdls_event_cb = wlan_cfg80211_tdls_event_callback;
1395 tdls_cfg.tdls_evt_cb_data = psoc;
Jeff Johnson1d40f5b2018-03-02 08:35:53 -08001396 tdls_cfg.tdls_peer_context = hdd_ctx;
1397 tdls_cfg.tdls_reg_peer = hdd_tdls_register_peer;
1398 tdls_cfg.tdls_dereg_peer = hdd_tdls_deregister_peer;
Kabilan Kannan44a58372017-12-06 18:16:11 -08001399 tdls_cfg.tdls_wmm_cb = hdd_wmm_is_acm_allowed;
1400 tdls_cfg.tdls_wmm_cb_data = psoc;
1401 tdls_cfg.tdls_rx_cb = wlan_cfg80211_tdls_rx_callback;
1402 tdls_cfg.tdls_rx_cb_data = psoc;
1403 tdls_cfg.tdls_dp_vdev_update = hdd_update_dp_vdev_flags;
1404
1405 status = ucfg_tdls_update_config(psoc, &tdls_cfg);
1406 if (status != QDF_STATUS_SUCCESS) {
1407 hdd_err("failed pmo psoc configuration");
1408 return -EINVAL;
1409 }
1410
1411 hdd_ctx->tdls_umac_comp_active = true;
1412 /* enable napier specific tdls data path */
1413 hdd_ctx->tdls_nap_active = true;
1414
1415 return 0;
1416}
1417
Wu Gaoca416ff2018-09-17 11:05:07 +08001418#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1419static void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1420 struct wma_tgt_services *cfg)
1421{
1422 bool roam_offload_enable;
1423
Dustin Brown1dbefe62018-09-11 16:32:03 -07001424 ucfg_mlme_get_roaming_offload(hdd_ctx->psoc, &roam_offload_enable);
1425 ucfg_mlme_set_roaming_offload(hdd_ctx->psoc,
Wu Gaoca416ff2018-09-17 11:05:07 +08001426 roam_offload_enable &
1427 cfg->en_roam_offload);
1428}
1429#else
1430static inline void hdd_update_roam_offload(struct hdd_context *hdd_ctx,
1431 struct wma_tgt_services *cfg)
1432{
1433}
1434#endif
1435
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001436static void hdd_update_tgt_services(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001437 struct wma_tgt_services *cfg)
1438{
1439 struct hdd_config *config = hdd_ctx->config;
Wu Gao66454f12018-09-26 19:55:41 +08001440 bool arp_offload_enable;
Wu Gao1ab05582018-11-08 16:22:49 +08001441 bool mawc_enabled;
Wu Gaobdb7f272018-07-05 19:33:26 +08001442#ifdef FEATURE_WLAN_TDLS
1443 bool tdls_support;
1444 bool tdls_off_channel;
1445 bool tdls_buffer_sta;
1446 uint32_t tdls_uapsd_mask;
1447#endif
jiad7b8a5e02018-11-26 16:37:57 +08001448 bool value;
1449
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001450 /* Set up UAPSD */
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05301451 ucfg_mlme_set_sap_uapsd_flag(hdd_ctx->psoc, cfg->uapsd);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001452
Krishna Kumaar Natarajan4f1d7722017-03-03 21:12:51 -08001453 /* 11AX mode support */
1454 if ((config->dot11Mode == eHDD_DOT11_MODE_11ax ||
1455 config->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY) && !cfg->en_11ax)
1456 config->dot11Mode = eHDD_DOT11_MODE_11ac;
1457
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001458 /* 11AC mode support */
1459 if ((config->dot11Mode == eHDD_DOT11_MODE_11ac ||
1460 config->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY) && !cfg->en_11ac)
1461 config->dot11Mode = eHDD_DOT11_MODE_AUTO;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001462
1463 /* ARP offload: override user setting if invalid */
Wu Gao66454f12018-09-26 19:55:41 +08001464 arp_offload_enable =
1465 ucfg_pmo_is_arp_offload_enabled(hdd_ctx->psoc);
1466 ucfg_pmo_set_arp_offload_enabled(hdd_ctx->psoc,
1467 arp_offload_enable & cfg->arp_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001468#ifdef FEATURE_WLAN_SCAN_PNO
1469 /* PNO offload */
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001470 hdd_debug("PNO Capability in f/w = %d", cfg->pno_offload);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001471 if (cfg->pno_offload)
1472 config->PnoOffload = true;
1473#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001474#ifdef FEATURE_WLAN_TDLS
Dustin Brown1dbefe62018-09-11 16:32:03 -07001475 cfg_tdls_get_support_enable(hdd_ctx->psoc, &tdls_support);
1476 cfg_tdls_set_support_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001477 tdls_support & cfg->en_tdls);
1478
Dustin Brown1dbefe62018-09-11 16:32:03 -07001479 cfg_tdls_get_off_channel_enable(hdd_ctx->psoc, &tdls_off_channel);
1480 cfg_tdls_set_off_channel_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001481 tdls_off_channel &&
1482 cfg->en_tdls_offchan);
1483
Dustin Brown1dbefe62018-09-11 16:32:03 -07001484 cfg_tdls_get_buffer_sta_enable(hdd_ctx->psoc, &tdls_buffer_sta);
1485 cfg_tdls_set_buffer_sta_enable(hdd_ctx->psoc,
Wu Gaobdb7f272018-07-05 19:33:26 +08001486 tdls_buffer_sta &&
1487 cfg->en_tdls_uapsd_buf_sta);
1488
Dustin Brown1dbefe62018-09-11 16:32:03 -07001489 cfg_tdls_get_uapsd_mask(hdd_ctx->psoc, &tdls_uapsd_mask);
Wu Gaobdb7f272018-07-05 19:33:26 +08001490 if (tdls_uapsd_mask && cfg->en_tdls_uapsd_sleep_sta)
Dustin Brown1dbefe62018-09-11 16:32:03 -07001491 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, true);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07001492 else
Dustin Brown1dbefe62018-09-11 16:32:03 -07001493 cfg_tdls_set_sleep_sta_enable(hdd_ctx->psoc, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001494#endif
Wu Gaoca416ff2018-09-17 11:05:07 +08001495 hdd_update_roam_offload(hdd_ctx, cfg);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05301496
Dustin Brown05d81302018-09-11 16:49:22 -07001497 if (ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value) ==
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05301498 QDF_STATUS_SUCCESS)
1499 value &= cfg->get_peer_info_enabled;
1500
Wu Gao1ab05582018-11-08 16:22:49 +08001501 ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled);
1502 ucfg_mlme_set_mawc_enabled(hdd_ctx->psoc,
1503 mawc_enabled & cfg->is_fw_mawc_capable);
Kabilan Kannan44a58372017-12-06 18:16:11 -08001504 hdd_update_tdls_config(hdd_ctx);
Jeff Johnson16528362018-06-14 12:34:16 -07001505 sme_update_tgt_services(hdd_ctx->mac_handle, cfg);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001506}
1507
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001508/**
1509 * hdd_update_vdev_nss() - sets the vdev nss
1510 * @hdd_ctx: HDD context
1511 *
1512 * Sets the Nss per vdev type based on INI
1513 *
1514 * Return: None
1515 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001516static void hdd_update_vdev_nss(struct hdd_context *hdd_ctx)
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001517{
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001518 uint8_t max_supp_nss = 1;
Jeff Johnson16528362018-06-14 12:34:16 -07001519 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301520 QDF_STATUS status;
1521 bool bval;
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001522
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301523 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
1524 if (!QDF_IS_STATUS_SUCCESS(status))
1525 hdd_err("unable to get vht_enable2x2");
1526
1527 if (bval && !cds_is_sub_20_mhz_enabled())
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001528 max_supp_nss = 2;
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301529
1530 hdd_debug("max nss %d", max_supp_nss);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001531
Jeff Johnson16528362018-06-14 12:34:16 -07001532 mac_handle = hdd_ctx->mac_handle;
1533 sme_update_vdev_type_nss(mac_handle, max_supp_nss,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301534 NSS_CHAINS_BAND_2GHZ);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001535
Jeff Johnson16528362018-06-14 12:34:16 -07001536 sme_update_vdev_type_nss(mac_handle, max_supp_nss,
gaurank kathpalia651abcd2018-11-12 22:41:23 +05301537 NSS_CHAINS_BAND_5GHZ);
Kiran Kumar Lokere666bf852016-05-02 12:23:02 -07001538}
1539
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301540/**
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301541 * hdd_update_wiphy_vhtcap() - Updates wiphy vhtcap fields
1542 * @hdd_ctx: HDD context
1543 *
1544 * Updates wiphy vhtcap fields
1545 *
1546 * Return: None
1547 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001548static void hdd_update_wiphy_vhtcap(struct hdd_context *hdd_ctx)
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301549{
1550 struct ieee80211_supported_band *band_5g =
1551 hdd_ctx->wiphy->bands[NL80211_BAND_5GHZ];
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301552 QDF_STATUS status;
1553 uint8_t value = 0, value1 = 0;
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301554
1555 if (!band_5g) {
1556 hdd_debug("5GHz band disabled, skipping capability population");
1557 return;
1558 }
1559
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301560 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
1561 &value);
1562 if (!QDF_IS_STATUS_SUCCESS(status))
1563 hdd_err("unable to get tx_bfee_ant_supp");
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301564
Abhinav Kumare057b412018-10-09 17:28:16 +05301565 band_5g->vht_cap.cap |=
1566 (value << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301567
1568 value1 = NUM_OF_SOUNDING_DIMENSIONS;
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301569 band_5g->vht_cap.cap |=
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301570 (value1 << IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301571
Dustin Brown7e761c72018-07-31 13:50:17 -07001572 hdd_debug("Updated wiphy vhtcap:0x%x, CSNAntSupp:%d, NumSoundDim:%d",
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301573 band_5g->vht_cap.cap, value, value1);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05301574}
1575
1576/**
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301577 * hdd_update_hw_dbs_capable() - sets the dbs capability of the device
1578 * @hdd_ctx: HDD context
1579 *
1580 * Sets the DBS capability as per INI and firmware capability
1581 *
1582 * Return: None
1583 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001584static void hdd_update_hw_dbs_capable(struct hdd_context *hdd_ctx)
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301585{
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301586 uint8_t hw_dbs_capable = 0;
Krunal Sonidf29bc42018-11-15 13:26:29 -08001587 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
1588 QDF_STATUS status;
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301589
Krunal Sonidf29bc42018-11-15 13:26:29 -08001590 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
1591 &dual_mac_feature);
1592 if (status != QDF_STATUS_SUCCESS)
1593 hdd_err("can't get dual_mac_feature value");
1594 if (policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc)) {
1595 switch (dual_mac_feature) {
1596 case ENABLE_DBS_CXN_AND_SCAN:
1597 case ENABLE_DBS_CXN_AND_ENABLE_SCAN_WITH_ASYNC_SCAN_OFF:
1598 case ENABLE_DBS_CXN_AND_DISABLE_SIMULTANEOUS_SCAN:
1599 hw_dbs_capable = 1;
1600 break;
1601 default:
1602 hw_dbs_capable = 0;
1603 break;
1604 }
1605 }
Jeff Johnson16528362018-06-14 12:34:16 -07001606 sme_update_hw_dbs_capable(hdd_ctx->mac_handle, hw_dbs_capable);
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05301607}
1608
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001609static void hdd_update_tgt_ht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001610 struct wma_tgt_ht_cap *cfg)
1611{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301612 QDF_STATUS status;
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301613 qdf_size_t value_len;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301614 uint32_t value;
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301615 uint8_t mpdu_density;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301616 struct mlme_ht_capabilities_info ht_cap_info;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001617 uint8_t mcs_set[SIZE_OF_SUPPORTED_MCS_SET];
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301618 bool b_enable1x1;
Jeff Johnson16528362018-06-14 12:34:16 -07001619
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001620 /* get the MPDU density */
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301621 status = ucfg_mlme_get_ht_mpdu_density(hdd_ctx->psoc, &mpdu_density);
1622 if (QDF_IS_STATUS_ERROR(status)) {
1623 hdd_err("could not get HT MPDU Density");
1624 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001625 }
1626
1627 /*
1628 * MPDU density:
1629 * override user's setting if value is larger
1630 * than the one supported by target
1631 */
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05301632 if (mpdu_density > cfg->mpdu_density) {
1633 status = ucfg_mlme_set_ht_mpdu_density(hdd_ctx->psoc,
1634 cfg->mpdu_density);
1635 if (QDF_IS_STATUS_ERROR(status))
1636 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001637 }
1638
1639 /* get the HT capability info */
Dustin Brown1dbefe62018-09-11 16:32:03 -07001640 status = ucfg_mlme_get_ht_cap_info(hdd_ctx->psoc, &ht_cap_info);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301641 if (QDF_STATUS_SUCCESS != status) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001642 hdd_err("could not get HT capability info");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001643 return;
1644 }
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05301645
1646 /* check and update RX STBC */
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301647 if (ht_cap_info.rx_stbc && !cfg->ht_rx_stbc)
1648 ht_cap_info.rx_stbc = cfg->ht_rx_stbc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001649
1650 /* Set the LDPC capability */
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301651 ht_cap_info.adv_coding_cap = cfg->ht_rx_ldpc;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001652
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301653 if (ht_cap_info.short_gi_20_mhz && !cfg->ht_sgi_20)
1654 ht_cap_info.short_gi_20_mhz = cfg->ht_sgi_20;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001655
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301656 if (ht_cap_info.short_gi_40_mhz && !cfg->ht_sgi_40)
1657 ht_cap_info.short_gi_40_mhz = cfg->ht_sgi_40;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001658
1659 hdd_ctx->num_rf_chains = cfg->num_rf_chains;
1660 hdd_ctx->ht_tx_stbc_supported = cfg->ht_tx_stbc;
1661
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301662 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &b_enable1x1);
1663 if (!QDF_IS_STATUS_SUCCESS(status))
1664 hdd_err("unable to get vht_enable2x2");
1665
1666 b_enable1x1 = b_enable1x1 && (cfg->num_rf_chains == 2);
1667
1668 status = ucfg_mlme_set_vht_enable2x2(hdd_ctx->psoc, b_enable1x1);
1669 if (!QDF_IS_STATUS_SUCCESS(status))
1670 hdd_err("unable to set vht_enable2x2");
1671
Abhinav Kumare057b412018-10-09 17:28:16 +05301672 if (!b_enable1x1) {
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301673 ht_cap_info.tx_stbc = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001674
1675 /* 1x1 */
1676 /* Update Rx Highest Long GI data Rate */
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301677 status = ucfg_mlme_cfg_set_vht_rx_supp_data_rate(
1678 hdd_ctx->psoc,
1679 VHT_RX_HIGHEST_SUPPORTED_DATA_RATE_1_1);
1680 if (!QDF_IS_STATUS_SUCCESS(status))
1681 hdd_err("Failed to set rx_supp_data_rate");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001682 /* Update Tx Highest Long GI data Rate */
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301683 status = ucfg_mlme_cfg_set_vht_tx_supp_data_rate(
1684 hdd_ctx->psoc,
1685 VHT_TX_HIGHEST_SUPPORTED_DATA_RATE_1_1);
1686 if (!QDF_IS_STATUS_SUCCESS(status))
1687 hdd_err("Failed to set tx_supp_data_rate");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001688 }
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301689 if (!(cfg->ht_tx_stbc && b_enable1x1))
Vignesh Viswanathan78182502018-08-06 15:13:30 +05301690 ht_cap_info.tx_stbc = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001691
Dustin Brown1dbefe62018-09-11 16:32:03 -07001692 status = ucfg_mlme_set_ht_cap_info(hdd_ctx->psoc, ht_cap_info);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301693 if (status != QDF_STATUS_SUCCESS)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001694 hdd_err("could not set HT capability to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001695#define WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES 0xff
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301696 value_len = SIZE_OF_SUPPORTED_MCS_SET;
1697 if (ucfg_mlme_get_supported_mcs_set(
1698 hdd_ctx->psoc, mcs_set,
1699 &value_len) == QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001700 hdd_debug("Read MCS rate set");
gaurank kathpalia18b49362018-04-15 23:12:03 +05301701 if (cfg->num_rf_chains > SIZE_OF_SUPPORTED_MCS_SET)
1702 cfg->num_rf_chains = SIZE_OF_SUPPORTED_MCS_SET;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301703
1704 if (b_enable1x1) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001705 for (value = 0; value < cfg->num_rf_chains; value++)
1706 mcs_set[value] =
1707 WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES;
1708
Karthik Kantamnenie3bbd7f2018-09-19 20:27:32 +05301709 status = ucfg_mlme_set_supported_mcs_set(
1710 hdd_ctx->psoc,
1711 mcs_set,
1712 (qdf_size_t)SIZE_OF_SUPPORTED_MCS_SET);
1713 if (QDF_IS_STATUS_ERROR(status))
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001714 hdd_err("could not set MCS SET to CCM");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001715 }
1716 }
1717#undef WLAN_HDD_RX_MCS_ALL_NSTREAM_RATES
1718}
1719
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001720static void hdd_update_tgt_vht_cap(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001721 struct wma_tgt_vht_cap *cfg)
1722{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301723 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001724 struct wiphy *wiphy = hdd_ctx->wiphy;
1725 struct ieee80211_supported_band *band_5g =
Srinivas Girigowda11c28e02017-06-27 20:06:21 -07001726 wiphy->bands[HDD_NL80211_BAND_5GHZ];
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001727 uint32_t ch_width = eHT_CHANNEL_WIDTH_80MHZ;
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001728 struct wma_caps_per_phy caps_per_phy;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301729 uint8_t val = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730
Dustin Brown5e06bd32016-10-04 12:49:10 -07001731 if (!band_5g) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001732 hdd_debug("5GHz band disabled, skipping capability population");
Dustin Brown5e06bd32016-10-04 12:49:10 -07001733 return;
1734 }
1735
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301736 status = ucfg_mlme_update_vht_cap(hdd_ctx->psoc, cfg);
1737 if (QDF_IS_STATUS_ERROR(status))
1738 hdd_err("could not update vht capabilities");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001739
1740 if (WMI_VHT_CAP_MAX_MPDU_LEN_11454 == cfg->vht_max_mpdu)
1741 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
1742 else if (WMI_VHT_CAP_MAX_MPDU_LEN_7935 == cfg->vht_max_mpdu)
1743 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
1744 else
1745 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
1746
1747
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001748 if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_80P80MHZ)) {
Abhinav Kumare057b412018-10-09 17:28:16 +05301749 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc,
1750 VHT_CAP_160_AND_80P80_SUPP);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301751 if (QDF_IS_STATUS_ERROR(status))
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001752 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001753 band_5g->vht_cap.cap |=
1754 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001755 ch_width = eHT_CHANNEL_WIDTH_80P80MHZ;
1756 } else if (cfg->supp_chan_width & (1 << eHT_CHANNEL_WIDTH_160MHZ)) {
Abhinav Kumare057b412018-10-09 17:28:16 +05301757 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc,
1758 VHT_CAP_160_SUPP);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301759 if (QDF_IS_STATUS_ERROR(status))
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08001760 hdd_err("could not set the VHT CAP 160");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001761 band_5g->vht_cap.cap |=
1762 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001763 ch_width = eHT_CHANNEL_WIDTH_160MHZ;
1764 }
Kiran Kumar Lokere4bbbd0d2017-02-07 00:06:43 -08001765
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301766 status =
1767 ucfg_mlme_cfg_get_vht_chan_width(hdd_ctx->psoc, &val);
1768 if (QDF_IS_STATUS_ERROR(status))
1769 hdd_err("could not get channel_width");
1770
1771 val = QDF_MIN(val, ch_width);
Abhinav Kumare057b412018-10-09 17:28:16 +05301772 status = ucfg_mlme_set_vht_ch_width(hdd_ctx->psoc, val);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301773 if (QDF_IS_STATUS_ERROR(status))
1774 hdd_err("could not set the channel width");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001775
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001776 if (cfg->vht_rx_ldpc & WMI_VHT_CAP_RX_LDPC) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001777 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
Sandeep Puligilla305d5092018-04-16 14:40:50 -07001778 hdd_debug("VHT RxLDPC capability is set");
1779 } else {
1780 /*
1781 * Get the RX LDPC capability for the NON DBS
1782 * hardware mode for 5G band
1783 */
1784 status = wma_get_caps_for_phyidx_hwmode(&caps_per_phy,
1785 HW_MODE_DBS_NONE, CDS_BAND_5GHZ);
1786 if ((QDF_IS_STATUS_SUCCESS(status)) &&
1787 (caps_per_phy.vht_5g & WMI_VHT_CAP_RX_LDPC)) {
1788 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXLDPC;
1789 hdd_debug("VHT RX LDPC capability is set");
1790 }
1791 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001792
1793 if (cfg->vht_short_gi_80 & WMI_VHT_CAP_SGI_80MHZ)
1794 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
1795 if (cfg->vht_short_gi_160 & WMI_VHT_CAP_SGI_160MHZ)
1796 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
1797
1798 if (cfg->vht_tx_stbc & WMI_VHT_CAP_TX_STBC)
1799 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_TXSTBC;
1800
1801 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_1SS)
1802 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_1;
1803 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_2SS)
1804 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_2;
1805 if (cfg->vht_rx_stbc & WMI_VHT_CAP_RX_STBC_3SS)
1806 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_RXSTBC_3;
1807
1808 band_5g->vht_cap.cap |=
1809 (cfg->vht_max_ampdu_len_exp <<
1810 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT);
1811
1812 if (cfg->vht_su_bformer & WMI_VHT_CAP_SU_BFORMER)
1813 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
1814 if (cfg->vht_su_bformee & WMI_VHT_CAP_SU_BFORMEE)
1815 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
1816 if (cfg->vht_mu_bformer & WMI_VHT_CAP_MU_BFORMER)
1817 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
1818 if (cfg->vht_mu_bformee & WMI_VHT_CAP_MU_BFORMEE)
1819 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
1820
1821 if (cfg->vht_txop_ps & WMI_VHT_CAP_TXOP_PS)
1822 band_5g->vht_cap.cap |= IEEE80211_VHT_CAP_VHT_TXOP_PS;
1823
1824}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001825
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001826/**
1827 * hdd_generate_macaddr_auto() - Auto-generate mac address
1828 * @hdd_ctx: Pointer to the HDD context
1829 *
1830 * Auto-generate mac address using device serial number.
1831 * Keep the first 3 bytes of OUI as before and replace
1832 * the last 3 bytes with the lower 3 bytes of serial number.
1833 *
1834 * Return: 0 for success
1835 * Non zero failure code for errors
1836 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001837static int hdd_generate_macaddr_auto(struct hdd_context *hdd_ctx)
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001838{
1839 unsigned int serialno = 0;
1840 struct qdf_mac_addr mac_addr = {
1841 {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00}
1842 };
1843
Yuanyuan Liuf97e8222016-09-21 10:31:38 -07001844 serialno = pld_socinfo_get_serial_number(hdd_ctx->parent_dev);
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07001845 if (serialno == 0)
1846 return -EINVAL;
1847
1848 serialno &= 0x00ffffff;
1849
1850 mac_addr.bytes[3] = (serialno >> 16) & 0xff;
1851 mac_addr.bytes[4] = (serialno >> 8) & 0xff;
1852 mac_addr.bytes[5] = serialno & 0xff;
1853
1854 hdd_update_macaddr(hdd_ctx->config, mac_addr);
1855 return 0;
1856}
1857
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301858/**
1859 * hdd_update_ra_rate_limit() - Update RA rate limit from target
1860 * configuration to cfg_ini in HDD
1861 * @hdd_ctx: Pointer to hdd_ctx
1862 * @cfg: target configuration
1863 *
1864 * Return: None
1865 */
1866#ifdef FEATURE_WLAN_RA_FILTERING
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001867static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301868 struct wma_tgt_cfg *cfg)
1869{
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05301870 ucfg_fwol_set_is_rate_limit_enabled(hdd_ctx->psoc,
1871 cfg->is_ra_rate_limit_enabled);
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301872}
1873#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07001874static void hdd_update_ra_rate_limit(struct hdd_context *hdd_ctx,
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05301875 struct wma_tgt_cfg *cfg)
1876{
1877}
1878#endif
1879
Jeff Johnsonf9176382018-07-17 19:15:58 -07001880static void hdd_sar_target_config(struct hdd_context *hdd_ctx,
1881 struct wma_tgt_cfg *cfg)
1882{
1883 hdd_ctx->sar_version = cfg->sar_version;
1884}
1885
Jeff Johnson8abc5932018-06-02 22:51:37 -07001886void hdd_update_tgt_cfg(hdd_handle_t hdd_handle, struct wma_tgt_cfg *cfg)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001887{
Rajeev Kumarf49dfdb2017-01-13 15:40:35 -08001888 int ret;
Jeff Johnsonea70b942018-07-02 09:42:31 -07001889 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301890 uint8_t temp_band_cap, band_capability;
Naveen Rawat64e477e2016-05-20 10:34:56 -07001891 struct cds_config_info *cds_cfg = cds_get_ini_config();
Nitesh Shahe50711f2017-04-26 16:30:45 +05301892 uint8_t antenna_mode;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301893 uint8_t sub_20_chan_width;
Arif Hussainee10f902017-12-27 16:30:17 -08001894 QDF_STATUS status;
Jeff Johnson16528362018-06-14 12:34:16 -07001895 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05301896 bool bval = false;
1897 uint8_t value = 0;
Arif Hussainbd5194c2018-11-27 19:01:15 -08001898 uint32_t fine_time_meas_cap = 0;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301899
gaurank kathpalia843f7c32018-07-02 18:04:14 +05301900 if (!hdd_ctx) {
1901 hdd_err("HDD context is NULL");
1902 return;
1903 }
Dustin Brownbd68fe12017-11-21 15:28:52 -08001904 ret = hdd_objmgr_create_and_store_pdev(hdd_ctx);
1905 if (ret) {
Dustin Brown64204d22018-08-15 16:35:19 -07001906 QDF_DEBUG_PANIC("Failed to create pdev; errno:%d", ret);
1907 return;
1908 }
1909
1910 hdd_debug("New pdev has been created with pdev_id = %u",
Dustin Brown07901ec2018-09-07 11:02:41 -07001911 hdd_ctx->pdev->pdev_objmgr.wlan_pdev_id);
Dustin Brown64204d22018-08-15 16:35:19 -07001912
Dustin Brown07901ec2018-09-07 11:02:41 -07001913 status = dispatcher_pdev_open(hdd_ctx->pdev);
Dustin Brown64204d22018-08-15 16:35:19 -07001914 if (QDF_IS_STATUS_ERROR(status)) {
1915 QDF_DEBUG_PANIC("dispatcher pdev open failed; status:%d",
1916 status);
1917 return;
Selvaraj, Sridhar0672a122016-12-29 16:11:48 +05301918 }
Kiran Kumar Lokerea3de2262017-04-12 12:15:04 -07001919
Sandeep Puligillab7beb472018-08-13 22:54:20 -07001920 status = hdd_component_pdev_open(hdd_ctx->pdev);
1921 if (QDF_IS_STATUS_ERROR(status)) {
1922 QDF_DEBUG_PANIC("hdd component pdev open failed; status:%d",
1923 status);
1924 return;
1925 }
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05301926 cdp_pdev_set_ctrl_pdev(cds_get_context(QDF_MODULE_ID_SOC),
1927 cds_get_context(QDF_MODULE_ID_TXRX),
Dustin Brown07901ec2018-09-07 11:02:41 -07001928 (struct cdp_ctrl_objmgr_pdev *)hdd_ctx->pdev);
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05301929
Dustin Brown07901ec2018-09-07 11:02:41 -07001930 wlan_pdev_set_dp_handle(hdd_ctx->pdev,
Sravan Kumar Kairamcb5fd012018-07-04 17:43:22 +05301931 cds_get_context(QDF_MODULE_ID_TXRX));
1932
Will Huang07244172018-05-14 14:23:30 +08001933 hdd_objmgr_update_tgt_max_vdev_psoc(hdd_ctx, cfg->max_intf_count);
1934
Dustin Brown1dbefe62018-09-11 16:32:03 -07001935 ucfg_ipa_set_dp_handle(hdd_ctx->psoc,
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05301936 cds_get_context(QDF_MODULE_ID_SOC));
Dustin Brown1dbefe62018-09-11 16:32:03 -07001937 ucfg_ipa_set_txrx_handle(hdd_ctx->psoc,
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05301938 cds_get_context(QDF_MODULE_ID_TXRX));
Dustin Brown07901ec2018-09-07 11:02:41 -07001939 ucfg_ipa_reg_sap_xmit_cb(hdd_ctx->pdev,
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05301940 hdd_softap_hard_start_xmit);
Dustin Brown07901ec2018-09-07 11:02:41 -07001941 ucfg_ipa_reg_send_to_nw_cb(hdd_ctx->pdev,
Sravan Kumar Kairam858073b2018-03-13 09:03:32 +05301942 hdd_ipa_send_skb_to_network);
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05301943
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301944 status = ucfg_mlme_get_sub_20_chan_width(hdd_ctx->psoc,
1945 &sub_20_chan_width);
1946 if (QDF_IS_STATUS_ERROR(status)) {
1947 hdd_err("Failed to get sub_20_chan_width config");
1948 return;
1949 }
1950
Naveen Rawat64e477e2016-05-20 10:34:56 -07001951 if (cds_cfg) {
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301952 if (sub_20_chan_width !=
1953 WLAN_SUB_20_CH_WIDTH_NONE && !cfg->sub_20_support) {
Naveen Rawat64e477e2016-05-20 10:34:56 -07001954 hdd_err("User requested sub 20 MHz channel width but unsupported by FW.");
1955 cds_cfg->sub_20_channel_width =
1956 WLAN_SUB_20_CH_WIDTH_NONE;
1957 } else {
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05301958 cds_cfg->sub_20_channel_width = sub_20_chan_width;
Naveen Rawat64e477e2016-05-20 10:34:56 -07001959 }
1960 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001961
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301962 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
1963 if (QDF_IS_STATUS_ERROR(status)) {
1964 hdd_err("Failed to get MLME band capability");
1965 return;
1966 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001967
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301968 /* first store the INI band capability */
1969 temp_band_cap = band_capability;
1970
1971 band_capability = cfg->band_cap;
Vignesh Viswanathan731186f2017-09-18 13:47:37 +05301972 hdd_ctx->is_fils_roaming_supported =
1973 cfg->services.is_fils_roaming_supported;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001974
Vignesh Viswanathan694e28e2018-01-18 20:53:57 +05301975 hdd_ctx->config->is_11k_offload_supported =
1976 cfg->services.is_11k_offload_supported;
1977
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08001978 /*
1979 * now overwrite the target band capability with INI
1980 * setting if INI setting is a subset
1981 */
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301982 if ((band_capability == BAND_ALL) &&
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001983 (temp_band_cap != BAND_ALL))
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301984 band_capability = temp_band_cap;
1985 else if ((band_capability != BAND_ALL) &&
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08001986 (temp_band_cap != BAND_ALL) &&
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301987 (band_capability != temp_band_cap)) {
Jeff Johnsonb8969cb2016-08-15 12:38:19 -07001988 hdd_warn("ini BandCapability not supported by the target");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001989 }
1990
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05301991 status = ucfg_mlme_set_band_capability(hdd_ctx->psoc, band_capability);
1992 if (QDF_IS_STATUS_ERROR(status)) {
1993 hdd_err("Failed to set MLME Band Capability");
1994 return;
1995 }
1996
1997 hdd_ctx->curr_band = band_capability;
Amar Singhal58b45ef2017-08-01 13:43:54 -07001998
Hanumanth Reddy Pothula2a8a7402017-07-03 14:06:11 +05301999 if (!cds_is_driver_recovering() || cds_is_driver_in_bad_state()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002000 hdd_ctx->reg.reg_domain = cfg->reg_domain;
2001 hdd_ctx->reg.eeprom_rd_ext = cfg->eeprom_rd_ext;
2002 }
2003
2004 /* This can be extended to other configurations like ht, vht cap... */
2005
Anurag Chouhanc5548422016-02-24 18:33:27 +05302006 if (!qdf_is_macaddr_zero(&cfg->hw_macaddr)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002007 hdd_update_macaddr(hdd_ctx->config, cfg->hw_macaddr);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07002008 hdd_ctx->update_mac_addr_to_fw = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002009 } else {
Yuanyuan Liu5bdfad72016-07-21 10:33:04 -07002010 static struct qdf_mac_addr default_mac_addr = {
2011 {0x00, 0x0A, 0xF5, 0x89, 0x89, 0xFF}
2012 };
2013 if (qdf_is_macaddr_equal(&hdd_ctx->config->intfMacAddr[0],
2014 &default_mac_addr)) {
2015 if (hdd_generate_macaddr_auto(hdd_ctx) != 0)
2016 hdd_err("Fail to auto-generate MAC, using MAC from ini file "
2017 MAC_ADDRESS_STR,
2018 MAC_ADDR_ARRAY(hdd_ctx->config->
2019 intfMacAddr[0].bytes));
2020 } else {
2021 hdd_err("Invalid MAC passed from target, using MAC from ini file "
2022 MAC_ADDRESS_STR,
2023 MAC_ADDR_ARRAY(hdd_ctx->config->
2024 intfMacAddr[0].bytes));
2025 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -07002026 hdd_ctx->update_mac_addr_to_fw = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002027 }
2028
2029 hdd_ctx->target_fw_version = cfg->target_fw_version;
Sandeep Puligilla3d6a8e22016-10-11 18:57:14 -07002030 hdd_ctx->target_fw_vers_ext = cfg->target_fw_vers_ext;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002031
Ryan Hsuc6918552018-05-16 13:29:59 -07002032 hdd_ctx->hw_bd_id = cfg->hw_bd_id;
2033 qdf_mem_copy(&hdd_ctx->hw_bd_info, &cfg->hw_bd_info,
2034 sizeof(cfg->hw_bd_info));
2035
Dustin Brownbee82832018-07-23 10:10:51 -07002036 if (cfg->max_intf_count > CSR_ROAM_SESSION_MAX) {
2037 hdd_err("fw max vdevs (%u) > host max vdevs (%u); using %u",
2038 cfg->max_intf_count, CSR_ROAM_SESSION_MAX,
2039 CSR_ROAM_SESSION_MAX);
2040 hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
2041 } else {
2042 hdd_ctx->max_intf_count = cfg->max_intf_count;
2043 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002044
Jeff Johnsonf9176382018-07-17 19:15:58 -07002045 hdd_sar_target_config(hdd_ctx, cfg);
Jeff Johnsonc875e242016-09-23 18:12:34 -07002046 hdd_lpass_target_config(hdd_ctx, cfg);
Ryan Hsu3c8f79f2015-12-02 16:45:09 -08002047
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002048 hdd_ctx->ap_arpns_support = cfg->ap_arpns_support;
2049 hdd_update_tgt_services(hdd_ctx, &cfg->services);
2050
2051 hdd_update_tgt_ht_cap(hdd_ctx, &cfg->ht_cap);
2052
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002053 hdd_update_tgt_vht_cap(hdd_ctx, &cfg->vht_cap);
Krishna Kumaar Natarajaned1efd92016-09-24 18:05:47 -07002054 if (cfg->services.en_11ax) {
2055 hdd_info("11AX: 11ax is enabled - update HDD config");
2056 hdd_update_tgt_he_cap(hdd_ctx, cfg);
2057 }
Varun Reddy Yeturue93d2462018-05-22 13:54:52 -07002058 hdd_update_tgt_twt_cap(hdd_ctx, cfg);
Tushnim Bhattacharyyaf44a9d82016-07-05 10:52:06 -07002059
2060 hdd_update_vdev_nss(hdd_ctx);
2061
Nitesh Shahdb5ea0d2017-03-22 15:17:47 +05302062 hdd_update_hw_dbs_capable(hdd_ctx);
gaurank kathpalia5fcefa92018-10-24 15:03:15 +05302063 hdd_ctx->dynamic_nss_chains_support =
2064 cfg->dynamic_nss_chains_support;
Arif Hussainbd5194c2018-11-27 19:01:15 -08002065 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc, &fine_time_meas_cap);
2066 fine_time_meas_cap &= cfg->fine_time_measurement_cap;
2067 status = ucfg_mlme_set_fine_time_meas_cap(hdd_ctx->psoc,
2068 fine_time_meas_cap);
2069 if (QDF_IS_STATUS_ERROR(status)) {
2070 hdd_err("failed to set fine_time_meas_cap, 0x%x, ox%x",
2071 fine_time_meas_cap, cfg->fine_time_measurement_cap);
2072 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
2073 &fine_time_meas_cap);
2074 }
2075
Krunal Sonie3531942016-04-12 17:43:53 -07002076 hdd_ctx->fine_time_meas_cap_target = cfg->fine_time_measurement_cap;
Arif Hussainbd5194c2018-11-27 19:01:15 -08002077 hdd_debug("fine_time_meas_cap: 0x%x", fine_time_meas_cap);
Archana Ramachandran393f3792015-11-13 17:13:21 -08002078
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302079 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
2080 if (!QDF_IS_STATUS_SUCCESS(status))
2081 hdd_err("unable to get vht_enable2x2");
2082
2083 antenna_mode = (bval == 0x01) ?
Nitesh Shahe50711f2017-04-26 16:30:45 +05302084 HDD_ANTENNA_MODE_2X2 : HDD_ANTENNA_MODE_1X1;
2085 hdd_update_smps_antenna_mode(hdd_ctx, antenna_mode);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002086 hdd_debug("Init current antenna mode: %d",
Arif Hussainee10f902017-12-27 16:30:17 -08002087 hdd_ctx->current_antenna_mode);
Archana Ramachandran393f3792015-11-13 17:13:21 -08002088
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05302089 hdd_ctx->rcpi_enabled = cfg->rcpi_enabled;
Anurag Chouhan04dbf6d2016-09-08 15:32:52 +05302090 hdd_update_ra_rate_limit(hdd_ctx, cfg);
Arun Khandavalli3dd06de2016-08-17 10:20:29 +05302091
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302092 status = ucfg_mlme_cfg_get_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
Abhinav Kumare057b412018-10-09 17:28:16 +05302093 &value);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302094 if (QDF_IS_STATUS_ERROR(status)) {
2095 status = false;
2096 hdd_err("set tx_bfee_ant_supp failed");
2097 }
2098
2099 if ((value >
Arif Hussainee10f902017-12-27 16:30:17 -08002100 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF) &&
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302101 !cfg->tx_bfee_8ss_enabled) {
2102 status =
2103 ucfg_mlme_cfg_set_vht_tx_bfee_ant_supp(hdd_ctx->psoc,
2104 WNI_CFG_VHT_CSN_BEAMFORMEE_ANT_SUPPORTED_FW_DEF);
2105 if (QDF_IS_STATUS_ERROR(status)) {
2106 status = false;
2107 hdd_err("set tx_bfee_ant_supp failed");
2108 }
2109 }
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302110
Jeff Johnson16528362018-06-14 12:34:16 -07002111 mac_handle = hdd_ctx->mac_handle;
Nachiket Kukade8b4bfd82017-05-25 18:34:48 +05302112
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05302113 hdd_debug("txBFCsnValue %d", value);
Nachiket Kukade33c34e32017-07-07 18:45:04 +05302114
2115 /*
2116 * Update txBFCsnValue and NumSoundingDim values to vhtcap in wiphy
2117 */
2118 hdd_update_wiphy_vhtcap(hdd_ctx);
Manjeet Singh70d3d932016-12-20 20:41:10 +05302119
Rajeev Kumar Sirasanagandla47873002016-09-09 13:46:09 +05302120 hdd_ctx->wmi_max_len = cfg->wmi_max_len;
2121
Yue Macd359b72017-10-03 15:21:00 -07002122 /*
2123 * This needs to be done after HDD pdev is created and stored since
2124 * it will access the HDD pdev object lock.
2125 */
2126 hdd_runtime_suspend_context_init(hdd_ctx);
2127
Deepak Dhamdhere13230d32016-05-26 00:46:53 -07002128 /* Configure NAN datapath features */
2129 hdd_nan_datapath_target_config(hdd_ctx, cfg);
Arif Hussain759a0232017-03-20 13:17:18 -07002130 hdd_ctx->dfs_cac_offload = cfg->dfs_cac_offload;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08002131 hdd_ctx->lte_coex_ant_share = cfg->services.lte_coex_ant_share;
Liangwei Dong0da14262018-07-03 03:30:23 -04002132 hdd_ctx->obss_scan_offload = cfg->services.obss_scan_offload;
Jeff Johnson16528362018-06-14 12:34:16 -07002133 status = sme_cfg_set_int(mac_handle, WNI_CFG_OBSS_DETECTION_OFFLOAD,
Arif Hussainee10f902017-12-27 16:30:17 -08002134 cfg->obss_detection_offloaded);
2135 if (QDF_IS_STATUS_ERROR(status))
2136 hdd_err("Couldn't pass WNI_CFG_OBSS_DETECTION_OFFLOAD to CFG");
Arif Hussain05fb4872018-01-03 16:02:55 -08002137
Jeff Johnson16528362018-06-14 12:34:16 -07002138 status = sme_cfg_set_int(mac_handle,
Arif Hussain05fb4872018-01-03 16:02:55 -08002139 WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD,
2140 cfg->obss_color_collision_offloaded);
2141 if (QDF_IS_STATUS_ERROR(status))
2142 hdd_err("Failed to set WNI_CFG_OBSS_COLOR_COLLISION_OFFLOAD");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002143}
2144
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002145bool hdd_dfs_indicate_radar(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002146{
Jeff Johnson9d295242017-08-29 14:39:48 -07002147 struct hdd_adapter *adapter;
Jeff Johnson87251032017-08-29 13:31:11 -07002148 struct hdd_ap_ctx *ap_ctx;
Arif Hussain224d3812018-11-16 17:58:38 -08002149 bool dfs_disable_channel_switch = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150
Jiachao Wuf610d912018-01-23 17:47:32 +08002151 if (!hdd_ctx) {
2152 hdd_info("Couldn't get hdd_ctx");
2153 return true;
2154 }
2155
Arif Hussain224d3812018-11-16 17:58:38 -08002156 ucfg_mlme_get_dfs_disable_channel_switch(hdd_ctx->psoc,
2157 &dfs_disable_channel_switch);
2158 if (dfs_disable_channel_switch) {
Jeff Johnson36e74c42017-09-18 08:15:42 -07002159 hdd_info("skip tx block hdd_ctx=%pK, disableDFSChSwitch=%d",
Arif Hussain224d3812018-11-16 17:58:38 -08002160 hdd_ctx, dfs_disable_channel_switch);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302161 return true;
Arif Hussaincd151632017-02-11 16:57:19 -08002162 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002163
Dustin Brown920397d2017-12-13 16:27:50 -08002164 hdd_for_each_adapter(hdd_ctx, adapter) {
Arif Hussaincd151632017-02-11 16:57:19 -08002165 ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
2166
2167 if ((QDF_SAP_MODE == adapter->device_mode ||
2168 QDF_P2P_GO_MODE == adapter->device_mode) &&
Dustin Brown07901ec2018-09-07 11:02:41 -07002169 (wlan_reg_is_passive_or_disable_ch(hdd_ctx->pdev,
Jeff Johnson01206862017-10-27 20:55:59 -07002170 ap_ctx->operating_channel))) {
Arif Hussaincd151632017-02-11 16:57:19 -08002171 WLAN_HDD_GET_AP_CTX_PTR(adapter)->dfs_cac_block_tx =
2172 true;
2173 hdd_info("tx blocked for session: %d",
Jeff Johnson1b780e42017-10-31 14:11:45 -07002174 adapter->session_id);
bings6fb9bf62018-07-05 14:01:53 +08002175 if (adapter->txrx_vdev)
2176 cdp_fc_vdev_flush(
2177 cds_get_context(QDF_MODULE_ID_SOC),
bings0e03a982018-05-09 08:40:59 +08002178 adapter->txrx_vdev);
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302179 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002180 }
Edhar, Mahesh Kumar695468e2015-10-19 12:06:20 +05302181
2182 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002183}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002184
Jeff Johnson030cd902018-11-11 10:19:40 -08002185bool hdd_is_valid_mac_address(const uint8_t *mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002186{
2187 int xdigit = 0;
2188 int separator = 0;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07002189
Jeff Johnson030cd902018-11-11 10:19:40 -08002190 while (*mac_addr) {
2191 if (isxdigit(*mac_addr)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002192 xdigit++;
Jeff Johnson030cd902018-11-11 10:19:40 -08002193 } else if (':' == *mac_addr) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002194 if (0 == xdigit || ((xdigit / 2) - 1) != separator)
2195 break;
2196
2197 ++separator;
2198 } else {
2199 /* Invalid MAC found */
Jeff Johnson030cd902018-11-11 10:19:40 -08002200 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002201 }
Jeff Johnson030cd902018-11-11 10:19:40 -08002202 ++mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002203 }
2204 return xdigit == 12 && (separator == 5 || separator == 0);
2205}
2206
2207/**
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302208 * hdd_mon_mode_ether_setup() - Update monitor mode struct net_device.
2209 * @dev: Handle to struct net_device to be updated.
2210 *
2211 * Return: None
2212 */
2213static void hdd_mon_mode_ether_setup(struct net_device *dev)
2214{
2215 dev->header_ops = NULL;
2216 dev->type = ARPHRD_IEEE80211_RADIOTAP;
2217 dev->hard_header_len = ETH_HLEN;
2218 dev->mtu = ETH_DATA_LEN;
2219 dev->addr_len = ETH_ALEN;
2220 dev->tx_queue_len = 1000; /* Ethernet wants good queues */
2221 dev->flags = IFF_BROADCAST|IFF_MULTICAST;
2222 dev->priv_flags |= IFF_TX_SKB_SHARING;
2223
2224 memset(dev->broadcast, 0xFF, ETH_ALEN);
2225}
2226
Nirav Shah73713f72018-05-17 14:50:41 +05302227#ifdef FEATURE_MONITOR_MODE_SUPPORT
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302228/**
chenguo71303962018-10-24 19:44:34 +08002229 * hdd_mon_turn_off_ps_and_wow() - Update monitor mode struct net_device.
2230 * @hdd_ctx: Pointer to HDD context.
2231 *
2232 * Return: None
2233 */
2234static void hdd_mon_turn_off_ps_and_wow(struct hdd_context *hdd_ctx)
2235{
2236 ucfg_pmo_set_power_save_mode(hdd_ctx->psoc, PS_NOT_SUPPORTED);
2237 ucfg_pmo_set_wow_enable(hdd_ctx->psoc, PMO_WOW_DISABLE_BOTH);
2238}
2239
2240/**
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002241 * __hdd__mon_open() - HDD Open function
2242 * @dev: Pointer to net_device structure
2243 *
2244 * This is called in response to ifconfig up
2245 *
2246 * Return: 0 for success; non-zero for failure
2247 */
2248static int __hdd_mon_open(struct net_device *dev)
2249{
2250 int ret;
Ravi Joshia307f632017-07-17 23:41:41 -07002251 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
2252 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002253
Dustin Brownfdf17c12018-03-14 12:55:34 -07002254 hdd_enter_dev(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002255
2256 ret = wlan_hdd_validate_context(hdd_ctx);
2257 if (ret)
2258 return ret;
2259
Arun Khandavallif5c0e0c2016-09-07 20:39:21 +05302260 hdd_mon_mode_ether_setup(dev);
Ravi Joshia307f632017-07-17 23:41:41 -07002261
2262 if (con_mode == QDF_GLOBAL_MONITOR_MODE) {
Dustin Brown3ecc8782018-09-19 16:37:13 -07002263 ret = hdd_psoc_idle_restart(hdd_ctx);
Ravi Joshia307f632017-07-17 23:41:41 -07002264 if (ret) {
2265 hdd_err("Failed to start WLAN modules return");
2266 return ret;
2267 }
2268 hdd_err("hdd_wlan_start_modules() successful !");
2269
2270 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
2271 ret = hdd_start_adapter(adapter);
2272 if (ret) {
2273 hdd_err("Failed to start adapter :%d",
2274 adapter->device_mode);
2275 return ret;
2276 }
2277 hdd_err("hdd_start_adapters() successful !");
2278 }
chenguo71303962018-10-24 19:44:34 +08002279 hdd_mon_turn_off_ps_and_wow(hdd_ctx);
Ravi Joshia307f632017-07-17 23:41:41 -07002280 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
2281 }
2282
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002283 ret = hdd_set_mon_rx_cb(dev);
Ravi Joshi4f095952017-06-29 15:39:19 -07002284
2285 if (!ret)
2286 ret = hdd_enable_monitor_mode(dev);
2287
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002288 return ret;
2289}
2290
2291/**
2292 * hdd_mon_open() - Wrapper function for __hdd_mon_open to protect it from SSR
2293 * @dev: Pointer to net_device structure
2294 *
2295 * This is called in response to ifconfig up
2296 *
2297 * Return: 0 for success; non-zero for failure
2298 */
Jeff Johnson590e2012016-10-05 16:16:24 -07002299static int hdd_mon_open(struct net_device *dev)
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002300{
2301 int ret;
2302
2303 cds_ssr_protect(__func__);
2304 ret = __hdd_mon_open(dev);
2305 cds_ssr_unprotect(__func__);
2306
2307 return ret;
2308}
Nirav Shah73713f72018-05-17 14:50:41 +05302309#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002310
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002311static QDF_STATUS
2312wlan_hdd_update_dbs_scan_and_fw_mode_config(void)
2313{
2314 struct policy_mgr_dual_mac_config cfg = {0};
2315 QDF_STATUS status;
Krunal Soni13b50f82018-09-27 12:37:03 -07002316 uint32_t channel_select_logic_conc = 0;
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002317 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Krunal Sonidf29bc42018-11-15 13:26:29 -08002318 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002319
2320 if (!hdd_ctx) {
2321 hdd_err("HDD context is NULL");
2322 return QDF_STATUS_E_FAILURE;
2323 }
2324
2325
Dustin Brown1dbefe62018-09-11 16:32:03 -07002326 if (!policy_mgr_is_hw_dbs_capable(hdd_ctx->psoc))
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002327 return QDF_STATUS_SUCCESS;
2328
2329 cfg.scan_config = 0;
2330 cfg.fw_mode_config = 0;
2331 cfg.set_dual_mac_cb = policy_mgr_soc_set_dual_mac_cfg_cb;
Krunal Sonidf29bc42018-11-15 13:26:29 -08002332 status =
Krunal Soni13b50f82018-09-27 12:37:03 -07002333 ucfg_policy_mgr_get_chnl_select_plcy(hdd_ctx->psoc,
2334 &channel_select_logic_conc);
Krunal Sonidf29bc42018-11-15 13:26:29 -08002335 if (status != QDF_STATUS_SUCCESS) {
2336 hdd_err("ucfg_policy_mgr_get_chnl_select_plcy failed, use def");
2337 return status;
2338 }
2339 status =
2340 ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
2341 &dual_mac_feature);
2342 if (status != QDF_STATUS_SUCCESS) {
2343 hdd_err("ucfg_policy_mgr_get_dual_mac_feature failed, use def");
2344 return status;
2345 }
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002346
Krunal Sonidf29bc42018-11-15 13:26:29 -08002347 if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) {
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002348 status = policy_mgr_get_updated_scan_and_fw_mode_config(
Dustin Brown1dbefe62018-09-11 16:32:03 -07002349 hdd_ctx->psoc, &cfg.scan_config,
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002350 &cfg.fw_mode_config,
Krunal Sonidf29bc42018-11-15 13:26:29 -08002351 dual_mac_feature,
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002352 channel_select_logic_conc);
2353
2354 if (status != QDF_STATUS_SUCCESS) {
2355 hdd_err("wma_get_updated_scan_and_fw_mode_config failed %d",
2356 status);
2357 return status;
2358 }
2359 }
2360
2361 hdd_debug("send scan_cfg: 0x%x fw_mode_cfg: 0x%x to fw",
2362 cfg.scan_config, cfg.fw_mode_config);
2363
2364 status = sme_soc_set_dual_mac_config(cfg);
2365 if (status != QDF_STATUS_SUCCESS) {
2366 hdd_err("sme_soc_set_dual_mac_config failed %d", status);
2367 return status;
2368 }
2369
2370 return QDF_STATUS_SUCCESS;
2371}
2372
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07002373/**
Arun Khandavallifae92942016-08-01 13:31:08 +05302374 * hdd_start_adapter() - Wrapper function for device specific adapter
2375 * @adapter: pointer to HDD adapter
2376 *
2377 * This function is called to start the device specific adapter for
2378 * the mode passed in the adapter's device_mode.
2379 *
2380 * Return: 0 for success; non-zero for failure
2381 */
Jeff Johnson9d295242017-08-29 14:39:48 -07002382int hdd_start_adapter(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05302383{
2384
2385 int ret;
Jeff Johnsonc1e62782017-11-09 09:50:17 -08002386 enum QDF_OPMODE device_mode = adapter->device_mode;
Arun Khandavallifae92942016-08-01 13:31:08 +05302387
Dustin Brownfdf17c12018-03-14 12:55:34 -07002388 hdd_enter_dev(adapter->dev);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08002389 hdd_debug("Start_adapter for mode : %d", adapter->device_mode);
Arun Khandavallifae92942016-08-01 13:31:08 +05302390
2391 switch (device_mode) {
2392 case QDF_P2P_CLIENT_MODE:
2393 case QDF_P2P_DEVICE_MODE:
2394 case QDF_OCB_MODE:
2395 case QDF_STA_MODE:
2396 case QDF_MONITOR_MODE:
2397 ret = hdd_start_station_adapter(adapter);
2398 if (ret)
2399 goto err_start_adapter;
Alok Kumar81e1d732018-09-04 11:10:36 +05302400
2401 hdd_nud_ignore_tracking(adapter, false);
Arun Khandavallifae92942016-08-01 13:31:08 +05302402 break;
2403 case QDF_P2P_GO_MODE:
2404 case QDF_SAP_MODE:
2405 ret = hdd_start_ap_adapter(adapter);
2406 if (ret)
2407 goto err_start_adapter;
2408 break;
Arun Khandavallib2f6c262016-08-18 19:07:19 +05302409 case QDF_IBSS_MODE:
2410 /*
2411 * For IBSS interface is initialized as part of
2412 * hdd_init_station_mode()
2413 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08002414 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302415 case QDF_FTM_MODE:
Dustin Browndb2a8be2017-12-20 11:49:56 -08002416 /* vdevs are dynamically managed by firmware in FTM */
2417 goto exit_with_success;
Arun Khandavallifae92942016-08-01 13:31:08 +05302418 default:
2419 hdd_err("Invalid session type %d", device_mode);
2420 QDF_ASSERT(0);
2421 goto err_start_adapter;
2422 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08002423
Arun Khandavallifae92942016-08-01 13:31:08 +05302424 if (hdd_set_fw_params(adapter))
2425 hdd_err("Failed to set the FW params for the adapter!");
2426
Dustin Browne7e71d32018-05-11 16:00:08 -07002427 if (adapter->session_id != HDD_SESSION_ID_INVALID) {
2428 ret = wlan_hdd_cfg80211_register_frames(adapter);
2429 if (ret < 0) {
2430 hdd_err("Failed to register frames - ret %d", ret);
2431 goto err_start_adapter;
2432 }
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302433 }
Dustin Browne7e71d32018-05-11 16:00:08 -07002434
Zhu Jianmin6a7b7022018-03-10 21:42:21 +08002435 wlan_hdd_update_dbs_scan_and_fw_mode_config();
Ganesh Kondabattini0dc1a6e2017-07-29 12:59:19 +05302436
Dustin Browndb2a8be2017-12-20 11:49:56 -08002437exit_with_success:
Dustin Browne74003f2018-03-14 12:51:58 -07002438 hdd_exit();
Dustin Browndb2a8be2017-12-20 11:49:56 -08002439
Arun Khandavallifae92942016-08-01 13:31:08 +05302440 return 0;
Dustin Browndb2a8be2017-12-20 11:49:56 -08002441
Arun Khandavallifae92942016-08-01 13:31:08 +05302442err_start_adapter:
2443 return -EINVAL;
2444}
2445
2446/**
Komal Seelamf2136bb2016-09-28 18:30:44 +05302447 * hdd_enable_power_management() - API to Enable Power Management
2448 *
2449 * API invokes Bus Interface Layer power management functionality
2450 *
2451 * Return: None
2452 */
2453static void hdd_enable_power_management(void)
2454{
2455 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2456
2457 if (!hif_ctx) {
2458 hdd_err("Bus Interface Context is Invalid");
2459 return;
2460 }
2461
2462 hif_enable_power_management(hif_ctx, cds_is_packet_log_enabled());
2463}
2464
2465/**
2466 * hdd_disable_power_management() - API to disable Power Management
2467 *
2468 * API disable Bus Interface Layer Power management functionality
2469 *
2470 * Return: None
2471 */
2472static void hdd_disable_power_management(void)
2473{
2474 void *hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
2475
2476 if (!hif_ctx) {
2477 hdd_err("Bus Interface Context is Invalid");
2478 return;
2479 }
2480
2481 hif_disable_power_management(hif_ctx);
2482}
2483
Ryan Hsuaadba072018-04-20 13:01:53 -07002484void hdd_update_hw_sw_info(struct hdd_context *hdd_ctx)
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302485{
2486 void *hif_sc;
Dustin Brown6f17a022017-07-19 13:40:55 -07002487 size_t target_hw_name_len;
2488 const char *target_hw_name;
Ryan Hsuaadba072018-04-20 13:01:53 -07002489 uint8_t *buf;
2490 uint32_t buf_len;
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302491
2492 hif_sc = cds_get_context(QDF_MODULE_ID_HIF);
2493 if (!hif_sc) {
2494 hdd_err("HIF context is NULL");
2495 return;
2496 }
2497
Ryan Hsuaadba072018-04-20 13:01:53 -07002498 hif_get_hw_info(hif_sc, &hdd_ctx->target_hw_version,
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302499 &hdd_ctx->target_hw_revision,
Dustin Brown6f17a022017-07-19 13:40:55 -07002500 &target_hw_name);
2501
2502 if (hdd_ctx->target_hw_name)
2503 qdf_mem_free(hdd_ctx->target_hw_name);
2504
2505 target_hw_name_len = strlen(target_hw_name) + 1;
2506 hdd_ctx->target_hw_name = qdf_mem_malloc(target_hw_name_len);
2507 if (hdd_ctx->target_hw_name)
2508 qdf_mem_copy(hdd_ctx->target_hw_name, target_hw_name,
2509 target_hw_name_len);
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302510
Ryan Hsuaadba072018-04-20 13:01:53 -07002511 buf = qdf_mem_malloc(WE_MAX_STR_LEN);
2512 if (buf) {
2513 buf_len = hdd_wlan_get_version(hdd_ctx, WE_MAX_STR_LEN, buf);
2514 hdd_info("%s", buf);
2515 qdf_mem_free(buf);
2516 }
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302517}
2518
2519/**
gbian62edd7e2017-03-07 13:12:13 +08002520 * hdd_update_cds_ac_specs_params() - update cds ac_specs params
2521 * @hdd_ctx: Pointer to hdd context
2522 *
2523 * Return: none
2524 */
2525static void
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002526hdd_update_cds_ac_specs_params(struct hdd_context *hdd_ctx)
gbian62edd7e2017-03-07 13:12:13 +08002527{
jitiphil8e15ea62018-11-16 18:05:34 +05302528 uint8_t tx_sched_wrr_param[TX_SCHED_WRR_PARAMS_NUM] = {0};
2529 qdf_size_t out_size = 0;
gbian62edd7e2017-03-07 13:12:13 +08002530 int i;
Jeff Johnson2b6982c2018-05-29 14:56:11 -07002531 struct cds_context *cds_ctx;
gbian62edd7e2017-03-07 13:12:13 +08002532
2533 if (NULL == hdd_ctx)
2534 return;
2535
2536 if (NULL == hdd_ctx->config) {
2537 /* Do nothing if hdd_ctx is invalid */
2538 hdd_err("%s: Warning: hdd_ctx->cfg_ini is NULL", __func__);
2539 return;
2540 }
2541
2542 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
2543
2544 if (!cds_ctx) {
2545 hdd_err("Invalid CDS Context");
2546 return;
2547 }
2548
2549 for (i = 0; i < OL_TX_NUM_WMM_AC; i++) {
2550 switch (i) {
2551 case OL_TX_WMM_AC_BE:
jitiphil8e15ea62018-11-16 18:05:34 +05302552 qdf_uint8_array_parse(
2553 cfg_get(hdd_ctx->psoc,
2554 CFG_DP_ENABLE_TX_SCHED_WRR_BE),
2555 tx_sched_wrr_param,
2556 sizeof(tx_sched_wrr_param),
2557 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002558 break;
2559 case OL_TX_WMM_AC_BK:
jitiphil8e15ea62018-11-16 18:05:34 +05302560 qdf_uint8_array_parse(
2561 cfg_get(hdd_ctx->psoc,
2562 CFG_DP_ENABLE_TX_SCHED_WRR_BK),
2563 tx_sched_wrr_param,
2564 sizeof(tx_sched_wrr_param),
2565 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002566 break;
2567 case OL_TX_WMM_AC_VI:
jitiphil8e15ea62018-11-16 18:05:34 +05302568 qdf_uint8_array_parse(
2569 cfg_get(hdd_ctx->psoc,
2570 CFG_DP_ENABLE_TX_SCHED_WRR_VI),
2571 tx_sched_wrr_param,
2572 sizeof(tx_sched_wrr_param),
2573 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002574 break;
2575 case OL_TX_WMM_AC_VO:
jitiphil8e15ea62018-11-16 18:05:34 +05302576 qdf_uint8_array_parse(
2577 cfg_get(hdd_ctx->psoc,
2578 CFG_DP_ENABLE_TX_SCHED_WRR_VO),
2579 tx_sched_wrr_param,
2580 sizeof(tx_sched_wrr_param),
2581 &out_size);
gbian62edd7e2017-03-07 13:12:13 +08002582 break;
2583 default:
gbian62edd7e2017-03-07 13:12:13 +08002584 break;
2585 }
2586
jitiphil8e15ea62018-11-16 18:05:34 +05302587 if (out_size == TX_SCHED_WRR_PARAMS_NUM) {
gbian62edd7e2017-03-07 13:12:13 +08002588 cds_ctx->ac_specs[i].wrr_skip_weight =
2589 tx_sched_wrr_param[0];
2590 cds_ctx->ac_specs[i].credit_threshold =
2591 tx_sched_wrr_param[1];
2592 cds_ctx->ac_specs[i].send_limit =
2593 tx_sched_wrr_param[2];
2594 cds_ctx->ac_specs[i].credit_reserve =
2595 tx_sched_wrr_param[3];
2596 cds_ctx->ac_specs[i].discard_weight =
2597 tx_sched_wrr_param[4];
2598 }
2599
jitiphil8e15ea62018-11-16 18:05:34 +05302600 out_size = 0;
gbian62edd7e2017-03-07 13:12:13 +08002601 }
2602}
2603
Ryan Hsuaadba072018-04-20 13:01:53 -07002604uint32_t hdd_wlan_get_version(struct hdd_context *hdd_ctx,
2605 const size_t version_len, uint8_t *version)
2606{
2607 uint32_t size;
2608 uint32_t msp_id = 0, mspid = 0, siid = 0, crmid = 0, sub_id = 0;
2609
2610 if (!hdd_ctx) {
2611 hdd_err("Invalid context, HDD context is null");
2612 return 0;
2613 }
2614
Ashish Kumar Dhanotiya7353f882018-05-15 12:50:19 +05302615 if (!version || version_len == 0) {
Ryan Hsuaadba072018-04-20 13:01:53 -07002616 hdd_err("Invalid buffer pointr or buffer len\n");
2617 return 0;
2618 }
2619
2620 msp_id = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
2621 mspid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
2622 siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
2623 crmid = hdd_ctx->target_fw_version & 0x7fff;
2624 sub_id = (hdd_ctx->target_fw_vers_ext & 0xf0000000) >> 28;
2625
2626 size = scnprintf(version, version_len,
Ryan Hsuc6918552018-05-16 13:29:59 -07002627 "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 -07002628 QWLAN_VERSIONSTR,
2629 msp_id, mspid, siid, crmid, sub_id,
Ryan Hsuc6918552018-05-16 13:29:59 -07002630 hdd_ctx->target_hw_name,
2631 hdd_ctx->hw_bd_info.bdf_version,
2632 hdd_ctx->hw_bd_info.ref_design_id,
2633 hdd_ctx->hw_bd_info.customer_id,
2634 hdd_ctx->hw_bd_info.project_id,
2635 hdd_ctx->hw_bd_info.board_data_rev);
Ryan Hsuaadba072018-04-20 13:01:53 -07002636
2637 return size;
2638}
2639
Rachit Kankane0dc3e852018-05-07 17:33:42 +05302640int hdd_set_11ax_rate(struct hdd_adapter *adapter, int set_value,
2641 struct sap_config *sap_config)
2642{
2643 uint8_t preamble = 0, nss = 0, rix = 0;
2644 int ret;
2645 mac_handle_t mac_handle = adapter->hdd_ctx->mac_handle;
2646
2647 if (!sap_config) {
2648 if (!sme_is_feature_supported_by_fw(DOT11AX)) {
2649 hdd_err("Target does not support 11ax");
2650 return -EIO;
2651 }
2652 } else if (sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax &&
2653 sap_config->SapHw_mode != eCSR_DOT11_MODE_11ax_ONLY) {
2654 hdd_err("Invalid hw mode, SAP hw_mode= 0x%x, ch = %d",
2655 sap_config->SapHw_mode, sap_config->channel);
2656 return -EIO;
2657 }
2658
2659 if (set_value != 0xff) {
2660 rix = RC_2_RATE_IDX_11AX(set_value);
2661 preamble = WMI_RATE_PREAMBLE_HE;
2662 nss = HT_RC_2_STREAMS_11AX(set_value);
2663
2664 set_value = hdd_assemble_rate_code(preamble, nss, rix);
2665 } else {
2666 ret = sme_set_auto_rate_he_ltf(mac_handle, adapter->session_id,
2667 QCA_WLAN_HE_LTF_AUTO);
2668 }
2669
2670 hdd_info("SET_11AX_RATE val %d rix %d preamble %x nss %d",
2671 set_value, rix, preamble, nss);
2672
2673 ret = wma_cli_set_command(adapter->session_id,
2674 WMI_VDEV_PARAM_FIXED_RATE,
2675 set_value, VDEV_CMD);
2676
2677 return ret;
2678}
2679
2680int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate)
2681{
2682 int set_value;
2683
2684 if (sme_is_feature_supported_by_fw(DOT11AX))
2685 set_value = WMI_ASSEMBLE_RATECODE_V1(rate, nss, preamble);
2686 else
2687 set_value = (preamble << 6) | (nss << 4) | rate;
2688
2689 return set_value;
2690}
2691
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002692#ifdef FEATURE_WLAN_WAPI
2693/**
2694 * hdd_wapi_security_sta_exist() - return wapi security sta exist or not
2695 *
2696 * This API returns the wapi security station exist or not
2697 *
2698 * Return: true - wapi security station exist
2699 */
2700static bool hdd_wapi_security_sta_exist(void)
2701{
2702 struct hdd_adapter *adapter = NULL;
2703 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
2704
2705 hdd_for_each_adapter(hdd_ctx, adapter) {
2706 if ((adapter->device_mode == QDF_STA_MODE) &&
2707 adapter->wapi_info.wapi_mode &&
2708 (adapter->wapi_info.wapi_auth_mode != WAPI_AUTH_MODE_OPEN))
2709 return true;
2710 }
2711 return false;
2712}
2713#else
2714static bool hdd_wapi_security_sta_exist(void)
2715{
2716 return false;
2717}
2718#endif
2719
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002720#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002721static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
2722 struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
2723{
Jeff Johnson9d295242017-08-29 14:39:48 -07002724 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002725 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002726
2727 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
2728 if (!adapter) {
2729 hdd_err("Adapter is NULL");
2730 return PM_MAX_NUM_OF_MODE;
2731 }
2732
2733 return policy_mgr_convert_device_mode_to_qdf_type(
2734 adapter->device_mode);
2735}
2736
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002737static void hdd_register_policy_manager_callback(
2738 struct wlan_objmgr_psoc *psoc)
2739{
2740 struct policy_mgr_hdd_cbacks hdd_cbacks;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07002741
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002742 qdf_mem_zero(&hdd_cbacks, sizeof(hdd_cbacks));
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002743 hdd_cbacks.sap_restart_chan_switch_cb =
Jeff Johnson23812942017-10-06 11:33:55 -07002744 hdd_sap_restart_chan_switch_cb;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002745 hdd_cbacks.wlan_hdd_get_channel_for_sap_restart =
2746 wlan_hdd_get_channel_for_sap_restart;
Tushnim Bhattacharyya9fb2e422017-03-23 09:49:10 -07002747 hdd_cbacks.get_mode_for_non_connected_vdev =
2748 wlan_hdd_get_mode_for_non_connected_vdev;
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05302749 hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode;
Liangwei Dong3fa5cba2018-07-16 06:41:55 -04002750 hdd_cbacks.hdd_wapi_security_sta_exist =
2751 hdd_wapi_security_sta_exist;
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002752 if (QDF_STATUS_SUCCESS !=
2753 policy_mgr_register_hdd_cb(psoc, &hdd_cbacks)) {
2754 hdd_err("HDD callback registration with policy manager failed");
2755 }
2756}
2757#else
2758static void hdd_register_policy_manager_callback(
2759 struct wlan_objmgr_psoc *psoc)
2760{
2761}
2762#endif
2763
jiadff1ac132018-11-26 16:27:48 +08002764#ifdef WLAN_FEATURE_NAN_DATAPATH
Jeff Johnsond49c4a12017-08-28 12:08:05 -07002765static void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002766{
2767 struct nan_callbacks cb_obj = {0};
2768
2769 cb_obj.ndi_open = hdd_ndi_open;
2770 cb_obj.ndi_close = hdd_ndi_close;
2771 cb_obj.ndi_start = hdd_ndi_start;
2772 cb_obj.ndi_delete = hdd_ndi_delete;
2773 cb_obj.drv_ndi_create_rsp_handler = hdd_ndi_drv_ndi_create_rsp_handler;
2774 cb_obj.drv_ndi_delete_rsp_handler = hdd_ndi_drv_ndi_delete_rsp_handler;
2775
Naveen Rawat37f62c82017-03-26 22:24:43 -07002776 cb_obj.new_peer_ind = hdd_ndp_new_peer_handler;
2777 cb_obj.get_peer_idx = hdd_ndp_get_peer_idx;
Naveen Rawatb3143ea2017-03-26 22:25:46 -07002778 cb_obj.peer_departed_ind = hdd_ndp_peer_departed_handler;
Naveen Rawat37f62c82017-03-26 22:24:43 -07002779
Dustin Brown1dbefe62018-09-11 16:32:03 -07002780 os_if_nan_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj);
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002781}
jiadff1ac132018-11-26 16:27:48 +08002782#else
2783static inline void hdd_nan_register_callbacks(struct hdd_context *hdd_ctx)
2784{
2785}
2786#endif
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002787
Dustin Brown26b3d042017-12-21 11:13:27 -08002788#ifdef CONFIG_LEAK_DETECTION
Dustin Brown4c5b9902017-12-19 11:17:19 -08002789/**
2790 * hdd_check_for_leaks() - Perform runtime memory leak checks
Dustin Browna6246dd2018-05-24 14:35:58 -07002791 * @hdd_ctx: the global HDD context
Dustin Brown29533f22018-07-24 13:11:56 -07002792 * @is_ssr: true if SSR is in progress
Dustin Brown4c5b9902017-12-19 11:17:19 -08002793 *
2794 * This API triggers runtime memory leak detection. This feature enforces the
2795 * policy that any memory allocated at runtime must also be released at runtime.
2796 *
2797 * Allocating memory at runtime and releasing it at unload is effectively a
2798 * memory leak for configurations which never unload (e.g. LONU, statically
2799 * compiled driver). Such memory leaks are NOT false positives, and must be
2800 * fixed.
2801 *
2802 * Return: None
2803 */
Dustin Brown29533f22018-07-24 13:11:56 -07002804static void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
Dustin Brown4bc0a622017-12-06 15:56:50 -08002805{
Dustin Brown4c5b9902017-12-19 11:17:19 -08002806 /* DO NOT REMOVE these checks; for false positives, read above first */
2807
Dustin Brown1dbefe62018-09-11 16:32:03 -07002808 wlan_objmgr_psoc_check_for_peer_leaks(hdd_ctx->psoc);
2809 wlan_objmgr_psoc_check_for_vdev_leaks(hdd_ctx->psoc);
2810 wlan_objmgr_psoc_check_for_pdev_leaks(hdd_ctx->psoc);
Dustin Brown29533f22018-07-24 13:11:56 -07002811
2812 /* many adapter resources are not freed by design during SSR */
2813 if (is_ssr)
2814 return;
2815
Dustin Brown677e0862017-10-10 16:30:09 -07002816 qdf_mc_timer_check_for_leaks();
Dustin Brown8e711502017-12-07 16:49:11 -08002817 qdf_nbuf_map_check_for_leaks();
Dustin Browne6b9d5a2017-12-14 15:18:49 -08002818 qdf_mem_check_for_leaks();
Dustin Brown4bc0a622017-12-06 15:56:50 -08002819}
2820
Dustin Brown26b3d042017-12-21 11:13:27 -08002821#define hdd_debug_domain_set(domain) qdf_debug_domain_set(domain)
2822#else
Dustin Brown29533f22018-07-24 13:11:56 -07002823static inline void hdd_check_for_leaks(struct hdd_context *hdd_ctx, bool is_ssr)
2824{ }
Dustin Brown26b3d042017-12-21 11:13:27 -08002825
2826#define hdd_debug_domain_set(domain)
2827#endif /* CONFIG_LEAK_DETECTION */
2828
gbian62edd7e2017-03-07 13:12:13 +08002829/**
Paul Zhange03cf4c2018-01-19 18:33:22 +08002830 * hdd_update_country_code - Update country code
2831 * @hdd_ctx: HDD context
2832 *
2833 * Update country code based on module parameter country_code
2834 *
2835 * Return: 0 on success and errno on failure
2836 */
2837static int hdd_update_country_code(struct hdd_context *hdd_ctx)
2838{
2839 if (!country_code)
2840 return 0;
2841
2842 return hdd_reg_set_country(hdd_ctx, country_code);
2843}
2844
Dustin Browne7e71d32018-05-11 16:00:08 -07002845int hdd_wlan_start_modules(struct hdd_context *hdd_ctx, bool reinit)
Arun Khandavallifae92942016-08-01 13:31:08 +05302846{
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07002847 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05302848 qdf_device_t qdf_dev;
2849 QDF_STATUS status;
Arun Khandavallifae92942016-08-01 13:31:08 +05302850 bool unint = false;
2851 void *hif_ctx;
Jingxiang Ge95912f82018-04-19 12:01:26 +08002852 struct target_psoc_info *tgt_hdl;
Arun Khandavallifae92942016-08-01 13:31:08 +05302853
Arun Khandavallifae92942016-08-01 13:31:08 +05302854 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
2855 if (!qdf_dev) {
2856 hdd_err("QDF Device Context is Invalid return");
2857 return -EINVAL;
2858 }
2859
Dustin Brown4c663222018-10-23 14:19:36 -07002860 hdd_psoc_idle_timer_stop(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05302861
Dustin Brown1fe30a82017-10-03 16:13:36 -07002862 mutex_lock(&hdd_ctx->iface_change_lock);
Arun Khandavalli5a62a822017-11-14 19:43:00 +05302863 if (hdd_ctx->driver_status == DRIVER_MODULES_ENABLED) {
2864 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07002865 hdd_debug("Driver modules already Enabled");
Dustin Browne74003f2018-03-14 12:51:58 -07002866 hdd_exit();
Arun Khandavalli5a62a822017-11-14 19:43:00 +05302867 return 0;
2868 }
2869
Dustin Brown1fe30a82017-10-03 16:13:36 -07002870 hdd_ctx->start_modules_in_progress = true;
2871
Arun Khandavallifae92942016-08-01 13:31:08 +05302872 switch (hdd_ctx->driver_status) {
2873 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown550f6d22017-12-14 15:44:01 -08002874 hdd_info("Wlan transitioning (UNINITIALIZED -> CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +05302875 unint = true;
2876 /* Fall through dont add break here */
2877 case DRIVER_MODULES_CLOSED:
Dustin Brown1a20b082018-08-03 17:27:15 -07002878 hdd_info("Wlan transitioning (CLOSED -> ENABLED)");
Dustin Brown550f6d22017-12-14 15:44:01 -08002879
Dustin Brown26b3d042017-12-21 11:13:27 -08002880 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_ACTIVE);
Dustin Brown4bc0a622017-12-06 15:56:50 -08002881
Arun Khandavallifae92942016-08-01 13:31:08 +05302882 if (!reinit && !unint) {
2883 ret = pld_power_on(qdf_dev->dev);
2884 if (ret) {
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07002885 hdd_err("Failed to power up device; errno:%d",
Dustin Browndca39692017-11-09 15:30:25 -08002886 ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05302887 goto release_lock;
2888 }
2889 }
Yuanyuan Liuf8fe4bc2017-06-07 16:55:58 -07002890
2891 pld_set_fw_log_mode(hdd_ctx->parent_dev,
2892 hdd_ctx->config->enable_fw_log);
Arun Khandavallifae92942016-08-01 13:31:08 +05302893 ret = hdd_hif_open(qdf_dev->dev, qdf_dev->drv_hdl, qdf_dev->bid,
2894 qdf_dev->bus_type,
2895 (reinit == true) ? HIF_ENABLE_TYPE_REINIT :
2896 HIF_ENABLE_TYPE_PROBE);
2897 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002898 hdd_err("Failed to open hif; errno: %d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +05302899 goto power_down;
2900 }
2901
2902 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
Arun Khandavalli1318b992016-08-09 11:04:57 +05302903 if (!hif_ctx) {
2904 hdd_err("hif context is null!!");
Dustin Browndca39692017-11-09 15:30:25 -08002905 ret = -EINVAL;
Arun Khandavalli1318b992016-08-09 11:04:57 +05302906 goto power_down;
2907 }
2908
Arun Khandavallifae92942016-08-01 13:31:08 +05302909 status = ol_cds_init(qdf_dev, hif_ctx);
2910 if (status != QDF_STATUS_SUCCESS) {
Dustin Browndca39692017-11-09 15:30:25 -08002911 hdd_err("No Memory to Create BMI Context; status: %d",
2912 status);
2913 ret = qdf_status_to_os_return(status);
Arun Khandavallifae92942016-08-01 13:31:08 +05302914 goto hif_close;
2915 }
2916
jitiphil4c256a32018-09-07 08:51:52 +05302917 ucfg_ipa_component_config_update(hdd_ctx->psoc);
Sravan Kumar Kairamd01b4452018-03-07 17:37:09 +05302918
gbian62edd7e2017-03-07 13:12:13 +08002919 hdd_update_cds_ac_specs_params(hdd_ctx);
2920
Dustin Brown1dbefe62018-09-11 16:32:03 -07002921 status = hdd_component_psoc_open(hdd_ctx->psoc);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05302922 if (QDF_IS_STATUS_ERROR(status)) {
2923 hdd_err("Failed to Open legacy components; status: %d",
2924 status);
2925 ret = qdf_status_to_os_return(status);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05302926 goto cds_free;
2927 }
2928
2929 ret = hdd_update_config(hdd_ctx);
2930 if (ret) {
2931 hdd_err("Failed to update configuration; errno: %d",
2932 ret);
2933 goto cds_free;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05302934 }
2935
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +05302936 status = wbuff_module_init();
2937 if (QDF_IS_STATUS_ERROR(status))
2938 hdd_err("WBUFF init unsuccessful; status: %d", status);
2939
Dustin Brown1dbefe62018-09-11 16:32:03 -07002940 status = cds_open(hdd_ctx->psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07002941 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002942 hdd_err("Failed to Open CDS; status: %d", status);
Dustin Brown28b17892017-10-10 13:29:38 -07002943 ret = qdf_status_to_os_return(status);
Krunal Sonie71838d2018-09-27 10:45:05 -07002944 goto psoc_close;
Arun Khandavallifae92942016-08-01 13:31:08 +05302945 }
2946
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +05302947 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
2948
Manjunathappa Prakashb6b4ff12018-06-04 12:32:33 -07002949 if (hdd_ctx->config->rx_thread_affinity_mask)
2950 cds_set_rx_thread_cpu_mask(
2951 hdd_ctx->config->rx_thread_affinity_mask);
2952
2953 /* initialize components configurations after psoc open */
Mukul Sharma9d797a02017-01-05 20:26:03 +05302954 ret = hdd_update_components_config(hdd_ctx);
2955 if (ret) {
Dustin Browndca39692017-11-09 15:30:25 -08002956 hdd_err("Failed to update component configs; errno: %d",
Mukul Sharma9d797a02017-01-05 20:26:03 +05302957 ret);
2958 goto close;
2959 }
Sourav Mohapatra674925f2018-04-16 11:16:58 +05302960
Dustin Brown1dbefe62018-09-11 16:32:03 -07002961 status = cds_dp_open(hdd_ctx->psoc);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002962 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002963 hdd_err("Failed to Open cds post open; status: %d",
2964 status);
2965 ret = qdf_status_to_os_return(status);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07002966 goto close;
2967 }
Mukul Sharma9d797a02017-01-05 20:26:03 +05302968
Sourav Mohapatra674925f2018-04-16 11:16:58 +05302969 ret = hdd_register_cb(hdd_ctx);
2970 if (ret) {
2971 hdd_err("Failed to register HDD callbacks!");
2972 goto cds_txrx_free;
2973 }
2974
Naveen Rawatcb5c5402017-03-22 10:12:19 -07002975 /*
2976 * NAN compoenet requires certian operations like, open adapter,
2977 * close adapter, etc. to be initiated by HDD, for those
2978 * register HDD callbacks with UMAC's NAN componenet.
2979 */
2980 hdd_nan_register_callbacks(hdd_ctx);
2981
Jeff Johnson3a280122017-09-13 07:42:00 -07002982 status = cds_pre_enable();
Arun Khandavallifae92942016-08-01 13:31:08 +05302983 if (!QDF_IS_STATUS_SUCCESS(status)) {
Dustin Browndca39692017-11-09 15:30:25 -08002984 hdd_err("Failed to pre-enable CDS; status: %d", status);
2985 ret = qdf_status_to_os_return(status);
Sourav Mohapatra674925f2018-04-16 11:16:58 +05302986 goto deregister_cb;
Arun Khandavallifae92942016-08-01 13:31:08 +05302987 }
2988
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002989 hdd_register_policy_manager_callback(
Dustin Brown1dbefe62018-09-11 16:32:03 -07002990 hdd_ctx->psoc);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -07002991
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05302992 hdd_sysfs_create_driver_root_obj();
Dustin Brown1dbefe62018-09-11 16:32:03 -07002993 hdd_sysfs_create_version_interface(hdd_ctx->psoc);
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05302994 hdd_sysfs_create_powerstats_interface();
Arunk Khandavalli67193d52017-02-21 12:03:48 +05302995 hdd_update_hw_sw_info(hdd_ctx);
Dustin Brown550f6d22017-12-14 15:44:01 -08002996
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05302997 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
2998 hdd_err("in ftm mode, no need to configure cds modules");
Dustin Browndca39692017-11-09 15:30:25 -08002999 ret = -EINVAL;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05303000 break;
3001 }
Dustin Browndca39692017-11-09 15:30:25 -08003002
Dustin Browne7e71d32018-05-11 16:00:08 -07003003 ret = hdd_configure_cds(hdd_ctx);
Dustin Browndca39692017-11-09 15:30:25 -08003004 if (ret) {
3005 hdd_err("Failed to Enable cds modules; errno: %d", ret);
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05303006 goto destroy_driver_sysfs;
Arun Khandavallifae92942016-08-01 13:31:08 +05303007 }
Dustin Browndca39692017-11-09 15:30:25 -08003008
Komal Seelamf2136bb2016-09-28 18:30:44 +05303009 hdd_enable_power_management();
Dustin Brown550f6d22017-12-14 15:44:01 -08003010
Arun Khandavallifae92942016-08-01 13:31:08 +05303011 break;
Dustin Brown550f6d22017-12-14 15:44:01 -08003012
Arun Khandavallifae92942016-08-01 13:31:08 +05303013 default:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -07003014 QDF_DEBUG_PANIC("Unknown driver state:%d",
Arun Khandavallifae92942016-08-01 13:31:08 +05303015 hdd_ctx->driver_status);
Dustin Browndca39692017-11-09 15:30:25 -08003016 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +05303017 goto release_lock;
3018 }
Dustin Brown550f6d22017-12-14 15:44:01 -08003019
Dustin Brown1a20b082018-08-03 17:27:15 -07003020 hdd_ctx->driver_status = DRIVER_MODULES_ENABLED;
3021 hdd_info("Wlan transitioned (now ENABLED)");
3022
Arun Khandavallia172c3e2016-08-26 17:33:13 +05303023 hdd_ctx->start_modules_in_progress = false;
Dustin Brownad698ae2018-09-05 17:19:30 -07003024
Arun Khandavallifae92942016-08-01 13:31:08 +05303025 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown550f6d22017-12-14 15:44:01 -08003026
Dustin Browne74003f2018-03-14 12:51:58 -07003027 hdd_exit();
Dustin Brown550f6d22017-12-14 15:44:01 -08003028
Arun Khandavallifae92942016-08-01 13:31:08 +05303029 return 0;
3030
Arunk Khandavalli890f6d92018-10-30 20:18:28 +05303031destroy_driver_sysfs:
3032 hdd_sysfs_destroy_powerstats_interface();
3033 hdd_sysfs_destroy_version_interface();
3034 hdd_sysfs_destroy_driver_root_obj();
Rajeev Kumarbe021242017-02-16 16:12:23 -08003035 cds_post_disable();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003036
Sourav Mohapatra674925f2018-04-16 11:16:58 +05303037deregister_cb:
3038 hdd_deregister_cb(hdd_ctx);
3039
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003040cds_txrx_free:
Dustin Brown1dbefe62018-09-11 16:32:03 -07003041 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
Jingxiang Ge95912f82018-04-19 12:01:26 +08003042
3043 if (tgt_hdl && target_psoc_get_wmi_ready(tgt_hdl)) {
3044 hdd_runtime_suspend_context_deinit(hdd_ctx);
Dustin Brown07901ec2018-09-07 11:02:41 -07003045 dispatcher_pdev_close(hdd_ctx->pdev);
Jingxiang Ge95912f82018-04-19 12:01:26 +08003046 hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
3047 }
3048
Dustin Brown1dbefe62018-09-11 16:32:03 -07003049 cds_dp_close(hdd_ctx->psoc);
Dustin Brown550f6d22017-12-14 15:44:01 -08003050
Arun Khandavallifae92942016-08-01 13:31:08 +05303051close:
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003052 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -08003053 hdd_info("Wlan transition aborted (now CLOSED)");
3054
Dustin Brown1dbefe62018-09-11 16:32:03 -07003055 cds_close(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +05303056
Krunal Sonie71838d2018-09-27 10:45:05 -07003057psoc_close:
Dustin Brown1dbefe62018-09-11 16:32:03 -07003058 hdd_component_psoc_close(hdd_ctx->psoc);
Dustin Brown28b17892017-10-10 13:29:38 -07003059 cds_deinit_ini_config();
3060
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -07003061cds_free:
Arun Khandavallifae92942016-08-01 13:31:08 +05303062 ol_cds_free();
3063
3064hif_close:
Jeff Johnson60dc2b12017-09-28 14:56:02 -07003065 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
3066 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303067power_down:
3068 if (!reinit && !unint)
3069 pld_power_off(qdf_dev->dev);
3070release_lock:
Arun Khandavallia172c3e2016-08-26 17:33:13 +05303071 hdd_ctx->start_modules_in_progress = false;
Arun Khandavallifae92942016-08-01 13:31:08 +05303072 mutex_unlock(&hdd_ctx->iface_change_lock);
Abhinav Kumar7ae9b7b2017-12-19 15:11:54 +05303073 if (hdd_ctx->target_hw_name) {
3074 qdf_mem_free(hdd_ctx->target_hw_name);
3075 hdd_ctx->target_hw_name = NULL;
3076 }
Dustin Brown29533f22018-07-24 13:11:56 -07003077
3078 hdd_check_for_leaks(hdd_ctx, reinit);
Dustin Brown26b3d042017-12-21 11:13:27 -08003079 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -08003080
Dustin Browne74003f2018-03-14 12:51:58 -07003081 hdd_exit();
Rajeev Kumara3f672f2017-02-16 13:59:37 -08003082
Srinivas Girigowdabafb8b72017-10-11 17:52:32 -07003083 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +05303084}
3085
Naveen Rawat910726a2017-03-06 11:42:51 -08003086#ifdef WIFI_POS_CONVERGED
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003087static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003088{
3089 int ret = os_if_wifi_pos_register_nl();
3090
3091 if (ret)
3092 hdd_err("os_if_wifi_pos_register_nl failed");
3093
3094 return ret;
3095}
3096
3097static int hdd_deactivate_wifi_pos(void)
3098{
3099 int ret = os_if_wifi_pos_deregister_nl();
3100
3101 if (ret)
3102 hdd_err("os_if_wifi_pos_deregister_nl failed");
3103
3104 return ret;
3105}
3106
3107/**
3108 * hdd_populate_wifi_pos_cfg - populates wifi_pos parameters
3109 * @hdd_ctx: hdd context
3110 *
3111 * Return: status of operation
3112 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003113static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003114{
Dustin Brown1dbefe62018-09-11 16:32:03 -07003115 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Wu Gao1ab05582018-11-08 16:22:49 +08003116 uint16_t neighbor_scan_max_chan_time;
3117 uint16_t neighbor_scan_min_chan_time;
Naveen Rawat910726a2017-03-06 11:42:51 -08003118
3119 wifi_pos_set_oem_target_type(psoc, hdd_ctx->target_type);
3120 wifi_pos_set_oem_fw_version(psoc, hdd_ctx->target_fw_version);
3121 wifi_pos_set_drv_ver_major(psoc, QWLAN_VERSION_MAJOR);
3122 wifi_pos_set_drv_ver_minor(psoc, QWLAN_VERSION_MINOR);
3123 wifi_pos_set_drv_ver_patch(psoc, QWLAN_VERSION_PATCH);
3124 wifi_pos_set_drv_ver_build(psoc, QWLAN_VERSION_BUILD);
Wu Gao1ab05582018-11-08 16:22:49 +08003125 ucfg_mlme_get_neighbor_scan_max_chan_time(psoc,
3126 &neighbor_scan_max_chan_time);
3127 ucfg_mlme_get_neighbor_scan_min_chan_time(psoc,
3128 &neighbor_scan_min_chan_time);
3129 wifi_pos_set_dwell_time_min(psoc, neighbor_scan_min_chan_time);
3130 wifi_pos_set_dwell_time_max(psoc, neighbor_scan_max_chan_time);
Naveen Rawat910726a2017-03-06 11:42:51 -08003131}
3132#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003133static int hdd_activate_wifi_pos(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003134{
3135 return oem_activate_service(hdd_ctx);
3136}
3137
3138static int hdd_deactivate_wifi_pos(void)
3139{
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05303140 return oem_deactivate_service();
Naveen Rawat910726a2017-03-06 11:42:51 -08003141}
3142
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003143static void hdd_populate_wifi_pos_cfg(struct hdd_context *hdd_ctx)
Naveen Rawat910726a2017-03-06 11:42:51 -08003144{
3145}
3146#endif
3147
Arun Khandavallifae92942016-08-01 13:31:08 +05303148/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003149 * __hdd_open() - HDD Open function
3150 * @dev: Pointer to net_device structure
3151 *
3152 * This is called in response to ifconfig up
3153 *
3154 * Return: 0 for success; non-zero for failure
3155 */
3156static int __hdd_open(struct net_device *dev)
3157{
Jeff Johnson9d295242017-08-29 14:39:48 -07003158 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003159 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003160 int ret;
3161
Dustin Brownfdf17c12018-03-14 12:55:34 -07003162 hdd_enter_dev(dev);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303163 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_OPEN_REQUEST,
Jeff Johnson1b780e42017-10-31 14:11:45 -07003164 adapter->session_id, adapter->device_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003165
Ashish Kumar Dhanotiya15a7db52017-08-03 10:27:34 +05303166 /* Nothing to be done if device is unloading */
3167 if (cds_is_driver_unloading()) {
3168 hdd_err("Driver is unloading can not open the hdd");
3169 return -EBUSY;
3170 }
3171
Dustin Brown01847752017-10-25 13:56:27 -07003172 if (cds_is_driver_recovering()) {
3173 hdd_err("WLAN is currently recovering; Please try again.");
3174 return -EBUSY;
3175 }
3176
Sourav Mohapatra421d42b2017-12-29 16:33:23 +05303177 if (qdf_atomic_read(&hdd_ctx->con_mode_flag)) {
3178 hdd_err("con_mode_handler is in progress; Please try again.");
3179 return -EBUSY;
3180 }
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303181
Sourav Mohapatra421d42b2017-12-29 16:33:23 +05303182 mutex_lock(&hdd_init_deinit_lock);
Jeff Johnson5794d4f2018-12-04 11:57:09 -08003183 hdd_start_driver_ops_timer(HDD_DRV_OP_IFF_UP);
Hanumanth Reddy Pothula006f3832017-10-12 15:52:43 +05303184
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303185 /*
3186 * This scenario can be hit in cases where in the wlan driver after
3187 * registering the netdevices and there is a failure in driver
3188 * initialization. So return error gracefully because the netdevices
3189 * will be de-registered as part of the load failure.
3190 */
3191
3192 if (!cds_is_driver_loaded()) {
3193 hdd_err("Failed to start the wlan driver!!");
3194 ret = -EIO;
3195 goto err_hdd_hdd_init_deinit_lock;
3196 }
Abhishek Singh23edd1c2016-05-05 11:56:06 +05303197
Dustin Brown3ecc8782018-09-19 16:37:13 -07003198 ret = hdd_psoc_idle_restart(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303199 if (ret) {
3200 hdd_err("Failed to start WLAN modules return");
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303201 goto err_hdd_hdd_init_deinit_lock;
Arun Khandavallifae92942016-08-01 13:31:08 +05303202 }
3203
Arun Khandavallifae92942016-08-01 13:31:08 +05303204 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
3205 ret = hdd_start_adapter(adapter);
3206 if (ret) {
3207 hdd_err("Failed to start adapter :%d",
3208 adapter->device_mode);
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303209 goto err_hdd_hdd_init_deinit_lock;
Arun Khandavallifae92942016-08-01 13:31:08 +05303210 }
3211 }
3212
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003213 set_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
3214 if (hdd_conn_is_connected(WLAN_HDD_GET_STATION_CTX_PTR(adapter))) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003215 hdd_debug("Enabling Tx Queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003216 /* Enable TX queues only when we are connected */
3217 wlan_hdd_netif_queue_control(adapter,
Arun Khandavallifae92942016-08-01 13:31:08 +05303218 WLAN_START_ALL_NETIF_QUEUE,
3219 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003220 }
3221
Naveen Rawat286def52016-09-23 15:38:02 -07003222 /* Enable carrier and transmit queues for NDI */
3223 if (WLAN_HDD_IS_NDI(adapter)) {
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07003224 hdd_debug("Enabling Tx Queues");
Naveen Rawat286def52016-09-23 15:38:02 -07003225 wlan_hdd_netif_queue_control(adapter,
3226 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
3227 WLAN_CONTROL_PATH);
3228 }
3229
Naveen Rawat910726a2017-03-06 11:42:51 -08003230 hdd_populate_wifi_pos_cfg(hdd_ctx);
Arunk Khandavalli40943af2017-05-15 19:25:34 +05303231 hdd_lpass_notify_start(hdd_ctx, adapter);
Naveen Rawat910726a2017-03-06 11:42:51 -08003232
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303233err_hdd_hdd_init_deinit_lock:
Hanumanth Reddy Pothula006f3832017-10-12 15:52:43 +05303234 hdd_stop_driver_ops_timer();
Arunk Khandavalli16d84252017-06-21 15:26:29 +05303235 mutex_unlock(&hdd_init_deinit_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003236 return ret;
3237}
3238
Arun Khandavallifae92942016-08-01 13:31:08 +05303239
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003240/**
3241 * hdd_open() - Wrapper function for __hdd_open to protect it from SSR
3242 * @dev: Pointer to net_device structure
3243 *
3244 * This is called in response to ifconfig up
3245 *
3246 * Return: 0 for success; non-zero for failure
3247 */
Jeff Johnson590e2012016-10-05 16:16:24 -07003248static int hdd_open(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003249{
3250 int ret;
3251
3252 cds_ssr_protect(__func__);
3253 ret = __hdd_open(dev);
3254 cds_ssr_unprotect(__func__);
3255
3256 return ret;
3257}
3258
3259/**
3260 * __hdd_stop() - HDD stop function
3261 * @dev: Pointer to net_device structure
3262 *
3263 * This is called in response to ifconfig down
3264 *
3265 * Return: 0 for success; non-zero for failure
3266 */
3267static int __hdd_stop(struct net_device *dev)
3268{
Jeff Johnson9d295242017-08-29 14:39:48 -07003269 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003270 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003271 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -07003272 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003273
Dustin Brownfdf17c12018-03-14 12:55:34 -07003274 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003275
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303276 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_STOP_REQUEST,
Jeff Johnson1b780e42017-10-31 14:11:45 -07003277 adapter->session_id, adapter->device_mode));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003278
3279 ret = wlan_hdd_validate_context(hdd_ctx);
Arunk Khandavalli987c8d52018-06-21 17:40:31 +05303280 if (ret) {
3281 set_bit(DOWN_DURING_SSR, &adapter->event_flags);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003282 return ret;
Arunk Khandavalli987c8d52018-06-21 17:40:31 +05303283 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003284
3285 /* Nothing to be done if the interface is not opened */
3286 if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003287 hdd_err("NETDEV Interface is not OPENED");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003288 return -ENODEV;
3289 }
3290
3291 /* Make sure the interface is marked as closed */
3292 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303293
Jeff Johnson16528362018-06-14 12:34:16 -07003294 mac_handle = hdd_ctx->mac_handle;
3295
Mukul Sharmad16c2022017-07-25 18:56:12 +05303296 hdd_debug("Disabling Auto Power save timer");
3297 sme_ps_disable_auto_ps_timer(
Jeff Johnson16528362018-06-14 12:34:16 -07003298 mac_handle,
Jeff Johnson1b780e42017-10-31 14:11:45 -07003299 adapter->session_id);
Mukul Sharmad16c2022017-07-25 18:56:12 +05303300
3301 /*
3302 * Disable TX on the interface, after this hard_start_xmit() will not
3303 * be called on that interface
3304 */
Dustin Browna7bb6ae2018-08-16 16:51:50 -07003305 hdd_debug("Disabling queues, adapter device mode: %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07003306 qdf_opmode_str(adapter->device_mode), adapter->device_mode);
Kabilan Kannan8dac3502017-10-30 12:40:27 -07003307
Himanshu Agarwal865201d2017-04-12 15:45:31 +05303308 wlan_hdd_netif_queue_control(adapter,
3309 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
3310 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003311
Arunk Khandavalli40943af2017-05-15 19:25:34 +05303312 if (adapter->device_mode == QDF_STA_MODE)
3313 hdd_lpass_notify_stop(hdd_ctx);
3314
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003315 /*
Naveen Rawat286def52016-09-23 15:38:02 -07003316 * NAN data interface is different in some sense. The traffic on NDI is
3317 * bursty in nature and depends on the need to transfer. The service
3318 * layer may down the interface after the usage and up again when
3319 * required. In some sense, the NDI is expected to be available
3320 * (like SAP) iface until NDI delete request is issued by the service
3321 * layer. Skip BSS termination and adapter deletion for NAN Data
3322 * interface (NDI).
3323 */
3324 if (WLAN_HDD_IS_NDI(adapter))
3325 return 0;
3326
3327 /*
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003328 * The interface is marked as down for outside world (aka kernel)
3329 * But the driver is pretty much alive inside. The driver needs to
3330 * tear down the existing connection on the netdev (session)
3331 * cleanup the data pipes and wait until the control plane is stabilized
3332 * for this interface. The call also needs to wait until the above
3333 * mentioned actions are completed before returning to the caller.
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003334 * Notice that hdd_stop_adapter is requested not to close the session
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003335 * That is intentional to be able to scan if it is a STA/P2P interface
3336 */
Dustin Browndb2a8be2017-12-20 11:49:56 -08003337 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003338
3339 /* DeInit the adapter. This ensures datapath cleanup as well */
3340 hdd_deinit_adapter(hdd_ctx, adapter, true);
3341
Dustin Brown4c663222018-10-23 14:19:36 -07003342 if (!hdd_is_any_interface_open(hdd_ctx))
3343 hdd_psoc_idle_timer_start(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +05303344
Dustin Browne74003f2018-03-14 12:51:58 -07003345 hdd_exit();
Dustin Brown4c663222018-10-23 14:19:36 -07003346
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003347 return 0;
3348}
3349
3350/**
3351 * hdd_stop() - Wrapper function for __hdd_stop to protect it from SSR
3352 * @dev: pointer to net_device structure
3353 *
3354 * This is called in response to ifconfig down
3355 *
3356 * Return: 0 for success and error number for failure
3357 */
Jeff Johnson590e2012016-10-05 16:16:24 -07003358static int hdd_stop(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003359{
3360 int ret;
3361
3362 cds_ssr_protect(__func__);
3363 ret = __hdd_stop(dev);
3364 cds_ssr_unprotect(__func__);
3365
3366 return ret;
3367}
3368
3369/**
3370 * __hdd_uninit() - HDD uninit function
3371 * @dev: Pointer to net_device structure
3372 *
3373 * This is called during the netdev unregister to uninitialize all data
3374 * associated with the device
3375 *
3376 * Return: None
3377 */
3378static void __hdd_uninit(struct net_device *dev)
3379{
Jeff Johnson9d295242017-08-29 14:39:48 -07003380 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnson399c6272017-08-30 10:51:00 -07003381 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003382
Dustin Brownfdf17c12018-03-14 12:55:34 -07003383 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003384
3385 do {
3386 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003387 hdd_err("Invalid magic");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003388 break;
3389 }
3390
Jeff Johnson399c6272017-08-30 10:51:00 -07003391 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3392 if (!hdd_ctx) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003393 hdd_err("NULL hdd_ctx");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003394 break;
3395 }
3396
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003397 if (dev != adapter->dev)
3398 hdd_err("Invalid device reference");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003399
Jeff Johnson399c6272017-08-30 10:51:00 -07003400 hdd_deinit_adapter(hdd_ctx, adapter, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003401
3402 /* after uninit our adapter structure will no longer be valid */
3403 adapter->dev = NULL;
3404 adapter->magic = 0;
3405 } while (0);
3406
Dustin Browne74003f2018-03-14 12:51:58 -07003407 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003408}
3409
3410/**
3411 * hdd_uninit() - Wrapper function to protect __hdd_uninit from SSR
3412 * @dev: pointer to net_device structure
3413 *
3414 * This is called during the netdev unregister to uninitialize all data
3415 * associated with the device
3416 *
3417 * Return: none
3418 */
3419static void hdd_uninit(struct net_device *dev)
3420{
3421 cds_ssr_protect(__func__);
3422 __hdd_uninit(dev);
3423 cds_ssr_unprotect(__func__);
3424}
3425
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003426static int hdd_open_cesium_nl_sock(void)
3427{
3428#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3429 struct netlink_kernel_cfg cfg = {
3430 .groups = WLAN_NLINK_MCAST_GRP_ID,
3431 .input = NULL
3432 };
3433#endif
3434 int ret = 0;
3435
3436#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
3437 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3438#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
3439 THIS_MODULE,
3440#endif
3441 &cfg);
3442#else
3443 cesium_nl_srv_sock = netlink_kernel_create(&init_net, WLAN_NLINK_CESIUM,
3444 WLAN_NLINK_MCAST_GRP_ID,
3445 NULL, NULL, THIS_MODULE);
3446#endif
3447
3448 if (cesium_nl_srv_sock == NULL) {
Jeff Johnson1346fab2016-08-15 13:09:42 -07003449 hdd_err("NLINK: cesium netlink_kernel_create failed");
Rajeev Kumar8e3e2832015-11-06 16:02:54 -08003450 ret = -ECONNREFUSED;
3451 }
3452
3453 return ret;
3454}
3455
3456static void hdd_close_cesium_nl_sock(void)
3457{
3458 if (NULL != cesium_nl_srv_sock) {
3459 netlink_kernel_release(cesium_nl_srv_sock);
3460 cesium_nl_srv_sock = NULL;
3461 }
3462}
3463
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303464void hdd_update_dynamic_mac(struct hdd_context *hdd_ctx,
3465 struct qdf_mac_addr *curr_mac_addr,
3466 struct qdf_mac_addr *new_mac_addr)
3467{
3468 uint8_t i;
3469
3470 hdd_enter();
3471
3472 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
3473 if (!qdf_mem_cmp(curr_mac_addr->bytes,
3474 &hdd_ctx->dynamic_mac_list[i].bytes[0],
3475 sizeof(struct qdf_mac_addr))) {
3476 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i],
3477 new_mac_addr->bytes,
3478 sizeof(struct qdf_mac_addr));
3479 break;
3480 }
3481 }
3482
3483 hdd_exit();
3484}
3485
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003486/**
3487 * __hdd_set_mac_address() - set the user specified mac address
3488 * @dev: Pointer to the net device.
3489 * @addr: Pointer to the sockaddr.
3490 *
3491 * This function sets the user specified mac address using
Jeff Johnson06095fb2018-05-06 16:16:42 -07003492 * the command ifconfig wlanX hw ether <mac address>.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003493 *
3494 * Return: 0 for success, non zero for failure
3495 */
3496static int __hdd_set_mac_address(struct net_device *dev, void *addr)
3497{
Jeff Johnson9d295242017-08-29 14:39:48 -07003498 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +05303499 struct hdd_adapter *adapter_temp;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003500 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003501 struct sockaddr *psta_mac_addr = addr;
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303502 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003503 int ret;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303504 struct qdf_mac_addr mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003505
Dustin Brownfdf17c12018-03-14 12:55:34 -07003506 hdd_enter_dev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003507
Hanumanth Reddy Pothula5c7a7812018-03-09 12:55:32 +05303508 if (netif_running(dev)) {
3509 hdd_err("On iface up, set mac address change isn't supported");
3510 return -EBUSY;
3511 }
3512
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003513 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
3514 ret = wlan_hdd_validate_context(hdd_ctx);
3515 if (0 != ret)
3516 return ret;
3517
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303518 qdf_mem_copy(&mac_addr, psta_mac_addr->sa_data, sizeof(mac_addr));
Ashish Kumar Dhanotiyae533f6c2018-06-19 21:16:07 +05303519 adapter_temp = hdd_get_adapter_by_macaddr(hdd_ctx, mac_addr.bytes);
3520 if (adapter_temp) {
3521 if (!qdf_str_cmp(adapter_temp->dev->name, dev->name))
3522 return 0;
3523 hdd_err("%s adapter exist with same address " MAC_ADDRESS_STR,
3524 adapter_temp->dev->name,
Ashish Kumar Dhanotiyaf974f332018-04-19 16:03:15 +05303525 MAC_ADDR_ARRAY(mac_addr.bytes));
3526 return -EINVAL;
3527 }
3528
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05303529 qdf_ret_status = wlan_hdd_validate_mac_address(&mac_addr);
3530 if (QDF_IS_STATUS_ERROR(qdf_ret_status))
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303531 return -EINVAL;
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303532
Ashish Kumar Dhanotiya8bfef122018-04-18 16:48:27 +05303533 hdd_info("Changing MAC to " MAC_ADDRESS_STR " of the interface %s ",
3534 MAC_ADDR_ARRAY(mac_addr.bytes), dev->name);
Ashish Kumar Dhanotiyaaa0ca602018-02-21 17:42:55 +05303535
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303536 hdd_update_dynamic_mac(hdd_ctx, &adapter->mac_addr, &mac_addr);
Jeff Johnson1e851a12017-10-28 14:36:12 -07003537 memcpy(&adapter->mac_addr, psta_mac_addr->sa_data, ETH_ALEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003538 memcpy(dev->dev_addr, psta_mac_addr->sa_data, ETH_ALEN);
3539
Dustin Browne74003f2018-03-14 12:51:58 -07003540 hdd_exit();
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303541 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003542}
3543
3544/**
3545 * hdd_set_mac_address() - Wrapper function to protect __hdd_set_mac_address()
3546 * function from SSR
3547 * @dev: pointer to net_device structure
3548 * @addr: Pointer to the sockaddr
3549 *
3550 * This function sets the user specified mac address using
Jeff Johnson06095fb2018-05-06 16:16:42 -07003551 * the command ifconfig wlanX hw ether <mac address>.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003552 *
3553 * Return: 0 for success.
3554 */
3555static int hdd_set_mac_address(struct net_device *dev, void *addr)
3556{
3557 int ret;
3558
3559 cds_ssr_protect(__func__);
3560 ret = __hdd_set_mac_address(dev, addr);
3561 cds_ssr_unprotect(__func__);
3562
3563 return ret;
3564}
3565
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003566uint8_t *wlan_hdd_get_intf_addr(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003567{
3568 int i;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003569
Dustin Brown61cc3932018-10-18 16:12:13 -07003570 i = qdf_ffz(hdd_ctx->config->intfAddrMask);
3571 if (i < 0 || i >= QDF_MAX_CONCURRENCY_PERSONA)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003572 return NULL;
3573
3574 hdd_ctx->config->intfAddrMask |= (1 << i);
Dustin Brown61cc3932018-10-18 16:12:13 -07003575
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303576 qdf_mem_copy(&hdd_ctx->dynamic_mac_list[i].bytes,
3577 &hdd_ctx->config->intfMacAddr[i].bytes,
3578 sizeof(struct qdf_mac_addr));
Dustin Brown61cc3932018-10-18 16:12:13 -07003579 return hdd_ctx->config->intfMacAddr[i].bytes;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003580}
3581
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07003582void wlan_hdd_release_intf_addr(struct hdd_context *hdd_ctx,
3583 uint8_t *releaseAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003584{
3585 int i;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003586
Anurag Chouhan6d760662016-02-20 16:05:43 +05303587 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003588 if (!memcmp(releaseAddr,
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05303589 hdd_ctx->dynamic_mac_list[i].bytes,
Dustin Brown61cc3932018-10-18 16:12:13 -07003590 QDF_MAC_ADDR_SIZE)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003591 hdd_ctx->config->intfAddrMask &= ~(1 << i);
3592 break;
3593 }
3594 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003595}
3596
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003597/**
3598 * __hdd_set_multicast_list() - set the multicast address list
3599 * @dev: Pointer to the WLAN device.
3600 * @skb: Pointer to OS packet (sk_buff).
3601 *
3602 * This funciton sets the multicast address list.
3603 *
3604 * Return: None
3605 */
3606static void __hdd_set_multicast_list(struct net_device *dev)
3607{
Jeff Johnson9d295242017-08-29 14:39:48 -07003608 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Dustin Brown0f874482018-06-13 14:39:22 -07003609 int i = 0, errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003610 struct netdev_hw_addr *ha;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07003611 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303612 struct pmo_mc_addr_list_params *mc_list_request = NULL;
Dustin Brown1dbefe62018-09-11 16:32:03 -07003613 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303614 int mc_count = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003615
Dustin Brownfdf17c12018-03-14 12:55:34 -07003616 hdd_enter_dev(dev);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303617 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303618 goto out;
Mukul Sharma51c44942015-10-30 19:30:19 +05303619
Dustin Brown0f874482018-06-13 14:39:22 -07003620 errno = wlan_hdd_validate_context(hdd_ctx);
3621 if (errno)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303622 goto out;
3623
Dustin Brown0f874482018-06-13 14:39:22 -07003624 errno = hdd_validate_adapter(adapter);
3625 if (errno)
Dustin Brownc788acb2017-08-01 17:43:51 -07003626 goto out;
3627
Arunk Khandavalli6a227882017-12-12 19:31:08 +05303628 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED) {
3629 hdd_err("%s: Driver module is closed", __func__);
Dustin Brown0f874482018-06-13 14:39:22 -07003630 goto out;
Arunk Khandavalli6a227882017-12-12 19:31:08 +05303631 }
3632
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303633 mc_list_request = qdf_mem_malloc(sizeof(*mc_list_request));
Min Liu74a1a502018-10-10 19:59:07 +08003634 if (!mc_list_request)
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303635 goto out;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003636
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05303637 /* Delete already configured multicast address list */
3638 if (adapter->mc_addr_list.mc_cnt > 0) {
Dustin Brown0f874482018-06-13 14:39:22 -07003639 hdd_debug("clear previously configured MC address list");
Hanumanth Reddy Pothulaca84ec52017-02-21 12:09:45 +05303640 hdd_disable_and_flush_mc_addr_list(adapter,
3641 pmo_mc_list_change_notify);
3642 }
3643
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003644 if (dev->flags & IFF_ALLMULTI) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003645 hdd_debug("allow all multicast frames");
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303646 hdd_disable_and_flush_mc_addr_list(adapter,
3647 pmo_mc_list_change_notify);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003648 } else {
3649 mc_count = netdev_mc_count(dev);
Wu Gaod7dd6e42018-10-16 17:22:56 +08003650 if (mc_count > ucfg_pmo_max_mc_addr_supported(psoc)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003651 hdd_debug("Exceeded max MC filter addresses (%d). Allowing all MC frames by disabling MC address filtering",
Wu Gaod7dd6e42018-10-16 17:22:56 +08003652 ucfg_pmo_max_mc_addr_supported(psoc));
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303653 hdd_disable_and_flush_mc_addr_list(adapter,
3654 pmo_mc_list_change_notify);
stonezdf2bdfd2018-11-20 14:45:06 +08003655 adapter->mc_addr_list.mc_cnt = 0;
Dustin Brown0f874482018-06-13 14:39:22 -07003656 goto free_req;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003657 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003658 netdev_for_each_mc_addr(ha, dev) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003659 hdd_debug("ha_addr[%d] "MAC_ADDRESS_STR,
Sachin Ahujaa69c72a2016-09-03 15:59:33 +05303660 i, MAC_ADDR_ARRAY(ha->addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003661 if (i == mc_count)
3662 break;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303663 memset(&(mc_list_request->mc_addr[i].bytes),
3664 0, ETH_ALEN);
3665 memcpy(&(mc_list_request->mc_addr[i].bytes),
3666 ha->addr, ETH_ALEN);
Dustin Brown0f874482018-06-13 14:39:22 -07003667 hdd_debug("mlist[%d] = %pM", i,
3668 mc_list_request->mc_addr[i].bytes);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003669 i++;
3670 }
3671 }
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303672
stonezdf2bdfd2018-11-20 14:45:06 +08003673 adapter->mc_addr_list.mc_cnt = mc_count;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303674 mc_list_request->psoc = psoc;
Jeff Johnson1b780e42017-10-31 14:11:45 -07003675 mc_list_request->vdev_id = adapter->session_id;
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303676 mc_list_request->count = mc_count;
Dustin Brown0f874482018-06-13 14:39:22 -07003677
3678 errno = hdd_cache_mc_addr_list(mc_list_request);
3679 if (errno) {
3680 hdd_err("Failed to cache MC address list for vdev %u; errno:%d",
3681 adapter->session_id, errno);
3682 goto free_req;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003683 }
Dustin Brown0f874482018-06-13 14:39:22 -07003684
3685 hdd_enable_mc_addr_filtering(adapter, pmo_mc_list_change_notify);
3686
3687free_req:
3688 qdf_mem_free(mc_list_request);
3689
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303690out:
Dustin Browne74003f2018-03-14 12:51:58 -07003691 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003692}
3693
Mukul Sharmaff2ac2e2017-01-16 15:51:29 +05303694
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003695/**
3696 * hdd_set_multicast_list() - SSR wrapper function for __hdd_set_multicast_list
3697 * @dev: pointer to net_device
3698 *
3699 * Return: none
3700 */
3701static void hdd_set_multicast_list(struct net_device *dev)
3702{
3703 cds_ssr_protect(__func__);
3704 __hdd_set_multicast_list(dev);
3705 cds_ssr_unprotect(__func__);
3706}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003707
3708/**
3709 * hdd_select_queue() - used by Linux OS to decide which queue to use first
3710 * @dev: Pointer to the WLAN device.
3711 * @skb: Pointer to OS packet (sk_buff).
3712 *
3713 * This function is registered with the Linux OS for network
3714 * core to decide which queue to use first.
3715 *
3716 * Return: ac, Queue Index/access category corresponding to UP in IP header
3717 */
3718static uint16_t hdd_select_queue(struct net_device *dev, struct sk_buff *skb
3719#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
3720 , void *accel_priv
3721#endif
3722#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
3723 , select_queue_fallback_t fallback
3724#endif
3725)
3726{
3727 return hdd_wmm_select_queue(dev, skb);
3728}
3729
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003730static const struct net_device_ops wlan_drv_ops = {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003731 .ndo_open = hdd_open,
3732 .ndo_stop = hdd_stop,
3733 .ndo_uninit = hdd_uninit,
3734 .ndo_start_xmit = hdd_hard_start_xmit,
3735 .ndo_tx_timeout = hdd_tx_timeout,
3736 .ndo_get_stats = hdd_get_stats,
3737 .ndo_do_ioctl = hdd_ioctl,
3738 .ndo_set_mac_address = hdd_set_mac_address,
3739 .ndo_select_queue = hdd_select_queue,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003740 .ndo_set_rx_mode = hdd_set_multicast_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003741};
3742
Nirav Shah73713f72018-05-17 14:50:41 +05303743#ifdef FEATURE_MONITOR_MODE_SUPPORT
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003744/* Monitor mode net_device_ops, doesnot Tx and most of operations. */
Srinivas Girigowdab841da72017-03-25 18:04:39 -07003745static const struct net_device_ops wlan_mon_drv_ops = {
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003746 .ndo_open = hdd_mon_open,
3747 .ndo_stop = hdd_stop,
3748 .ndo_get_stats = hdd_get_stats,
3749};
3750
3751/**
3752 * hdd_set_station_ops() - update net_device ops for monitor mode
Jeff Johnson5505db82017-11-02 21:19:23 -07003753 * @dev: Handle to struct net_device to be updated.
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003754 * Return: None
3755 */
Jeff Johnson5505db82017-11-02 21:19:23 -07003756void hdd_set_station_ops(struct net_device *dev)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003757{
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003758 if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam())
Jeff Johnson5505db82017-11-02 21:19:23 -07003759 dev->netdev_ops = &wlan_mon_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003760 else
Jeff Johnson5505db82017-11-02 21:19:23 -07003761 dev->netdev_ops = &wlan_drv_ops;
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003762}
Nirav Shah73713f72018-05-17 14:50:41 +05303763#else
3764void hdd_set_station_ops(struct net_device *dev)
3765{
3766 dev->netdev_ops = &wlan_drv_ops;
3767}
3768#endif
Manjunathappa Prakash59f861d2016-04-21 10:33:31 -07003769
3770/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08003771 * hdd_alloc_station_adapter() - allocate the station hdd adapter
3772 * @hdd_ctx: global hdd context
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003773 * @mac_addr: mac address to assign to the interface
Ryan Hsu07495ea2016-01-21 15:25:39 -08003774 * @name: User-visible name of the interface
3775 *
3776 * hdd adapter pointer would point to the netdev->priv space, this function
Jeff Johnson62018292018-05-06 16:18:35 -07003777 * would retrieve the pointer, and setup the hdd adapter configuration.
Ryan Hsu07495ea2016-01-21 15:25:39 -08003778 *
3779 * Return: the pointer to hdd adapter, otherwise NULL
3780 */
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003781static struct hdd_adapter *
3782hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr,
3783 unsigned char name_assign_type, const char *name)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003784{
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003785 struct net_device *dev;
3786 struct hdd_adapter *adapter;
Jeff Johnson40dae4e2017-08-29 14:00:25 -07003787 struct hdd_station_ctx *sta_ctx;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303788 QDF_STATUS qdf_status;
jitiphil377bcc12018-10-05 19:46:08 +05303789 void *soc;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003790
jitiphil377bcc12018-10-05 19:46:08 +05303791 soc = cds_get_context(QDF_MODULE_ID_SOC);
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003792 /* cfg80211 initialization and registration */
3793 dev = alloc_netdev_mq(sizeof(*adapter), name,
Ryan Hsu07495ea2016-01-21 15:25:39 -08003794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003795 name_assign_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003796#endif
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003797 (cds_get_conparam() == QDF_GLOBAL_MONITOR_MODE ?
3798 hdd_mon_mode_ether_setup : ether_setup),
3799 NUM_TX_QUEUES);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003800
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003801 if (!dev) {
3802 hdd_err("Failed to allocate new net_device '%s'", name);
3803 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003804 }
3805
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003806 adapter = netdev_priv(dev);
3807
3808 qdf_mem_zero(adapter, sizeof(*adapter));
3809 sta_ctx = &adapter->session.station;
3810 qdf_mem_set(sta_ctx->conn_info.staId, sizeof(sta_ctx->conn_info.staId),
3811 HDD_WLAN_INVALID_STA_ID);
3812 adapter->dev = dev;
3813 adapter->hdd_ctx = hdd_ctx;
3814 adapter->magic = WLAN_HDD_ADAPTER_MAGIC;
3815 adapter->session_id = HDD_SESSION_ID_INVALID;
3816
3817 qdf_status = qdf_event_create(&adapter->qdf_session_open_event);
3818 if (QDF_IS_STATUS_ERROR(qdf_status))
3819 goto free_net_dev;
3820
3821 qdf_status = qdf_event_create(&adapter->qdf_session_close_event);
3822 if (QDF_IS_STATUS_ERROR(qdf_status))
3823 goto free_net_dev;
3824
3825 adapter->offloads_configured = false;
3826 adapter->is_link_up_service_needed = false;
3827 adapter->disconnection_in_progress = false;
3828 adapter->send_mode_change = true;
3829
3830 /* Init the net_device structure */
3831 strlcpy(dev->name, name, IFNAMSIZ);
3832
3833 qdf_mem_copy(dev->dev_addr, mac_addr, sizeof(tSirMacAddr));
3834 qdf_mem_copy(adapter->mac_addr.bytes, mac_addr, sizeof(tSirMacAddr));
3835 dev->watchdog_timeo = HDD_TX_TIMEOUT;
3836
jitiphil377bcc12018-10-05 19:46:08 +05303837 if (cdp_cfg_get(soc,
3838 cfg_dp_enable_ip_tcp_udp_checksum_offload))
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003839 dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
3840 dev->features |= NETIF_F_RXCSUM;
3841
3842 hdd_set_tso_flags(hdd_ctx, dev);
3843 hdd_set_station_ops(adapter->dev);
3844
3845 hdd_dev_setup_destructor(dev);
3846 dev->ieee80211_ptr = &adapter->wdev;
3847 dev->tx_queue_len = HDD_NETDEV_TX_QUEUE_LEN;
3848 adapter->wdev.wiphy = hdd_ctx->wiphy;
3849 adapter->wdev.netdev = dev;
3850
3851 /* set dev's parent to underlying device */
3852 SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
3853 hdd_wmm_init(adapter);
3854 spin_lock_init(&adapter->pause_map_lock);
3855 adapter->start_time = qdf_system_ticks();
3856 adapter->last_time = adapter->start_time;
3857
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003858 return adapter;
Dustin Brownef5fc2d2018-09-11 11:02:00 -07003859
3860free_net_dev:
3861 free_netdev(adapter->dev);
3862
3863 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003864}
3865
Jeff Johnson9d295242017-08-29 14:39:48 -07003866static QDF_STATUS hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003867{
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003868 struct net_device *dev = adapter->dev;
3869 int ret;
3870
Dustin Brown491d54b2018-03-14 12:39:11 -07003871 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003872
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08003873 if (rtnl_held) {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003874 if (strnchr(dev->name, IFNAMSIZ - 1, '%')) {
3875
3876 ret = dev_alloc_name(dev, dev->name);
3877 if (ret < 0) {
3878 hdd_err(
3879 "unable to get dev name: %s, err = 0x%x",
3880 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303881 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003882 }
3883 }
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003884
3885 ret = register_netdevice(dev);
3886 if (ret) {
3887 hdd_err("register_netdevice(%s) failed, err = 0x%x",
3888 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303889 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003890 }
3891 } else {
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003892 ret = register_netdev(dev);
3893 if (ret) {
3894 hdd_err("register_netdev(%s) failed, err = 0x%x",
3895 dev->name, ret);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303896 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003897 }
3898 }
3899 set_bit(NET_DEVICE_REGISTERED, &adapter->event_flags);
3900
Dustin Browne74003f2018-03-14 12:51:58 -07003901 hdd_exit();
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07003902
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303903 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003904}
3905
Pragaspathi Thilagaraj3551caa2018-09-26 15:52:56 +05303906QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id,
3907 QDF_STATUS qdf_status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003908{
Krunal Sonib51eec72017-11-20 21:53:01 -08003909 struct hdd_adapter *adapter;
3910 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003911
Krunal Sonib51eec72017-11-20 21:53:01 -08003912 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3913 if (!hdd_ctx) {
3914 hdd_err("Invalid HDD_CTX");
3915 return QDF_STATUS_E_FAILURE;
3916 }
3917
3918 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
3919 if (NULL == adapter) {
Naveen Rawat23a3b912018-05-30 17:45:52 -07003920 hdd_err("NULL adapter for %d", session_id);
Krunal Sonib51eec72017-11-20 21:53:01 -08003921 return QDF_STATUS_E_INVAL;
3922 }
Pragaspathi Thilagaraj3551caa2018-09-26 15:52:56 +05303923
3924 if (qdf_status == QDF_STATUS_SUCCESS)
3925 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
3926
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303927 qdf_event_set(&adapter->qdf_session_open_event);
Krunal Sonib51eec72017-11-20 21:53:01 -08003928 hdd_debug("session %d opened", adapter->session_id);
3929
3930 return QDF_STATUS_SUCCESS;
3931}
3932
3933QDF_STATUS hdd_sme_close_session_callback(uint8_t session_id)
3934{
3935 struct hdd_adapter *adapter;
3936 struct hdd_context *hdd_ctx;
3937
3938 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
3939 if (!hdd_ctx) {
3940 hdd_err("Invalid HDD_CTX");
3941 return QDF_STATUS_E_FAILURE;
3942 }
3943
3944 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003945 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003946 hdd_err("NULL adapter");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303947 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003948 }
3949
3950 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08003951 hdd_err("Invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303952 return QDF_STATUS_NOT_INITIALIZED;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003953 }
3954
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003955 /*
3956 * For NAN Data interface, the close session results in the final
3957 * indication to the userspace
3958 */
Rakesh Sunki3480f962016-08-29 17:29:53 -07003959 if (adapter->device_mode == QDF_NDI_MODE)
3960 hdd_ndp_session_end_handler(adapter);
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07003961
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003962 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
3963
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003964 /*
3965 * We can be blocked while waiting for scheduled work to be
3966 * flushed, and the adapter structure can potentially be freed, in
3967 * which case the magic will have been reset. So make sure the
3968 * magic is still good, and hence the adapter structure is still
3969 * valid, before signaling completion
3970 */
3971 if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
Nachiket Kukade08b9f292017-11-17 18:27:37 +05303972 qdf_event_set(&adapter->qdf_session_close_event);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003973
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303974 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003975}
3976
Jeff Johnson9d295242017-08-29 14:39:48 -07003977int hdd_vdev_ready(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003978{
Min Liu8c5d99e2018-09-10 17:18:44 +08003979 struct wlan_objmgr_vdev *vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07003980 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003981
Min Liu8c5d99e2018-09-10 17:18:44 +08003982 vdev = hdd_objmgr_get_vdev(adapter);
3983 if (!vdev)
3984 return -EINVAL;
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003985
Min Liu8c5d99e2018-09-10 17:18:44 +08003986 status = pmo_vdev_ready(vdev);
3987 if (QDF_IS_STATUS_ERROR(status)) {
3988 hdd_objmgr_put_vdev(adapter);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003989 return qdf_status_to_os_return(status);
Min Liu8c5d99e2018-09-10 17:18:44 +08003990 }
3991
3992 status = ucfg_reg_11d_vdev_created_update(vdev);
3993 if (QDF_IS_STATUS_ERROR(status)) {
3994 hdd_objmgr_put_vdev(adapter);
3995 return qdf_status_to_os_return(status);
3996 }
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07003997
3998 if (wma_capability_enhanced_mcast_filter())
Min Liu8c5d99e2018-09-10 17:18:44 +08003999 status = ucfg_pmo_enhanced_mc_filter_enable(vdev);
Dustin Brown8d8d9fe2017-07-18 16:01:25 -07004000 else
Min Liu8c5d99e2018-09-10 17:18:44 +08004001 status = ucfg_pmo_enhanced_mc_filter_disable(vdev);
4002
4003 hdd_objmgr_put_vdev(adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -07004004
4005 return qdf_status_to_os_return(status);
4006}
4007
Jeff Johnson9d295242017-08-29 14:39:48 -07004008int hdd_vdev_destroy(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07004009{
4010 QDF_STATUS status;
Dustin Brown2da29eb2018-07-13 14:23:12 -07004011 int errno;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004012 struct hdd_context *hdd_ctx;
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004013 uint8_t vdev_id;
Min Liu8c5d99e2018-09-10 17:18:44 +08004014 struct wlan_objmgr_vdev *vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004015
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004016 vdev_id = adapter->session_id;
4017 hdd_info("destroying vdev %d", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004018
4019 /* vdev created sanity check */
4020 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
Dustin Brown2da29eb2018-07-13 14:23:12 -07004021 hdd_err("vdev %u does not exist", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004022 return -EINVAL;
4023 }
Dustin Brown2da29eb2018-07-13 14:23:12 -07004024
Min Liu8c5d99e2018-09-10 17:18:44 +08004025 vdev = hdd_objmgr_get_vdev(adapter);
4026 if (!vdev)
4027 return -EINVAL;
Ashish Kumar Dhanotiya68ee2e42018-11-19 21:15:14 +05304028
4029 ucfg_pmo_del_wow_pattern(vdev);
Min Liu8c5d99e2018-09-10 17:18:44 +08004030 status = ucfg_reg_11d_vdev_delete_update(vdev);
Abhishek Singh935e4772018-11-21 14:14:10 +05304031 ucfg_scan_vdev_set_disable(vdev, REASON_VDEV_DOWN);
Min Liu8c5d99e2018-09-10 17:18:44 +08004032 hdd_objmgr_put_vdev(adapter);
Yue Maf9782842017-05-08 12:49:49 -07004033
Dustin Brownd28772b2017-03-17 14:16:07 -07004034 /* close sme session (destroy vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304035 qdf_event_reset(&adapter->qdf_session_close_event);
Dustin Brownd28772b2017-03-17 14:16:07 -07004036 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson16528362018-06-14 12:34:16 -07004037 status = sme_close_session(hdd_ctx->mac_handle, adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004038 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Brown2da29eb2018-07-13 14:23:12 -07004039 hdd_err("failed to close sme session; status:%d", status);
Jiachao Wu2c42c222018-01-15 18:13:19 +08004040 goto release_vdev;
Dustin Brownd28772b2017-03-17 14:16:07 -07004041 }
4042
4043 /* block on a completion variable until sme session is closed */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304044 status = qdf_wait_for_event_completion(
4045 &adapter->qdf_session_close_event,
Abhishek Singh13bf0ce2018-10-24 14:26:14 +05304046 SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
Dustin Brown2da29eb2018-07-13 14:23:12 -07004047
4048 if (QDF_IS_STATUS_ERROR(status)) {
4049 clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
4050
Dustin Brownd28772b2017-03-17 14:16:07 -07004051 if (adapter->device_mode == QDF_NDI_MODE)
4052 hdd_ndp_session_end_handler(adapter);
Dustin Brown2da29eb2018-07-13 14:23:12 -07004053
4054 if (status == QDF_STATUS_E_TIMEOUT)
4055 hdd_err("timed out waiting for sme close session");
4056 else if (adapter->qdf_session_close_event.force_set)
4057 hdd_info("SSR occurred during sme close session");
4058 else
4059 hdd_err("failed to wait for sme close session; status:%u",
4060 status);
Dustin Brownd28772b2017-03-17 14:16:07 -07004061 }
Jiachao Wu2c42c222018-01-15 18:13:19 +08004062
Yue Maf9782842017-05-08 12:49:49 -07004063release_vdev:
Jiachao Wu2c42c222018-01-15 18:13:19 +08004064
Sandeep Puligillaef415362017-08-30 16:37:13 -07004065 /* do vdev logical destroy via objmgr */
Dustin Brownb277dd62018-01-26 15:17:33 -08004066 errno = hdd_objmgr_release_and_destroy_vdev(adapter);
Sandeep Puligillaef415362017-08-30 16:37:13 -07004067 if (errno) {
Dustin Brownb277dd62018-01-26 15:17:33 -08004068 hdd_err("failed to destroy objmgr vdev; errno:%d", errno);
Sandeep Puligillaef415362017-08-30 16:37:13 -07004069 return errno;
4070 }
4071
Rajeev Kumar6e0cbff2017-12-01 18:14:30 -08004072 hdd_info("vdev %d destroyed successfully", vdev_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004073
4074 return 0;
4075}
4076
Krunal Sonib51eec72017-11-20 21:53:01 -08004077static int hdd_set_sme_session_param(struct hdd_adapter *adapter,
4078 struct sme_session_params *session_param,
Jeff Johnson6a18c962018-07-01 09:09:37 -07004079 csr_roam_complete_cb callback,
Krunal Sonib51eec72017-11-20 21:53:01 -08004080 void *callback_ctx)
Dustin Brownd28772b2017-03-17 14:16:07 -07004081{
Dustin Brownd28772b2017-03-17 14:16:07 -07004082 uint32_t type;
4083 uint32_t sub_type;
Krunal Sonib51eec72017-11-20 21:53:01 -08004084 QDF_STATUS status;
Dustin Brownd28772b2017-03-17 14:16:07 -07004085
4086 /* determine vdev (sub)type */
4087 status = cds_get_vdev_types(adapter->device_mode, &type, &sub_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304088 if (QDF_STATUS_SUCCESS != status) {
Dustin Brownd28772b2017-03-17 14:16:07 -07004089 hdd_err("failed to get vdev type: %d", status);
4090 return qdf_status_to_os_return(status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004091 }
Krunal Sonib51eec72017-11-20 21:53:01 -08004092 session_param->sme_session_id = adapter->session_id;
4093 session_param->self_mac_addr = (uint8_t *)&adapter->mac_addr;
4094 session_param->type_of_persona = type;
4095 session_param->subtype_of_persona = sub_type;
4096 session_param->session_open_cb = hdd_sme_open_session_callback;
4097 session_param->session_close_cb = hdd_sme_close_session_callback;
4098 session_param->callback = callback;
4099 session_param->callback_ctx = callback_ctx;
4100
4101 return 0;
4102}
4103
gaurank kathpalia78af1932018-10-27 20:33:10 +05304104static void
4105hdd_store_nss_chains_cfg_in_vdev(struct hdd_adapter *adapter)
4106{
4107 struct wlan_mlme_nss_chains vdev_ini_cfg;
4108 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
4109
gaurank kathpaliab414bce2018-11-09 18:44:46 +05304110 /* Populate the nss chain params from ini for this vdev type */
gaurank kathpalia78af1932018-10-27 20:33:10 +05304111 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
4112 adapter->device_mode,
4113 hdd_ctx->num_rf_chains);
gaurank kathpaliab414bce2018-11-09 18:44:46 +05304114
4115 /* Store the nss chain config into the vdev */
4116 sme_store_nss_chains_cfg_in_vdev(adapter->vdev, &vdev_ini_cfg);
gaurank kathpalia78af1932018-10-27 20:33:10 +05304117}
gaurank kathpalia6982d472018-10-31 21:54:15 +05304118
4119bool hdd_is_vdev_in_conn_state(struct hdd_adapter *adapter)
4120{
4121 switch (adapter->device_mode) {
4122 case QDF_STA_MODE:
4123 case QDF_P2P_CLIENT_MODE:
4124 case QDF_P2P_DEVICE_MODE:
4125 return hdd_conn_is_connected(
4126 WLAN_HDD_GET_STATION_CTX_PTR(adapter));
4127 case QDF_SAP_MODE:
4128 case QDF_P2P_GO_MODE:
4129 return (test_bit(SOFTAP_BSS_STARTED,
4130 &adapter->event_flags));
4131 default:
4132 hdd_err("Device mode %d invalid", adapter->device_mode);
4133 return 0;
4134 }
4135
4136 return 0;
4137}
4138
Krunal Sonib51eec72017-11-20 21:53:01 -08004139int hdd_vdev_create(struct hdd_adapter *adapter,
Jeff Johnson6a18c962018-07-01 09:09:37 -07004140 csr_roam_complete_cb callback, void *ctx)
Krunal Sonib51eec72017-11-20 21:53:01 -08004141{
4142 QDF_STATUS status;
4143 int errno;
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304144 bool bval;
Krunal Sonib51eec72017-11-20 21:53:01 -08004145 struct hdd_context *hdd_ctx;
4146 struct sme_session_params sme_session_params = {0};
Min Liu8c5d99e2018-09-10 17:18:44 +08004147 struct wlan_objmgr_vdev *vdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08004148
4149 hdd_info("creating new vdev");
Dustin Brownd28772b2017-03-17 14:16:07 -07004150
4151 /* do vdev create via objmgr */
4152 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Dustin Brown07901ec2018-09-07 11:02:41 -07004153 errno = hdd_objmgr_create_and_store_vdev(hdd_ctx->pdev, adapter);
Dustin Brownd28772b2017-03-17 14:16:07 -07004154 if (errno) {
4155 hdd_err("failed to create objmgr vdev: %d", errno);
4156 return errno;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004157 }
Dustin Brownd28772b2017-03-17 14:16:07 -07004158
4159 /* Open a SME session (prepare vdev in firmware via legacy API) */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304160 status = qdf_event_reset(&adapter->qdf_session_open_event);
4161 if (QDF_STATUS_SUCCESS != status) {
4162 hdd_err("failed to reinit session open event");
4163 return -EINVAL;
4164 }
Krunal Sonib51eec72017-11-20 21:53:01 -08004165 errno = hdd_set_sme_session_param(adapter, &sme_session_params,
4166 callback, ctx);
4167 if (errno) {
4168 hdd_err("failed to populating SME params");
4169 goto objmgr_vdev_destroy_procedure;
4170 }
Jeff Johnson16528362018-06-14 12:34:16 -07004171 status = sme_open_session(hdd_ctx->mac_handle, &sme_session_params);
Dustin Brownd28772b2017-03-17 14:16:07 -07004172 if (QDF_IS_STATUS_ERROR(status)) {
4173 hdd_err("failed to open sme session: %d", status);
4174 errno = qdf_status_to_os_return(status);
Krunal Soni4a020c72017-10-30 20:58:40 -07004175 goto objmgr_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004176 }
4177
4178 /* block on a completion variable until sme session is opened */
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304179 status = qdf_wait_for_event_completion(&adapter->qdf_session_open_event,
Abhishek Singh13bf0ce2018-10-24 14:26:14 +05304180 SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304181 if (QDF_STATUS_SUCCESS != status) {
4182 if (adapter->qdf_session_open_event.force_set) {
4183 /*
4184 * SSR/PDR has caused shutdown, which has forcefully
4185 * set the event. Return without the closing session.
4186 */
4187 adapter->session_id = HDD_SESSION_ID_INVALID;
4188 hdd_err("Session open event forcefully set");
4189 return -EINVAL;
Nachiket Kukade08b9f292017-11-17 18:27:37 +05304190 }
Jeff Johnsonc66d3102018-02-28 11:58:26 -08004191
4192 if (QDF_STATUS_E_TIMEOUT == status)
4193 hdd_err("Session failed to open within timeout period");
4194 else
4195 hdd_err("Failed to wait for session open event(status-%d)",
4196 status);
4197 errno = -ETIMEDOUT;
4198 set_bit(SME_SESSION_OPENED, &adapter->event_flags);
4199 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004200 }
4201
Pragaspathi Thilagaraj3551caa2018-09-26 15:52:56 +05304202 if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
4203 hdd_err("Session failed to open due to vdev create failure");
4204 errno = -EINVAL;
4205 goto objmgr_vdev_destroy_procedure;
4206 }
4207
Dustin Brownd28772b2017-03-17 14:16:07 -07004208 /* firmware ready for component communication, raise vdev_ready event */
4209 errno = hdd_vdev_ready(adapter);
4210 if (errno) {
4211 hdd_err("failed to dispatch vdev ready event: %d", errno);
Krunal Soni4a020c72017-10-30 20:58:40 -07004212 goto hdd_vdev_destroy_procedure;
Dustin Brownd28772b2017-03-17 14:16:07 -07004213 }
4214
Naveen Rawat2b430892018-03-13 13:58:18 -07004215 if (adapter->device_mode == QDF_STA_MODE) {
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304216 bval = false;
4217 status = ucfg_mlme_get_rtt_mac_randomization(hdd_ctx->psoc,
4218 &bval);
4219 if (QDF_IS_STATUS_ERROR(status))
4220 hdd_err("unable to get RTT MAC randomization value");
4221
4222 hdd_debug("setting RTT mac randomization param: %d", bval);
Naveen Rawat2b430892018-03-13 13:58:18 -07004223 errno = sme_cli_set_command(adapter->session_id,
4224 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_INITIATOR_RANDOM_MAC,
Karthik Kantamneni9180c752018-11-14 12:14:17 +05304225 bval,
Naveen Rawat2b430892018-03-13 13:58:18 -07004226 VDEV_CMD);
4227 if (0 != errno)
4228 hdd_err("RTT mac randomization param set failed %d",
4229 errno);
4230 }
4231
Bala Venkatesh110b03e2018-07-10 16:02:08 +05304232 if (adapter->device_mode == QDF_STA_MODE ||
Min Liu8c5d99e2018-09-10 17:18:44 +08004233 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
4234 vdev = hdd_objmgr_get_vdev(adapter);
4235 if (!vdev)
4236 goto hdd_vdev_destroy_procedure;
4237 wlan_vdev_set_max_peer_count(vdev, HDD_MAX_VDEV_PEER_COUNT);
4238 hdd_objmgr_put_vdev(adapter);
4239 }
Bala Venkatesh110b03e2018-07-10 16:02:08 +05304240
gaurank kathpalia78af1932018-10-27 20:33:10 +05304241 hdd_store_nss_chains_cfg_in_vdev(adapter);
4242
Jeff Johnson1b780e42017-10-31 14:11:45 -07004243 hdd_info("vdev %d created successfully", adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004244
4245 return 0;
4246
4247 /*
4248 * Due to legacy constraints, we need to destroy in the same order as
4249 * create. So, split error handling into 2 cases to accommodate.
4250 */
4251
Krunal Soni4a020c72017-10-30 20:58:40 -07004252objmgr_vdev_destroy_procedure:
Dustin Brown7d043f62017-03-27 12:07:36 -07004253 QDF_BUG(!hdd_objmgr_release_and_destroy_vdev(adapter));
Dustin Brownd28772b2017-03-17 14:16:07 -07004254
4255 return errno;
4256
Krunal Soni4a020c72017-10-30 20:58:40 -07004257hdd_vdev_destroy_procedure:
Dustin Brownd28772b2017-03-17 14:16:07 -07004258 QDF_BUG(!hdd_vdev_destroy(adapter));
4259
4260 return errno;
4261}
4262
Jeff Johnson9d295242017-08-29 14:39:48 -07004263QDF_STATUS hdd_init_station_mode(struct hdd_adapter *adapter)
Dustin Brownd28772b2017-03-17 14:16:07 -07004264{
Jeff Johnsonb9424862017-10-30 08:49:35 -07004265 struct hdd_station_ctx *sta_ctx = &adapter->session.station;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004266 struct hdd_context *hdd_ctx;
Dustin Brownd28772b2017-03-17 14:16:07 -07004267 QDF_STATUS status;
4268 int ret_val;
Jeff Johnson16528362018-06-14 12:34:16 -07004269 mac_handle_t mac_handle;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304270 bool bval = false;
Dustin Brownd28772b2017-03-17 14:16:07 -07004271
Dustin Brownd28772b2017-03-17 14:16:07 -07004272 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Jeff Johnson16528362018-06-14 12:34:16 -07004273 mac_handle = hdd_ctx->mac_handle;
4274 sme_set_curr_device_mode(mac_handle, adapter->device_mode);
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304275 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
4276 if (!QDF_IS_STATUS_SUCCESS(status))
4277 hdd_err("unable to get vht_enable2x2");
4278 sme_set_pdev_ht_vht_ies(mac_handle, bval);
4279
Jeff Johnson16528362018-06-14 12:34:16 -07004280 sme_set_vdev_ies_per_band(mac_handle, adapter->session_id);
Dustin Brownd28772b2017-03-17 14:16:07 -07004281
Jeff Johnson7f2c5912018-03-23 11:42:28 -07004282 hdd_roam_profile_init(adapter);
4283 hdd_register_wext(adapter->dev);
4284
Varun Reddy Yeturu9e0032c2017-07-12 18:39:59 -07004285 hdd_conn_set_connection_state(adapter, eConnectionState_NotConnected);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004286
Jeff Johnsond377dce2017-10-04 10:32:42 -07004287 qdf_mem_set(sta_ctx->conn_info.staId,
4288 sizeof(sta_ctx->conn_info.staId), HDD_WLAN_INVALID_STA_ID);
Hanumanth Reddy Pothulab2d729c2017-05-30 11:49:53 +05304289
Deepak Dhamdherea2785822016-11-17 01:17:45 -08004290 /* set fast roaming capability in sme session */
Jeff Johnson16528362018-06-14 12:34:16 -07004291 status = sme_config_fast_roaming(mac_handle, adapter->session_id,
Abhishek Singh1f217ec2017-12-22 11:48:27 +05304292 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004293 /* Set the default operation channel */
Jeff Johnsond377dce2017-10-04 10:32:42 -07004294 sta_ctx->conn_info.operationChannel =
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +05304295 hdd_ctx->config->operating_channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004296
4297 /* Make the default Auth Type as OPEN */
Jeff Johnsond377dce2017-10-04 10:32:42 -07004298 sta_ctx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004299
4300 status = hdd_init_tx_rx(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304301 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004302 hdd_err("hdd_init_tx_rx() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004303 status, status);
4304 goto error_init_txrx;
4305 }
4306
4307 set_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4308
4309 status = hdd_wmm_adapter_init(adapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304310 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004311 hdd_err("hdd_wmm_adapter_init() failed, status code %08d [x%08x]",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004312 status, status);
4313 goto error_wmm_init;
4314 }
4315
4316 set_bit(WMM_INIT_DONE, &adapter->event_flags);
4317
Jeff Johnson1b780e42017-10-31 14:11:45 -07004318 ret_val = sme_cli_set_command(adapter->session_id,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004319 WMI_PDEV_PARAM_BURST_ENABLE,
Dundi Raviteja3aa01be2018-05-21 18:58:59 +05304320 HDD_ENABLE_SIFS_BURST_DEFAULT,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004321 PDEV_CMD);
Dustin Brownd28772b2017-03-17 14:16:07 -07004322 if (ret_val)
4323 hdd_err("WMI_PDEV_PARAM_BURST_ENABLE set failed %d", ret_val);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004324
Poddar, Siddarth4b3f7312017-11-02 17:00:20 +05304325 /*
4326 * In case of USB tethering, LRO is disabled. If SSR happened
4327 * during that time, then as part of SSR init, do not enable
4328 * the LRO again. Keep the LRO state same as before SSR.
4329 */
jitiphil377bcc12018-10-05 19:46:08 +05304330 if (cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
4331 cfg_dp_lro_enable) &&
4332 !(qdf_atomic_read(&hdd_ctx->vendor_disable_lro_flag)))
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -07004333 adapter->dev->features |= NETIF_F_LRO;
Rajeev Kumar Sirasanagandla996e5292016-11-22 21:20:33 +05304334
4335 /* rcpi info initialization */
4336 qdf_mem_zero(&adapter->rcpi, sizeof(adapter->rcpi));
4337
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304338 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004339
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004340error_wmm_init:
4341 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4342 hdd_deinit_tx_rx(adapter);
4343error_init_txrx:
Dustin Brownd28772b2017-03-17 14:16:07 -07004344 hdd_unregister_wext(adapter->dev);
Dustin Brownd28772b2017-03-17 14:16:07 -07004345 QDF_BUG(!hdd_vdev_destroy(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004346
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004347 return status;
4348}
4349
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304350/**
Krunal Soni4a020c72017-10-30 20:58:40 -07004351 * hdd_deinit_station_mode() - De-initialize the station adapter
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304352 * @hdd_ctx: global hdd context
4353 * @adapter: HDD adapter
Jeff Johnson590e2012016-10-05 16:16:24 -07004354 * @rtnl_held: Used to indicate whether or not the caller is holding
4355 * the kernel rtnl_mutex
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304356 *
4357 * This function De-initializes the STA/P2P/OCB adapter.
4358 *
4359 * Return: None.
4360 */
Krunal Soni4a020c72017-10-30 20:58:40 -07004361static void hdd_deinit_station_mode(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004362 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004363 bool rtnl_held)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304364{
Dustin Brownfdf17c12018-03-14 12:55:34 -07004365 hdd_enter_dev(adapter->dev);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304366
Hanumanth Reddy Pothula7a657402016-09-07 20:59:18 +05304367 if (adapter->dev) {
4368 if (rtnl_held)
4369 adapter->dev->wireless_handlers = NULL;
4370 else {
4371 rtnl_lock();
4372 adapter->dev->wireless_handlers = NULL;
4373 rtnl_unlock();
4374 }
4375 }
4376
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304377 if (test_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags)) {
4378 hdd_deinit_tx_rx(adapter);
4379 clear_bit(INIT_TX_RX_SUCCESS, &adapter->event_flags);
4380 }
4381
4382 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
4383 hdd_wmm_adapter_close(adapter);
4384 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
4385 }
4386
Krunal Sonib51eec72017-11-20 21:53:01 -08004387
Dustin Browne74003f2018-03-14 12:51:58 -07004388 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304389}
4390
Krunal Sonib51eec72017-11-20 21:53:01 -08004391void hdd_deinit_adapter(struct hdd_context *hdd_ctx,
4392 struct hdd_adapter *adapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004393 bool rtnl_held)
4394{
Dustin Brown491d54b2018-03-14 12:39:11 -07004395 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05304396
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004397 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004398 case QDF_STA_MODE:
4399 case QDF_P2P_CLIENT_MODE:
4400 case QDF_P2P_DEVICE_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08004401 case QDF_IBSS_MODE:
4402 case QDF_NDI_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004403 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004404 hdd_deinit_station_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004405 break;
4406 }
4407
Krunal Soni9b04c9b2016-03-10 13:08:05 -08004408 case QDF_SAP_MODE:
4409 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004410 {
Krunal Soni4a020c72017-10-30 20:58:40 -07004411 hdd_deinit_ap_mode(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004412 break;
4413 }
4414
4415 default:
4416 break;
4417 }
4418
Dustin Browne74003f2018-03-14 12:51:58 -07004419 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004420}
4421
Min Liu8c5d99e2018-09-10 17:18:44 +08004422static void hdd_cleanup_adapter(struct hdd_context *hdd_ctx,
4423 struct hdd_adapter *adapter,
Jeff Johnson590e2012016-10-05 16:16:24 -07004424 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004425{
Jeff Johnson5505db82017-11-02 21:19:23 -07004426 struct net_device *dev = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004427
4428 if (adapter)
Jeff Johnson5505db82017-11-02 21:19:23 -07004429 dev = adapter->dev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004430 else {
Jeff Johnson5880d792016-08-15 13:32:30 -07004431 hdd_err("adapter is Null");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004432 return;
4433 }
4434
Alok Kumarb64650c2018-03-23 17:05:11 +05304435 hdd_nud_deinit_tracking(adapter);
4436 qdf_mutex_destroy(&adapter->disconnection_status_lock);
Nachiket Kukade5f0ce4f2018-06-15 19:47:37 +05304437 hdd_apf_context_destroy(adapter);
Min Liu8c5d99e2018-09-10 17:18:44 +08004438 qdf_spinlock_destroy(&adapter->vdev_lock);
Alok Kumarb64650c2018-03-23 17:05:11 +05304439
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05304440 wlan_hdd_debugfs_csr_deinit(adapter);
Arunk Khandavallica56d4b2018-11-29 15:46:00 +05304441 if (adapter->device_mode == QDF_STA_MODE)
4442 hdd_sysfs_destroy_adapter_root_obj(adapter);
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05304443
Rajeev Kumardca5f812016-02-04 17:28:06 -08004444 hdd_debugfs_exit(adapter);
Selvaraj, Sridhar4ea106e2016-08-05 20:34:46 +05304445
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004446 /*
4447 * The adapter is marked as closed. When hdd_wlan_exit() call returns,
4448 * the driver is almost closed and cannot handle either control
4449 * messages or data. However, unregister_netdevice() call above will
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004450 * eventually invoke hdd_stop(ndo_close) driver callback, which attempts
4451 * to close the active connections(basically excites control path) which
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004452 * is not right. Setting this flag helps hdd_stop() to recognize that
4453 * the interface is closed and restricts any operations on that
4454 */
4455 clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
4456
4457 if (test_bit(NET_DEVICE_REGISTERED, &adapter->event_flags)) {
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004458 if (rtnl_held)
Jeff Johnson5505db82017-11-02 21:19:23 -07004459 unregister_netdevice(dev);
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004460 else
Jeff Johnson5505db82017-11-02 21:19:23 -07004461 unregister_netdev(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004462 /*
4463 * Note that the adapter is no longer valid at this point
4464 * since the memory has been reclaimed
4465 */
4466 }
4467}
4468
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004469static QDF_STATUS hdd_check_for_existing_macaddr(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07004470 tSirMacAddr macAddr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004471{
Jeff Johnson9d295242017-08-29 14:39:48 -07004472 struct hdd_adapter *adapter;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07004473
Dustin Brown920397d2017-12-13 16:27:50 -08004474 hdd_for_each_adapter(hdd_ctx, adapter) {
4475 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
4476 macAddr, sizeof(tSirMacAddr))) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304477 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004478 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004479 }
Dustin Brown920397d2017-12-13 16:27:50 -08004480
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304481 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004482}
Ryan Hsu07495ea2016-01-21 15:25:39 -08004483
Arun Khandavalli2358d522016-05-16 18:05:37 +05304484#ifdef CONFIG_FW_LOGS_BASED_ON_INI
4485/**
4486 * hdd_set_fw_log_params() - Set log parameters to FW
4487 * @hdd_ctx: HDD Context
4488 * @adapter: HDD Adapter
4489 *
4490 * This function set the FW Debug log level based on the INI.
4491 *
4492 * Return: None
4493 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004494static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004495 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304496{
4497 uint8_t count = 0, numentries = 0,
4498 moduleloglevel[FW_MODULE_LOG_LEVEL_STRING_LENGTH];
4499 uint32_t value = 0;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304500 QDF_STATUS status;
4501 uint16_t enable_fw_log_level, enable_fw_log_type;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304502 int ret;
4503
Arun Khandavallifae92942016-08-01 13:31:08 +05304504 if (QDF_GLOBAL_FTM_MODE == cds_get_conparam() ||
4505 (!hdd_ctx->config->enable_fw_log)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08004506 hdd_debug("enable_fw_log not enabled in INI or in FTM mode return");
Arun Khandavalli2358d522016-05-16 18:05:37 +05304507 return;
4508 }
4509
Arun Khandavallifae92942016-08-01 13:31:08 +05304510 /* Enable FW logs based on INI configuration */
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304511 status = ucfg_fwol_get_enable_fw_log_type(hdd_ctx->psoc,
4512 &enable_fw_log_type);
4513 if (QDF_IS_STATUS_ERROR(status))
4514 return;
Jeff Johnson1b780e42017-10-31 14:11:45 -07004515 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304516 WMI_DBGLOG_TYPE,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304517 enable_fw_log_type,
Arun Khandavallifae92942016-08-01 13:31:08 +05304518 DBG_CMD);
4519 if (ret != 0)
4520 hdd_err("Failed to enable FW log type ret %d",
4521 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304522
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304523 status = ucfg_fwol_get_enable_fw_log_level(hdd_ctx->psoc,
4524 &enable_fw_log_level);
4525 if (QDF_IS_STATUS_ERROR(status))
4526 return;
Jeff Johnson1b780e42017-10-31 14:11:45 -07004527 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304528 WMI_DBGLOG_LOG_LEVEL,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304529 enable_fw_log_level,
Arun Khandavallifae92942016-08-01 13:31:08 +05304530 DBG_CMD);
4531 if (ret != 0)
4532 hdd_err("Failed to enable FW log level ret %d",
4533 ret);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304534
4535 hdd_string_to_u8_array(
4536 hdd_ctx->config->enableFwModuleLogLevel,
4537 moduleloglevel,
4538 &numentries,
4539 FW_MODULE_LOG_LEVEL_STRING_LENGTH);
4540
4541 while (count < numentries) {
4542 /*
4543 * FW module log level input string looks like
4544 * below:
4545 * gFwDebugModuleLoglevel=<FW Module ID>,
4546 * <Log Level>,...
4547 * For example:
4548 * gFwDebugModuleLoglevel=
4549 * 1,0,2,1,3,2,4,3,5,4,6,5,7,6
4550 * Above input string means :
4551 * For FW module ID 1 enable log level 0
4552 * For FW module ID 2 enable log level 1
4553 * For FW module ID 3 enable log level 2
4554 * For FW module ID 4 enable log level 3
4555 * For FW module ID 5 enable log level 4
4556 * For FW module ID 6 enable log level 5
4557 * For FW module ID 7 enable log level 6
4558 */
4559
Nishank Aggarwale239d962017-03-03 12:26:02 +05304560 if ((moduleloglevel[count] > WLAN_MODULE_ID_MAX)
4561 || (moduleloglevel[count + 1] > DBGLOG_LVL_MAX)) {
4562 hdd_err("Module id %d and dbglog level %d input length is more than max",
4563 moduleloglevel[count],
4564 moduleloglevel[count + 1]);
4565 return;
4566 }
4567
4568 value = moduleloglevel[count] << 16;
4569 value |= moduleloglevel[count + 1];
Jeff Johnson1b780e42017-10-31 14:11:45 -07004570 ret = sme_cli_set_command(adapter->session_id,
Arun Khandavallifae92942016-08-01 13:31:08 +05304571 WMI_DBGLOG_MOD_LOG_LEVEL,
4572 value, DBG_CMD);
4573 if (ret != 0)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304574 hdd_err("Failed to enable FW module log level %d ret %d",
4575 value, ret);
4576
4577 count += 2;
4578 }
Arun Khandavallifae92942016-08-01 13:31:08 +05304579
Arun Khandavalli2358d522016-05-16 18:05:37 +05304580}
4581#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004582static void hdd_set_fw_log_params(struct hdd_context *hdd_ctx,
Jeff Johnson9d295242017-08-29 14:39:48 -07004583 struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304584{
4585}
4586
4587#endif
4588
4589/**
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004590 * hdd_configure_chain_mask() - programs chain mask to firmware
4591 * @adapter: HDD adapter
4592 *
4593 * Return: 0 on success or errno on failure
4594 */
4595static int hdd_configure_chain_mask(struct hdd_adapter *adapter)
4596{
Naveen Rawat98322472018-03-06 10:29:42 -08004597 QDF_STATUS status;
4598 struct wma_caps_per_phy non_dbs_phy_cap;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004599 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304600 bool enable2x2 = false, enable_bt_chain_sep = false;
Krunal Sonidf29bc42018-11-15 13:26:29 -08004601 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
4602
4603 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
4604 &dual_mac_feature);
4605 if (!QDF_IS_STATUS_SUCCESS(status))
4606 hdd_err("unable to get dual mac feature");
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304607
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304608 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &enable2x2);
4609 if (QDF_IS_STATUS_ERROR(status))
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304610 hdd_err("unable to get vht_enable2x2");
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004611
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304612 status = ucfg_mlme_get_bt_chain_separation_flag(hdd_ctx->psoc,
4613 &enable_bt_chain_sep);
4614 if (QDF_IS_STATUS_ERROR(status))
4615 hdd_debug("unable to get BT chain separation. using default");
4616
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304617 hdd_debug("enable2x2: %d, lte_coex: %d, disable_DBS: %d",
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304618 enable2x2, hdd_ctx->lte_coex_ant_share,
Krunal Sonidf29bc42018-11-15 13:26:29 -08004619 dual_mac_feature);
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304620 hdd_debug("enable_bt_chain_separation %d", enable_bt_chain_sep);
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004621
Naveen Rawat98322472018-03-06 10:29:42 -08004622 status = wma_get_caps_for_phyidx_hwmode(&non_dbs_phy_cap,
4623 HW_MODE_DBS_NONE,
4624 CDS_BAND_ALL);
4625 if (QDF_IS_STATUS_ERROR(status)) {
4626 hdd_err("couldn't get phy caps. skip chain mask programming");
4627 return qdf_status_to_os_return(status);
4628 }
4629
4630 if (non_dbs_phy_cap.tx_chain_mask_2G < 3 ||
4631 non_dbs_phy_cap.rx_chain_mask_2G < 3 ||
4632 non_dbs_phy_cap.tx_chain_mask_5G < 3 ||
4633 non_dbs_phy_cap.rx_chain_mask_5G < 3) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07004634 hdd_debug("firmware not capable. skip chain mask programming");
Naveen Rawat98322472018-03-06 10:29:42 -08004635 return 0;
4636 }
4637
Pragaspathi Thilagaraj4b5c0602018-11-14 22:35:23 +05304638 if (enable2x2 && !enable_bt_chain_sep) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07004639 hdd_debug("2x2 enabled. skip chain mask programming");
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004640 return 0;
4641 }
4642
Krunal Sonidf29bc42018-11-15 13:26:29 -08004643 if (dual_mac_feature != DISABLE_DBS_CXN_AND_SCAN) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07004644 hdd_debug("DBS enabled(%d). skip chain mask programming",
Krunal Sonidf29bc42018-11-15 13:26:29 -08004645 dual_mac_feature);
Naveen Rawatb54c72b2018-02-05 10:39:06 -08004646 return 0;
4647 }
4648
Naveen Rawatdacb5032018-02-08 15:23:24 -08004649 if (hdd_ctx->lte_coex_ant_share) {
Dustin Browna7bb6ae2018-08-16 16:51:50 -07004650 hdd_debug("lte ant sharing enabled. skip chainmask programming");
Naveen Rawatdacb5032018-02-08 15:23:24 -08004651 return 0;
4652 }
4653
Dustin Brown1dbefe62018-09-11 16:32:03 -07004654 status = ucfg_mlme_configure_chain_mask(hdd_ctx->psoc,
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304655 adapter->session_id);
4656 if (status != QDF_STATUS_SUCCESS)
4657 goto error;
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004658
4659 return 0;
4660
4661error:
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +05304662 hdd_err("WMI PDEV set param failed");
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004663 return -EINVAL;
4664}
4665
4666/**
Dundi Raviteja3b637092018-09-12 13:42:50 +05304667 * hdd_send_coex_config_params() - Send coex config params to FW
4668 * @hdd_ctx: HDD context
4669 * @adapter: Primary adapter context
4670 *
4671 * This function is used to send all coex config related params to FW
4672 *
4673 * Return: 0 on success and -EINVAL on failure
4674 */
4675static int hdd_send_coex_config_params(struct hdd_context *hdd_ctx,
4676 struct hdd_adapter *adapter)
4677{
4678 struct coex_config_params coex_cfg_params = {0};
4679 struct wlan_fwol_coex_config config = {0};
Dustin Brown05d81302018-09-11 16:49:22 -07004680 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Dundi Raviteja3b637092018-09-12 13:42:50 +05304681 QDF_STATUS status;
4682
4683 if (!hdd_ctx) {
4684 hdd_err("hdd_ctx is invalid");
4685 goto err;
4686 }
4687
4688 if (!adapter) {
4689 hdd_err("adapter is invalid");
4690 goto err;
4691 }
4692
4693 if (!psoc) {
4694 hdd_err("HDD psoc is invalid");
4695 goto err;
4696 }
4697
4698 status = ucfg_fwol_get_coex_config_params(psoc, &config);
4699 if (QDF_IS_STATUS_ERROR(status)) {
4700 hdd_err("Unable to get coex config params");
4701 goto err;
4702 }
4703
4704 coex_cfg_params.vdev_id = adapter->session_id;
4705 coex_cfg_params.config_type = WMI_COEX_CONFIG_TX_POWER;
4706 coex_cfg_params.config_arg1 = config.max_tx_power_for_btc;
4707
4708 status = sme_send_coex_config_cmd(&coex_cfg_params);
4709 if (QDF_IS_STATUS_ERROR(status)) {
4710 hdd_err("Failed to send coex Tx power");
4711 goto err;
4712 }
4713
4714 coex_cfg_params.config_type = WMI_COEX_CONFIG_HANDOVER_RSSI;
4715 coex_cfg_params.config_arg1 = config.wlan_low_rssi_threshold;
4716
4717 status = sme_send_coex_config_cmd(&coex_cfg_params);
4718 if (QDF_IS_STATUS_ERROR(status)) {
4719 hdd_err("Failed to send coex handover RSSI");
4720 goto err;
4721 }
4722
4723 coex_cfg_params.config_type = WMI_COEX_CONFIG_BTC_MODE;
4724 coex_cfg_params.config_arg1 = config.btc_mode;
4725
4726 status = sme_send_coex_config_cmd(&coex_cfg_params);
4727 if (QDF_IS_STATUS_ERROR(status)) {
4728 hdd_err("Failed to send coex BTC mode");
4729 goto err;
4730 }
4731
4732 coex_cfg_params.config_type = WMI_COEX_CONFIG_ANTENNA_ISOLATION;
4733 coex_cfg_params.config_arg1 = config.antenna_isolation;
4734
4735 status = sme_send_coex_config_cmd(&coex_cfg_params);
4736 if (QDF_IS_STATUS_ERROR(status)) {
4737 hdd_err("Failed to send coex antenna isolation");
4738 goto err;
4739 }
4740
4741 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_LOW_RSSI_THRESHOLD;
4742 coex_cfg_params.config_arg1 = config.bt_low_rssi_threshold;
4743
4744 status = sme_send_coex_config_cmd(&coex_cfg_params);
4745 if (QDF_IS_STATUS_ERROR(status)) {
4746 hdd_err("Failed to send coex BT low RSSI threshold");
4747 goto err;
4748 }
4749
4750 coex_cfg_params.config_type = WMI_COEX_CONFIG_BT_INTERFERENCE_LEVEL;
4751 coex_cfg_params.config_arg1 = config.bt_interference_low_ll;
4752 coex_cfg_params.config_arg2 = config.bt_interference_low_ul;
4753 coex_cfg_params.config_arg3 = config.bt_interference_medium_ll;
4754 coex_cfg_params.config_arg4 = config.bt_interference_medium_ul;
4755 coex_cfg_params.config_arg5 = config.bt_interference_high_ll;
4756 coex_cfg_params.config_arg6 = config.bt_interference_high_ul;
4757
4758 status = sme_send_coex_config_cmd(&coex_cfg_params);
4759 if (QDF_IS_STATUS_ERROR(status)) {
4760 hdd_err("Failed to send coex BT interference level");
4761 goto err;
4762 }
4763 return 0;
4764err:
4765 return -EINVAL;
4766}
4767
4768/**
Arun Khandavalli2358d522016-05-16 18:05:37 +05304769 * hdd_set_fw_params() - Set parameters to firmware
4770 * @adapter: HDD adapter
4771 *
4772 * This function Sets various parameters to fw once the
4773 * adapter is started.
4774 *
4775 * Return: 0 on success or errno on failure
4776 */
Jeff Johnson9d295242017-08-29 14:39:48 -07004777int hdd_set_fw_params(struct hdd_adapter *adapter)
Arun Khandavalli2358d522016-05-16 18:05:37 +05304778{
4779 int ret;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304780 uint16_t upper_brssi_thresh, lower_brssi_thresh, rts_profile;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304781 bool enable_dtim_1chrx;
4782 QDF_STATUS status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07004783 struct hdd_context *hdd_ctx;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304784 bool bval = false;
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05304785 uint8_t max_amsdu_len;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304786
Dustin Brownfdf17c12018-03-14 12:55:34 -07004787 hdd_enter_dev(adapter->dev);
Arun Khandavalli2358d522016-05-16 18:05:37 +05304788
4789 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
4790 if (!hdd_ctx)
4791 return -EINVAL;
4792
Dustin Brown732ab9c2017-06-15 13:24:09 -07004793 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) {
4794 hdd_debug("FTM Mode is active; nothing to do");
4795 return 0;
4796 }
4797
Jeff Johnson1b780e42017-10-31 14:11:45 -07004798 ret = sme_cli_set_command(adapter->session_id,
Ashish Kumar Dhanotiyab8630ab2017-07-21 14:18:14 +05304799 WMI_PDEV_PARAM_DTIM_SYNTH,
4800 hdd_ctx->config->enable_lprx, PDEV_CMD);
4801 if (ret) {
4802 hdd_err("Failed to set LPRx");
4803 goto error;
4804 }
4805
Ashish Kumar Dhanotiya191d1642018-02-08 17:43:09 +05304806
4807 ret = sme_cli_set_command(
4808 adapter->session_id,
4809 WMI_PDEV_PARAM_1CH_DTIM_OPTIMIZED_CHAIN_SELECTION,
4810 hdd_ctx->config->enable_dtim_selection_diversity,
4811 PDEV_CMD);
4812 if (ret) {
4813 hdd_err("Failed to set DTIM_OPTIMIZED_CHAIN_SELECTION");
4814 goto error;
4815 }
4816
Ashish Kumar Dhanotiya48dac7d2018-03-28 14:59:50 +05304817 ret = sme_cli_set_command(
4818 adapter->session_id,
4819 WMI_PDEV_PARAM_TX_SCH_DELAY,
4820 hdd_ctx->config->enable_tx_sch_delay,
4821 PDEV_CMD);
4822 if (ret) {
4823 hdd_err("Failed to set WMI_PDEV_PARAM_TX_SCH_DELAY");
4824 goto error;
4825 }
4826
Ashish Kumar Dhanotiya959b38c2018-04-06 21:07:57 +05304827 ret = sme_cli_set_command(
4828 adapter->session_id,
4829 WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE,
4830 hdd_ctx->config->enable_secondary_rate,
4831 PDEV_CMD);
4832 if (ret) {
4833 hdd_err("Failed to set WMI_PDEV_PARAM_SECONDARY_RETRY_ENABLE");
4834 goto error;
4835 }
4836
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304837 if (adapter->device_mode == QDF_STA_MODE) {
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304838 status = ucfg_get_upper_brssi_thresh(hdd_ctx->psoc,
4839 &upper_brssi_thresh);
4840 if (QDF_IS_STATUS_ERROR(status))
4841 return -EINVAL;
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304842
Jeff Johnson1b780e42017-10-31 14:11:45 -07004843 sme_set_smps_cfg(adapter->session_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304844 HDD_STA_SMPS_PARAM_UPPER_BRSSI_THRESH,
4845 upper_brssi_thresh);
4846
4847 status = ucfg_get_lower_brssi_thresh(hdd_ctx->psoc,
4848 &lower_brssi_thresh);
4849 if (QDF_IS_STATUS_ERROR(status))
4850 return -EINVAL;
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304851
Jeff Johnson1b780e42017-10-31 14:11:45 -07004852 sme_set_smps_cfg(adapter->session_id,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +05304853 HDD_STA_SMPS_PARAM_LOWER_BRSSI_THRESH,
4854 lower_brssi_thresh);
4855
4856 status = ucfg_get_enable_dtim_1chrx(hdd_ctx->psoc,
4857 &enable_dtim_1chrx);
4858 if (QDF_IS_STATUS_ERROR(status))
4859 return -EINVAL;
4860
4861 sme_set_smps_cfg(adapter->session_id,
4862 HDD_STA_SMPS_PARAM_DTIM_1CHRX_ENABLE,
4863 enable_dtim_1chrx);
Ashish Kumar Dhanotiyab28338c2017-07-21 20:12:34 +05304864 }
4865
Abhinav Kumarb074f2f2018-09-15 15:32:11 +05304866 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
4867 if (!QDF_IS_STATUS_SUCCESS(status))
4868 hdd_err("unable to get vht_enable2x2");
4869
4870 if (bval) {
Dustin Brown732ab9c2017-06-15 13:24:09 -07004871 hdd_debug("configuring 2x2 mode fw params");
4872
Vignesh Viswanathana851d752018-10-03 19:44:38 +05304873 ret = sme_set_cck_tx_fir_override(hdd_ctx->mac_handle,
4874 adapter->session_id);
Dustin Brown732ab9c2017-06-15 13:24:09 -07004875 if (ret) {
4876 hdd_err("WMI_PDEV_PARAM_ENABLE_CCK_TXFIR_OVERRIDE set failed %d",
4877 ret);
4878 goto error;
4879 }
Liangwei Dong22810e82018-03-15 03:42:12 -04004880
4881 if (hdd_configure_chain_mask(adapter))
4882 goto error;
Dustin Brown732ab9c2017-06-15 13:24:09 -07004883 } else {
Arun Khandavalli2358d522016-05-16 18:05:37 +05304884#define HDD_DTIM_1CHAIN_RX_ID 0x5
4885#define HDD_SMPS_PARAM_VALUE_S 29
Dustin Brown732ab9c2017-06-15 13:24:09 -07004886 hdd_debug("configuring 1x1 mode fw params");
4887
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004888 /*
4889 * Disable DTIM 1 chain Rx when in 1x1,
4890 * we are passing two value
4891 * as param_id << 29 | param_value.
4892 * Below param_value = 0(disable)
4893 */
Jeff Johnson1b780e42017-10-31 14:11:45 -07004894 ret = sme_cli_set_command(adapter->session_id,
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004895 WMI_STA_SMPS_PARAM_CMDID,
4896 HDD_DTIM_1CHAIN_RX_ID <<
4897 HDD_SMPS_PARAM_VALUE_S,
4898 VDEV_CMD);
4899 if (ret) {
4900 hdd_err("DTIM 1 chain set failed %d", ret);
4901 goto error;
4902 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05304903
Arun Khandavalli2358d522016-05-16 18:05:37 +05304904#undef HDD_DTIM_1CHAIN_RX_ID
4905#undef HDD_SMPS_PARAM_VALUE_S
Naveen Rawat269b4ed2017-12-07 06:47:32 -08004906
4907 if (hdd_configure_chain_mask(adapter))
4908 goto error;
Krishna Kumaar Natarajanaa938722016-08-21 23:18:53 -07004909 }
4910
Vignesh Viswanathana851d752018-10-03 19:44:38 +05304911 ret = sme_set_enable_mem_deep_sleep(hdd_ctx->mac_handle,
4912 adapter->session_id);
Dustin Brown732ab9c2017-06-15 13:24:09 -07004913 if (ret) {
4914 hdd_err("WMI_PDEV_PARAM_HYST_EN set failed %d", ret);
4915 goto error;
4916 }
Arun Khandavalli2358d522016-05-16 18:05:37 +05304917
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304918 status = ucfg_fwol_get_rts_profile(hdd_ctx->psoc, &rts_profile);
4919 if (QDF_IS_STATUS_ERROR(status))
4920 return -EINVAL;
4921
Jeff Johnson1b780e42017-10-31 14:11:45 -07004922 ret = sme_cli_set_command(adapter->session_id,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004923 WMI_VDEV_PARAM_ENABLE_RTSCTS,
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05304924 rts_profile,
Dustin Brown732ab9c2017-06-15 13:24:09 -07004925 VDEV_CMD);
4926 if (ret) {
4927 hdd_err("FAILED TO SET RTSCTS Profile ret:%d", ret);
4928 goto error;
Arun Khandavalli2358d522016-05-16 18:05:37 +05304929 }
4930
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05304931 status = ucfg_mlme_get_max_amsdu_num(hdd_ctx->psoc, &max_amsdu_len);
4932 if (QDF_IS_STATUS_ERROR(status)) {
4933 hdd_err("Failed to get Max AMSDU Num");
4934 goto error;
4935 }
4936
4937 hdd_debug("SET AMSDU num %d", max_amsdu_len);
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004938
Jeff Johnson1b780e42017-10-31 14:11:45 -07004939 ret = wma_cli_set_command(adapter->session_id,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004940 GEN_VDEV_PARAM_AMSDU,
Vignesh Viswanathanddc89e52018-11-02 18:43:42 +05304941 max_amsdu_len,
Deepak Dhamdhere612392c2016-08-28 02:56:51 -07004942 GEN_CMD);
4943 if (ret != 0) {
4944 hdd_err("GEN_VDEV_PARAM_AMSDU set failed %d", ret);
4945 goto error;
4946 }
4947
Arun Khandavalli2358d522016-05-16 18:05:37 +05304948 hdd_set_fw_log_params(hdd_ctx, adapter);
Dundi Raviteja3b637092018-09-12 13:42:50 +05304949
4950 ret = hdd_send_coex_config_params(hdd_ctx, adapter);
4951 if (ret) {
4952 hdd_warn("Error initializing coex config params");
4953 goto error;
4954 }
4955
Dustin Browne74003f2018-03-14 12:51:58 -07004956 hdd_exit();
Dustin Brown732ab9c2017-06-15 13:24:09 -07004957
Arun Khandavalli2358d522016-05-16 18:05:37 +05304958 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +05304959
Arun Khandavalli2358d522016-05-16 18:05:37 +05304960error:
4961 return -EINVAL;
4962}
4963
Ryan Hsu07495ea2016-01-21 15:25:39 -08004964/**
Abhinav Kumarcc959f12018-08-09 13:58:30 +05304965 * hdd_init_completion() - Initialize Completion Variables
4966 * @adapter: HDD adapter
4967 *
4968 * This function Initialize the completion variables for
4969 * a particular adapter
4970 *
4971 * Return: None
4972 */
4973static void hdd_init_completion(struct hdd_adapter *adapter)
4974{
4975 init_completion(&adapter->disconnect_comp_var);
4976 init_completion(&adapter->roaming_comp_var);
4977 init_completion(&adapter->linkup_event_var);
4978 init_completion(&adapter->cancel_rem_on_chan_var);
4979 init_completion(&adapter->rem_on_chan_ready_event);
4980 init_completion(&adapter->sta_authorized_event);
4981 init_completion(&adapter->offchannel_tx_event);
4982 init_completion(&adapter->tx_action_cnf_event);
4983 init_completion(&adapter->ibss_peer_info_comp);
4984 init_completion(&adapter->lfr_fw_status.disable_lfr_event);
4985}
4986
4987/**
Ryan Hsu07495ea2016-01-21 15:25:39 -08004988 * hdd_open_adapter() - open and setup the hdd adatper
4989 * @hdd_ctx: global hdd context
4990 * @session_type: type of the interface to be created
4991 * @iface_name: User-visible name of the interface
4992 * @macAddr: MAC address to assign to the interface
4993 * @name_assign_type: the name of assign type of the netdev
4994 * @rtnl_held: the rtnl lock hold flag
4995 *
4996 * This function open and setup the hdd adpater according to the device
4997 * type request, assign the name, the mac address assigned, and then prepared
4998 * the hdd related parameters, queue, lock and ready to start.
4999 *
5000 * Return: the pointer of hdd adapter, otherwise NULL.
5001 */
Jeff Johnson9d295242017-08-29 14:39:48 -07005002struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t session_type,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005003 const char *iface_name, tSirMacAddr macAddr,
Ryan Hsu07495ea2016-01-21 15:25:39 -08005004 unsigned char name_assign_type,
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08005005 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005006{
Jeff Johnson9d295242017-08-29 14:39:48 -07005007 struct hdd_adapter *adapter = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305008 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05305009 uint8_t i;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005010
5011 if (hdd_ctx->current_intf_count >= hdd_ctx->max_intf_count) {
5012 /*
5013 * Max limit reached on the number of vdevs configured by the
5014 * host. Return error
5015 */
Arun Khandavallifae92942016-08-01 13:31:08 +05305016 hdd_err("Unable to add virtual intf: currentVdevCnt=%d,hostConfiguredVdevCnt=%d",
5017 hdd_ctx->current_intf_count, hdd_ctx->max_intf_count);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005018 return NULL;
5019 }
5020
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05305021 status = wlan_hdd_validate_mac_address((struct qdf_mac_addr *)macAddr);
5022 if (QDF_IS_STATUS_ERROR(status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005023 /* Not received valid macAddr */
Arun Khandavallifae92942016-08-01 13:31:08 +05305024 hdd_err("Unable to add virtual intf: Not able to get valid mac address");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005025 return NULL;
5026 }
Pragaspathi Thilagaraj84b72842018-09-19 22:06:57 +05305027
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005028 status = hdd_check_for_existing_macaddr(hdd_ctx, macAddr);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305029 if (QDF_STATUS_E_FAILURE == status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05305030 hdd_err("Duplicate MAC addr: " MAC_ADDRESS_STR
5031 " already exists",
5032 MAC_ADDR_ARRAY(macAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005033 return NULL;
5034 }
5035
5036 switch (session_type) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005037 case QDF_STA_MODE:
Ashish Kumar Dhanotiya6784b502018-10-17 12:51:10 +05305038 /*
5039 * Reset locally administered bit for dynamic_mac_list
5040 * also as while releasing the MAC address for any interface
5041 * mac will be compared with dynamic mac list
5042 */
5043 for (i = 0; i < QDF_MAX_CONCURRENCY_PERSONA; i++) {
5044 if (!qdf_mem_cmp(
5045 macAddr,
5046 &hdd_ctx->dynamic_mac_list[i].bytes[0],
5047 sizeof(struct qdf_mac_addr))) {
5048 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(
5049 hdd_ctx->dynamic_mac_list[i].bytes);
5050 break;
5051 }
5052 }
5053
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005054 /* Reset locally administered bit if the device mode is STA */
5055 WLAN_HDD_RESET_LOCALLY_ADMINISTERED_BIT(macAddr);
Dustin Brown7e761c72018-07-31 13:50:17 -07005056 hdd_debug("locally administered bit reset in sta mode: "
5057 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005058 /* fall through */
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005059 case QDF_P2P_CLIENT_MODE:
5060 case QDF_P2P_DEVICE_MODE:
5061 case QDF_OCB_MODE:
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07005062 case QDF_NDI_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305063 case QDF_MONITOR_MODE:
Ryan Hsu07495ea2016-01-21 15:25:39 -08005064 adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
5065 name_assign_type,
5066 iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005067
5068 if (NULL == adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05305069 hdd_err("failed to allocate adapter for session %d",
5070 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005071 return NULL;
5072 }
5073
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005074 if (QDF_P2P_CLIENT_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005075 adapter->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005076 else if (QDF_P2P_DEVICE_MODE == session_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005077 adapter->wdev.iftype = NL80211_IFTYPE_P2P_DEVICE;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305078 else if (QDF_MONITOR_MODE == session_type)
5079 adapter->wdev.iftype = NL80211_IFTYPE_MONITOR;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005080 else
5081 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
5082
5083 adapter->device_mode = session_type;
5084
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005085
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005086 /*
5087 * Workqueue which gets scheduled in IPv4 notification
5088 * callback
5089 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005090 INIT_WORK(&adapter->ipv4_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005091 hdd_ipv4_notifier_work_queue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005092
5093#ifdef WLAN_NS_OFFLOAD
5094 /*
5095 * Workqueue which gets scheduled in IPv6
5096 * notification callback.
5097 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005098 INIT_WORK(&adapter->ipv6_notifier_work,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005099 hdd_ipv6_notifier_work_queue);
5100#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005101 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005102 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08005103 goto err_free_netdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005104
5105 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005106 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005107 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305108 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5109 WLAN_CONTROL_PATH);
Arun Khandavallifae92942016-08-01 13:31:08 +05305110
Alok Kumarb64650c2018-03-23 17:05:11 +05305111 hdd_nud_init_tracking(adapter);
Arunk Khandavallica56d4b2018-11-29 15:46:00 +05305112 if (adapter->device_mode == QDF_STA_MODE ||
5113 adapter->device_mode == QDF_P2P_DEVICE_MODE)
5114 hdd_sysfs_create_adapter_root_obj(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305115 qdf_mutex_create(&adapter->disconnection_status_lock);
5116
Ravi Joshi1a292562017-05-18 16:28:54 -07005117 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005118
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005119 case QDF_P2P_GO_MODE:
5120 case QDF_SAP_MODE:
Ryan Hsu07495ea2016-01-21 15:25:39 -08005121 adapter = hdd_wlan_create_ap_dev(hdd_ctx, macAddr,
5122 name_assign_type,
5123 (uint8_t *) iface_name);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005124 if (NULL == adapter) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005125 hdd_err("failed to allocate adapter for session %d",
Arun Khandavallifae92942016-08-01 13:31:08 +05305126 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005127 return NULL;
5128 }
5129
5130 adapter->wdev.iftype =
5131 (session_type ==
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005132 QDF_SAP_MODE) ? NL80211_IFTYPE_AP :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005133 NL80211_IFTYPE_P2P_GO;
5134 adapter->device_mode = session_type;
5135
Mahesh Kumar Kalikot Veetilaff94862017-07-28 11:06:19 -07005136 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005137 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005138 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08005139
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005140 hdd_debug("Disabling queues");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005141 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305142 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5143 WLAN_CONTROL_PATH);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305144
5145 /*
5146 * Workqueue which gets scheduled in IPv4 notification
5147 * callback
5148 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005149 INIT_WORK(&adapter->ipv4_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305150 hdd_ipv4_notifier_work_queue);
5151
5152#ifdef WLAN_NS_OFFLOAD
5153 /*
5154 * Workqueue which gets scheduled in IPv6
5155 * notification callback.
5156 */
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005157 INIT_WORK(&adapter->ipv6_notifier_work,
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305158 hdd_ipv6_notifier_work_queue);
5159#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005160 break;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305161 case QDF_FTM_MODE:
5162 adapter = hdd_alloc_station_adapter(hdd_ctx, macAddr,
5163 name_assign_type,
Lin Bai1c678482017-12-18 18:29:11 +08005164 iface_name);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305165 if (NULL == adapter) {
5166 hdd_err("Failed to allocate adapter for FTM mode");
5167 return NULL;
5168 }
5169 adapter->wdev.iftype = NL80211_IFTYPE_STATION;
5170 adapter->device_mode = session_type;
5171 status = hdd_register_interface(adapter, rtnl_held);
Krunal Sonib51eec72017-11-20 21:53:01 -08005172 if (QDF_STATUS_SUCCESS != status)
Jingxiang Geb49aa302018-01-17 20:54:15 +08005173 goto err_free_netdev;
Krunal Sonib51eec72017-11-20 21:53:01 -08005174
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305175 /* Stop the Interface TX queue. */
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005176 hdd_debug("Disabling queues");
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305177 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305178 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5179 WLAN_CONTROL_PATH);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +05305180 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005181 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005182 hdd_err("Invalid session type %d", session_type);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05305183 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005184 return NULL;
5185 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005186
Min Liu8c5d99e2018-09-10 17:18:44 +08005187 qdf_spinlock_create(&adapter->vdev_lock);
5188
Abhinav Kumarcc959f12018-08-09 13:58:30 +05305189 hdd_init_completion(adapter);
hqueaa33ee2017-05-04 17:56:35 +08005190 INIT_WORK(&adapter->scan_block_work, wlan_hdd_cfg80211_scan_block_cb);
Min Liu9be5d4a2018-05-17 11:51:53 +08005191 qdf_list_create(&adapter->blocked_scan_request_q, WLAN_MAX_SCAN_COUNT);
5192 qdf_mutex_create(&adapter->blocked_scan_request_q_lock);
hqueaa33ee2017-05-04 17:56:35 +08005193
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305194 if (QDF_STATUS_SUCCESS == status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005195 /* Add it to the hdd's session list. */
Dustin Brown920397d2017-12-13 16:27:50 -08005196 status = hdd_add_adapter_back(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005197 }
5198
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305199 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005200 if (NULL != adapter) {
5201 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
5202 adapter = NULL;
5203 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005204
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005205 return NULL;
5206 }
Nachiket Kukade5f0ce4f2018-06-15 19:47:37 +05305207 hdd_apf_context_init(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005208
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305209 if (QDF_STATUS_SUCCESS == status) {
Dustin Brown1dbefe62018-09-11 16:32:03 -07005210 policy_mgr_set_concurrency_mode(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005211 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005212
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005213 /* Adapter successfully added. Increment the vdev count */
5214 hdd_ctx->current_intf_count++;
5215
Jeff Johnson5880d792016-08-15 13:32:30 -07005216 hdd_debug("current_intf_count=%d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005217 hdd_ctx->current_intf_count);
5218
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08005219 hdd_check_and_restart_sap_with_non_dfs_acs();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005220 }
5221
Rajeev Kumardca5f812016-02-04 17:28:06 -08005222 if (QDF_STATUS_SUCCESS != hdd_debugfs_init(adapter))
Mahesh Kumar Kalikot Veetil80dda9a2017-07-17 11:38:03 -07005223 hdd_err("Interface %s wow debug_fs init failed",
5224 netdev_name(adapter->dev));
5225
Ajit Pal Singh106c1412018-04-18 18:08:49 +05305226 hdd_register_hl_netdev_fc_timer(adapter,
5227 hdd_tx_resume_timer_expired_handler);
5228
Mahesh Kumar Kalikot Veetil80dda9a2017-07-17 11:38:03 -07005229 hdd_info("%s interface created. iftype: %d", netdev_name(adapter->dev),
5230 session_type);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005231
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05305232 if (adapter->device_mode == QDF_STA_MODE)
5233 wlan_hdd_debugfs_csr_init(adapter);
5234
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005235 return adapter;
5236
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005237err_free_netdev:
Jeff Johnson1e851a12017-10-28 14:36:12 -07005238 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
Hanumanth Reddy Pothula00a39e72016-11-09 21:32:16 +05305239 free_netdev(adapter->dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005240
5241 return NULL;
5242}
5243
Dustin Brown728d65a2018-10-02 16:27:52 -07005244static void __hdd_close_adapter(struct hdd_context *hdd_ctx,
5245 struct hdd_adapter *adapter,
5246 bool rtnl_held)
5247{
5248 qdf_list_destroy(&adapter->blocked_scan_request_q);
5249 qdf_mutex_destroy(&adapter->blocked_scan_request_q_lock);
5250 policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode);
5251
5252 hdd_cleanup_adapter(hdd_ctx, adapter, rtnl_held);
5253
5254 if (hdd_ctx->current_intf_count != 0)
5255 hdd_ctx->current_intf_count--;
5256}
5257
5258void hdd_close_adapter(struct hdd_context *hdd_ctx,
5259 struct hdd_adapter *adapter,
5260 bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005261{
Dustin Brown920397d2017-12-13 16:27:50 -08005262 /*
Dustin Brown728d65a2018-10-02 16:27:52 -07005263 * Stop the global bus bandwidth timer while touching the adapter list
5264 * to avoid bad memory access by the timer handler.
Dustin Brown920397d2017-12-13 16:27:50 -08005265 */
Dustin Brown920397d2017-12-13 16:27:50 -08005266 hdd_bus_bw_compute_timer_stop(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005267
Dustin Brown920397d2017-12-13 16:27:50 -08005268 hdd_remove_adapter(hdd_ctx, adapter);
Dustin Brown728d65a2018-10-02 16:27:52 -07005269 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005270
Dustin Brown920397d2017-12-13 16:27:50 -08005271 /* conditionally restart the bw timer */
5272 hdd_bus_bw_compute_timer_try_start(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005273}
5274
Dustin Brown728d65a2018-10-02 16:27:52 -07005275void hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005276{
Dustin Brown920397d2017-12-13 16:27:50 -08005277 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005278
Dustin Brown491d54b2018-03-14 12:39:11 -07005279 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005280
Dustin Brown728d65a2018-10-02 16:27:52 -07005281 while (QDF_IS_STATUS_SUCCESS(hdd_remove_front_adapter(hdd_ctx,
5282 &adapter))) {
5283 wlan_hdd_release_intf_addr(hdd_ctx, adapter->mac_addr.bytes);
5284 __hdd_close_adapter(hdd_ctx, adapter, rtnl_held);
5285 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005286
Dustin Browne74003f2018-03-14 12:51:58 -07005287 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005288}
5289
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005290void wlan_hdd_reset_prob_rspies(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005291{
Anurag Chouhan6d760662016-02-20 16:05:43 +05305292 struct qdf_mac_addr *bssid = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005293 tSirUpdateIE updateIE;
Jeff Johnson16528362018-06-14 12:34:16 -07005294 mac_handle_t mac_handle;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005295
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005296 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005297 case QDF_STA_MODE:
5298 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005299 {
Jeff Johnsond377dce2017-10-04 10:32:42 -07005300 struct hdd_station_ctx *sta_ctx =
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005301 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Jeff Johnsond377dce2017-10-04 10:32:42 -07005302 bssid = &sta_ctx->conn_info.bssId;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005303 break;
5304 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005305 case QDF_SAP_MODE:
5306 case QDF_P2P_GO_MODE:
5307 case QDF_IBSS_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005308 {
Jeff Johnson1e851a12017-10-28 14:36:12 -07005309 bssid = &adapter->mac_addr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005310 break;
5311 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005312 case QDF_FTM_MODE:
5313 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005314 default:
5315 /*
5316 * wlan_hdd_reset_prob_rspies should not have been called
5317 * for these kind of devices
5318 */
Jeff Johnson5880d792016-08-15 13:32:30 -07005319 hdd_err("Unexpected request for the current device type %d",
Jeff Johnson9c4f93d2017-10-04 08:56:22 -07005320 adapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005321 return;
5322 }
5323
Anurag Chouhanc5548422016-02-24 18:33:27 +05305324 qdf_copy_macaddr(&updateIE.bssid, bssid);
Jeff Johnson1b780e42017-10-31 14:11:45 -07005325 updateIE.smeSessionId = adapter->session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005326 updateIE.ieBufferlength = 0;
5327 updateIE.pAdditionIEBuffer = NULL;
5328 updateIE.append = true;
5329 updateIE.notify = false;
Jeff Johnson16528362018-06-14 12:34:16 -07005330 mac_handle = hdd_adapter_get_mac_handle(adapter);
5331 if (sme_update_add_ie(mac_handle,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005332 &updateIE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305333 eUPDATE_IE_PROBE_RESP) == QDF_STATUS_E_FAILURE) {
Jeff Johnson5880d792016-08-15 13:32:30 -07005334 hdd_err("Could not pass on PROBE_RSP_BCN data to PE");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005335 }
5336}
5337
Dustin Browndb2a8be2017-12-20 11:49:56 -08005338QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
5339 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005340{
Liangwei Dongad89c762018-06-01 01:56:23 -04005341 return hdd_stop_adapter_ext(hdd_ctx, adapter, 0);
5342}
5343
5344QDF_STATUS hdd_stop_adapter_ext(struct hdd_context *hdd_ctx,
5345 struct hdd_adapter *adapter,
5346 enum hdd_adapter_stop_flag_t flag)
5347{
Dustin Brownd747ecd2018-10-26 16:32:22 -07005348 QDF_STATUS status = QDF_STATUS_SUCCESS;
5349 struct hdd_station_ctx *sta_ctx;
Jeff Johnson025618c2018-03-18 14:41:00 -07005350 struct csr_roam_profile *roam_profile;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005351 union iwreq_data wrqu;
5352 tSirUpdateIE updateIE;
5353 unsigned long rc;
Jeff Johnsone4c11db2018-05-05 23:22:32 -07005354 tsap_config_t *sap_config;
Jeff Johnson16528362018-06-14 12:34:16 -07005355 mac_handle_t mac_handle;
Min Liu8c5d99e2018-09-10 17:18:44 +08005356 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005357
Dustin Brown491d54b2018-03-14 12:39:11 -07005358 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005359
Dustin Browne7e71d32018-05-11 16:00:08 -07005360 if (adapter->session_id != HDD_SESSION_ID_INVALID)
5361 wlan_hdd_cfg80211_deregister_frames(adapter);
5362
Alok Kumarb64650c2018-03-23 17:05:11 +05305363 hdd_nud_ignore_tracking(adapter, true);
5364 hdd_nud_reset_tracking(adapter);
Alok Kumar016a1ac2018-09-16 09:55:50 +05305365 hdd_nud_flush_work(adapter);
hangtian9c47aaf2018-11-26 17:59:39 +08005366 hdd_stop_tsf_sync(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305367
Varun Reddy Yeturu8a5d3d42017-08-02 13:03:27 -07005368 hdd_debug("Disabling queues");
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305369 wlan_hdd_netif_queue_control(adapter,
5370 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
5371 WLAN_CONTROL_PATH);
Tushnim Bhattacharyya9bd058f2017-12-27 14:01:31 -08005372 /*
5373 * if this is the last active connection check & stop the
5374 * opportunistic timer first
5375 */
Dustin Brownd747ecd2018-10-26 16:32:22 -07005376 if ((policy_mgr_get_connection_count(hdd_ctx->psoc) == 1 &&
5377 policy_mgr_mode_specific_connection_count(hdd_ctx->psoc,
5378 policy_mgr_convert_device_mode_to_qdf_type(
5379 adapter->device_mode), NULL) == 1) ||
5380 !policy_mgr_get_connection_count(hdd_ctx->psoc))
Tushnim Bhattacharyya9bd058f2017-12-27 14:01:31 -08005381 policy_mgr_check_and_stop_opportunistic_timer(
Dustin Brown1dbefe62018-09-11 16:32:03 -07005382 hdd_ctx->psoc, adapter->session_id);
Jeff Johnson16528362018-06-14 12:34:16 -07005383
5384 mac_handle = hdd_ctx->mac_handle;
5385
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005386 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005387 case QDF_STA_MODE:
5388 case QDF_P2P_CLIENT_MODE:
5389 case QDF_IBSS_MODE:
5390 case QDF_P2P_DEVICE_MODE:
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005391 case QDF_NDI_MODE:
Dustin Brownd747ecd2018-10-26 16:32:22 -07005392 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5393
5394 if (adapter->device_mode == QDF_NDI_MODE ||
5395 hdd_conn_is_connected(sta_ctx) ||
5396 hdd_is_connecting(sta_ctx)) {
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005397 INIT_COMPLETION(adapter->disconnect_comp_var);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005398
Jeff Johnson025618c2018-03-18 14:41:00 -07005399 roam_profile = hdd_roam_profile(adapter);
5400 /* For NDI do not use roam_profile */
Dustin Brownd747ecd2018-10-26 16:32:22 -07005401 if (adapter->device_mode == QDF_NDI_MODE)
5402 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005403 mac_handle,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005404 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005405 eCSR_DISCONNECT_REASON_NDI_DELETE);
Jeff Johnson025618c2018-03-18 14:41:00 -07005406 else if (roam_profile->BSSType ==
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005407 eCSR_BSS_TYPE_START_IBSS)
Dustin Brownd747ecd2018-10-26 16:32:22 -07005408 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005409 mac_handle,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005410 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005411 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
Abhinav Kumar19a7a402018-07-12 17:36:57 +05305412 else if (adapter->device_mode == QDF_STA_MODE)
5413 wlan_hdd_disconnect(adapter,
5414 eCSR_DISCONNECT_REASON_DEAUTH);
5415 else
Dustin Brownd747ecd2018-10-26 16:32:22 -07005416 status = sme_roam_disconnect(
Jeff Johnson16528362018-06-14 12:34:16 -07005417 mac_handle,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005418 adapter->session_id,
Deepak Dhamdhere13983f22016-05-31 19:06:09 -07005419 eCSR_DISCONNECT_REASON_UNSPECIFIED);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005420 /* success implies disconnect is queued */
5421 if (QDF_IS_STATUS_SUCCESS(status) &&
5422 adapter->device_mode != QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005423 rc = wait_for_completion_timeout(
5424 &adapter->disconnect_comp_var,
5425 msecs_to_jiffies
5426 (WLAN_WAIT_TIME_DISCONNECT));
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08005427 if (!rc)
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005428 hdd_warn("disconn_comp_var wait fail");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005429 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005430 if (QDF_IS_STATUS_ERROR(status))
Varun Reddy Yeturu96dced72017-03-29 18:03:54 -07005431 hdd_warn("failed to post disconnect");
Dustin Brownd747ecd2018-10-26 16:32:22 -07005432
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005433 memset(&wrqu, '\0', sizeof(wrqu));
5434 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
5435 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
5436 wireless_send_event(adapter->dev, SIOCGIWAP, &wrqu,
5437 NULL);
Sachin Ahuja988fd102016-09-15 17:16:25 +05305438 }
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005439
Dustin Brownd747ecd2018-10-26 16:32:22 -07005440 wlan_hdd_scan_abort(adapter);
Wu Gao4a1ec8c2018-07-23 19:18:40 +08005441 wlan_hdd_cleanup_actionframe(adapter);
Abhishek Singh1e94d7a2015-11-30 17:26:54 +05305442 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Sridhar Selvaraj8c6f5e82017-08-21 14:53:46 +05305443 hdd_clear_fils_connection_info(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005444 hdd_deregister_tx_flow_control(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005445
5446#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005447 cancel_work_sync(&adapter->ipv4_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005448#ifdef WLAN_NS_OFFLOAD
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005449 cancel_work_sync(&adapter->ipv6_notifier_work);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005450#endif
5451#endif
5452
Min Liu8c5d99e2018-09-10 17:18:44 +08005453 if (adapter->device_mode == QDF_STA_MODE) {
5454 struct wlan_objmgr_vdev *vdev;
5455
5456 vdev = hdd_objmgr_get_vdev(adapter);
5457 if (vdev) {
5458 wlan_cfg80211_sched_scan_stop(vdev);
5459 hdd_objmgr_put_vdev(adapter);
5460 }
5461 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08005462
5463 if (wlan_hdd_try_disconnect(adapter)) {
Dustin Brownd747ecd2018-10-26 16:32:22 -07005464 hdd_err("Can't disconnect adapter");
Dustin Browndb2a8be2017-12-20 11:49:56 -08005465 return QDF_STATUS_E_FAILURE;
Krunal Soni985b8132017-02-10 18:49:08 -08005466 }
Dustin Browndb2a8be2017-12-20 11:49:56 -08005467
Himanshu Agarwalb229a142017-12-21 10:16:45 +05305468 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005469 break;
5470
Rajeev Kumar3b906202018-02-01 10:55:14 -08005471 case QDF_MONITOR_MODE:
5472 wlan_hdd_scan_abort(adapter);
5473 hdd_deregister_tx_flow_control(adapter);
5474 hdd_vdev_destroy(adapter);
5475 break;
5476
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005477 case QDF_SAP_MODE:
Will Huang7049bae2018-08-13 17:25:02 +08005478 if (test_bit(ACS_PENDING, &adapter->event_flags)) {
5479 cds_flush_delayed_work(&adapter->acs_pending_work);
5480 clear_bit(ACS_PENDING, &adapter->event_flags);
5481 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005482
wadesongf9b15ed2017-12-14 14:12:32 +08005483 wlan_hdd_scan_abort(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005484
Arunk Khandavalli96c122f2017-10-17 11:49:36 +05305485 sap_config = &adapter->session.ap.sap_config;
Dustin Brownd747ecd2018-10-26 16:32:22 -07005486 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
5487
Dustin Brown07901ec2018-09-07 11:02:41 -07005488 ucfg_ipa_flush(hdd_ctx->pdev);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005489
Liangwei Dongad89c762018-06-01 01:56:23 -04005490 if (!(flag & HDD_IN_CAC_WORK_TH_CONTEXT))
5491 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
Jeff Johnson46807cd2018-04-29 21:32:22 -07005492 /* fallthrough */
Dustin Browna5cf8e02017-10-19 16:04:19 -07005493
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005494 case QDF_P2P_GO_MODE:
Krunal Soni22208392017-09-29 18:10:34 -07005495 cds_flush_work(&adapter->sap_stop_bss_work);
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05305496 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Dustin Browna5cf8e02017-10-19 16:04:19 -07005497 wlan_hdd_undo_acs(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005498
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005499 if (adapter->device_mode == QDF_P2P_GO_MODE)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005500 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5501
5502 hdd_deregister_tx_flow_control(adapter);
Kapil Guptac1224bf2017-06-22 21:22:40 +05305503 hdd_destroy_acs_timer(adapter);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005504
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005505 mutex_lock(&hdd_ctx->sap_lock);
5506 if (test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005507 status = wlansap_stop_bss(
5508 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005509
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305510 if (QDF_IS_STATUS_SUCCESS(status)) {
Jeff Johnsonca2530c2017-09-30 18:25:40 -07005511 struct hdd_hostapd_state *hostapd_state =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005512 WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter);
Anurag Chouhance0dc992016-02-16 18:18:03 +05305513 qdf_event_reset(&hostapd_state->
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05305514 qdf_stop_bss_event);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005515 status = qdf_wait_for_event_completion(
Nachiket Kukade0396b732017-11-14 16:35:16 +05305516 &hostapd_state->qdf_stop_bss_event,
Vignesh Viswanathan865daaa2018-10-11 19:30:44 +05305517 SME_CMD_START_STOP_BSS_TIMEOUT);
Dustin Brownd747ecd2018-10-26 16:32:22 -07005518 if (QDF_IS_STATUS_ERROR(status))
Jeff Johnson5880d792016-08-15 13:32:30 -07005519 hdd_err("failure waiting for wlansap_stop_bss %d",
Dustin Brownd747ecd2018-10-26 16:32:22 -07005520 status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005521 } else {
Jeff Johnson5880d792016-08-15 13:32:30 -07005522 hdd_err("failure in wlansap_stop_bss");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005523 }
Dustin Brownd747ecd2018-10-26 16:32:22 -07005524
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005525 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -07005526 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08005527 adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005528 adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07005529 hdd_green_ap_start_state_mc(hdd_ctx,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305530 adapter->device_mode,
5531 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005532
Anurag Chouhanc5548422016-02-24 18:33:27 +05305533 qdf_copy_macaddr(&updateIE.bssid,
Jeff Johnson1e851a12017-10-28 14:36:12 -07005534 &adapter->mac_addr);
Jeff Johnson1b780e42017-10-31 14:11:45 -07005535 updateIE.smeSessionId = adapter->session_id;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005536 updateIE.ieBufferlength = 0;
5537 updateIE.pAdditionIEBuffer = NULL;
5538 updateIE.append = false;
5539 updateIE.notify = false;
Dustin Brownd747ecd2018-10-26 16:32:22 -07005540
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005541 /* Probe bcn reset */
Dustin Brownd747ecd2018-10-26 16:32:22 -07005542 status = sme_update_add_ie(mac_handle, &updateIE,
5543 eUPDATE_IE_PROBE_BCN);
5544 if (status == QDF_STATUS_E_FAILURE)
5545 hdd_err("Could not pass PROBE_RSP_BCN to PE");
5546
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005547 /* Assoc resp reset */
Dustin Brownd747ecd2018-10-26 16:32:22 -07005548 status = sme_update_add_ie(mac_handle, &updateIE,
5549 eUPDATE_IE_ASSOC_RESP);
5550 if (status == QDF_STATUS_E_FAILURE)
5551 hdd_err("Could not pass ASSOC_RSP to PE");
5552
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005553 /* Reset WNI_CFG_PROBE_RSP Flags */
5554 wlan_hdd_reset_prob_rspies(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005555 }
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08005556 clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
Jeff Johnsonb9424862017-10-30 08:49:35 -07005557 qdf_mem_free(adapter->session.ap.beacon);
5558 adapter->session.ap.beacon = NULL;
Jiachao Wub1e1ddd2018-05-21 12:04:15 +08005559
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305560 /*
5561 * If Do_Not_Break_Stream was enabled clear avoid channel list.
5562 */
Min Liu8c5d99e2018-09-10 17:18:44 +08005563 vdev = hdd_objmgr_get_vdev(adapter);
5564 if (vdev) {
5565 if (policy_mgr_is_dnsc_set(vdev))
5566 wlan_hdd_send_avoid_freq_for_dnbs(hdd_ctx, 0);
5567 hdd_objmgr_put_vdev(adapter);
5568 }
Ajit Pal Singh747b6802017-05-24 15:42:03 +05305569
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305570#ifdef WLAN_OPEN_SOURCE
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005571 cancel_work_sync(&adapter->ipv4_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305572#ifdef WLAN_NS_OFFLOAD
Jeff Johnsonb527ebe2017-10-28 13:14:03 -07005573 cancel_work_sync(&adapter->ipv6_notifier_work);
Hanumanth Reddy Pothulaaaa3f882017-10-05 17:45:00 +05305574#endif
5575#endif
Dustin Browndb2a8be2017-12-20 11:49:56 -08005576
5577 hdd_vdev_destroy(adapter);
5578
Krunal Sonib51eec72017-11-20 21:53:01 -08005579 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005580 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08005581 case QDF_OCB_MODE:
Dustin Brownd747ecd2018-10-26 16:32:22 -07005582 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Krishna Kumaar Natarajane58b4092017-01-25 15:47:35 -08005583 cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
Dustin Brownd747ecd2018-10-26 16:32:22 -07005584 cds_get_context(QDF_MODULE_ID_TXRX),
5585 sta_ctx->conn_info.staId[0]);
Zhang Qian79d0d132018-02-05 13:40:16 +08005586 hdd_deregister_tx_flow_control(adapter);
5587 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005588 break;
5589 default:
5590 break;
5591 }
5592
Ajit Pal Singh106c1412018-04-18 18:08:49 +05305593 hdd_deregister_hl_netdev_fc_timer(adapter);
5594
Dustin Brown04348372017-12-14 16:13:39 -08005595 if (adapter->scan_info.default_scan_ies) {
5596 qdf_mem_free(adapter->scan_info.default_scan_ies);
5597 adapter->scan_info.default_scan_ies = NULL;
5598 }
5599
Dustin Browne74003f2018-03-14 12:51:58 -07005600 hdd_exit();
Dustin Brownd747ecd2018-10-26 16:32:22 -07005601
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305602 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005603}
5604
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305605/**
5606 * hdd_deinit_all_adapters - deinit all adapters
5607 * @hdd_ctx: HDD context
5608 * @rtnl_held: True if RTNL lock held
5609 *
5610 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005611void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305612{
Jeff Johnson9d295242017-08-29 14:39:48 -07005613 struct hdd_adapter *adapter;
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305614
Dustin Brown491d54b2018-03-14 12:39:11 -07005615 hdd_enter();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305616
Dustin Brown920397d2017-12-13 16:27:50 -08005617 hdd_for_each_adapter(hdd_ctx, adapter)
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305618 hdd_deinit_adapter(hdd_ctx, adapter, rtnl_held);
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305619
Dustin Browne74003f2018-03-14 12:51:58 -07005620 hdd_exit();
Hanumanth Reddy Pothula9f4048f2016-09-30 15:06:57 +05305621}
5622
Dustin Browndb2a8be2017-12-20 11:49:56 -08005623QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005624{
Jeff Johnson9d295242017-08-29 14:39:48 -07005625 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005626
Dustin Brown491d54b2018-03-14 12:39:11 -07005627 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005628
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05305629 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
5630
Dustin Brown920397d2017-12-13 16:27:50 -08005631 hdd_for_each_adapter(hdd_ctx, adapter)
Dustin Browndb2a8be2017-12-20 11:49:56 -08005632 hdd_stop_adapter(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005633
Dustin Browne74003f2018-03-14 12:51:58 -07005634 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005635
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305636 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005637}
5638
Paul Zhang84fa9382017-11-10 21:18:21 +08005639static void hdd_reset_scan_operation(struct hdd_context *hdd_ctx,
5640 struct hdd_adapter *adapter)
5641{
5642 switch (adapter->device_mode) {
5643 case QDF_STA_MODE:
5644 case QDF_P2P_CLIENT_MODE:
5645 case QDF_IBSS_MODE:
5646 case QDF_P2P_DEVICE_MODE:
5647 case QDF_NDI_MODE:
5648 wlan_hdd_scan_abort(adapter);
5649 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
Min Liu8c5d99e2018-09-10 17:18:44 +08005650 if (adapter->device_mode == QDF_STA_MODE) {
5651 struct wlan_objmgr_vdev *vdev;
5652
5653 vdev = hdd_objmgr_get_vdev(adapter);
5654 if (vdev) {
5655 wlan_cfg80211_sched_scan_stop(vdev);
5656 hdd_objmgr_put_vdev(adapter);
5657 }
5658 }
Paul Zhang84fa9382017-11-10 21:18:21 +08005659 break;
5660 case QDF_P2P_GO_MODE:
5661 wlan_hdd_cleanup_remain_on_channel_ctx(adapter);
5662 break;
5663 case QDF_SAP_MODE:
Abhinav Kumarb638b5d2018-03-26 12:25:41 +05305664 qdf_atomic_set(&adapter->session.ap.acs_in_progress, 0);
Paul Zhang84fa9382017-11-10 21:18:21 +08005665 wlan_hdd_undo_acs(adapter);
5666 break;
5667 default:
5668 break;
5669 }
5670}
5671
Ke Huangc067b8d2018-05-21 15:50:13 +08005672#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
5673/**
5674 * hdd_adapter_abort_tx_flow() - Abort the tx flow control
5675 * @pAdapter: pointer to hdd_adapter_t
5676 *
5677 * Resume tx and stop the tx flow control timer if the tx is paused
5678 * and the flow control timer is running. This function is called by
5679 * SSR to avoid the inconsistency of tx status before and after SSR.
5680 *
5681 * Return: void
5682 */
5683static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
5684{
5685 if (adapter->hdd_stats.tx_rx_stats.is_txflow_paused &&
5686 QDF_TIMER_STATE_RUNNING ==
5687 qdf_mc_timer_get_current_state(
5688 &adapter->tx_flow_control_timer)) {
5689 hdd_tx_resume_timer_expired_handler(adapter);
5690 qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
5691 }
5692}
5693#endif
5694
Jeff Johnsond49c4a12017-08-28 12:08:05 -07005695QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005696{
Jeff Johnson9d295242017-08-29 14:39:48 -07005697 struct hdd_adapter *adapter;
Jeff Johnsond377dce2017-10-04 10:32:42 -07005698 struct hdd_station_ctx *sta_ctx;
Yue Mad5b4b9f2017-05-26 16:23:40 -07005699 struct qdf_mac_addr peerMacAddr;
Yue Ma42654682018-01-11 16:55:24 -08005700 int sta_id;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05305701 bool value;
Min Liu8c5d99e2018-09-10 17:18:44 +08005702 struct wlan_objmgr_vdev *vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005703
Dustin Brown491d54b2018-03-14 12:39:11 -07005704 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005705
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +05305706 cds_flush_work(&hdd_ctx->sap_pre_cac_work);
5707
Dustin Brown920397d2017-12-13 16:27:50 -08005708 hdd_for_each_adapter(hdd_ctx, adapter) {
Dustin Brown5e89ef82018-03-14 11:50:23 -07005709 hdd_info("[SSR] reset adapter with device mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07005710 qdf_opmode_str(adapter->device_mode),
Dustin Brown5e89ef82018-03-14 11:50:23 -07005711 adapter->device_mode);
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305712
Ke Huangc067b8d2018-05-21 15:50:13 +08005713#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
5714 hdd_adapter_abort_tx_flow(adapter);
5715#endif
5716
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305717 if ((adapter->device_mode == QDF_STA_MODE) ||
Paul Zhang679025e2018-03-08 22:39:44 +08005718 (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Ganesh Kondabattini9e4fbbb2017-05-24 16:53:02 +05305719 /* Stop tdls timers */
Min Liu8c5d99e2018-09-10 17:18:44 +08005720 vdev = hdd_objmgr_get_vdev(adapter);
5721 if (vdev) {
5722 hdd_notify_tdls_reset_adapter(vdev);
5723 hdd_objmgr_put_vdev(adapter);
5724 }
Paul Zhang679025e2018-03-08 22:39:44 +08005725 adapter->session.station.hdd_reassoc_scenario = false;
5726 }
Dustin Brown05d81302018-09-11 16:49:22 -07005727 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05305728 if (value &&
Arun Khandavallicc544b32017-01-30 19:52:16 +05305729 adapter->device_mode == QDF_SAP_MODE) {
5730 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305731 WLAN_STOP_ALL_NETIF_QUEUE,
Arun Khandavallicc544b32017-01-30 19:52:16 +05305732 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005733 if (test_bit(SOFTAP_BSS_STARTED,
Krunal Sonib51eec72017-11-20 21:53:01 -08005734 &adapter->event_flags))
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005735 hdd_sap_indicate_disconnect_for_sta(adapter);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005736 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
5737 } else {
Arun Khandavallicc544b32017-01-30 19:52:16 +05305738 wlan_hdd_netif_queue_control(adapter,
Himanshu Agarwal865201d2017-04-12 15:45:31 +05305739 WLAN_STOP_ALL_NETIF_QUEUE_N_CARRIER,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005740 WLAN_CONTROL_PATH);
Manikandan Mohan0a44ec82017-02-17 15:06:11 -08005741 }
Nijun Gong104ccc72018-08-07 10:43:56 +08005742 /*
5743 * Clear fc flag if it was set before SSR to avoid TX queues
5744 * permanently stopped after SSR.
5745 * Here WLAN_START_ALL_NETIF_QUEUE will actually not start any
5746 * queue since it's blocked by reason WLAN_CONTROL_PATH.
5747 */
5748 if (adapter->pause_map & (1 << WLAN_DATA_FLOW_CONTROL))
5749 wlan_hdd_netif_queue_control(adapter,
5750 WLAN_START_ALL_NETIF_QUEUE,
5751 WLAN_DATA_FLOW_CONTROL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005752
Paul Zhang84fa9382017-11-10 21:18:21 +08005753 hdd_reset_scan_operation(hdd_ctx, adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005754
5755 hdd_deinit_tx_rx(adapter);
Dustin Brown1dbefe62018-09-11 16:32:03 -07005756 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -07005757 adapter->device_mode, adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -07005758 hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +05305759 false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005760 if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
5761 hdd_wmm_adapter_close(adapter);
5762 clear_bit(WMM_INIT_DONE, &adapter->event_flags);
5763 }
5764
Vignesh Viswanathan2eb18742017-09-08 11:18:59 +05305765 if (adapter->device_mode == QDF_STA_MODE)
5766 hdd_clear_fils_connection_info(adapter);
5767
Wu Gao3545e642017-07-14 19:24:41 +08005768 if (adapter->device_mode == QDF_SAP_MODE) {
Jingxiang Geec113592018-08-09 15:40:39 +08005769 wlansap_cleanup_cac_timer(
5770 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Wu Gao3545e642017-07-14 19:24:41 +08005771 /*
5772 * If adapter is SAP, set session ID to invalid
5773 * since SAP session will be cleanup during SSR.
5774 */
Wu Gao36717432016-11-21 15:09:48 +08005775 wlansap_set_invalid_session(
5776 WLAN_HDD_GET_SAP_CTX_PTR(adapter));
Wu Gao3545e642017-07-14 19:24:41 +08005777 }
5778
Yue Ma42654682018-01-11 16:55:24 -08005779 /* Delete connection peers if any to avoid peer object leaks */
Yue Mad5b4b9f2017-05-26 16:23:40 -07005780 if (adapter->device_mode == QDF_STA_MODE ||
5781 adapter->device_mode == QDF_P2P_CLIENT_MODE) {
Jeff Johnsond377dce2017-10-04 10:32:42 -07005782 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
Yue Mad5b4b9f2017-05-26 16:23:40 -07005783 qdf_copy_macaddr(&peerMacAddr,
Jeff Johnsond377dce2017-10-04 10:32:42 -07005784 &sta_ctx->conn_info.bssId);
Yue Mad5b4b9f2017-05-26 16:23:40 -07005785
Yue Ma42654682018-01-11 16:55:24 -08005786 } else if (adapter->device_mode == QDF_P2P_GO_MODE) {
Wu Gao6b81fc52018-05-24 19:27:27 +08005787 clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
Yue Ma42654682018-01-11 16:55:24 -08005788 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
5789 if (adapter->sta_info[sta_id].in_use) {
5790 hdd_debug("[SSR] deregister STA with ID %d",
5791 sta_id);
5792 hdd_softap_deregister_sta(adapter,
5793 sta_id);
5794 adapter->sta_info[sta_id].in_use = 0;
5795 }
5796 }
Yue Mad5b4b9f2017-05-26 16:23:40 -07005797 }
5798
Alok Kumarb64650c2018-03-23 17:05:11 +05305799 hdd_nud_ignore_tracking(adapter, true);
Alok Kumar016a1ac2018-09-16 09:55:50 +05305800 hdd_nud_reset_tracking(adapter);
5801 hdd_nud_flush_work(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305802 hdd_set_disconnect_status(adapter, false);
hangtian9c47aaf2018-11-26 17:59:39 +08005803 hdd_stop_tsf_sync(adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05305804
Tiger Yu94a5a5c2018-03-09 21:22:26 +08005805 hdd_softap_deinit_tx_rx(adapter);
Tiger Yu8c387702018-07-06 16:56:42 +08005806 hdd_deregister_tx_flow_control(adapter);
Tiger Yu94a5a5c2018-03-09 21:22:26 +08005807
Yue Maf9782842017-05-08 12:49:49 -07005808 /* Destroy vdev which will be recreated during reinit. */
5809 hdd_vdev_destroy(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005810 }
5811
Dustin Browne74003f2018-03-14 12:51:58 -07005812 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005813
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05305814 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005815}
5816
Dustin Brown4c663222018-10-23 14:19:36 -07005817bool hdd_is_any_interface_open(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305818{
Dustin Brown920397d2017-12-13 16:27:50 -08005819 struct hdd_adapter *adapter;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305820
Dustin Brown4c663222018-10-23 14:19:36 -07005821 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE) {
Arun Khandavalliba479c42017-07-26 21:29:40 +05305822 hdd_info("FTM mode, don't close the module");
Dustin Brown4c663222018-10-23 14:19:36 -07005823 return true;
Arun Khandavalliba479c42017-07-26 21:29:40 +05305824 }
5825
Dustin Brown920397d2017-12-13 16:27:50 -08005826 hdd_for_each_adapter(hdd_ctx, adapter) {
5827 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags) ||
Dustin Brown4c663222018-10-23 14:19:36 -07005828 test_bit(SME_SESSION_OPENED, &adapter->event_flags))
5829 return true;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305830 }
5831
Dustin Brown4c663222018-10-23 14:19:36 -07005832 return false;
Ashish Kumar Dhanotiya486c13a2017-03-03 12:57:56 +05305833}
5834
yeshwanth sriram guntukaea63f632017-08-30 19:31:56 +05305835bool hdd_is_interface_up(struct hdd_adapter *adapter)
Arun Khandavallifae92942016-08-01 13:31:08 +05305836{
5837 if (test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags))
5838 return true;
5839 else
5840 return false;
5841}
5842
Anurag Chouhanc4092922016-09-08 15:56:11 +05305843#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) \
bingsbdcd4a22017-06-20 09:27:00 +08005844 && !defined(WITH_BACKPORTS) && !defined(IEEE80211_PRIVACY)
Anurag Chouhanc4092922016-09-08 15:56:11 +05305845struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
5846 struct ieee80211_channel *channel,
5847 const u8 *bssid, const u8 *ssid,
5848 size_t ssid_len)
5849{
5850 return cfg80211_get_bss(wiphy, channel, bssid,
5851 ssid, ssid_len,
5852 WLAN_CAPABILITY_ESS,
5853 WLAN_CAPABILITY_ESS);
5854}
5855#else
5856struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy,
5857 struct ieee80211_channel *channel,
5858 const u8 *bssid, const u8 *ssid,
5859 size_t ssid_len)
5860{
5861 return cfg80211_get_bss(wiphy, channel, bssid,
5862 ssid, ssid_len,
5863 IEEE80211_BSS_TYPE_ESS,
5864 IEEE80211_PRIVACY_ANY);
5865}
5866#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05305867
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305868#if defined CFG80211_CONNECT_BSS || \
5869 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305870#if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305871 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305872/**
5873 * hdd_convert_timeout_reason() - Convert to kernel specific enum
5874 * @timeout_reason: reason for connect timeout
5875 *
5876 * This function is used to convert host timeout
5877 * reason enum to kernel specific enum.
5878 *
5879 * Return: nl timeout enum
5880 */
5881static enum nl80211_timeout_reason hdd_convert_timeout_reason(
5882 tSirResultCodes timeout_reason)
5883{
5884 switch (timeout_reason) {
5885 case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE:
5886 return NL80211_TIMEOUT_SCAN;
5887 case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE:
5888 return NL80211_TIMEOUT_AUTH;
5889 case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE:
5890 return NL80211_TIMEOUT_ASSOC;
5891 default:
5892 return NL80211_TIMEOUT_UNSPECIFIED;
5893 }
5894}
5895
5896/**
5897 * hdd_cfg80211_connect_timeout() - API to send connection timeout reason
5898 * @dev: network device
5899 * @bssid: bssid to which we want to associate
5900 * @timeout_reason: reason for connect timeout
5901 *
5902 * This API is used to send connection timeout reason to supplicant
5903 *
5904 * Return: void
5905 */
5906static void hdd_cfg80211_connect_timeout(struct net_device *dev,
5907 const u8 *bssid,
5908 tSirResultCodes timeout_reason)
5909{
5910 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005911
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305912 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
5913
5914 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL,
5915 nl_timeout_reason);
5916}
5917
5918/**
5919 * __hdd_connect_bss() - API to send connection status to supplicant
5920 * @dev: network device
5921 * @bssid: bssid to which we want to associate
5922 * @req_ie: Request Information Element
5923 * @req_ie_len: len of the req IE
5924 * @resp_ie: Response IE
5925 * @resp_ie_len: len of ht response IE
5926 * @status: status
5927 * @gfp: Kernel Flag
5928 * @timeout_reason: reason for connect timeout
5929 *
5930 * Return: void
5931 */
5932static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5933 struct cfg80211_bss *bss, const u8 *req_ie,
5934 size_t req_ie_len, const u8 *resp_ie,
5935 size_t resp_ie_len, int status, gfp_t gfp,
5936 tSirResultCodes timeout_reason)
5937{
5938 enum nl80211_timeout_reason nl_timeout_reason;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07005939
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305940 nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason);
5941
5942 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
5943 resp_ie, resp_ie_len, status, gfp,
5944 nl_timeout_reason);
5945}
5946#else
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305947#if defined CFG80211_CONNECT_TIMEOUT || \
5948 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305949static void hdd_cfg80211_connect_timeout(struct net_device *dev,
5950 const u8 *bssid,
5951 tSirResultCodes timeout_reason)
5952{
5953 cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL);
5954}
5955#endif
5956
5957static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5958 struct cfg80211_bss *bss, const u8 *req_ie,
5959 size_t req_ie_len, const u8 *resp_ie,
5960 size_t resp_ie_len, int status, gfp_t gfp,
5961 tSirResultCodes timeout_reason)
5962{
5963 cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len,
5964 resp_ie, resp_ie_len, status, gfp);
5965}
5966#endif
5967
Abhishek Singha84d3952016-09-13 13:45:05 +05305968/**
5969 * hdd_connect_bss() - API to send connection status to supplicant
5970 * @dev: network device
5971 * @bssid: bssid to which we want to associate
5972 * @req_ie: Request Information Element
5973 * @req_ie_len: len of the req IE
5974 * @resp_ie: Response IE
5975 * @resp_ie_len: len of ht response IE
5976 * @status: status
5977 * @gfp: Kernel Flag
5978 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305979 * @timeout_reason: reason for connect timeout
Abhishek Singha84d3952016-09-13 13:45:05 +05305980 *
5981 * The API is a wrapper to send connection status to supplicant
5982 *
5983 * Return: Void
5984 */
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05305985#if defined CFG80211_CONNECT_TIMEOUT || \
5986 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
Abhishek Singha84d3952016-09-13 13:45:05 +05305987static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
5988 struct cfg80211_bss *bss, const u8 *req_ie,
5989 size_t req_ie_len, const u8 *resp_ie,
5990 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305991 bool connect_timeout,
5992 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05305993{
5994 if (connect_timeout)
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305995 hdd_cfg80211_connect_timeout(dev, bssid, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305996 else
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05305997 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
5998 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05305999}
6000#else
6001static void hdd_connect_bss(struct net_device *dev, const u8 *bssid,
6002 struct cfg80211_bss *bss, const u8 *req_ie,
6003 size_t req_ie_len, const u8 *resp_ie,
6004 size_t resp_ie_len, int status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306005 bool connect_timeout,
6006 tSirResultCodes timeout_reason)
Abhishek Singha84d3952016-09-13 13:45:05 +05306007{
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306008 __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie,
6009 resp_ie_len, status, gfp, timeout_reason);
Abhishek Singha84d3952016-09-13 13:45:05 +05306010}
6011#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05306012
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306013#if defined(WLAN_FEATURE_FILS_SK)
6014#if defined(CFG80211_CONNECT_DONE) || \
6015 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
6016#if defined(CFG80211_FILS_SK_OFFLOAD_SUPPORT) || \
6017 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306018/**
6019 * hdd_populate_fils_params() - Populate FILS keys to connect response
6020 * @fils_params: connect response to supplicant
6021 * @fils_kek: FILS kek
6022 * @fils_kek_len: FILS kek length
6023 * @pmk: FILS PMK
6024 * @pmk_len: FILS PMK length
6025 * @pmkid: PMKID
6026 * @fils_seq_num: FILS Seq number
6027 *
6028 * Return: None
6029 */
6030static void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6031 *fils_params, const uint8_t *fils_kek,
6032 size_t fils_kek_len, const uint8_t *pmk,
6033 size_t pmk_len, const uint8_t *pmkid,
6034 uint16_t fils_seq_num)
6035{
6036 /* Increament seq number to be used for next FILS */
6037 fils_params->fils_erp_next_seq_num = fils_seq_num + 1;
6038 fils_params->update_erp_next_seq_num = true;
6039 fils_params->fils_kek = fils_kek;
6040 fils_params->fils_kek_len = fils_kek_len;
6041 fils_params->pmk = pmk;
6042 fils_params->pmk_len = pmk_len;
6043 fils_params->pmkid = pmkid;
6044}
6045#else
6046static inline void hdd_populate_fils_params(struct cfg80211_connect_resp_params
6047 *fils_params, const uint8_t
6048 *fils_kek, size_t fils_kek_len,
6049 const uint8_t *pmk, size_t pmk_len,
6050 const uint8_t *pmkid,
6051 uint16_t fils_seq_num)
6052{ }
6053#endif
6054
Jeff Johnson172237b2017-11-07 15:32:59 -08006055void hdd_update_hlp_info(struct net_device *dev,
6056 struct csr_roam_info *roam_info)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306057{
6058 struct sk_buff *skb;
6059 uint16_t skb_len;
6060 struct llc_snap_hdr_t *llc_hdr;
6061 QDF_STATUS status;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306062 uint8_t *hlp_data;
6063 uint16_t hlp_data_len;
6064 struct fils_join_rsp_params *roam_fils_params
6065 = roam_info->fils_join_rsp;
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306066 struct hdd_adapter *padapter = WLAN_HDD_GET_PRIV_PTR(dev);
6067
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306068 if (!roam_fils_params) {
6069 hdd_err("FILS Roam Param NULL");
6070 return;
6071 }
6072
Srinivas Girigowda3cc8e912017-11-28 18:11:57 -08006073 if (!roam_fils_params->hlp_data_len) {
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306074 hdd_err("FILS HLP Data NULL, len %d",
6075 roam_fils_params->hlp_data_len);
6076 return;
6077 }
6078
6079 hlp_data = roam_fils_params->hlp_data;
6080 hlp_data_len = roam_fils_params->hlp_data_len;
6081
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306082 /* Calculate skb length */
6083 skb_len = (2 * ETH_ALEN) + hlp_data_len;
6084 skb = qdf_nbuf_alloc(NULL, skb_len, 0, 4, false);
6085 if (skb == NULL) {
6086 hdd_err("HLP packet nbuf alloc fails");
6087 return;
6088 }
6089
6090 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->dst_mac.bytes,
6091 QDF_MAC_ADDR_SIZE);
6092 qdf_mem_copy(skb_put(skb, ETH_ALEN), roam_fils_params->src_mac.bytes,
6093 QDF_MAC_ADDR_SIZE);
6094
6095 llc_hdr = (struct llc_snap_hdr_t *) hlp_data;
6096 if (IS_SNAP(llc_hdr)) {
6097 hlp_data += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
6098 hlp_data_len += LLC_SNAP_HDR_OFFSET_ETHERTYPE;
6099 }
6100
6101 qdf_mem_copy(skb_put(skb, hlp_data_len), hlp_data, hlp_data_len);
6102
6103 /*
6104 * This HLP packet is formed from HLP info encapsulated
6105 * in assoc response frame which is AEAD encrypted.
6106 * Hence, this checksum validation can be set unnecessary.
6107 * i.e. network layer need not worry about checksum.
6108 */
6109 skb->ip_summed = CHECKSUM_UNNECESSARY;
6110
6111 status = hdd_rx_packet_cbk(padapter, skb);
6112 if (QDF_IS_STATUS_ERROR(status)) {
6113 hdd_err("Sending HLP packet fails");
6114 return;
6115 }
6116 hdd_debug("send HLP packet to netif successfully");
6117}
6118
6119/**
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306120 * hdd_connect_done() - Wrapper API to call cfg80211_connect_done
6121 * @dev: network device
6122 * @bssid: bssid to which we want to associate
6123 * @bss: cfg80211 bss info
6124 * @roam_info: information about connected bss
6125 * @req_ie: Request Information Element
6126 * @req_ie_len: len of the req IE
6127 * @resp_ie: Response IE
6128 * @resp_ie_len: len of ht response IE
6129 * @status: status
6130 * @gfp: allocation flags
6131 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
6132 * @timeout_reason: reason for connect timeout
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306133 *
6134 * This API is used as wrapper to send FILS key/sequence number
6135 * params etc. to supplicant in case of FILS connection
6136 *
6137 * Return: None
6138 */
6139static void hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006140 struct cfg80211_bss *bss,
6141 struct csr_roam_info *roam_info,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306142 const u8 *req_ie, size_t req_ie_len,
6143 const u8 *resp_ie, size_t resp_ie_len, u16 status,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006144 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306145 tSirResultCodes timeout_reason)
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306146{
6147 struct cfg80211_connect_resp_params fils_params;
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306148 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6149 struct fils_join_rsp_params *roam_fils_params =
6150 roam_info->fils_join_rsp;
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006151
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306152 qdf_mem_zero(&fils_params, sizeof(fils_params));
6153
6154 if (!roam_fils_params) {
6155 fils_params.status = WLAN_STATUS_UNSPECIFIED_FAILURE;
6156 } else {
6157 fils_params.status = status;
6158 fils_params.bssid = bssid;
Srinivas Girigowdae975f532018-01-05 14:03:05 -08006159 fils_params.timeout_reason =
6160 hdd_convert_timeout_reason(timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306161 fils_params.req_ie = req_ie;
6162 fils_params.req_ie_len = req_ie_len;
6163 fils_params.resp_ie = resp_ie;
6164 fils_params.resp_ie_len = resp_ie_len;
6165 fils_params.bss = bss;
6166 hdd_populate_fils_params(&fils_params, roam_fils_params->kek,
6167 roam_fils_params->kek_len,
6168 roam_fils_params->fils_pmk,
6169 roam_fils_params->fils_pmk_len,
6170 roam_fils_params->fils_pmkid,
6171 roam_info->fils_seq_num);
Sridhar Selvaraje5260442017-08-19 10:12:03 +05306172 hdd_save_gtk_params(adapter, roam_info, false);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306173 }
6174 hdd_debug("FILS indicate connect status %d seq no %d",
6175 fils_params.status,
6176 fils_params.fils_erp_next_seq_num);
6177
6178 cfg80211_connect_done(dev, &fils_params, gfp);
6179
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306180 if (roam_fils_params && roam_fils_params->hlp_data_len)
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306181 hdd_update_hlp_info(dev, roam_info);
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306182
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306183 /* Clear all the FILS key info */
6184 if (roam_fils_params && roam_fils_params->fils_pmk)
6185 qdf_mem_free(roam_fils_params->fils_pmk);
6186 if (roam_fils_params)
6187 qdf_mem_free(roam_fils_params);
6188 roam_info->fils_join_rsp = NULL;
6189}
6190#else
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006191static inline void
6192hdd_connect_done(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006193 struct cfg80211_bss *bss, struct csr_roam_info *roam_info,
Jeff Johnson4f7f7c62017-10-05 08:53:41 -07006194 const u8 *req_ie, size_t req_ie_len,
6195 const u8 *resp_ie, size_t resp_ie_len, u16 status,
6196 gfp_t gfp, bool connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306197 tSirResultCodes timeout_reason)
Vignesh Viswanathana1bb0922017-09-15 12:58:48 +05306198{ }
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306199#endif
6200#endif
6201
Vignesh Viswanathan3fa1d382017-08-02 19:36:43 +05306202#if defined(WLAN_FEATURE_FILS_SK) && \
6203 (defined(CFG80211_CONNECT_DONE) || \
6204 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)))
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306205/**
6206 * hdd_fils_update_connect_results() - API to send fils connection status to
6207 * supplicant.
6208 * @dev: network device
6209 * @bssid: bssid to which we want to associate
6210 * @bss: cfg80211 bss info
6211 * @roam_info: information about connected bss
6212 * @req_ie: Request Information Element
6213 * @req_ie_len: len of the req IE
6214 * @resp_ie: Response IE
6215 * @resp_ie_len: len of ht response IE
6216 * @status: status
6217 * @gfp: allocation flags
6218 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
6219 * @timeout_reason: reason for connect timeout
6220 *
6221 * The API is a wrapper to send connection status to supplicant
6222 *
6223 * Return: 0 if success else failure
6224 */
6225static int hdd_fils_update_connect_results(struct net_device *dev,
6226 const u8 *bssid,
6227 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08006228 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306229 size_t req_ie_len, const u8 *resp_ie,
6230 size_t resp_ie_len, u16 status, gfp_t gfp,
6231 bool connect_timeout,
6232 tSirResultCodes timeout_reason)
6233{
Dustin Brown491d54b2018-03-14 12:39:11 -07006234 hdd_enter();
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306235 if (!roam_info || !roam_info->is_fils_connection)
6236 return -EINVAL;
6237
6238 hdd_connect_done(dev, bssid, bss, roam_info, req_ie, req_ie_len,
6239 resp_ie, resp_ie_len, status, gfp, connect_timeout,
Vignesh Viswanathanc6d1e1c2017-09-18 12:32:49 +05306240 timeout_reason);
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306241 return 0;
6242}
6243#else
6244static inline int hdd_fils_update_connect_results(struct net_device *dev,
6245 const u8 *bssid,
6246 struct cfg80211_bss *bss,
Jeff Johnson172237b2017-11-07 15:32:59 -08006247 struct csr_roam_info *roam_info, const u8 *req_ie,
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306248 size_t req_ie_len, const u8 *resp_ie,
6249 size_t resp_ie_len, u16 status, gfp_t gfp,
6250 bool connect_timeout,
6251 tSirResultCodes timeout_reason)
6252{
6253 return -EINVAL;
6254}
6255#endif
6256
Anurag Chouhanc4092922016-09-08 15:56:11 +05306257/**
6258 * hdd_connect_result() - API to send connection status to supplicant
6259 * @dev: network device
6260 * @bssid: bssid to which we want to associate
6261 * @roam_info: information about connected bss
6262 * @req_ie: Request Information Element
6263 * @req_ie_len: len of the req IE
6264 * @resp_ie: Response IE
6265 * @resp_ie_len: len of ht response IE
6266 * @status: status
6267 * @gfp: Kernel Flag
Abhishek Singha84d3952016-09-13 13:45:05 +05306268 * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306269 * @timeout_reason: reason for connect timeout
Anurag Chouhanc4092922016-09-08 15:56:11 +05306270 *
6271 * The API is a wrapper to send connection status to supplicant
6272 * and allow runtime suspend
6273 *
6274 * Return: Void
6275 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05306276void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006277 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306278 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05306279 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306280 bool connect_timeout,
6281 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05306282{
Jeff Johnson9d295242017-08-29 14:39:48 -07006283 struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306284 struct cfg80211_bss *bss = NULL;
Jingxiang Ge929c7932018-01-24 14:01:12 +08006285 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(padapter);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306286
6287 if (WLAN_STATUS_SUCCESS == status) {
6288 struct ieee80211_channel *chan;
6289 int freq;
6290 int chan_no = roam_info->pBssDesc->channelId;
6291
6292 if (chan_no <= 14)
6293 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07006294 HDD_NL80211_BAND_2GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306295 else
6296 freq = ieee80211_channel_to_frequency(chan_no,
Srinivas Girigowda38f1ded2017-06-12 23:00:38 -07006297 HDD_NL80211_BAND_5GHZ);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306298
6299 chan = ieee80211_get_channel(padapter->wdev.wiphy, freq);
6300 bss = hdd_cfg80211_get_bss(padapter->wdev.wiphy, chan, bssid,
6301 roam_info->u.pConnectedProfile->SSID.ssId,
6302 roam_info->u.pConnectedProfile->SSID.length);
6303 }
Komal Seelama89be8d2016-09-29 11:09:26 +05306304
Sridhar Selvaraj0d5d2c72017-08-17 17:30:01 +05306305 if (hdd_fils_update_connect_results(dev, bssid, bss,
6306 roam_info, req_ie, req_ie_len, resp_ie,
6307 resp_ie_len, status, gfp, connect_timeout,
6308 timeout_reason) != 0) {
6309 hdd_connect_bss(dev, bssid, bss, req_ie,
6310 req_ie_len, resp_ie, resp_ie_len,
6311 status, gfp, connect_timeout, timeout_reason);
6312 }
Komal Seelama89be8d2016-09-29 11:09:26 +05306313
Jingxiang Geb49aa302018-01-17 20:54:15 +08006314 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07006315 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306316}
6317#else
6318void hdd_connect_result(struct net_device *dev, const u8 *bssid,
Jeff Johnson172237b2017-11-07 15:32:59 -08006319 struct csr_roam_info *roam_info, const u8 *req_ie,
Anurag Chouhanc4092922016-09-08 15:56:11 +05306320 size_t req_ie_len, const u8 *resp_ie,
Abhishek Singha84d3952016-09-13 13:45:05 +05306321 size_t resp_ie_len, u16 status, gfp_t gfp,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306322 bool connect_timeout,
6323 tSirResultCodes timeout_reason)
Anurag Chouhanc4092922016-09-08 15:56:11 +05306324{
Jeff Johnson9d295242017-08-29 14:39:48 -07006325 struct hdd_adapter *padapter = (struct hdd_adapter *) netdev_priv(dev);
Jingxiang Ge929c7932018-01-24 14:01:12 +08006326 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(padapter);
Komal Seelama89be8d2016-09-29 11:09:26 +05306327
Anurag Chouhanc4092922016-09-08 15:56:11 +05306328 cfg80211_connect_result(dev, bssid, req_ie, req_ie_len,
6329 resp_ie, resp_ie_len, status, gfp);
Prashanth Bhatta87b6dc02017-01-19 15:17:58 -08006330
Jingxiang Geb49aa302018-01-17 20:54:15 +08006331 qdf_runtime_pm_allow_suspend(&hdd_ctx->runtime_context.connect);
Dustin Brownceed67e2017-05-26 11:57:31 -07006332 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_CONNECT);
Anurag Chouhanc4092922016-09-08 15:56:11 +05306333}
6334#endif
6335
Nirav Shah73713f72018-05-17 14:50:41 +05306336#ifdef FEATURE_MONITOR_MODE_SUPPORT
Jeff Johnsond9952752018-04-18 12:15:35 -07006337int wlan_hdd_set_mon_chan(struct hdd_adapter *adapter, uint32_t chan,
6338 uint32_t bandwidth)
6339{
6340 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
6341 struct hdd_station_ctx *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
6342 struct hdd_mon_set_ch_info *ch_info = &sta_ctx->ch_info;
6343 QDF_STATUS status;
Jeff Johnson43837af2018-10-17 12:44:05 -07006344 mac_handle_t mac_handle = hdd_ctx->mac_handle;
Jeff Johnsond9952752018-04-18 12:15:35 -07006345 struct qdf_mac_addr bssid;
6346 struct csr_roam_profile roam_profile;
6347 struct ch_params ch_params;
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006348 eConnectionState connstate;
Jeff Johnsond9952752018-04-18 12:15:35 -07006349
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006350 if (hdd_get_conparam() != QDF_GLOBAL_MONITOR_MODE &&
6351 adapter->device_mode != QDF_STA_MODE) {
6352 hdd_err("Not supported, device is not in monitor mode or sta mission mode");
Jeff Johnsond9952752018-04-18 12:15:35 -07006353 return -EINVAL;
6354 }
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006355 if (adapter->device_mode == QDF_STA_MODE &&
6356 hdd_ctx->config->enable_change_channel_bandwidth) {
6357 connstate = sta_ctx->conn_info.connState;
6358 if (eConnectionState_Associated == connstate ||
6359 eConnectionState_Connecting == connstate) {
6360 return -EINVAL;
6361 }
6362 }
Jeff Johnsond9952752018-04-18 12:15:35 -07006363
Visweswara Tanuku006313a2018-04-12 12:26:34 +05306364 /* Validate Channel */
6365 if (!WLAN_REG_IS_24GHZ_CH(chan) && !WLAN_REG_IS_5GHZ_CH(chan)) {
6366 hdd_err("Channel %d Not supported", chan);
6367 return -EINVAL;
6368 }
6369
6370 if (WLAN_REG_IS_24GHZ_CH(chan)) {
6371 if (bandwidth == CH_WIDTH_80MHZ) {
6372 hdd_err("BW80 not possible in 2.4GHz band");
6373 return -EINVAL;
6374 }
6375 if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 14) &&
6376 (bandwidth != CH_WIDTH_MAX)) {
6377 hdd_err("Only BW20 possible on channel 14");
6378 return -EINVAL;
6379 }
6380 }
6381
6382 if (WLAN_REG_IS_5GHZ_CH(chan)) {
6383 if ((bandwidth != CH_WIDTH_20MHZ) && (chan == 165) &&
6384 (bandwidth != CH_WIDTH_MAX)) {
6385 hdd_err("Only BW20 possible on channel 165");
6386 return -EINVAL;
6387 }
6388 }
6389
Jeff Johnsond9952752018-04-18 12:15:35 -07006390 hdd_debug("Set monitor mode Channel %d", chan);
6391 qdf_mem_zero(&roam_profile, sizeof(roam_profile));
6392 roam_profile.ChannelInfo.ChannelList = &ch_info->channel;
6393 roam_profile.ChannelInfo.numOfChannels = 1;
6394 roam_profile.phyMode = ch_info->phy_mode;
6395 roam_profile.ch_params.ch_width = bandwidth;
6396 hdd_select_cbmode(adapter, chan, &roam_profile.ch_params);
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006397 if (hdd_ctx->config->enable_change_channel_bandwidth &&
Jeff Johnson43837af2018-10-17 12:44:05 -07006398 (!sme_find_session_by_bssid(mac_handle, adapter->mac_addr.bytes))) {
6399 status = sme_create_mon_session(mac_handle,
Rajeev Kumar Sirasanagandlae3b59912018-08-24 15:53:31 +05306400 adapter->mac_addr.bytes,
6401 adapter->session_id);
Chaoli Zhou75b062f2018-06-11 12:36:54 +08006402 if (status != QDF_STATUS_SUCCESS) {
6403 hdd_err("Status: %d Failed to create session.",
6404 status);
6405 return qdf_status_to_os_return(status);
6406 }
6407 }
Jeff Johnsond9952752018-04-18 12:15:35 -07006408 qdf_mem_copy(bssid.bytes, adapter->mac_addr.bytes,
6409 QDF_MAC_ADDR_SIZE);
6410
6411 ch_params.ch_width = bandwidth;
Dustin Brown07901ec2018-09-07 11:02:41 -07006412 wlan_reg_set_channel_params(hdd_ctx->pdev, chan, 0, &ch_params);
Jeff Johnsond9952752018-04-18 12:15:35 -07006413 if (ch_params.ch_width == CH_WIDTH_INVALID) {
6414 hdd_err("Invalid capture channel or bandwidth for a country");
6415 return -EINVAL;
6416 }
6417 if (wlan_hdd_change_hw_mode_for_given_chnl(adapter, chan,
6418 POLICY_MGR_UPDATE_REASON_SET_OPER_CHAN)) {
6419 hdd_err("Failed to change hw mode");
6420 return -EINVAL;
6421 }
6422
Jeff Johnson16528362018-06-14 12:34:16 -07006423 status = sme_roam_channel_change_req(hdd_ctx->mac_handle,
6424 bssid, &ch_params,
Jeff Johnsond9952752018-04-18 12:15:35 -07006425 &roam_profile);
6426 if (status) {
6427 hdd_err("Status: %d Failed to set sme_roam Channel for monitor mode",
6428 status);
6429 }
6430
6431 adapter->mon_chan = chan;
6432 adapter->mon_bandwidth = bandwidth;
6433 return qdf_status_to_os_return(status);
6434}
Nirav Shah73713f72018-05-17 14:50:41 +05306435#endif
Anurag Chouhanc4092922016-09-08 15:56:11 +05306436
Wu Gaodf929f12018-05-25 18:12:25 +08006437#ifdef MSM_PLATFORM
6438/**
6439 * hdd_stop_p2p_go() - call cfg80211 API to stop P2P GO
6440 * @adapter: pointer to adapter
6441 *
6442 * This function calls cfg80211 API to stop P2P GO
6443 *
6444 * Return: None
6445 */
6446static void hdd_stop_p2p_go(struct hdd_adapter *adapter)
6447{
6448 hdd_debug("[SSR] send stop ap to supplicant");
6449 cfg80211_ap_stopped(adapter->dev, GFP_KERNEL);
6450}
6451
6452static inline void hdd_delete_sta(struct hdd_adapter *adapter)
6453{
6454}
6455#else
6456static inline void hdd_stop_p2p_go(struct hdd_adapter *adapter)
6457{
6458}
6459
6460/**
6461 * hdd_delete_sta() - call cfg80211 API to delete STA
6462 * @adapter: pointer to adapter
6463 *
6464 * This function calls cfg80211 API to delete STA
6465 *
6466 * Return: None
6467 */
6468static void hdd_delete_sta(struct hdd_adapter *adapter)
6469{
6470 struct qdf_mac_addr bcast_mac = QDF_MAC_ADDR_BCAST_INIT;
6471
6472 hdd_debug("[SSR] send restart supplicant");
6473 /* event supplicant to restart */
6474 cfg80211_del_sta(adapter->dev,
6475 (const u8 *)&bcast_mac.bytes[0],
6476 GFP_KERNEL);
6477}
6478#endif
6479
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006480QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006481{
Jeff Johnson9d295242017-08-29 14:39:48 -07006482 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006483 eConnectionState connState;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05306484 bool value;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006485
Dustin Brown491d54b2018-03-14 12:39:11 -07006486 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006487
Dustin Brown920397d2017-12-13 16:27:50 -08006488 hdd_for_each_adapter(hdd_ctx, adapter) {
Arun Khandavallifae92942016-08-01 13:31:08 +05306489 if (!hdd_is_interface_up(adapter))
Dustin Brown920397d2017-12-13 16:27:50 -08006490 continue;
Arun Khandavallifae92942016-08-01 13:31:08 +05306491
Yue Ma42654682018-01-11 16:55:24 -08006492 hdd_debug("[SSR] start adapter with device mode %s(%d)",
Dustin Brown458027c2018-10-19 12:26:27 -07006493 qdf_opmode_str(adapter->device_mode),
Yue Ma42654682018-01-11 16:55:24 -08006494 adapter->device_mode);
6495
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006496 hdd_wmm_init(adapter);
6497
6498 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006499 case QDF_STA_MODE:
6500 case QDF_P2P_CLIENT_MODE:
6501 case QDF_P2P_DEVICE_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006502
6503 connState = (WLAN_HDD_GET_STATION_CTX_PTR(adapter))
6504 ->conn_info.connState;
6505
Krunal Sonib51eec72017-11-20 21:53:01 -08006506 hdd_start_station_adapter(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006507 /* Open the gates for HDD to receive Wext commands */
Jeff Johnsonc72c5732017-10-28 12:49:37 -07006508 adapter->is_link_up_service_needed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006509
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006510 /* Indicate disconnect event to supplicant
6511 * if associated previously
6512 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006513 if (eConnectionState_Associated == connState ||
Yue Macd961442015-10-20 16:15:31 -07006514 eConnectionState_IbssConnected == connState ||
6515 eConnectionState_NotConnected == connState ||
6516 eConnectionState_IbssDisconnected == connState ||
6517 eConnectionState_Disconnecting == connState) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006518 union iwreq_data wrqu;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006519
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006520 memset(&wrqu, '\0', sizeof(wrqu));
6521 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
6522 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
6523 wireless_send_event(adapter->dev, SIOCGIWAP,
6524 &wrqu, NULL);
Jeff Johnsonb9424862017-10-30 08:49:35 -07006525 adapter->session.station.
Jeff Johnson690fe952017-10-25 11:48:39 -07006526 hdd_reassoc_scenario = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006527
6528 /* indicate disconnected event to nl80211 */
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05306529 wlan_hdd_cfg80211_indicate_disconnect(
6530 adapter->dev, false,
6531 WLAN_REASON_UNSPECIFIED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006532 } else if (eConnectionState_Connecting == connState) {
6533 /*
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006534 * Indicate connect failure to supplicant if we
6535 * were in the process of connecting
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006536 */
Anurag Chouhanc4092922016-09-08 15:56:11 +05306537 hdd_connect_result(adapter->dev, NULL, NULL,
yeshwanth sriram guntukaaf7b73f2017-02-22 17:35:32 +05306538 NULL, 0, NULL, 0,
6539 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006540 GFP_KERNEL, false, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006541 }
6542
6543 hdd_register_tx_flow_control(adapter,
6544 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08006545 hdd_tx_resume_cb,
6546 hdd_tx_flow_control_is_pause);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006547
Arunk Khandavalli40943af2017-05-15 19:25:34 +05306548 hdd_lpass_notify_start(hdd_ctx, adapter);
Alok Kumarb64650c2018-03-23 17:05:11 +05306549 hdd_nud_ignore_tracking(adapter, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006550 break;
6551
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006552 case QDF_SAP_MODE:
Dustin Brown05d81302018-09-11 16:49:22 -07006553 ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05306554 &value);
6555 if (value)
Krunal Sonib51eec72017-11-20 21:53:01 -08006556 hdd_start_ap_adapter(adapter);
Arun Khandavallicc544b32017-01-30 19:52:16 +05306557
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006558 break;
6559
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006560 case QDF_P2P_GO_MODE:
Wu Gaodf929f12018-05-25 18:12:25 +08006561 hdd_delete_sta(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006562 break;
Arunk Khandavalli062fb032017-10-04 12:18:15 +05306563 case QDF_MONITOR_MODE:
Krunal Sonib51eec72017-11-20 21:53:01 -08006564 hdd_start_station_adapter(adapter);
Arunk Khandavalli062fb032017-10-04 12:18:15 +05306565 hdd_set_mon_rx_cb(adapter->dev);
6566 wlan_hdd_set_mon_chan(adapter, adapter->mon_chan,
6567 adapter->mon_bandwidth);
6568 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006569 default:
6570 break;
6571 }
Krunal Soni9c2ee032017-07-18 13:49:54 -07006572 /*
6573 * Action frame registered in one adapter which will
6574 * applicable to all interfaces
6575 */
6576 wlan_hdd_cfg80211_register_frames(adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006577 }
6578
Wu Gaodf929f12018-05-25 18:12:25 +08006579 hdd_for_each_adapter(hdd_ctx, adapter) {
6580 if (!hdd_is_interface_up(adapter))
6581 continue;
6582
6583 if (adapter->device_mode == QDF_P2P_GO_MODE)
6584 hdd_stop_p2p_go(adapter);
6585 }
6586
Dustin Browne74003f2018-03-14 12:51:58 -07006587 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006588
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306589 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006590}
6591
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006592QDF_STATUS hdd_get_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006593 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006594{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306595 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006596 qdf_list_node_t *node;
6597
6598 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006599
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006600 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006601 status = qdf_list_peek_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006602 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006603
6604 if (QDF_IS_STATUS_ERROR(status))
6605 return status;
6606
6607 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6608
6609 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006610}
6611
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006612QDF_STATUS hdd_get_next_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006613 struct hdd_adapter *current_adapter,
6614 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006615{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306616 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006617 qdf_list_node_t *node;
6618
6619 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006620
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006621 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Jeff Johnson19fc8e42017-10-30 19:53:49 -07006622 status = qdf_list_peek_next(&hdd_ctx->hdd_adapters,
Dustin Brown920397d2017-12-13 16:27:50 -08006623 &current_adapter->node,
6624 &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006625 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006626
6627 if (QDF_IS_STATUS_ERROR(status))
6628 return status;
6629
6630 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6631
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006632 return status;
6633}
6634
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006635QDF_STATUS hdd_remove_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006636 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006637{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306638 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006639
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006640 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006641 status = qdf_list_remove_node(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006642 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006643
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006644 return status;
6645}
6646
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006647QDF_STATUS hdd_remove_front_adapter(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006648 struct hdd_adapter **out_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006649{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306650 QDF_STATUS status;
Dustin Brown920397d2017-12-13 16:27:50 -08006651 qdf_list_node_t *node;
6652
6653 *out_adapter = NULL;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006654
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006655 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006656 status = qdf_list_remove_front(&hdd_ctx->hdd_adapters, &node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006657 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006658
6659 if (QDF_IS_STATUS_ERROR(status))
6660 return status;
6661
6662 *out_adapter = qdf_container_of(node, struct hdd_adapter, node);
6663
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006664 return status;
6665}
6666
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006667QDF_STATUS hdd_add_adapter_back(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006668 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006669{
Anurag Chouhanffb21542016-02-17 14:33:03 +05306670 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006671
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006672 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006673 status = qdf_list_insert_back(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006674 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006675
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006676 return status;
6677}
6678
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006679QDF_STATUS hdd_add_adapter_front(struct hdd_context *hdd_ctx,
Dustin Brown920397d2017-12-13 16:27:50 -08006680 struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006681{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306682 QDF_STATUS status;
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006683
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006684 qdf_spin_lock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006685 status = qdf_list_insert_front(&hdd_ctx->hdd_adapters, &adapter->node);
Rajeev Kumardd4dd082016-02-25 12:24:32 -08006686 qdf_spin_unlock_bh(&hdd_ctx->hdd_adapter_lock);
Dustin Brown920397d2017-12-13 16:27:50 -08006687
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006688 return status;
6689}
6690
Liangwei Dong3abfe8f2018-09-20 02:25:44 -04006691struct hdd_adapter *hdd_get_adapter_by_rand_macaddr(
6692 struct hdd_context *hdd_ctx, tSirMacAddr mac_addr)
6693{
6694 struct hdd_adapter *adapter;
6695
6696 hdd_for_each_adapter(hdd_ctx, adapter) {
6697 if ((adapter->device_mode == QDF_STA_MODE ||
6698 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6699 adapter->device_mode == QDF_P2P_DEVICE_MODE) &&
6700 ucfg_p2p_check_random_mac(hdd_ctx->psoc,
6701 adapter->session_id, mac_addr))
6702 return adapter;
6703 }
6704
6705 return NULL;
6706}
6707
Jeff Johnson9d295242017-08-29 14:39:48 -07006708struct hdd_adapter *hdd_get_adapter_by_macaddr(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006709 tSirMacAddr macAddr)
6710{
Jeff Johnson9d295242017-08-29 14:39:48 -07006711 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006712
Dustin Brown920397d2017-12-13 16:27:50 -08006713 hdd_for_each_adapter(hdd_ctx, adapter) {
6714 if (!qdf_mem_cmp(adapter->mac_addr.bytes,
6715 macAddr, sizeof(tSirMacAddr)))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006716 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006717 }
6718
6719 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006720}
6721
Jeff Johnson9d295242017-08-29 14:39:48 -07006722struct hdd_adapter *hdd_get_adapter_by_vdev(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006723 uint32_t vdev_id)
6724{
Jeff Johnson9d295242017-08-29 14:39:48 -07006725 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006726
Dustin Brown920397d2017-12-13 16:27:50 -08006727 hdd_for_each_adapter(hdd_ctx, adapter) {
Jeff Johnson1b780e42017-10-31 14:11:45 -07006728 if (adapter->session_id == vdev_id)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006729 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006730 }
6731
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006732 return NULL;
6733}
6734
Abhishek Singh7996eb72015-12-30 17:24:02 +05306735/**
6736 * hdd_get_adapter_by_sme_session_id() - Return adapter with
6737 * the sessionid
6738 * @hdd_ctx: hdd context.
6739 * @sme_session_id: sme session is for the adapter to get.
6740 *
6741 * This function is used to get the adapter with provided session id
6742 *
6743 * Return: adapter pointer if found
6744 *
6745 */
Jeff Johnson6dff3ee2017-10-06 14:58:57 -07006746struct hdd_adapter *
6747hdd_get_adapter_by_sme_session_id(struct hdd_context *hdd_ctx,
6748 uint32_t sme_session_id)
Abhishek Singh7996eb72015-12-30 17:24:02 +05306749{
Jeff Johnson9d295242017-08-29 14:39:48 -07006750 struct hdd_adapter *adapter;
Abhishek Singh7996eb72015-12-30 17:24:02 +05306751
Dustin Brown920397d2017-12-13 16:27:50 -08006752 hdd_for_each_adapter(hdd_ctx, adapter) {
6753 if (adapter->session_id == sme_session_id)
Abhishek Singh7996eb72015-12-30 17:24:02 +05306754 return adapter;
Abhishek Singh7996eb72015-12-30 17:24:02 +05306755 }
Dustin Brown920397d2017-12-13 16:27:50 -08006756
Abhishek Singh7996eb72015-12-30 17:24:02 +05306757 return NULL;
6758}
6759
Jeff Johnson9d295242017-08-29 14:39:48 -07006760struct hdd_adapter *hdd_get_adapter_by_iface_name(struct hdd_context *hdd_ctx,
Naveen Rawat4edb6822017-04-12 10:09:17 -07006761 const char *iface_name)
6762{
Jeff Johnson9d295242017-08-29 14:39:48 -07006763 struct hdd_adapter *adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07006764
Dustin Brown920397d2017-12-13 16:27:50 -08006765 hdd_for_each_adapter(hdd_ctx, adapter) {
6766 if (!qdf_str_cmp(adapter->dev->name, iface_name))
Naveen Rawat4edb6822017-04-12 10:09:17 -07006767 return adapter;
Naveen Rawat4edb6822017-04-12 10:09:17 -07006768 }
Dustin Brown920397d2017-12-13 16:27:50 -08006769
Naveen Rawat4edb6822017-04-12 10:09:17 -07006770 return NULL;
6771}
6772
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006773/**
6774 * hdd_get_adapter() - to get adapter matching the mode
6775 * @hdd_ctx: hdd context
6776 * @mode: adapter mode
6777 *
6778 * This routine will return the pointer to adapter matching
6779 * with the passed mode.
6780 *
6781 * Return: pointer to adapter or null
6782 */
Jeff Johnson9d295242017-08-29 14:39:48 -07006783struct hdd_adapter *hdd_get_adapter(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08006784 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006785{
Jeff Johnson9d295242017-08-29 14:39:48 -07006786 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006787
Dustin Brown920397d2017-12-13 16:27:50 -08006788 hdd_for_each_adapter(hdd_ctx, adapter) {
6789 if (adapter->device_mode == mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006790 return adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006791 }
6792
6793 return NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006794}
6795
Jeff Johnson36a0abf2018-05-20 11:24:25 -07006796enum QDF_OPMODE hdd_get_device_mode(uint32_t session_id)
Yeshwanth Sriram Guntuka469f9572018-02-12 13:28:22 +05306797{
6798 struct hdd_context *hdd_ctx;
6799 struct hdd_adapter *adapter;
6800
6801 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
6802 if (!hdd_ctx) {
6803 hdd_err("Invalid HDD context");
6804 return QDF_MAX_NO_OF_MODE;
6805 }
6806
6807 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx, session_id);
6808 if (!adapter) {
6809 hdd_err("Invalid HDD adapter");
6810 return QDF_MAX_NO_OF_MODE;
6811 }
6812
6813 return adapter->device_mode;
6814}
6815
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006816/**
6817 * hdd_get_operating_channel() - return operating channel of the device mode
6818 * @hdd_ctx: Pointer to the HDD context.
6819 * @mode: Device mode for which operating channel is required.
Jeff Johnson77f89bb2018-05-06 16:21:36 -07006820 * Supported modes:
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006821 * QDF_STA_MODE,
6822 * QDF_P2P_CLIENT_MODE,
6823 * QDF_SAP_MODE,
6824 * QDF_P2P_GO_MODE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006825 *
6826 * This API returns the operating channel of the requested device mode
6827 *
6828 * Return: channel number. "0" id the requested device is not found OR it is
6829 * not connected.
6830 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006831uint8_t hdd_get_operating_channel(struct hdd_context *hdd_ctx,
Jeff Johnsonc1e62782017-11-09 09:50:17 -08006832 enum QDF_OPMODE mode)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006833{
Jeff Johnson9d295242017-08-29 14:39:48 -07006834 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006835 uint8_t operatingChannel = 0;
6836
Dustin Brown920397d2017-12-13 16:27:50 -08006837 hdd_for_each_adapter(hdd_ctx, adapter) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006838 if (mode == adapter->device_mode) {
6839 switch (adapter->device_mode) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006840 case QDF_STA_MODE:
6841 case QDF_P2P_CLIENT_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006842 if (hdd_conn_is_connected
6843 (WLAN_HDD_GET_STATION_CTX_PTR
6844 (adapter))) {
6845 operatingChannel =
6846 (WLAN_HDD_GET_STATION_CTX_PTR
6847 (adapter))->conn_info.
6848 operationChannel;
6849 }
6850 break;
Krunal Soni9b04c9b2016-03-10 13:08:05 -08006851 case QDF_SAP_MODE:
6852 case QDF_P2P_GO_MODE:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006853 /* softap connection info */
6854 if (test_bit
6855 (SOFTAP_BSS_STARTED,
6856 &adapter->event_flags))
6857 operatingChannel =
6858 (WLAN_HDD_GET_AP_CTX_PTR
Jeff Johnson01206862017-10-27 20:55:59 -07006859 (adapter))->operating_channel;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006860 break;
6861 default:
6862 break;
6863 }
6864
Srinivas Girigowdab841da72017-03-25 18:04:39 -07006865 /* Found the device of interest. break the loop */
6866 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006867 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006868 }
Dustin Brown920397d2017-12-13 16:27:50 -08006869
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006870 return operatingChannel;
6871}
6872
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006873static inline QDF_STATUS hdd_unregister_wext_all_adapters(struct hdd_context *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006874 hdd_ctx)
6875{
Jeff Johnson9d295242017-08-29 14:39:48 -07006876 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006877
Dustin Brown491d54b2018-03-14 12:39:11 -07006878 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006879
Dustin Brown920397d2017-12-13 16:27:50 -08006880 hdd_for_each_adapter(hdd_ctx, adapter) {
6881 if (adapter->device_mode == QDF_STA_MODE ||
6882 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6883 adapter->device_mode == QDF_IBSS_MODE ||
6884 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
6885 adapter->device_mode == QDF_SAP_MODE ||
6886 adapter->device_mode == QDF_P2P_GO_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006887 hdd_unregister_wext(adapter->dev);
6888 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006889 }
6890
Dustin Browne74003f2018-03-14 12:51:58 -07006891 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006892
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306893 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006894}
6895
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006896QDF_STATUS hdd_abort_mac_scan_all_adapters(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006897{
Jeff Johnson9d295242017-08-29 14:39:48 -07006898 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006899
Dustin Brown491d54b2018-03-14 12:39:11 -07006900 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006901
Dustin Brown920397d2017-12-13 16:27:50 -08006902 hdd_for_each_adapter(hdd_ctx, adapter) {
6903 if (adapter->device_mode == QDF_STA_MODE ||
6904 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6905 adapter->device_mode == QDF_IBSS_MODE ||
6906 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
6907 adapter->device_mode == QDF_SAP_MODE ||
6908 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brown07901ec2018-09-07 11:02:41 -07006909 wlan_abort_scan(hdd_ctx->pdev, INVAL_PDEV_ID,
Jeff Johnson1b780e42017-10-31 14:11:45 -07006910 adapter->session_id, INVALID_SCAN_ID,
Vignesh Viswanathan19611c82018-01-16 16:20:40 +05306911 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006912 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006913 }
6914
Dustin Browne74003f2018-03-14 12:51:58 -07006915 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006916
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05306917 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006918}
6919
Dustin Brownf27bce82016-11-03 12:52:27 -07006920/**
6921 * hdd_abort_sched_scan_all_adapters() - stops scheduled (PNO) scans for all
6922 * adapters
6923 * @hdd_ctx: The HDD context containing the adapters to operate on
6924 *
6925 * return: QDF_STATUS_SUCCESS
6926 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006927static QDF_STATUS hdd_abort_sched_scan_all_adapters(struct hdd_context *hdd_ctx)
Dustin Brownf27bce82016-11-03 12:52:27 -07006928{
Jeff Johnson9d295242017-08-29 14:39:48 -07006929 struct hdd_adapter *adapter;
Dustin Brownf27bce82016-11-03 12:52:27 -07006930 int err;
6931
Dustin Brown491d54b2018-03-14 12:39:11 -07006932 hdd_enter();
Dustin Brownf27bce82016-11-03 12:52:27 -07006933
Dustin Brown920397d2017-12-13 16:27:50 -08006934 hdd_for_each_adapter(hdd_ctx, adapter) {
6935 if (adapter->device_mode == QDF_STA_MODE ||
6936 adapter->device_mode == QDF_P2P_CLIENT_MODE ||
6937 adapter->device_mode == QDF_IBSS_MODE ||
6938 adapter->device_mode == QDF_P2P_DEVICE_MODE ||
6939 adapter->device_mode == QDF_SAP_MODE ||
6940 adapter->device_mode == QDF_P2P_GO_MODE) {
Dustin Brownf27bce82016-11-03 12:52:27 -07006941 err = wlan_hdd_sched_scan_stop(adapter->dev);
6942 if (err)
6943 hdd_err("Unable to stop scheduled scan");
6944 }
Dustin Brownf27bce82016-11-03 12:52:27 -07006945 }
6946
Dustin Browne74003f2018-03-14 12:51:58 -07006947 hdd_exit();
Dustin Brownf27bce82016-11-03 12:52:27 -07006948
6949 return QDF_STATUS_SUCCESS;
6950}
6951
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006952#ifdef WLAN_NS_OFFLOAD
6953/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006954 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006955 * @hdd_ctx: Pointer to hdd context
6956 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006957 * Unregister for IPv6 address change notifications.
6958 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006959 * Return: None
6960 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006961static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006962{
6963 unregister_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006964}
6965
6966/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006967 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006968 * @hdd_ctx: Pointer to hdd context
6969 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006970 * Register for IPv6 address change notifications.
6971 *
6972 * Return: 0 on success and errno on failure.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006973 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006974static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006975{
6976 int ret;
6977
6978 hdd_ctx->ipv6_notifier.notifier_call = wlan_hdd_ipv6_changed;
6979 ret = register_inet6addr_notifier(&hdd_ctx->ipv6_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006980 if (ret) {
6981 hdd_err("Failed to register IPv6 notifier: %d", ret);
6982 goto out;
6983 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006984
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08006985 hdd_debug("Registered IPv6 notifier");
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006986out:
6987 return ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006988}
6989#else
6990/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006991 * hdd_wlan_unregister_ip6_notifier() - unregister IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006992 * @hdd_ctx: Pointer to hdd context
6993 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07006994 * Unregister for IPv6 address change notifications.
6995 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006996 * Return: None
6997 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07006998static void hdd_wlan_unregister_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08006999{
7000}
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007001
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007002/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007003 * hdd_wlan_register_ip6_notifier() - register IPv6 change notifier
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007004 * @hdd_ctx: Pointer to hdd context
7005 *
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007006 * Register for IPv6 address change notifications.
7007 *
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007008 * Return: None
7009 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007010static int hdd_wlan_register_ip6_notifier(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007011{
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007012 return 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007013}
7014#endif
7015
Alok Kumarb64650c2018-03-23 17:05:11 +05307016void hdd_set_disconnect_status(struct hdd_adapter *adapter, bool status)
7017{
7018 qdf_mutex_acquire(&adapter->disconnection_status_lock);
7019 adapter->disconnection_in_progress = status;
7020 qdf_mutex_release(&adapter->disconnection_status_lock);
7021 hdd_debug("setting disconnection status: %d", status);
7022}
7023
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007024/**
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007025 * hdd_register_notifiers - Register netdev notifiers.
7026 * @hdd_ctx: HDD context
7027 *
7028 * Register netdev notifiers like IPv4 and IPv6.
7029 *
7030 * Return: 0 on success and errno on failure
7031 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007032static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007033{
7034 int ret;
7035
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007036 ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
7037 if (ret)
Arun Khandavalli08479ba2017-08-07 19:56:23 +05307038 goto out;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007039
7040 hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
7041 ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
7042 if (ret) {
7043 hdd_err("Failed to register IPv4 notifier: %d", ret);
7044 goto unregister_ip6_notifier;
7045 }
7046
Alok Kumarb64650c2018-03-23 17:05:11 +05307047 ret = hdd_nud_register_netevent_notifier(hdd_ctx);
7048 if (ret) {
7049 hdd_err("Failed to register netevent notifier: %d",
7050 ret);
7051 goto unregister_inetaddr_notifier;
7052 }
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007053 return 0;
7054
Alok Kumarb64650c2018-03-23 17:05:11 +05307055unregister_inetaddr_notifier:
7056 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007057unregister_ip6_notifier:
7058 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007059out:
7060 return ret;
7061
7062}
7063
7064/**
7065 * hdd_unregister_notifiers - Unregister netdev notifiers.
7066 * @hdd_ctx: HDD context
7067 *
7068 * Unregister netdev notifiers like IPv4 and IPv6.
7069 *
7070 * Return: None.
7071 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007072void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007073{
Alok Kumarb64650c2018-03-23 17:05:11 +05307074 hdd_nud_unregister_netevent_notifier(hdd_ctx);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007075 hdd_wlan_unregister_ip6_notifier(hdd_ctx);
7076
7077 unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -07007078}
7079
7080/**
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007081 * hdd_exit_netlink_services - Exit netlink services
7082 * @hdd_ctx: HDD context
7083 *
7084 * Exit netlink services like cnss_diag, cesium netlink socket, ptt socket and
7085 * nl service.
7086 *
7087 * Return: None.
7088 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007089static void hdd_exit_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007090{
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307091 spectral_scan_deactivate_service();
7092 cnss_diag_deactivate_service();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007093 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007094 ptt_sock_deactivate_svc();
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307095 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007096
7097 nl_srv_exit();
7098}
7099
7100/**
7101 * hdd_init_netlink_services- Init netlink services
7102 * @hdd_ctx: HDD context
7103 *
7104 * Init netlink services like cnss_diag, cesium netlink socket, ptt socket and
7105 * nl service.
7106 *
7107 * Return: 0 on success and errno on failure.
7108 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007109static int hdd_init_netlink_services(struct hdd_context *hdd_ctx)
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007110{
7111 int ret;
7112
Ryan Hsuceddceb2016-04-28 10:20:14 -07007113 ret = wlan_hdd_nl_init(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007114 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007115 hdd_err("nl_srv_init failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007116 goto out;
7117 }
Ryan Hsuceddceb2016-04-28 10:20:14 -07007118 cds_set_radio_index(hdd_ctx->radio_index);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007119
Naveen Rawat910726a2017-03-06 11:42:51 -08007120 ret = hdd_activate_wifi_pos(hdd_ctx);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007121 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007122 hdd_err("hdd_activate_wifi_pos failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007123 goto err_nl_srv;
7124 }
7125
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307126 ptt_sock_activate_svc();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007127
7128 ret = hdd_open_cesium_nl_sock();
Ryan Hsu5e2e2052016-04-28 10:19:38 -07007129 if (ret)
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007130 hdd_err("hdd_open_cesium_nl_sock failed ret: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007131
7132 ret = cnss_diag_activate_service();
7133 if (ret) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007134 hdd_err("cnss_diag_activate_service failed: %d", ret);
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007135 goto err_close_cesium;
7136 }
7137
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307138 spectral_scan_activate_service();
Sandeep Puligilla019a1bd2018-02-04 22:57:44 -08007139
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007140 return 0;
7141
7142err_close_cesium:
7143 hdd_close_cesium_nl_sock();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007144 ptt_sock_deactivate_svc();
Vignesh Viswanathana1cb4b42018-05-17 21:19:27 +05307145 hdd_deactivate_wifi_pos();
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007146err_nl_srv:
7147 nl_srv_exit();
7148out:
7149 return ret;
7150}
7151
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007152/**
7153 * hdd_rx_wake_lock_destroy() - Destroy RX wakelock
7154 * @hdd_ctx: HDD context.
7155 *
7156 * Destroy RX wakelock.
7157 *
7158 * Return: None.
7159 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007160static void hdd_rx_wake_lock_destroy(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007161{
7162 qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock);
7163}
Prashanth Bhatta6a6a5552016-02-01 13:49:29 -08007164
7165/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007166 * hdd_rx_wake_lock_create() - Create RX wakelock
7167 * @hdd_ctx: HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007168 *
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007169 * Create RX wakelock.
7170 *
7171 * Return: None.
7172 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007173static void hdd_rx_wake_lock_create(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007174{
7175 qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock");
7176}
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007177
7178/**
Houston Hoffman160db392016-10-10 17:37:51 -07007179 * hdd_context_deinit() - Deinitialize HDD context
7180 * @hdd_ctx: HDD context.
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007181 *
Houston Hoffman160db392016-10-10 17:37:51 -07007182 * Deinitialize HDD context along with all the feature specific contexts but
7183 * do not free hdd context itself. Caller of this API is supposed to free
7184 * HDD context.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007185 *
Houston Hoffman160db392016-10-10 17:37:51 -07007186 * return: 0 on success and errno on failure.
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007187 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007188static int hdd_context_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007189{
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05307190 qdf_wake_lock_destroy(&hdd_ctx->monitor_mode_wakelock);
7191
Houston Hoffman160db392016-10-10 17:37:51 -07007192 wlan_hdd_cfg80211_deinit(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007193
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007194 hdd_sap_context_destroy(hdd_ctx);
7195
7196 hdd_rx_wake_lock_destroy(hdd_ctx);
7197
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007198 hdd_scan_context_destroy(hdd_ctx);
7199
Jeff Johnson19fc8e42017-10-30 19:53:49 -07007200 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07007201
Houston Hoffman160db392016-10-10 17:37:51 -07007202 return 0;
7203}
7204
Dustin Brown623e7e32018-09-05 14:27:50 -07007205void hdd_context_destroy(struct hdd_context *hdd_ctx)
Houston Hoffman160db392016-10-10 17:37:51 -07007206{
Rajeev Kumar493a31b2017-09-29 14:01:24 -07007207 cds_set_context(QDF_MODULE_ID_HDD, NULL);
Arunk Khandavalli3d267b42017-05-02 18:58:59 +05307208
Dustin Brown623e7e32018-09-05 14:27:50 -07007209 hdd_exit_netlink_services(hdd_ctx);
Hanumantha Reddy Pothula00c74f62016-11-24 20:13:32 +05307210 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
7211
Houston Hoffman160db392016-10-10 17:37:51 -07007212 hdd_context_deinit(hdd_ctx);
7213
Dustin Browndb2df2e2018-10-31 15:29:24 -07007214 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
7215
Anurag Chouhan600c3a02016-03-01 10:33:54 +05307216 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007217 hdd_ctx->config = NULL;
Dustin Brown84f46ea2018-02-15 11:57:36 -08007218 cfg_release();
7219
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08007220 wiphy_free(hdd_ctx->wiphy);
7221}
7222
7223/**
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05307224 * wlan_destroy_bug_report_lock() - Destroy bug report lock
7225 *
7226 * This function is used to destroy bug report lock
7227 *
7228 * Return: None
7229 */
7230static void wlan_destroy_bug_report_lock(void)
7231{
Jeff Johnson2b6982c2018-05-29 14:56:11 -07007232 struct cds_context *p_cds_context;
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +05307233
7234 p_cds_context = cds_get_global_context();
7235 if (!p_cds_context) {
7236 hdd_err("cds context is NULL");
7237 return;
7238 }
7239
7240 qdf_spinlock_destroy(&p_cds_context->bug_report_lock);
7241}
7242
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +05307243#ifdef DISABLE_CHANNEL_LIST
7244static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
7245{
7246 qdf_mutex_destroy(&hdd_ctx->cache_channel_lock);
7247}
7248#else
7249static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx)
7250{
7251}
7252#endif
7253
Dustin Brown92bd8382018-10-31 15:49:46 -07007254void hdd_wlan_exit(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007255{
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007256 struct wiphy *wiphy = hdd_ctx->wiphy;
Arun Khandavallifae92942016-08-01 13:31:08 +05307257 int driver_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007258
Dustin Brown491d54b2018-03-14 12:39:11 -07007259 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007260
Dustin Brown4c663222018-10-23 14:19:36 -07007261 hdd_psoc_idle_timer_stop(hdd_ctx);
Dustin Brown6470aba2018-09-05 09:49:58 -07007262
Arun Khandavallifae92942016-08-01 13:31:08 +05307263 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007264
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007265#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +05307266 if (QDF_TIMER_STATE_RUNNING ==
7267 qdf_mc_timer_get_current_state(&hdd_ctx->skip_acs_scan_timer)) {
7268 qdf_mc_timer_stop(&hdd_ctx->skip_acs_scan_timer);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007269 }
7270
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307271 if (!QDF_IS_STATUS_SUCCESS
Anurag Chouhan210db072016-02-22 18:42:15 +05307272 (qdf_mc_timer_destroy(&hdd_ctx->skip_acs_scan_timer))) {
Jeff Johnson5880d792016-08-15 13:32:30 -07007273 hdd_err("Cannot deallocate ACS Skip timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007274 }
Liangwei Dongaef84342016-10-21 05:28:00 -04007275 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
7276 qdf_mem_free(hdd_ctx->last_acs_channel_list);
7277 hdd_ctx->last_acs_channel_list = NULL;
7278 hdd_ctx->num_of_channels = 0;
7279 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007280#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007281
Arun Khandavallifae92942016-08-01 13:31:08 +05307282 mutex_lock(&hdd_ctx->iface_change_lock);
7283 driver_status = hdd_ctx->driver_status;
7284 mutex_unlock(&hdd_ctx->iface_change_lock);
7285
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007286 /*
7287 * Powersave Offload Case
7288 * Disable Idle Power Save Mode
7289 */
7290 hdd_set_idle_ps_config(hdd_ctx, false);
Sandeep Puligilla8fa28fd2017-11-02 12:19:33 -07007291 /* clear the scan queue in all the scenarios */
Dustin Brown07901ec2018-09-07 11:02:41 -07007292 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007293
Arun Khandavallifae92942016-08-01 13:31:08 +05307294 if (driver_status != DRIVER_MODULES_CLOSED) {
7295 hdd_unregister_wext_all_adapters(hdd_ctx);
7296 /*
7297 * Cancel any outstanding scan requests. We are about to close
7298 * all of our adapters, but an adapter structure is what SME
7299 * passes back to our callback function. Hence if there
7300 * are any outstanding scan requests then there is a
7301 * race condition between when the adapter is closed and
7302 * when the callback is invoked. We try to resolve that
7303 * race condition here by canceling any outstanding scans
7304 * before we close the adapters.
7305 * Note that the scans may be cancelled in an asynchronous
7306 * manner, so ideally there needs to be some kind of
7307 * synchronization. Rather than introduce a new
7308 * synchronization here, we will utilize the fact that we are
7309 * about to Request Full Power, and since that is synchronized,
7310 * the expectation is that by the time Request Full Power has
7311 * completed, all scans will be cancelled
7312 */
7313 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Dustin Brownf27bce82016-11-03 12:52:27 -07007314 hdd_abort_sched_scan_all_adapters(hdd_ctx);
Dustin Browndb2a8be2017-12-20 11:49:56 -08007315 hdd_stop_all_adapters(hdd_ctx);
bings29c99862017-11-01 13:54:13 +08007316 hdd_deinit_all_adapters(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007317 }
7318
Arunk Khandavalli830c9692018-03-22 12:17:40 +05307319 unregister_reboot_notifier(&system_reboot_notifier);
Arun Khandavalli08479ba2017-08-07 19:56:23 +05307320 unregister_netdevice_notifier(&hdd_netdev_notifier);
7321
Rachit Kankane30807332018-06-27 18:39:36 +05307322 qdf_dp_trace_deinit();
7323
Rajeev Kumar3fef4e82017-03-31 20:25:23 -07007324 hdd_wlan_stop_modules(hdd_ctx, false);
Hanumanth Reddy Pothula709a6362016-10-18 18:19:44 +05307325
Visweswara Tanukuc029a202018-11-27 10:42:10 +05307326 hdd_bus_bw_compute_timer_stop(hdd_ctx);
Dustin Brown86d196b2018-08-02 11:51:49 -07007327 hdd_bus_bandwidth_deinit(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -08007328 hdd_driver_memdump_deinit();
7329
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +05307330 qdf_nbuf_deinit_replenish_timer();
7331
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05307332 if (QDF_GLOBAL_MONITOR_MODE == hdd_get_conparam()) {
7333 hdd_info("Release wakelock for monitor mode!");
7334 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
7335 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
7336 }
7337
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307338 qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307339 qdf_spinlock_destroy(&hdd_ctx->connection_status_lock);
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +05307340 wlan_hdd_cache_chann_mutex_destroy(hdd_ctx);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05307341
Naveen Rawate02f8f52018-04-05 11:58:04 -07007342 osif_request_manager_deinit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007343
Dustin Brownd005ad82018-01-19 10:32:13 -08007344 hdd_close_all_adapters(hdd_ctx, false);
7345
Manishekar Chandrasekaranf7a1dad2016-06-23 06:43:47 +05307346 wlansap_global_deinit();
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05307347 /*
7348 * If there is re_init failure wiphy would have already de-registered
7349 * check the wiphy status before un-registering again
7350 */
Ashish Kumar Dhanotiyae16feb72017-03-31 19:39:37 +05307351 if (wiphy && wiphy->registered) {
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05307352 wiphy_unregister(wiphy);
7353 wlan_hdd_cfg80211_deinit(wiphy);
7354 hdd_lpass_notify_stop(hdd_ctx);
7355 }
Yuanyuan Liu3e918e52016-08-17 15:41:35 -07007356
Arun Khandavallifae92942016-08-01 13:31:08 +05307357 hdd_exit_netlink_services(hdd_ctx);
7358 mutex_destroy(&hdd_ctx->iface_change_lock);
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05307359#ifdef FEATURE_WLAN_CH_AVOID
7360 mutex_destroy(&hdd_ctx->avoid_freq_lock);
7361#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007362}
7363
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007364#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Liangwei Dongaef84342016-10-21 05:28:00 -04007365/**
7366 * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007367 * @data: pointer to struct hdd_context
Liangwei Dongaef84342016-10-21 05:28:00 -04007368 *
7369 * This function will reset acs_scan_status to eSAP_DO_NEW_ACS_SCAN.
7370 * Then new ACS request will do a fresh scan without reusing the cached
7371 * scan information.
7372 *
7373 * Return: void
7374 */
Tang Yingying523322d2017-01-17 23:28:43 +08007375static void hdd_skip_acs_scan_timer_handler(void *data)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007376{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007377 struct hdd_context *hdd_ctx = (struct hdd_context *) data;
Jeff Johnson16528362018-06-14 12:34:16 -07007378 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007379
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007380 hdd_debug("ACS Scan result expired. Reset ACS scan skip");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007381 hdd_ctx->skip_acs_scan_status = eSAP_DO_NEW_ACS_SCAN;
Liangwei Dongaef84342016-10-21 05:28:00 -04007382 qdf_spin_lock(&hdd_ctx->acs_skip_lock);
7383 qdf_mem_free(hdd_ctx->last_acs_channel_list);
7384 hdd_ctx->last_acs_channel_list = NULL;
7385 hdd_ctx->num_of_channels = 0;
7386 qdf_spin_unlock(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007387
Jeff Johnson16528362018-06-14 12:34:16 -07007388 mac_handle = hdd_ctx->mac_handle;
7389 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007390 return;
Jeff Johnson16528362018-06-14 12:34:16 -07007391 sme_scan_flush_result(mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007392}
7393#endif
7394
7395#ifdef QCA_HT_2040_COEX
Jeff Johnsone7672e72017-10-21 15:10:04 -07007396int hdd_wlan_set_ht2040_mode(struct hdd_adapter *adapter, uint16_t sta_id,
7397 struct qdf_mac_addr sta_mac, int channel_type)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007398{
7399 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307400 QDF_STATUS qdf_status;
Jeff Johnsone7672e72017-10-21 15:10:04 -07007401 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -07007402 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007403
7404 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
7405
7406 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307407 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007408 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307409
Jeff Johnson16528362018-06-14 12:34:16 -07007410 mac_handle = hdd_ctx->mac_handle;
7411 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007412 return -EINVAL;
7413
Jeff Johnson16528362018-06-14 12:34:16 -07007414 qdf_status = sme_notify_ht2040_mode(mac_handle, sta_id, sta_mac,
Jeff Johnson1b780e42017-10-31 14:11:45 -07007415 adapter->session_id, channel_type);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307416 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007417 hdd_err("Fail to send notification with ht2040 mode");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007418 return -EINVAL;
7419 }
7420
7421 return 0;
7422}
7423#endif
7424
7425/**
7426 * hdd_wlan_notify_modem_power_state() - notify FW with modem power status
7427 * @state: state
7428 *
7429 * This function notifies FW with modem power status
7430 *
7431 * Return: 0 if successful, error number otherwise
7432 */
7433int hdd_wlan_notify_modem_power_state(int state)
7434{
7435 int status;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307436 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007437 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -07007438 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007439
Anurag Chouhan6d760662016-02-20 16:05:43 +05307440 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007441 status = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307442 if (status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007443 return status;
Abhishek Singh23edd1c2016-05-05 11:56:06 +05307444
Jeff Johnson16528362018-06-14 12:34:16 -07007445 mac_handle = hdd_ctx->mac_handle;
7446 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007447 return -EINVAL;
7448
Jeff Johnson16528362018-06-14 12:34:16 -07007449 qdf_status = sme_notify_modem_power_state(mac_handle, state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307450 if (QDF_STATUS_SUCCESS != qdf_status) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007451 hdd_err("Fail to send notification with modem power state %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007452 state);
7453 return -EINVAL;
7454 }
7455 return 0;
7456}
7457
7458/**
7459 *
7460 * hdd_post_cds_enable_config() - HDD post cds start config helper
7461 * @adapter - Pointer to the HDD
7462 *
7463 * Return: None
7464 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007465QDF_STATUS hdd_post_cds_enable_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007466{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307467 QDF_STATUS qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007468
7469 /*
7470 * Send ready indication to the HDD. This will kick off the MAC
7471 * into a 'running' state and should kick off an initial scan.
7472 */
Jeff Johnson16528362018-06-14 12:34:16 -07007473 qdf_ret_status = sme_hdd_ready_ind(hdd_ctx->mac_handle);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05307474 if (!QDF_IS_STATUS_SUCCESS(qdf_ret_status)) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007475 hdd_err("sme_hdd_ready_ind() failed with status code %08d [x%08x]",
7476 qdf_ret_status, qdf_ret_status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307477 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007478 }
7479
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05307480 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007481}
7482
Sourav Mohapatra92ea8d62018-02-05 10:03:10 +05307483struct hdd_adapter *hdd_get_first_valid_adapter(struct hdd_context *hdd_ctx)
7484{
7485 struct hdd_adapter *adapter;
7486
7487 hdd_for_each_adapter(hdd_ctx, adapter) {
7488 if (adapter && adapter->magic == WLAN_HDD_ADAPTER_MAGIC)
7489 return adapter;
7490 }
7491
7492 return NULL;
7493}
7494
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007495/* wake lock APIs for HDD */
7496void hdd_prevent_suspend(uint32_t reason)
7497{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05307498 qdf_wake_lock_acquire(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007499}
7500
7501void hdd_allow_suspend(uint32_t reason)
7502{
Anurag Chouhana37b5b72016-02-21 14:53:42 +05307503 qdf_wake_lock_release(&wlan_wake_lock, reason);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007504}
7505
7506void hdd_prevent_suspend_timeout(uint32_t timeout, uint32_t reason)
7507{
Anurag Chouhan01cfa4e2016-09-04 15:10:49 +05307508 cds_host_diag_log_work(&wlan_wake_lock, timeout, reason);
7509 qdf_wake_lock_timeout_acquire(&wlan_wake_lock, timeout);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007510}
7511
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007512/* Initialize channel list in sme based on the country code */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007513QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007514{
Jeff Johnson16528362018-06-14 12:34:16 -07007515 return sme_init_chan_list(hdd_ctx->mac_handle,
Amar Singhal6f8592b2017-04-26 14:31:58 -07007516 hdd_ctx->reg.alpha2,
7517 hdd_ctx->reg.cc_src);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007518}
7519
7520/**
7521 * hdd_is_5g_supported() - check if hardware supports 5GHz
7522 * @hdd_ctx: Pointer to the hdd context
7523 *
7524 * HDD function to know if hardware supports 5GHz
7525 *
7526 * Return: true if hardware supports 5GHz
7527 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007528bool hdd_is_5g_supported(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007529{
Amar Singhal58b45ef2017-08-01 13:43:54 -07007530 if (!hdd_ctx)
zdingf54169a2016-10-12 17:08:45 +08007531 return true;
7532
Varun Reddy Yeturua48bc412017-11-17 15:33:35 -08007533 if (hdd_ctx->curr_band != BAND_2G)
zdingf54169a2016-10-12 17:08:45 +08007534 return true;
7535 else
7536 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007537}
7538
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007539static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007540{
7541 struct wiphy *wiphy;
Amar Singhale4f28ee2015-10-21 14:36:56 -07007542 int ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007543
7544 wiphy = hdd_ctx->wiphy;
7545
7546 /*
7547 * The channel information in
7548 * wiphy needs to be initialized before wiphy registration
7549 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07007550 ret_val = hdd_regulatory_init(hdd_ctx, wiphy);
7551 if (ret_val) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08007552 hdd_err("regulatory init failed");
Amar Singhale4f28ee2015-10-21 14:36:56 -07007553 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007554 }
7555
7556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
7557 wiphy->wowlan = &wowlan_support_reg_init;
7558#else
7559 wiphy->wowlan.flags = WIPHY_WOWLAN_ANY |
7560 WIPHY_WOWLAN_MAGIC_PKT |
7561 WIPHY_WOWLAN_DISCONNECT |
7562 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
7563 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
7564 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
7565 WIPHY_WOWLAN_4WAY_HANDSHAKE |
7566 WIPHY_WOWLAN_RFKILL_RELEASE;
7567
7568 wiphy->wowlan.n_patterns = (WOW_MAX_FILTER_LISTS *
7569 WOW_MAX_FILTERS_PER_LIST);
7570 wiphy->wowlan.pattern_min_len = WOW_MIN_PATTERN_SIZE;
7571 wiphy->wowlan.pattern_max_len = WOW_MAX_PATTERN_SIZE;
7572#endif
Liangwei Dong0da14262018-07-03 03:30:23 -04007573 if (hdd_ctx->obss_scan_offload) {
7574 hdd_debug("wmi_service_obss_scan supported");
7575 } else if (hdd_ctx->config->nChannelBondingMode24GHz) {
7576 hdd_debug("enable wpa_supp obss_scan");
7577 wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN;
7578 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007579
7580 /* registration of wiphy dev with cfg80211 */
Amar Singhale4f28ee2015-10-21 14:36:56 -07007581 ret_val = wlan_hdd_cfg80211_register(wiphy);
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05307582 if (0 > ret_val) {
Amar Singhale4f28ee2015-10-21 14:36:56 -07007583 hdd_err("wiphy registration failed");
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05307584 return ret_val;
7585 }
Amar Singhalac26de22018-06-22 12:53:06 -07007586
Kiran Kumar Lokere0508af92018-04-23 18:38:32 -07007587 /* Check the kernel version for upstream commit aced43ce780dc5 that
7588 * has support for processing user cell_base hints when wiphy is
7589 * self managed or check the backport flag for the same.
7590 */
Amar Singhalac26de22018-06-22 12:53:06 -07007591#if defined CFG80211_USER_HINT_CELL_BASE_SELF_MANAGED || \
7592 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0))
Kiran Kumar Lokere0508af92018-04-23 18:38:32 -07007593 hdd_send_wiphy_regd_sync_event(hdd_ctx);
7594#endif
Ashish Kumar Dhanotiya4da37922017-04-05 14:17:56 +05307595
Amar Singhal2d812012018-02-03 15:06:47 +08007596 pld_increment_driver_load_cnt(hdd_ctx->parent_dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007597
Amar Singhale4f28ee2015-10-21 14:36:56 -07007598 return ret_val;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007599}
7600
Mohit Khannaca4173b2017-09-12 21:52:19 -07007601#ifdef MSM_PLATFORM
7602/**
7603 * hdd_display_periodic_stats() - Function to display periodic stats
7604 * @hdd_ctx - handle to hdd context
7605 * @bool data_in_interval - true, if data detected in bw time interval
7606 *
7607 * The periodicity is determined by hdd_ctx->config->periodic_stats_disp_time.
7608 * Stats show up in wlan driver logs.
7609 *
7610 * Returns: None
7611 */
Mohit Khanna70322002018-05-15 19:21:32 -07007612static void hdd_display_periodic_stats(struct hdd_context *hdd_ctx,
7613 bool data_in_interval)
Mohit Khannaca4173b2017-09-12 21:52:19 -07007614{
Mohit Khanna70322002018-05-15 19:21:32 -07007615 static uint32_t counter;
Mohit Khannaca4173b2017-09-12 21:52:19 -07007616 static bool data_in_time_period;
7617 ol_txrx_pdev_handle pdev;
7618
7619 if (hdd_ctx->config->periodic_stats_disp_time == 0)
7620 return;
7621
7622 pdev = cds_get_context(QDF_MODULE_ID_TXRX);
7623 if (!pdev) {
7624 hdd_err("pdev is NULL");
7625 return;
7626 }
7627
7628 counter++;
7629 if (data_in_interval)
7630 data_in_time_period = data_in_interval;
7631
jitiphil869b9f72018-09-25 17:14:01 +05307632 if (counter * hdd_ctx->config->bus_bw_compute_interval >=
Mohit Khannaca4173b2017-09-12 21:52:19 -07007633 hdd_ctx->config->periodic_stats_disp_time * 1000) {
7634 if (data_in_time_period) {
Mohit Khanna70322002018-05-15 19:21:32 -07007635 wlan_hdd_display_txrx_stats(hdd_ctx);
7636 dp_txrx_dump_stats(cds_get_context(QDF_MODULE_ID_SOC));
7637 cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
7638 CDP_RX_RING_STATS,
7639 QDF_STATS_VERBOSITY_LEVEL_LOW);
Mohit Khannaca4173b2017-09-12 21:52:19 -07007640 cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
7641 CDP_TXRX_PATH_STATS,
7642 QDF_STATS_VERBOSITY_LEVEL_LOW);
7643 wlan_hdd_display_netif_queue_history
7644 (hdd_ctx, QDF_STATS_VERBOSITY_LEVEL_LOW);
7645 qdf_dp_trace_dump_stats();
7646 }
7647 counter = 0;
7648 data_in_time_period = false;
7649 }
7650}
7651
Ravi Joshie2331e82015-07-01 18:18:54 -07007652/**
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007653 * hdd_clear_rps_cpu_mask - clear RPS CPU mask for interfaces
7654 * @hdd_ctx: pointer to struct hdd_context
7655 *
7656 * Return: none
7657 */
7658static void hdd_clear_rps_cpu_mask(struct hdd_context *hdd_ctx)
7659{
7660 struct hdd_adapter *adapter;
7661
7662 hdd_for_each_adapter(hdd_ctx, adapter)
7663 hdd_send_rps_disable_ind(adapter);
7664}
7665
7666/**
Yuanyuan Liu13738502016-04-06 17:41:37 -07007667 * hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
Ravi Joshie2331e82015-07-01 18:18:54 -07007668 * @hdd_ctx - handle to hdd context
7669 * @tx_packets - transmit packet count
7670 * @rx_packets - receive packet count
7671 *
7672 * The function controls the bus bandwidth and dynamic control of
7673 * tcp delayed ack configuration
7674 *
7675 * Returns: None
7676 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07007677
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007678static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
Jeff Johnson590e2012016-10-05 16:16:24 -07007679 const uint64_t tx_packets,
7680 const uint64_t rx_packets)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007681{
Mohit Khannaca4173b2017-09-12 21:52:19 -07007682 u64 total_pkts = tx_packets + rx_packets;
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007683 uint64_t temp_tx = 0, avg_rx = 0;
7684 uint64_t no_rx_offload_pkts = 0, avg_no_rx_offload_pkts = 0;
7685 uint64_t rx_offload_pkts = 0, avg_rx_offload_pkts = 0;
Yuanyuan Liu13738502016-04-06 17:41:37 -07007686 enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_NONE;
Mohit Khannac3da7062017-02-08 21:08:56 -08007687 static enum wlan_tp_level next_rx_level = WLAN_SVC_TP_NONE;
Mohit Khannae71e2262015-11-10 09:37:24 -08007688 enum wlan_tp_level next_tx_level = WLAN_SVC_TP_NONE;
Ravi Joshib89e7f72016-09-07 13:43:15 -07007689 uint32_t delack_timer_cnt = hdd_ctx->config->tcp_delack_timer_count;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007690 uint16_t index = 0;
7691 bool vote_level_change = false;
7692 bool rx_level_change = false;
7693 bool tx_level_change = false;
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007694 bool rxthread_high_tput_req = false;
Mohit Khannaf7562c32018-07-05 17:42:36 -07007695 bool dptrace_high_tput_req;
Srinivas Girigowda50335342018-09-07 15:21:01 -07007696
jitiphil869b9f72018-09-25 17:14:01 +05307697 if (total_pkts > hdd_ctx->config->bus_bw_high_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007698 next_vote_level = PLD_BUS_WIDTH_HIGH;
jitiphil869b9f72018-09-25 17:14:01 +05307699 else if (total_pkts > hdd_ctx->config->bus_bw_medium_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007700 next_vote_level = PLD_BUS_WIDTH_MEDIUM;
jitiphil869b9f72018-09-25 17:14:01 +05307701 else if (total_pkts > hdd_ctx->config->bus_bw_low_threshold)
Yuanyuan Liu13738502016-04-06 17:41:37 -07007702 next_vote_level = PLD_BUS_WIDTH_LOW;
Yue Mad6478e42015-10-20 18:49:24 -07007703 else
Yuanyuan Liu13738502016-04-06 17:41:37 -07007704 next_vote_level = PLD_BUS_WIDTH_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007705
Mohit Khannaf7562c32018-07-05 17:42:36 -07007706 dptrace_high_tput_req =
7707 next_vote_level > PLD_BUS_WIDTH_NONE ? true : false;
7708
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007709 if (hdd_ctx->cur_vote_level != next_vote_level) {
Ravi Joshie2331e82015-07-01 18:18:54 -07007710 hdd_debug("trigger level %d, tx_packets: %lld, rx_packets: %lld",
7711 next_vote_level, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007712 hdd_ctx->cur_vote_level = next_vote_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007713 vote_level_change = true;
Yuanyuan Liu13738502016-04-06 17:41:37 -07007714 pld_request_bus_bandwidth(hdd_ctx->parent_dev, next_vote_level);
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007715 if ((next_vote_level == PLD_BUS_WIDTH_LOW) ||
7716 (next_vote_level == PLD_BUS_WIDTH_NONE)) {
Nirav Shahffc6a092016-06-09 16:09:08 +05307717 if (hdd_ctx->hbw_requested) {
7718 pld_remove_pm_qos(hdd_ctx->parent_dev);
7719 hdd_ctx->hbw_requested = false;
7720 }
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007721 if (hdd_ctx->dynamic_rps)
7722 hdd_clear_rps_cpu_mask(hdd_ctx);
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07007723 } else {
Nirav Shahffc6a092016-06-09 16:09:08 +05307724 if (!hdd_ctx->hbw_requested) {
7725 pld_request_pm_qos(hdd_ctx->parent_dev, 1);
7726 hdd_ctx->hbw_requested = true;
7727 }
Tang Yingying5a4ccf22018-03-30 15:58:27 +08007728 if (hdd_ctx->dynamic_rps)
7729 hdd_set_rps_cpu_mask(hdd_ctx);
Jeff Johnson59eb5fd2017-10-05 09:42:39 -07007730 }
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007731
Manjunathappa Prakashcb6df762018-05-29 18:54:58 -07007732 if (hdd_ctx->config->napi_cpu_affinity_mask)
7733 hdd_napi_apply_throughput_policy(hdd_ctx,
7734 tx_packets,
7735 rx_packets);
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007736
jitiphil869b9f72018-09-25 17:14:01 +05307737 if (rx_packets < hdd_ctx->config->bus_bw_low_threshold)
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007738 hdd_disable_rx_ol_for_low_tput(hdd_ctx, true);
7739 else
7740 hdd_disable_rx_ol_for_low_tput(hdd_ctx, false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007741 }
Mohit Khannae71e2262015-11-10 09:37:24 -08007742
Mohit Khannaf7562c32018-07-05 17:42:36 -07007743 qdf_dp_trace_apply_tput_policy(dptrace_high_tput_req);
7744
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007745 /*
7746 * Includes tcp+udp, if perf core is required for tcp, then
7747 * perf core is also required for udp.
7748 */
7749 no_rx_offload_pkts = hdd_ctx->no_rx_offload_pkt_cnt;
7750 hdd_ctx->no_rx_offload_pkt_cnt = 0;
7751 rx_offload_pkts = rx_packets - no_rx_offload_pkts;
Mohit Khannae71e2262015-11-10 09:37:24 -08007752
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007753 avg_no_rx_offload_pkts = (no_rx_offload_pkts +
7754 hdd_ctx->prev_no_rx_offload_pkts) / 2;
7755 hdd_ctx->prev_no_rx_offload_pkts = no_rx_offload_pkts;
Mohit Khannab1dd1e82017-02-04 15:14:38 -08007756
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007757 avg_rx_offload_pkts = (rx_offload_pkts +
7758 hdd_ctx->prev_rx_offload_pkts) / 2;
7759 hdd_ctx->prev_rx_offload_pkts = rx_offload_pkts;
7760
7761 avg_rx = avg_no_rx_offload_pkts + avg_rx_offload_pkts;
7762 /*
7763 * Takes care to set Rx_thread affinity for below case
7764 * 1)LRO/GRO not supported ROME case
7765 * 2)when rx_ol is disabled in cases like concurrency etc
7766 * 3)For UDP cases
7767 */
7768 if (avg_no_rx_offload_pkts >
jitiphil869b9f72018-09-25 17:14:01 +05307769 hdd_ctx->config->bus_bw_high_threshold)
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007770 rxthread_high_tput_req = true;
Poddar, Siddarth47c23402017-10-25 12:17:39 +05307771 else
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007772 rxthread_high_tput_req = false;
Poddar, Siddarth47c23402017-10-25 12:17:39 +05307773
Manjunathappa Prakash3a21bea2018-05-29 20:41:12 -07007774 if (cds_sched_handle_throughput_req(rxthread_high_tput_req))
7775 hdd_warn("Rx thread high_tput(%d) affinity request failed",
7776 rxthread_high_tput_req);
7777
7778 /* fine-tuning parameters for RX Flows */
jitiphil869b9f72018-09-25 17:14:01 +05307779 if (avg_rx > hdd_ctx->config->tcp_delack_thres_high) {
Ravi Joshifed83572016-10-07 16:20:37 -07007780 if ((hdd_ctx->cur_rx_level != WLAN_SVC_TP_HIGH) &&
7781 (++hdd_ctx->rx_high_ind_cnt == delack_timer_cnt)) {
7782 next_rx_level = WLAN_SVC_TP_HIGH;
7783 }
Ravi Joshib89e7f72016-09-07 13:43:15 -07007784 } else {
Ravi Joshib89e7f72016-09-07 13:43:15 -07007785 hdd_ctx->rx_high_ind_cnt = 0;
Mohit Khannac3da7062017-02-08 21:08:56 -08007786 next_rx_level = WLAN_SVC_TP_LOW;
Ravi Joshib89e7f72016-09-07 13:43:15 -07007787 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007788
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007789 if (hdd_ctx->cur_rx_level != next_rx_level) {
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007790 struct wlan_rx_tp_data rx_tp_data = {0};
7791
Ravi Joshie2331e82015-07-01 18:18:54 -07007792 hdd_debug("TCP DELACK trigger level %d, average_rx: %llu",
Jeff Johnsonb9feee42018-07-08 10:34:48 -07007793 next_rx_level, avg_rx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007794 hdd_ctx->cur_rx_level = next_rx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007795 rx_level_change = true;
Ravi Joshie2331e82015-07-01 18:18:54 -07007796 /* Send throughput indication only if it is enabled.
7797 * Disabling tcp_del_ack will revert the tcp stack behavior
7798 * to default delayed ack. Note that this will disable the
7799 * dynamic delayed ack mechanism across the system
7800 */
Manjunathappa Prakashbfd12762018-04-29 22:44:52 -07007801 if (hdd_ctx->en_tcp_delack_no_lro)
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007802 rx_tp_data.rx_tp_flags |= TCP_DEL_ACK_IND;
7803
Mohit Khanna6272fb682017-04-13 09:34:36 -07007804 if (hdd_ctx->config->enable_tcp_adv_win_scale)
7805 rx_tp_data.rx_tp_flags |= TCP_ADV_WIN_SCL;
7806
Manjunathappa Prakashc13cb5b2017-10-09 01:47:07 -07007807 rx_tp_data.level = next_rx_level;
Alok Kumar2fad6442018-11-08 19:19:28 +05307808 wlan_hdd_update_tcp_rx_param(hdd_ctx, &rx_tp_data);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007809 }
7810
Mohit Khannae71e2262015-11-10 09:37:24 -08007811 /* fine-tuning parameters for TX Flows */
7812 temp_tx = (tx_packets + hdd_ctx->prev_tx) / 2;
7813 hdd_ctx->prev_tx = tx_packets;
7814 if (temp_tx > hdd_ctx->config->tcp_tx_high_tput_thres)
7815 next_tx_level = WLAN_SVC_TP_HIGH;
7816 else
7817 next_tx_level = WLAN_SVC_TP_LOW;
7818
Prakash Manjunathappae73e3b52018-02-27 18:56:22 -08007819 if ((hdd_ctx->config->enable_tcp_limit_output) &&
7820 (hdd_ctx->cur_tx_level != next_tx_level)) {
Alok Kumar2fad6442018-11-08 19:19:28 +05307821 struct wlan_tx_tp_data tx_tp_data = {0};
7822
Mohit Khannae71e2262015-11-10 09:37:24 -08007823 hdd_debug("change TCP TX trigger level %d, average_tx: %llu",
7824 next_tx_level, temp_tx);
7825 hdd_ctx->cur_tx_level = next_tx_level;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007826 tx_level_change = true;
Alok Kumar2fad6442018-11-08 19:19:28 +05307827 tx_tp_data.level = next_tx_level;
7828 tx_tp_data.tcp_limit_output = true;
7829 wlan_hdd_update_tcp_tx_param(hdd_ctx, &tx_tp_data);
Mohit Khannae71e2262015-11-10 09:37:24 -08007830 }
7831
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007832 index = hdd_ctx->hdd_txrx_hist_idx;
Mohit Khannaafff9fb2016-11-16 20:22:03 -08007833 if (vote_level_change || tx_level_change || rx_level_change) {
7834 hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level;
7835 hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level;
7836 hdd_ctx->hdd_txrx_hist[index].next_vote_level = next_vote_level;
7837 hdd_ctx->hdd_txrx_hist[index].interval_rx = rx_packets;
7838 hdd_ctx->hdd_txrx_hist[index].interval_tx = tx_packets;
7839 hdd_ctx->hdd_txrx_hist[index].qtime = qdf_get_log_timestamp();
7840 hdd_ctx->hdd_txrx_hist_idx++;
7841 hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
7842 }
Mohit Khannaca4173b2017-09-12 21:52:19 -07007843
7844 hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007845}
7846
7847#define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
Rajeev Kumarb2b5e692018-08-31 15:12:40 -07007848static void __hdd_bus_bw_work_handler(struct work_struct *work)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007849{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007850 struct hdd_context *hdd_ctx = container_of(work, struct hdd_context,
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307851 bus_bw_work);
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05307852 struct hdd_adapter *adapter = NULL, *con_sap_adapter = NULL;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307853 uint64_t tx_packets = 0, rx_packets = 0;
Himanshu Agarwala6cedee2016-06-08 14:50:00 +05307854 uint64_t fwd_tx_packets = 0, fwd_rx_packets = 0;
7855 uint64_t fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007856 uint64_t total_tx = 0, total_rx = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307857 A_STATUS ret;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007858 bool connected = false;
7859 uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0;
7860
Prashanth Bhattaab004382016-10-11 16:08:11 -07007861 if (wlan_hdd_validate_context(hdd_ctx))
7862 return;
7863
Jeff Johnson214671b2017-10-30 19:45:23 -07007864 if (hdd_ctx->is_wiphy_suspended)
Jingxiang Gec64e1932017-08-22 14:38:59 +08007865 goto restart_timer;
7866
Dustin Brown920397d2017-12-13 16:27:50 -08007867 hdd_for_each_adapter(hdd_ctx, adapter) {
Manjeet Singh01327cc2016-09-03 12:14:25 +05307868 /*
7869 * Validate magic so we don't end up accessing
7870 * an invalid adapter.
7871 */
7872 if (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)
7873 continue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007874
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007875 if ((adapter->device_mode == QDF_STA_MODE ||
7876 adapter->device_mode == QDF_P2P_CLIENT_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007877 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->conn_info.connState
7878 != eConnectionState_Associated) {
7879
7880 continue;
7881 }
7882
Krunal Soni9b04c9b2016-03-10 13:08:05 -08007883 if ((adapter->device_mode == QDF_SAP_MODE ||
7884 adapter->device_mode == QDF_P2P_GO_MODE) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -07007885 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007886
7887 continue;
7888 }
7889
7890 tx_packets += HDD_BW_GET_DIFF(adapter->stats.tx_packets,
7891 adapter->prev_tx_packets);
7892 rx_packets += HDD_BW_GET_DIFF(adapter->stats.rx_packets,
7893 adapter->prev_rx_packets);
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307894
7895 if (adapter->device_mode == QDF_SAP_MODE ||
7896 adapter->device_mode == QDF_P2P_GO_MODE ||
7897 adapter->device_mode == QDF_IBSS_MODE) {
7898
Dhanashri Atrea8f82f22017-01-23 12:58:24 -08007899 ret = cdp_get_intra_bss_fwd_pkts_count(
7900 cds_get_context(QDF_MODULE_ID_SOC),
Jeff Johnson1b780e42017-10-31 14:11:45 -07007901 adapter->session_id,
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307902 &fwd_tx_packets, &fwd_rx_packets);
7903 if (ret == A_OK) {
7904 fwd_tx_packets_diff += HDD_BW_GET_DIFF(
7905 fwd_tx_packets,
7906 adapter->prev_fwd_tx_packets);
7907 fwd_rx_packets_diff += HDD_BW_GET_DIFF(
7908 fwd_tx_packets,
7909 adapter->prev_fwd_rx_packets);
7910 }
7911 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007912
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05307913 if (adapter->device_mode == QDF_SAP_MODE)
7914 con_sap_adapter = adapter;
7915
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007916 total_rx += adapter->stats.rx_packets;
7917 total_tx += adapter->stats.tx_packets;
7918
7919 spin_lock_bh(&hdd_ctx->bus_bw_lock);
7920 adapter->prev_tx_packets = adapter->stats.tx_packets;
7921 adapter->prev_rx_packets = adapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +05307922 adapter->prev_fwd_tx_packets = fwd_tx_packets;
7923 adapter->prev_fwd_rx_packets = fwd_rx_packets;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007924 spin_unlock_bh(&hdd_ctx->bus_bw_lock);
7925 connected = true;
7926 }
7927
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007928 if (!connected) {
Jeff Johnson760350b2016-08-15 14:01:52 -07007929 hdd_err("bus bandwidth timer running in disconnected state");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007930 return;
7931 }
7932
Yun Parka29974a2018-04-09 12:05:49 -07007933 /* add intra bss forwarded tx and rx packets */
7934 tx_packets += fwd_tx_packets_diff;
7935 rx_packets += fwd_rx_packets_diff;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007936
Dustin Brown07901ec2018-09-07 11:02:41 -07007937 if (ucfg_ipa_is_fw_wdi_activated(hdd_ctx->pdev)) {
7938 ucfg_ipa_uc_stat_query(hdd_ctx->pdev, &ipa_tx_packets,
7939 &ipa_rx_packets);
Yun Parka29974a2018-04-09 12:05:49 -07007940 tx_packets += (uint64_t)ipa_tx_packets;
7941 rx_packets += (uint64_t)ipa_rx_packets;
7942
Sravan Kumar Kairam86fce772018-04-26 14:15:30 +05307943 if (con_sap_adapter) {
7944 con_sap_adapter->stats.tx_packets += ipa_tx_packets;
7945 con_sap_adapter->stats.rx_packets += ipa_rx_packets;
7946 }
7947
Dustin Brown07901ec2018-09-07 11:02:41 -07007948 ucfg_ipa_set_perf_level(hdd_ctx->pdev, tx_packets, rx_packets);
7949 ucfg_ipa_uc_stat_request(hdd_ctx->pdev, 2);
Yun Parka29974a2018-04-09 12:05:49 -07007950 }
7951
7952 hdd_pld_request_bus_bandwidth(hdd_ctx, tx_packets, rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007953
Jingxiang Gec64e1932017-08-22 14:38:59 +08007954restart_timer:
Dustin Brown2ed60362017-01-18 12:25:50 -08007955 /* ensure periodic timer should still be running before restarting it */
Dustin Brownfce08d12017-01-17 16:29:38 -08007956 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown2ed60362017-01-18 12:25:50 -08007957 if (hdd_ctx->bus_bw_timer_running)
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +05307958 qdf_timer_mod(&hdd_ctx->bus_bw_timer,
jitiphil869b9f72018-09-25 17:14:01 +05307959 hdd_ctx->config->bus_bw_compute_interval);
Dustin Brownfce08d12017-01-17 16:29:38 -08007960 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08007961}
Prashanth Bhattaab004382016-10-11 16:08:11 -07007962
Rajeev Kumarb2b5e692018-08-31 15:12:40 -07007963static void hdd_bus_bw_work_handler(struct work_struct *work)
7964{
7965 cds_ssr_protect(__func__);
7966 __hdd_bus_bw_work_handler(work);
7967 cds_ssr_unprotect(__func__);
7968}
7969
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307970/**
7971 * __hdd_bus_bw_cbk() - Bus bandwidth data structure callback.
7972 * @arg: Argument of timer function
7973 *
7974 * Schedule a workqueue in this function where all the processing is done.
7975 *
7976 * Return: None.
7977 */
7978static void __hdd_bus_bw_cbk(void *arg)
7979{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07007980 struct hdd_context *hdd_ctx = (struct hdd_context *) arg;
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05307981
7982 if (wlan_hdd_validate_context(hdd_ctx))
7983 return;
7984
7985 schedule_work(&hdd_ctx->bus_bw_work);
7986}
7987
7988/**
7989 * hdd_bus_bw_cbk() - Wrapper for bus bw callback for SSR protection.
7990 * @arg: Argument of timer function
7991 *
7992 * Return: None.
7993 */
7994static void hdd_bus_bw_cbk(void *arg)
7995{
7996 cds_ssr_protect(__func__);
7997 __hdd_bus_bw_cbk(arg);
7998 cds_ssr_unprotect(__func__);
7999}
8000
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008001int hdd_bus_bandwidth_init(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07008002{
Dustin Brown35008ba2018-08-23 14:34:21 -07008003 hdd_enter();
8004
Prashanth Bhattaab004382016-10-11 16:08:11 -07008005 spin_lock_init(&hdd_ctx->bus_bw_lock);
Dustin Brown35008ba2018-08-23 14:34:21 -07008006 INIT_WORK(&hdd_ctx->bus_bw_work, hdd_bus_bw_work_handler);
Dustin Brownfce08d12017-01-17 16:29:38 -08008007 hdd_ctx->bus_bw_timer_running = false;
8008 qdf_spinlock_create(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown35008ba2018-08-23 14:34:21 -07008009 qdf_timer_init(NULL, &hdd_ctx->bus_bw_timer, hdd_bus_bw_cbk,
8010 (void *)hdd_ctx, QDF_TIMER_TYPE_SW);
8011
8012 hdd_exit();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008013
8014 return 0;
8015}
8016
Dustin Brown86d196b2018-08-02 11:51:49 -07008017void hdd_bus_bandwidth_deinit(struct hdd_context *hdd_ctx)
Prashanth Bhattaab004382016-10-11 16:08:11 -07008018{
Dustin Brown35008ba2018-08-23 14:34:21 -07008019 hdd_enter();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008020
Rajeev Kumarc27efb62018-08-31 14:21:22 -07008021 QDF_BUG(!hdd_ctx->bus_bw_timer_running);
Dustin Brown35008ba2018-08-23 14:34:21 -07008022
Poddar, Siddarth2333acb2017-01-09 16:45:39 +05308023 qdf_timer_free(&hdd_ctx->bus_bw_timer);
Dustin Brownfce08d12017-01-17 16:29:38 -08008024 qdf_spinlock_destroy(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown35008ba2018-08-23 14:34:21 -07008025
8026 hdd_exit();
Prashanth Bhattaab004382016-10-11 16:08:11 -07008027}
Lin Baic5c06882017-09-21 13:58:43 +08008028
Dustin Brown35008ba2018-08-23 14:34:21 -07008029#endif /* MSM_PLATFORM */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008030
8031/**
Nirav Shahed34b212016-04-25 10:59:16 +05308032 * wlan_hdd_init_tx_rx_histogram() - init tx/rx histogram stats
8033 * @hdd_ctx: hdd context
8034 *
8035 * Return: 0 for success or error code
8036 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008037static int wlan_hdd_init_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05308038{
8039 hdd_ctx->hdd_txrx_hist = qdf_mem_malloc(
8040 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Min Liu74a1a502018-10-10 19:59:07 +08008041 if (!hdd_ctx->hdd_txrx_hist)
Nirav Shahed34b212016-04-25 10:59:16 +05308042 return -ENOMEM;
Nirav Shahed34b212016-04-25 10:59:16 +05308043 return 0;
8044}
8045
8046/**
8047 * wlan_hdd_deinit_tx_rx_histogram() - deinit tx/rx histogram stats
8048 * @hdd_ctx: hdd context
8049 *
8050 * Return: none
8051 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008052void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx)
Nirav Shahed34b212016-04-25 10:59:16 +05308053{
Ashish Kumar Dhanotiyaaa2b17c2017-03-29 00:41:32 +05308054 if (!hdd_ctx || hdd_ctx->hdd_txrx_hist == NULL)
8055 return;
8056
8057 qdf_mem_free(hdd_ctx->hdd_txrx_hist);
8058 hdd_ctx->hdd_txrx_hist = NULL;
Nirav Shahed34b212016-04-25 10:59:16 +05308059}
8060
Nirav Shahda008342016-05-17 18:50:40 +05308061static uint8_t *convert_level_to_string(uint32_t level)
8062{
8063 switch (level) {
8064 /* initialize the wlan sub system */
8065 case WLAN_SVC_TP_NONE:
8066 return "NONE";
8067 case WLAN_SVC_TP_LOW:
8068 return "LOW";
8069 case WLAN_SVC_TP_MEDIUM:
8070 return "MED";
8071 case WLAN_SVC_TP_HIGH:
8072 return "HIGH";
8073 default:
8074 return "INVAL";
8075 }
8076}
8077
Nirav Shahed34b212016-04-25 10:59:16 +05308078
8079/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008080 * wlan_hdd_display_tx_rx_histogram() - display tx rx histogram
8081 * @hdd_ctx: hdd context
8082 *
8083 * Return: none
8084 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008085void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008086{
8087 int i;
8088
8089#ifdef MSM_PLATFORM
Nirav Shahe6194ac2018-07-13 11:04:41 +05308090 hdd_nofl_info("BW compute Interval: %dms",
jitiphil869b9f72018-09-25 17:14:01 +05308091 hdd_ctx->config->bus_bw_compute_interval);
Nirav Shahe6194ac2018-07-13 11:04:41 +05308092 hdd_nofl_info("BW High TH: %d BW Med TH: %d BW Low TH: %d",
jitiphil869b9f72018-09-25 17:14:01 +05308093 hdd_ctx->config->bus_bw_high_threshold,
8094 hdd_ctx->config->bus_bw_medium_threshold,
8095 hdd_ctx->config->bus_bw_low_threshold);
Nirav Shahe6194ac2018-07-13 11:04:41 +05308096 hdd_nofl_info("Enable TCP DEL ACK: %d",
8097 hdd_ctx->en_tcp_delack_no_lro);
8098 hdd_nofl_info("TCP DEL High TH: %d TCP DEL Low TH: %d",
jitiphil869b9f72018-09-25 17:14:01 +05308099 hdd_ctx->config->tcp_delack_thres_high,
8100 hdd_ctx->config->tcp_delack_thres_low);
Nirav Shahe6194ac2018-07-13 11:04:41 +05308101 hdd_nofl_info("TCP TX HIGH TP TH: %d (Use to set tcp_output_bytes_limit)",
8102 hdd_ctx->config->tcp_tx_high_tput_thres);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008103#endif
8104
Nirav Shahe6194ac2018-07-13 11:04:41 +05308105 hdd_nofl_info("Total entries: %d Current index: %d",
8106 NUM_TX_RX_HISTOGRAM, hdd_ctx->hdd_txrx_hist_idx);
Nirav Shahda008342016-05-17 18:50:40 +05308107
Nirav Shahe6194ac2018-07-13 11:04:41 +05308108 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 -08008109
8110 for (i = 0; i < NUM_TX_RX_HISTOGRAM; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008111 /* using hdd_log to avoid printing function name */
Mohit Khannaafff9fb2016-11-16 20:22:03 -08008112 if (hdd_ctx->hdd_txrx_hist[i].qtime > 0)
Nirav Shahe6194ac2018-07-13 11:04:41 +05308113 hdd_nofl_info("[%3d][%15llu]: %6llu, %6llu, %s, %s, %s",
8114 i, hdd_ctx->hdd_txrx_hist[i].qtime,
8115 hdd_ctx->hdd_txrx_hist[i].interval_rx,
8116 hdd_ctx->hdd_txrx_hist[i].interval_tx,
8117 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008118 hdd_ctx->hdd_txrx_hist[i].
8119 next_vote_level),
Nirav Shahe6194ac2018-07-13 11:04:41 +05308120 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008121 hdd_ctx->hdd_txrx_hist[i].
8122 next_rx_level),
Nirav Shahe6194ac2018-07-13 11:04:41 +05308123 convert_level_to_string(
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008124 hdd_ctx->hdd_txrx_hist[i].
8125 next_tx_level));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008126 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008127}
8128
8129/**
8130 * wlan_hdd_clear_tx_rx_histogram() - clear tx rx histogram
8131 * @hdd_ctx: hdd context
8132 *
8133 * Return: none
8134 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008135void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008136{
8137 hdd_ctx->hdd_txrx_hist_idx = 0;
Nirav Shahed34b212016-04-25 10:59:16 +05308138 qdf_mem_zero(hdd_ctx->hdd_txrx_hist,
8139 (sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008140}
8141
Mohit Khannaca4173b2017-09-12 21:52:19 -07008142/* length of the netif queue log needed per adapter */
8143#define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
8144
8145/**
8146 *
8147 * hdd_display_netif_queue_history_compact() - display compact netifq history
8148 * @hdd_ctx: hdd context
8149 *
8150 * Return: none
8151 */
8152static void
8153hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
8154{
8155 int adapter_num = 0;
8156 int i;
8157 int bytes_written;
8158 u32 tbytes;
8159 qdf_time_t total, pause, unpause, curr_time, delta;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008160 char temp_str[20 * WLAN_REASON_TYPE_MAX];
jiadbdefb252018-01-03 14:27:06 +08008161 char *comb_log_str;
8162 uint32_t comb_log_str_size;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008163 struct hdd_adapter *adapter = NULL;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008164
Dustin Brownbee82832018-07-23 10:10:51 -07008165 comb_log_str_size = (ADAP_NETIFQ_LOG_LEN * CSR_ROAM_SESSION_MAX) + 1;
jiadbdefb252018-01-03 14:27:06 +08008166 comb_log_str = qdf_mem_malloc(comb_log_str_size);
Min Liu74a1a502018-10-10 19:59:07 +08008167 if (!comb_log_str)
jiadbdefb252018-01-03 14:27:06 +08008168 return;
jiadbdefb252018-01-03 14:27:06 +08008169
Mohit Khannaca4173b2017-09-12 21:52:19 -07008170 bytes_written = 0;
Mohit Khannaca4173b2017-09-12 21:52:19 -07008171
Dustin Brown920397d2017-12-13 16:27:50 -08008172 hdd_for_each_adapter(hdd_ctx, adapter) {
Mohit Khannaca4173b2017-09-12 21:52:19 -07008173 curr_time = qdf_system_ticks();
8174 total = curr_time - adapter->start_time;
8175 delta = curr_time - adapter->last_time;
8176
8177 if (adapter->pause_map) {
8178 pause = adapter->total_pause_time + delta;
8179 unpause = adapter->total_unpause_time;
8180 } else {
8181 unpause = adapter->total_unpause_time + delta;
8182 pause = adapter->total_pause_time;
8183 }
8184
8185 tbytes = 0;
8186 qdf_mem_set(temp_str, 0, sizeof(temp_str));
8187 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
8188 if (adapter->queue_oper_stats[i].pause_count == 0)
8189 continue;
8190 tbytes +=
8191 snprintf(
8192 &temp_str[tbytes],
8193 (tbytes >= sizeof(temp_str) ?
8194 0 : sizeof(temp_str) - tbytes),
8195 "%d(%d,%d) ",
8196 i,
8197 adapter->queue_oper_stats[i].
8198 pause_count,
8199 adapter->queue_oper_stats[i].
8200 unpause_count);
8201 }
8202 if (tbytes >= sizeof(temp_str))
8203 hdd_warn("log truncated");
8204
8205 bytes_written += snprintf(&comb_log_str[bytes_written],
jiadbdefb252018-01-03 14:27:06 +08008206 bytes_written >= comb_log_str_size ? 0 :
8207 comb_log_str_size - bytes_written,
Mohit Khannaca4173b2017-09-12 21:52:19 -07008208 "[%d %d] (%d) %u/%ums %s|",
8209 adapter->session_id, adapter->device_mode,
8210 adapter->pause_map,
8211 qdf_system_ticks_to_msecs(pause),
8212 qdf_system_ticks_to_msecs(total),
8213 temp_str);
8214
Mohit Khannaca4173b2017-09-12 21:52:19 -07008215 adapter_num++;
8216 }
8217
8218 /* using QDF_TRACE to avoid printing function name */
8219 QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
8220 "STATS |%s", comb_log_str);
8221
jiadbdefb252018-01-03 14:27:06 +08008222 if (bytes_written >= comb_log_str_size)
Mohit Khannaca4173b2017-09-12 21:52:19 -07008223 hdd_warn("log string truncated");
jiadbdefb252018-01-03 14:27:06 +08008224
8225 qdf_mem_free(comb_log_str);
Mohit Khannaca4173b2017-09-12 21:52:19 -07008226}
8227
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008228/**
Srinivas Girigowdab841da72017-03-25 18:04:39 -07008229 * wlan_hdd_display_netif_queue_history() - display netif queue history
Jeff Johnson58adbcf2017-09-03 08:53:31 -07008230 * @hdd_ctx: hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008231 *
8232 * Return: none
8233 */
Mohit Khannaca4173b2017-09-12 21:52:19 -07008234void
8235wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
8236 enum qdf_stats_verbosity_level verb_lvl)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008237{
8238
Jeff Johnson9d295242017-08-29 14:39:48 -07008239 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008240 int i;
Nirav Shahda008342016-05-17 18:50:40 +05308241 qdf_time_t total, pause, unpause, curr_time, delta;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008242
Mohit Khannaca4173b2017-09-12 21:52:19 -07008243 if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
8244 hdd_display_netif_queue_history_compact(hdd_ctx);
8245 return;
8246 }
8247
Dustin Brown920397d2017-12-13 16:27:50 -08008248 hdd_for_each_adapter(hdd_ctx, adapter) {
Nirav Shahe6194ac2018-07-13 11:04:41 +05308249 hdd_nofl_info("Netif queue operation statistics:");
8250 hdd_nofl_info("Session_id %d device mode %d",
8251 adapter->session_id, adapter->device_mode);
8252 hdd_nofl_info("Current pause_map value %x", adapter->pause_map);
Nirav Shah617cff92016-04-25 10:24:24 +05308253 curr_time = qdf_system_ticks();
8254 total = curr_time - adapter->start_time;
Nirav Shahda008342016-05-17 18:50:40 +05308255 delta = curr_time - adapter->last_time;
Nirav Shah617cff92016-04-25 10:24:24 +05308256 if (adapter->pause_map) {
Nirav Shahda008342016-05-17 18:50:40 +05308257 pause = adapter->total_pause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05308258 unpause = adapter->total_unpause_time;
8259 } else {
Nirav Shahda008342016-05-17 18:50:40 +05308260 unpause = adapter->total_unpause_time + delta;
Nirav Shah617cff92016-04-25 10:24:24 +05308261 pause = adapter->total_pause_time;
8262 }
Nirav Shahe6194ac2018-07-13 11:04:41 +05308263 hdd_nofl_info("Total: %ums Pause: %ums Unpause: %ums",
8264 qdf_system_ticks_to_msecs(total),
8265 qdf_system_ticks_to_msecs(pause),
8266 qdf_system_ticks_to_msecs(unpause));
8267 hdd_nofl_info("reason_type: pause_cnt: unpause_cnt: pause_time");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008268
Nirav Shahda008342016-05-17 18:50:40 +05308269 for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
8270 qdf_time_t pause_delta = 0;
8271
8272 if (adapter->pause_map & (1 << i))
8273 pause_delta = delta;
8274
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008275 /* using hdd_log to avoid printing function name */
Nirav Shahe6194ac2018-07-13 11:04:41 +05308276 hdd_nofl_info("%s: %d: %d: %ums",
8277 hdd_reason_type_to_string(i),
8278 adapter->queue_oper_stats[i].pause_count,
8279 adapter->queue_oper_stats[i].
8280 unpause_count,
8281 qdf_system_ticks_to_msecs(
8282 adapter->queue_oper_stats[i].
8283 total_pause_time + pause_delta));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008284 }
8285
Nirav Shahe6194ac2018-07-13 11:04:41 +05308286 hdd_nofl_info("Netif queue operation history:");
8287 hdd_nofl_info("Total entries: %d current index %d",
8288 WLAN_HDD_MAX_HISTORY_ENTRY,
8289 adapter->history_index);
Nirav Shahda008342016-05-17 18:50:40 +05308290
Nirav Shahe6194ac2018-07-13 11:04:41 +05308291 hdd_nofl_info("index: time: action_type: reason_type: pause_map");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008292
8293 for (i = 0; i < WLAN_HDD_MAX_HISTORY_ENTRY; i++) {
Mohit Khanna3e2115b2016-10-11 13:18:29 -07008294 /* using hdd_log to avoid printing function name */
8295 if (adapter->queue_oper_history[i].time == 0)
8296 continue;
Nirav Shahe6194ac2018-07-13 11:04:41 +05308297 hdd_nofl_info("%d: %u: %s: %s: %x",
8298 i, qdf_system_ticks_to_msecs(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008299 adapter->queue_oper_history[i].time),
Nirav Shahe6194ac2018-07-13 11:04:41 +05308300 hdd_action_type_to_string(
8301 adapter->queue_oper_history[i].
8302 netif_action),
8303 hdd_reason_type_to_string(
8304 adapter->queue_oper_history[i].
8305 netif_reason),
8306 adapter->queue_oper_history[i].pause_map);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008307 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008308 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008309}
8310
8311/**
8312 * wlan_hdd_clear_netif_queue_history() - clear netif queue operation history
8313 * @hdd_ctx: hdd context
8314 *
8315 * Return: none
8316 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008317void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008318{
Jeff Johnson9d295242017-08-29 14:39:48 -07008319 struct hdd_adapter *adapter = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008320
Dustin Brown920397d2017-12-13 16:27:50 -08008321 hdd_for_each_adapter(hdd_ctx, adapter) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308322 qdf_mem_zero(adapter->queue_oper_stats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008323 sizeof(adapter->queue_oper_stats));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05308324 qdf_mem_zero(adapter->queue_oper_history,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008325 sizeof(adapter->queue_oper_history));
Nirav Shah617cff92016-04-25 10:24:24 +05308326 adapter->history_index = 0;
8327 adapter->start_time = adapter->last_time = qdf_system_ticks();
8328 adapter->total_pause_time = 0;
8329 adapter->total_unpause_time = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008330 }
8331}
8332
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008333#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8334/**
8335 * hdd_init_offloaded_packets_ctx() - Initialize offload packets context
8336 * @hdd_ctx: hdd global context
8337 *
8338 * Return: none
8339 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008340static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008341{
8342 uint8_t i;
8343
8344 mutex_init(&hdd_ctx->op_ctx.op_lock);
8345 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++) {
8346 hdd_ctx->op_ctx.op_table[i].request_id = MAX_REQUEST_ID;
8347 hdd_ctx->op_ctx.op_table[i].pattern_id = i;
8348 }
8349}
8350#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008351static void hdd_init_offloaded_packets_ctx(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008352{
8353}
8354#endif
8355
Yingying Tang95409972016-10-20 15:16:15 +08008356#ifdef WLAN_FEATURE_WOW_PULSE
8357/**
8358 * wlan_hdd_set_wow_pulse() - call SME to send wmi cmd of wow pulse
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008359 * @phddctx: struct hdd_context structure pointer
Yingying Tang95409972016-10-20 15:16:15 +08008360 * @enable: enable or disable this behaviour
8361 *
8362 * Return: int
8363 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008364static int wlan_hdd_set_wow_pulse(struct hdd_context *phddctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08008365{
Yingying Tang95409972016-10-20 15:16:15 +08008366 struct wow_pulse_mode wow_pulse_set_info;
8367 QDF_STATUS status;
8368
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008369 hdd_debug("wow pulse enable flag is %d", enable);
Yingying Tang95409972016-10-20 15:16:15 +08008370
Wu Gao66454f12018-09-26 19:55:41 +08008371 if (!ucfg_pmo_is_wow_pulse_enabled(phddctx->psoc))
Yingying Tang95409972016-10-20 15:16:15 +08008372 return 0;
8373
8374 /* prepare the request to send to SME */
8375 if (enable == true) {
8376 wow_pulse_set_info.wow_pulse_enable = true;
8377 wow_pulse_set_info.wow_pulse_pin =
Wu Gao66454f12018-09-26 19:55:41 +08008378 ucfg_pmo_get_wow_pulse_pin(phddctx->psoc);
8379
Yingying Tang95409972016-10-20 15:16:15 +08008380 wow_pulse_set_info.wow_pulse_interval_high =
Wu Gao66454f12018-09-26 19:55:41 +08008381 ucfg_pmo_get_wow_pulse_interval_high(phddctx->psoc);
8382
8383 wow_pulse_set_info.wow_pulse_interval_low =
8384 ucfg_pmo_get_wow_pulse_interval_low(phddctx->psoc);
Yingying Tang95409972016-10-20 15:16:15 +08008385 } else {
8386 wow_pulse_set_info.wow_pulse_enable = false;
8387 wow_pulse_set_info.wow_pulse_pin = 0;
8388 wow_pulse_set_info.wow_pulse_interval_low = 0;
8389 wow_pulse_set_info.wow_pulse_interval_high = 0;
8390 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008391 hdd_debug("enable %d pin %d low %d high %d",
Yingying Tang95409972016-10-20 15:16:15 +08008392 wow_pulse_set_info.wow_pulse_enable,
8393 wow_pulse_set_info.wow_pulse_pin,
8394 wow_pulse_set_info.wow_pulse_interval_low,
8395 wow_pulse_set_info.wow_pulse_interval_high);
8396
8397 status = sme_set_wow_pulse(&wow_pulse_set_info);
8398 if (QDF_STATUS_E_FAILURE == status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008399 hdd_debug("sme_set_wow_pulse failure!");
Yingying Tang95409972016-10-20 15:16:15 +08008400 return -EIO;
8401 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008402 hdd_debug("sme_set_wow_pulse success!");
Yingying Tang95409972016-10-20 15:16:15 +08008403 return 0;
8404}
8405#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008406static inline int wlan_hdd_set_wow_pulse(struct hdd_context *phddctx, bool enable)
Yingying Tang95409972016-10-20 15:16:15 +08008407{
8408 return 0;
8409}
8410#endif
8411
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008412#ifdef WLAN_FEATURE_FASTPATH
jitiphil377bcc12018-10-05 19:46:08 +05308413
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008414/**
8415 * hdd_enable_fastpath() - Enable fastpath if enabled in config INI
8416 * @hdd_cfg: hdd config
8417 * @context: lower layer context
8418 *
8419 * Return: none
8420 */
jitiphil377bcc12018-10-05 19:46:08 +05308421void hdd_enable_fastpath(struct hdd_context *hdd_ctx,
8422 void *context)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008423{
jitiphil377bcc12018-10-05 19:46:08 +05308424 if (cfg_get(hdd_ctx->psoc, CFG_DP_ENABLE_FASTPATH))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008425 hif_enable_fastpath(context);
8426}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008427#endif
8428
Yuanyuan Liu13738502016-04-06 17:41:37 -07008429#if defined(FEATURE_WLAN_CH_AVOID)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008430/**
8431 * hdd_set_thermal_level_cb() - set thermal level callback function
Jeff Johnson0e963082018-07-04 19:39:20 -07008432 * @hdd_handle: opaque handle for the hdd context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008433 * @level: thermal level
8434 *
8435 * Change IPA data path to SW path when the thermal throttle level greater
8436 * than 0, and restore the original data path when throttle level is 0
8437 *
8438 * Return: none
8439 */
Jeff Johnson0e963082018-07-04 19:39:20 -07008440static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008441{
Jeff Johnson0e963082018-07-04 19:39:20 -07008442 struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08008443
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008444 /* Change IPA to SW path when throttle level greater than 0 */
8445 if (level > THROTTLE_LEVEL_0)
Dustin Brown07901ec2018-09-07 11:02:41 -07008446 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008447 else
8448 /* restore original concurrency mode */
Dustin Brown07901ec2018-09-07 11:02:41 -07008449 ucfg_ipa_send_mcc_scc_msg(hdd_ctx->pdev, hdd_ctx->mcc_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008450}
8451
8452/**
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05308453 * hdd_get_safe_channel() - Get safe channel from current regulatory
8454 * @hdd_ctx: pointer to hdd context
8455 * @adapter: pointer to softap adapter
8456 *
8457 * This function is used to get safe channel from current regulatory valid
8458 * channels to restart SAP if failed to get safe channel from PCL.
8459 *
8460 * Return: Channel number to restart SAP in case of success. In case of any
8461 * failure, the channel number returned is zero.
8462 */
8463static uint8_t
8464hdd_get_safe_channel(struct hdd_context *hdd_ctx,
8465 struct hdd_adapter *adapter)
8466{
8467 struct sir_pcl_list pcl = {0};
8468 uint32_t i, j;
8469 bool found = false;
8470 int ret;
8471
8472 /* Try for safe channel from all valid channel */
8473 pcl.pcl_len = MAX_NUM_CHAN;
8474 ret = hdd_get_valid_chan(hdd_ctx, pcl.pcl_list,
8475 &pcl.pcl_len);
8476 if (ret) {
8477 hdd_err("error %d in getting valid channel list", ret);
8478 return INVALID_CHANNEL_ID;
8479 }
8480
8481 for (i = 0; i < pcl.pcl_len; i++) {
8482 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
8483 found = false;
8484 for (j = 0; j < hdd_ctx->unsafe_channel_count; j++) {
8485 if (pcl.pcl_list[i] ==
8486 hdd_ctx->unsafe_channel_list[j]) {
8487 hdd_debug("unsafe chan:%d", pcl.pcl_list[i]);
8488 found = true;
8489 break;
8490 }
8491 }
8492
8493 if (found)
8494 continue;
8495
8496 if ((pcl.pcl_list[i] >=
8497 adapter->session.ap.sap_config.acs_cfg.start_ch) &&
8498 (pcl.pcl_list[i] <=
8499 adapter->session.ap.sap_config.acs_cfg.end_ch)) {
8500 hdd_debug("found safe chan:%d", pcl.pcl_list[i]);
8501 return pcl.pcl_list[i];
8502 }
8503 }
8504
8505 return INVALID_CHANNEL_ID;
8506}
8507
8508#else
8509/**
8510 * hdd_set_thermal_level_cb() - set thermal level callback function
8511 * @hdd_handle: opaque handle for the hdd context
8512 * @level: thermal level
8513 *
8514 * Change IPA data path to SW path when the thermal throttle level greater
8515 * than 0, and restore the original data path when throttle level is 0
8516 *
8517 * Return: none
8518 */
8519static void hdd_set_thermal_level_cb(hdd_handle_t hdd_handle, u_int8_t level)
8520{
8521}
8522
8523/**
8524 * hdd_get_safe_channel() - Get safe channel from current regulatory
8525 * @hdd_ctx: pointer to hdd context
8526 * @adapter: pointer to softap adapter
8527 *
8528 * This function is used to get safe channel from current regulatory valid
8529 * channels to restart SAP if failed to get safe channel from PCL.
8530 *
8531 * Return: Channel number to restart SAP in case of success. In case of any
8532 * failure, the channel number returned is zero.
8533 */
8534static uint8_t
8535hdd_get_safe_channel(struct hdd_context *hdd_ctx,
8536 struct hdd_adapter *adapter)
8537{
8538 return 0;
8539}
8540#endif
8541
8542/**
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308543 * hdd_get_safe_channel_from_pcl_and_acs_range() - Get safe channel for SAP
8544 * restart
Manishekar Chandrasekarandb9b8672016-06-10 23:31:19 +05308545 * @adapter: AP adapter, which should be checked for NULL
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008546 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308547 * Get a safe channel to restart SAP. PCL already takes into account the
8548 * unsafe channels. So, the PCL is validated with the ACS range to provide
8549 * a safe channel for the SAP to restart.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008550 *
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308551 * Return: Channel number to restart SAP in case of success. In case of any
8552 * failure, the channel number returned is zero.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008553 */
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05308554static uint8_t
8555hdd_get_safe_channel_from_pcl_and_acs_range(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008556{
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308557 struct sir_pcl_list pcl;
8558 QDF_STATUS status;
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05308559 uint32_t i;
Jeff Johnson16528362018-06-14 12:34:16 -07008560 mac_handle_t mac_handle;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008561 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008562
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308563 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8564 if (!hdd_ctx) {
8565 hdd_err("invalid HDD context");
8566 return INVALID_CHANNEL_ID;
8567 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008568
Jeff Johnson16528362018-06-14 12:34:16 -07008569 mac_handle = hdd_ctx->mac_handle;
8570 if (!mac_handle) {
8571 hdd_err("invalid MAC handle");
Manishekar Chandrasekaran79746ac2016-06-24 04:45:33 +05308572 return INVALID_CHANNEL_ID;
8573 }
8574
Dustin Brown1dbefe62018-09-11 16:32:03 -07008575 status = policy_mgr_get_pcl_for_existing_conn(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08008576 PM_SAP_MODE, pcl.pcl_list, &pcl.pcl_len,
bings37bd58f2017-07-20 16:49:26 +08008577 pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list),
8578 false);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308579 if (QDF_IS_STATUS_ERROR(status)) {
8580 hdd_err("Get PCL failed");
8581 return INVALID_CHANNEL_ID;
8582 }
8583
Frank Liudc2cefb2017-06-21 15:38:18 +08008584 /*
8585 * In some scenarios, like hw dbs disabled, sap+sap case, if operating
8586 * channel is unsafe channel, the pcl may be empty, instead of return,
8587 * try to choose a safe channel from acs range.
8588 */
8589 if (!pcl.pcl_len)
8590 hdd_debug("pcl length is zero!");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308591
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008592 hdd_debug("start:%d end:%d",
Jeff Johnsonb9424862017-10-30 08:49:35 -07008593 adapter->session.ap.sap_config.acs_cfg.start_ch,
8594 adapter->session.ap.sap_config.acs_cfg.end_ch);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308595
8596 /* PCL already takes unsafe channel into account */
8597 for (i = 0; i < pcl.pcl_len; i++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008598 hdd_debug("chan[%d]:%d", i, pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308599 if ((pcl.pcl_list[i] >=
Jeff Johnsonb9424862017-10-30 08:49:35 -07008600 adapter->session.ap.sap_config.acs_cfg.start_ch) &&
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308601 (pcl.pcl_list[i] <=
Jeff Johnsonb9424862017-10-30 08:49:35 -07008602 adapter->session.ap.sap_config.acs_cfg.end_ch)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008603 hdd_debug("found PCL safe chan:%d", pcl.pcl_list[i]);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308604 return pcl.pcl_list[i];
8605 }
8606 }
8607
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008608 hdd_debug("no safe channel from PCL found in ACS range");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308609
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +05308610 return hdd_get_safe_channel(hdd_ctx, adapter);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308611}
8612
8613/**
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08008614 * hdd_switch_sap_channel() - Move SAP to the given channel
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308615 * @adapter: AP adapter
8616 * @channel: Channel
Min Liu2fef5792018-01-19 17:59:42 +08008617 * @forced: Force to switch channel, ignore SCC/MCC check
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308618 *
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -08008619 * Moves the SAP interface by invoking the function which
8620 * executes the callback to perform channel switch using (E)CSA.
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308621 *
8622 * Return: None
8623 */
Min Liu2fef5792018-01-19 17:59:42 +08008624void hdd_switch_sap_channel(struct hdd_adapter *adapter, uint8_t channel,
8625 bool forced)
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308626{
Jeff Johnson87251032017-08-29 13:31:11 -07008627 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008628 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -07008629 mac_handle_t mac_handle;
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308630
8631 if (!adapter) {
8632 hdd_err("invalid adapter");
8633 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008634 }
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308635
8636 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(adapter);
8637
Jeff Johnson16528362018-06-14 12:34:16 -07008638 mac_handle = hdd_adapter_get_mac_handle(adapter);
8639 if (!mac_handle) {
8640 hdd_err("invalid MAC handle");
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308641 return;
8642 }
8643
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -08008644 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8645
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008646 hdd_debug("chan:%d width:%d",
Jeff Johnson91df29d2017-10-27 19:29:50 -07008647 channel, hdd_ap_ctx->sap_config.ch_width_orig);
Manishekar Chandrasekaranc67b2bb2016-05-25 18:44:01 +05308648
Dustin Brown1dbefe62018-09-11 16:32:03 -07008649 policy_mgr_change_sap_channel_with_csa(hdd_ctx->psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -07008650 adapter->session_id, channel,
Min Liu2fef5792018-01-19 17:59:42 +08008651 hdd_ap_ctx->sap_config.ch_width_orig, forced);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008652}
Kapil Gupta8878ad92017-02-13 11:56:04 +05308653
Jeff Johnson9d295242017-08-29 14:39:48 -07008654int hdd_update_acs_timer_reason(struct hdd_adapter *adapter, uint8_t reason)
Kapil Gupta8878ad92017-02-13 11:56:04 +05308655{
8656 struct hdd_external_acs_timer_context *timer_context;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308657 int status;
8658 QDF_STATUS qdf_status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308659
8660 set_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
8661
8662 if (QDF_TIMER_STATE_RUNNING ==
Jeff Johnsonb9424862017-10-30 08:49:35 -07008663 qdf_mc_timer_get_current_state(&adapter->session.
Kapil Gupta8878ad92017-02-13 11:56:04 +05308664 ap.vendor_acs_timer)) {
Jeff Johnsonb9424862017-10-30 08:49:35 -07008665 qdf_mc_timer_stop(&adapter->session.ap.vendor_acs_timer);
Kapil Gupta8878ad92017-02-13 11:56:04 +05308666 }
8667 timer_context = (struct hdd_external_acs_timer_context *)
Jeff Johnsonb9424862017-10-30 08:49:35 -07008668 adapter->session.ap.vendor_acs_timer.user_data;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308669 timer_context->reason = reason;
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308670 qdf_status =
Jeff Johnsonb9424862017-10-30 08:49:35 -07008671 qdf_mc_timer_start(&adapter->session.ap.vendor_acs_timer,
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308672 WLAN_VENDOR_ACS_WAIT_TIME);
8673 if (qdf_status != QDF_STATUS_SUCCESS) {
8674 hdd_err("failed to start external acs timer");
8675 return -ENOSPC;
8676 }
8677 /* Update config to application */
8678 status = hdd_cfg80211_update_acs_config(adapter, reason);
Dustin Brown5e89ef82018-03-14 11:50:23 -07008679 hdd_info("Updated ACS config to nl with reason %d", reason);
Kapil Gupta8878ad92017-02-13 11:56:04 +05308680
Himanshu Agarwaldfc4dca2017-08-29 19:49:05 +05308681 return status;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308682}
8683
Nirav Shaheb017be2018-02-15 11:20:58 +05308684#if defined(FEATURE_WLAN_CH_AVOID)
Agrawal Ashish467dde42016-09-08 18:44:22 +05308685/**
8686 * hdd_unsafe_channel_restart_sap() - restart sap if sap is on unsafe channel
8687 * @hdd_ctx: hdd context pointer
8688 *
8689 * hdd_unsafe_channel_restart_sap check all unsafe channel list
8690 * and if ACS is enabled, driver will ask userspace to restart the
8691 * sap. User space on LTE coex indication restart driver.
8692 *
8693 * Return - none
8694 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008695void hdd_unsafe_channel_restart_sap(struct hdd_context *hdd_ctxt)
Agrawal Ashish467dde42016-09-08 18:44:22 +05308696{
Dustin Brown920397d2017-12-13 16:27:50 -08008697 struct hdd_adapter *adapter;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308698 uint32_t i;
8699 bool found = false;
8700 uint8_t restart_chan;
Krunal Sonidf29bc42018-11-15 13:26:29 -08008701 uint8_t scc_on_lte_coex = 0;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05308702 bool value;
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07008703 QDF_STATUS status;
8704 bool is_acs_support_for_dfs_ltecoex = cfg_default(CFG_USER_ACS_DFS_LTE);
8705 bool is_vendor_acs_support =
8706 cfg_default(CFG_USER_AUTO_CHANNEL_SELECTION);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008707
Dustin Brown920397d2017-12-13 16:27:50 -08008708 hdd_for_each_adapter(hdd_ctxt, adapter) {
8709 if (!(adapter->device_mode == QDF_SAP_MODE &&
8710 adapter->session.ap.sap_config.acs_cfg.acs_mode)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008711 hdd_debug("skip device mode:%d acs:%d",
Dustin Brown920397d2017-12-13 16:27:50 -08008712 adapter->device_mode,
8713 adapter->session.ap.sap_config.
8714 acs_cfg.acs_mode);
8715 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308716 }
8717
8718 found = false;
Krunal Sonidf29bc42018-11-15 13:26:29 -08008719 status =
8720 ucfg_policy_mgr_get_sta_sap_scc_lte_coex_chnl(hdd_ctxt->psoc,
8721 &scc_on_lte_coex);
8722 if (!QDF_IS_STATUS_SUCCESS(status))
8723 hdd_err("can't get scc on lte coex chnl, use def");
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07008724 /*
8725 * If STA+SAP is doing SCC & g_sta_sap_scc_on_lte_coex_chan
8726 * is set, no need to move SAP.
8727 */
Dustin Brown1dbefe62018-09-11 16:32:03 -07008728 if (policy_mgr_is_sta_sap_scc(hdd_ctxt->psoc,
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07008729 adapter->session.ap.operating_channel) &&
Krunal Sonidf29bc42018-11-15 13:26:29 -08008730 scc_on_lte_coex)
Tushnim Bhattacharyyad2e085d2018-06-18 11:58:50 -07008731 hdd_debug("SAP is allowed on SCC channel, no need to move SAP");
8732 else {
8733 for (i = 0; i < hdd_ctxt->unsafe_channel_count; i++) {
8734 if (adapter->session.ap.operating_channel ==
8735 hdd_ctxt->unsafe_channel_list[i]) {
8736 found = true;
8737 hdd_debug("operating ch:%d is unsafe",
8738 adapter->session.ap.operating_channel);
8739 break;
8740 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05308741 }
8742 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05308743 if (!found) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008744 hdd_debug("ch:%d is safe. no need to change channel",
Dustin Brown920397d2017-12-13 16:27:50 -08008745 adapter->session.ap.operating_channel);
8746 continue;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308747 }
8748
Harprit Chhabada1eeeb8d2018-09-14 15:16:56 -07008749 status = ucfg_mlme_get_acs_support_for_dfs_ltecoex(
8750 hdd_ctxt->psoc,
8751 &is_acs_support_for_dfs_ltecoex);
8752 if (!QDF_IS_STATUS_SUCCESS(status))
8753 hdd_err("get_acs_support_for_dfs_ltecoex failed,set def");
8754
8755 status = ucfg_mlme_get_vendor_acs_support(
8756 hdd_ctxt->psoc,
8757 &is_vendor_acs_support);
8758 if (!QDF_IS_STATUS_SUCCESS(status))
8759 hdd_err("get_vendor_acs_support failed, set default");
8760
8761 if (is_vendor_acs_support && is_acs_support_for_dfs_ltecoex) {
Dustin Brown920397d2017-12-13 16:27:50 -08008762 hdd_update_acs_timer_reason(adapter,
Kapil Gupta8878ad92017-02-13 11:56:04 +05308763 QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX);
Dustin Brown920397d2017-12-13 16:27:50 -08008764 continue;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308765 } else
8766 restart_chan =
8767 hdd_get_safe_channel_from_pcl_and_acs_range(
Dustin Brown920397d2017-12-13 16:27:50 -08008768 adapter);
Agrawal Ashish467dde42016-09-08 18:44:22 +05308769 if (!restart_chan) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008770 hdd_err("fail to restart SAP");
Agrawal Ashish467dde42016-09-08 18:44:22 +05308771 } else {
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08008772 /*
8773 * SAP restart due to unsafe channel. While
8774 * restarting the SAP, make sure to clear
8775 * acs_channel, channel to reset to
8776 * 0. Otherwise these settings will override
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05308777 * the ACS while restart.
Jeff Johnson0d52c7a2017-01-12 08:46:55 -08008778 */
Kondabattini, Ganesh2836c5a2016-09-20 17:10:19 +05308779 hdd_ctxt->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008780 hdd_debug("sending coex indication");
Agrawal Ashish467dde42016-09-08 18:44:22 +05308781 wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index,
8782 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Dustin Brown05d81302018-09-11 16:49:22 -07008783 ucfg_mlme_get_sap_internal_restart(hdd_ctxt->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05308784 &value);
8785 hdd_debug("driver to start sap: %d", value);
8786 if (value)
Min Liu2fef5792018-01-19 17:59:42 +08008787 hdd_switch_sap_channel(adapter, restart_chan,
8788 true);
Liangwei Dong6663d162017-07-10 03:29:36 -04008789 else
8790 return;
Agrawal Ashish467dde42016-09-08 18:44:22 +05308791 }
Agrawal Ashish467dde42016-09-08 18:44:22 +05308792 }
8793}
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +05308794
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008795/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008796 * hdd_init_channel_avoidance() - Initialize channel avoidance
8797 * @hdd_ctx: HDD global context
8798 *
8799 * Initialize the channel avoidance logic by retrieving the unsafe
Yuanyuan Liu13738502016-04-06 17:41:37 -07008800 * channel list from the platform driver and plumbing the data
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008801 * down to the lower layers. Then subscribe to subsequent channel
8802 * avoidance events.
8803 *
8804 * Return: None
8805 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008806static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008807{
8808 uint16_t unsafe_channel_count;
8809 int index;
8810
Yuanyuan Liu13738502016-04-06 17:41:37 -07008811 pld_get_wlan_unsafe_channel(hdd_ctx->parent_dev,
8812 hdd_ctx->unsafe_channel_list,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008813 &(hdd_ctx->unsafe_channel_count),
Amar Singhalb8d4f152016-02-10 10:21:43 -08008814 sizeof(uint16_t) * NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008815
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008816 hdd_debug("num of unsafe channels is %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008817 hdd_ctx->unsafe_channel_count);
8818
Anurag Chouhan6d760662016-02-20 16:05:43 +05308819 unsafe_channel_count = QDF_MIN((uint16_t)hdd_ctx->unsafe_channel_count,
Amar Singhalb8d4f152016-02-10 10:21:43 -08008820 (uint16_t)NUM_CHANNELS);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008821
8822 for (index = 0; index < unsafe_channel_count; index++) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08008823 hdd_debug("channel %d is not safe",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008824 hdd_ctx->unsafe_channel_list[index]);
8825
8826 }
8827
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008828}
Dustin Brown676a2322017-08-15 13:16:13 -07008829
Jeff Johnson9d295242017-08-29 14:39:48 -07008830static void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008831 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07008832{
8833 uint8_t restart_chan;
8834
8835 restart_chan = hdd_get_safe_channel_from_pcl_and_acs_range(adapter);
8836 if (!restart_chan) {
8837 hdd_alert("fail to restart SAP");
8838 return;
8839 }
8840
8841 /* SAP restart due to unsafe channel. While restarting
8842 * the SAP, make sure to clear acs_channel, channel to
8843 * reset to 0. Otherwise these settings will override
8844 * the ACS while restart.
8845 */
8846 hdd_ctx->acs_policy.acs_channel = AUTO_CHANNEL_SELECT;
Dustin Brown676a2322017-08-15 13:16:13 -07008847
8848 hdd_debug("sending coex indication");
8849
8850 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
8851 WLAN_SVC_LTE_COEX_IND, NULL, 0);
Min Liu2fef5792018-01-19 17:59:42 +08008852 hdd_switch_sap_channel(adapter, restart_chan, true);
Dustin Brown676a2322017-08-15 13:16:13 -07008853}
Liangwei Dong6e1a2092017-08-30 16:29:06 +08008854
8855int hdd_clone_local_unsafe_chan(struct hdd_context *hdd_ctx,
8856 uint16_t **local_unsafe_list, uint16_t *local_unsafe_list_count)
8857{
8858 uint32_t size;
8859 uint16_t *unsafe_list;
8860 uint16_t chan_count;
8861
8862 if (!hdd_ctx || !local_unsafe_list_count || !local_unsafe_list_count)
8863 return -EINVAL;
8864
8865 chan_count = QDF_MIN(hdd_ctx->unsafe_channel_count,
8866 NUM_CHANNELS);
8867 if (chan_count) {
8868 size = chan_count * sizeof(hdd_ctx->unsafe_channel_list[0]);
8869 unsafe_list = qdf_mem_malloc(size);
Min Liu74a1a502018-10-10 19:59:07 +08008870 if (!unsafe_list)
Liangwei Dong6e1a2092017-08-30 16:29:06 +08008871 return -ENOMEM;
Liangwei Dong6e1a2092017-08-30 16:29:06 +08008872 qdf_mem_copy(unsafe_list, hdd_ctx->unsafe_channel_list, size);
8873 } else {
8874 unsafe_list = NULL;
8875 }
8876
8877 *local_unsafe_list = unsafe_list;
8878 *local_unsafe_list_count = chan_count;
8879
8880 return 0;
8881}
8882
8883bool hdd_local_unsafe_channel_updated(struct hdd_context *hdd_ctx,
8884 uint16_t *local_unsafe_list, uint16_t local_unsafe_list_count)
8885{
8886 int i, j;
8887
8888 if (local_unsafe_list_count != hdd_ctx->unsafe_channel_count)
8889 return true;
8890 if (local_unsafe_list_count == 0)
8891 return false;
8892 for (i = 0; i < local_unsafe_list_count; i++) {
8893 for (j = 0; j < local_unsafe_list_count; j++)
8894 if (local_unsafe_list[i] ==
8895 hdd_ctx->unsafe_channel_list[j])
8896 break;
8897 if (j >= local_unsafe_list_count)
8898 break;
8899 }
8900 if (i >= local_unsafe_list_count) {
8901 hdd_info("unsafe chan list same");
8902 return false;
8903 }
8904
8905 return true;
8906}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008907#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008908static void hdd_init_channel_avoidance(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008909{
8910}
Dustin Brown676a2322017-08-15 13:16:13 -07008911
Jeff Johnson9d295242017-08-29 14:39:48 -07008912static inline void hdd_lte_coex_restart_sap(struct hdd_adapter *adapter,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008913 struct hdd_context *hdd_ctx)
Dustin Brown676a2322017-08-15 13:16:13 -07008914{
8915 hdd_debug("Channel avoidance is not enabled; Abort SAP restart");
8916}
Yuanyuan Liu13738502016-04-06 17:41:37 -07008917#endif /* defined(FEATURE_WLAN_CH_AVOID) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08008918
8919/**
Rajeev Kumard004abc2016-02-17 12:09:56 -08008920 * hdd_indicate_mgmt_frame() - Wrapper to indicate management frame to
8921 * user space
8922 * @frame_ind: Management frame data to be informed.
8923 *
8924 * This function is used to indicate management frame to
8925 * user space
8926 *
8927 * Return: None
8928 *
8929 */
8930void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind)
8931{
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008932 struct hdd_context *hdd_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -07008933 struct hdd_adapter *adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08008934 int i;
Pragaspathi Thilagaraj28ffc042018-07-18 15:19:36 +05308935 struct ieee80211_mgmt *mgmt =
8936 (struct ieee80211_mgmt *)frame_ind->frameBuf;
Rajeev Kumard004abc2016-02-17 12:09:56 -08008937
Dustin Browne7e71d32018-05-11 16:00:08 -07008938 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
8939 if (wlan_hdd_validate_context(hdd_ctx))
Rajeev Kumard004abc2016-02-17 12:09:56 -08008940 return;
8941
Pragaspathi Thilagaraj28ffc042018-07-18 15:19:36 +05308942 if (frame_ind->frame_len < ieee80211_hdrlen(mgmt->frame_control)) {
8943 hdd_err(" Invalid frame length");
8944 return;
8945 }
8946
Rajeev Kumard004abc2016-02-17 12:09:56 -08008947 if (SME_SESSION_ID_ANY == frame_ind->sessionId) {
8948 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
8949 adapter =
8950 hdd_get_adapter_by_sme_session_id(hdd_ctx, i);
8951 if (adapter)
8952 break;
8953 }
Wu Gaoa0230a62018-01-04 20:56:57 +08008954 } else if (SME_SESSION_ID_BROADCAST == frame_ind->sessionId) {
8955 hdd_for_each_adapter(hdd_ctx, adapter) {
8956 if ((NULL != adapter) &&
8957 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)) {
8958 __hdd_indicate_mgmt_frame(adapter,
8959 frame_ind->frame_len,
8960 frame_ind->frameBuf,
8961 frame_ind->frameType,
8962 frame_ind->rxChan,
8963 frame_ind->rxRssi);
8964 }
8965 }
8966 adapter = NULL;
Rajeev Kumard004abc2016-02-17 12:09:56 -08008967 } else {
8968 adapter = hdd_get_adapter_by_sme_session_id(hdd_ctx,
8969 frame_ind->sessionId);
8970 }
8971
8972 if ((NULL != adapter) &&
8973 (WLAN_HDD_ADAPTER_MAGIC == adapter->magic))
8974 __hdd_indicate_mgmt_frame(adapter,
8975 frame_ind->frame_len,
8976 frame_ind->frameBuf,
8977 frame_ind->frameType,
8978 frame_ind->rxChan,
8979 frame_ind->rxRssi);
Rajeev Kumard004abc2016-02-17 12:09:56 -08008980}
8981
Kapil Gupta8878ad92017-02-13 11:56:04 +05308982void hdd_acs_response_timeout_handler(void *context)
8983{
8984 struct hdd_external_acs_timer_context *timer_context =
8985 (struct hdd_external_acs_timer_context *)context;
Jeff Johnson9d295242017-08-29 14:39:48 -07008986 struct hdd_adapter *adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07008987 struct hdd_context *hdd_ctx;
Kapil Gupta8878ad92017-02-13 11:56:04 +05308988 uint8_t reason;
8989
Dustin Brown491d54b2018-03-14 12:39:11 -07008990 hdd_enter();
Kapil Gupta8878ad92017-02-13 11:56:04 +05308991 if (!timer_context) {
8992 hdd_err("invlaid timer context");
8993 return;
8994 }
8995 adapter = timer_context->adapter;
8996 reason = timer_context->reason;
8997
8998
8999 if ((!adapter) ||
9000 (adapter->magic != WLAN_HDD_ADAPTER_MAGIC)) {
9001 hdd_err("invalid adapter or adapter has invalid magic");
9002 return;
9003 }
9004 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
9005 if (wlan_hdd_validate_context(hdd_ctx))
9006 return;
9007
9008 if (test_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags))
9009 clear_bit(VENDOR_ACS_RESPONSE_PENDING, &adapter->event_flags);
9010 else
9011 return;
9012
9013 hdd_err("ACS timeout happened for %s reason %d",
9014 adapter->dev->name, reason);
Jeff Johnson16528362018-06-14 12:34:16 -07009015
Kapil Gupta8878ad92017-02-13 11:56:04 +05309016 switch (reason) {
9017 /* SAP init case */
9018 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_INIT:
9019 wlan_sap_set_vendor_acs(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
9020 false);
9021 wlan_hdd_cfg80211_start_acs(adapter);
9022 break;
9023 /* DFS detected on current channel */
9024 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS:
9025 wlan_sap_update_next_channel(
9026 WLAN_HDD_GET_SAP_CTX_PTR(adapter), 0, 0);
Jeff Johnson16528362018-06-14 12:34:16 -07009027 sme_update_new_channel_event(hdd_ctx->mac_handle,
Jeff Johnson1b780e42017-10-31 14:11:45 -07009028 adapter->session_id);
Kapil Gupta8878ad92017-02-13 11:56:04 +05309029 break;
9030 /* LTE coex event on current channel */
9031 case QCA_WLAN_VENDOR_ACS_SELECT_REASON_LTE_COEX:
9032 hdd_lte_coex_restart_sap(adapter, hdd_ctx);
9033 break;
9034 default:
9035 hdd_info("invalid reason for timer invoke");
9036
9037 }
9038}
9039
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009040/**
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009041 * hdd_override_ini_config - Override INI config
9042 * @hdd_ctx: HDD context
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009043 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009044 * Override INI config based on module parameter.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009045 *
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009046 * Return: None
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009047 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009048static void hdd_override_ini_config(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009049{
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309050 QDF_STATUS status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009051
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009052 if (0 == enable_dfs_chan_scan || 1 == enable_dfs_chan_scan) {
9053 hdd_ctx->config->enableDFSChnlScan = enable_dfs_chan_scan;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -08009054 hdd_debug("Module enable_dfs_chan_scan set to %d",
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009055 enable_dfs_chan_scan);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009056 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009057 if (0 == enable_11d || 1 == enable_11d) {
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309058 status = ucfg_mlme_set_11d_enabled(hdd_ctx->psoc, enable_11d);
9059 if (!QDF_IS_STATUS_SUCCESS(status))
9060 hdd_err("Failed to set 11d_enable flag");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009061 }
Leo Chang11545d62016-10-17 14:53:50 -07009062
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +05309063 if (hdd_ctx->config->action_oui_enable && !ucfg_action_oui_enabled()) {
9064 hdd_ctx->config->action_oui_enable = 0;
Sourav Mohapatra58841062018-11-19 16:33:27 +05309065 hdd_err("Ignore action oui ini, since no action_oui component");
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +05309066 }
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009067}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08009068
Ashish Kumar Dhanotiya12f68212018-09-04 22:00:14 +05309069#ifdef ENABLE_MTRACE_LOG
9070static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
9071{
9072 uint8_t module_id = 0;
9073 int qdf_print_idx = -1;
9074
9075 qdf_print_idx = qdf_get_pidx();
9076 for (module_id = 0; module_id < QDF_MODULE_ID_MAX; module_id++)
9077 qdf_print_set_category_verbose(
9078 qdf_print_idx,
9079 module_id, QDF_TRACE_LEVEL_TRACE,
9080 hdd_ctx->config->enable_mtrace);
9081}
9082#else
9083static void hdd_set_mtrace_for_each(struct hdd_context *hdd_ctx)
9084{
9085}
9086
9087#endif
9088
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009089/**
9090 * hdd_set_trace_level_for_each - Set trace level for each INI config
9091 * @hdd_ctx - HDD context
9092 *
9093 * Set trace level for each module based on INI config.
9094 *
9095 * Return: None
9096 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009097static void hdd_set_trace_level_for_each(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009098{
Wu Gaobc6eaa12018-11-30 14:17:45 +08009099 hdd_qdf_trace_enable(QDF_MODULE_ID_DP, 0x7f);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +05309100 hdd_qdf_trace_enable(QDF_MODULE_ID_MLME, 0xffff);
Sourav Mohapatra113685f2018-08-29 14:21:55 +05309101 hdd_qdf_trace_enable(QDF_MODULE_ID_FWOL, 0xffff);
Kiran Kumar Lokere4ce40482018-08-30 16:31:00 -07009102 hdd_qdf_trace_enable(QDF_MODULE_ID_CRYPTO, 0xffff);
Kiran Kumar Lokere798de7e2017-03-30 14:01:12 -07009103
Ashish Kumar Dhanotiya12f68212018-09-04 22:00:14 +05309104 hdd_set_mtrace_for_each(hdd_ctx);
9105
Nirav Shah5c083da2018-08-03 13:46:02 +05309106 hdd_cfg_print_global_config(hdd_ctx);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009107}
9108
9109/**
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009110 * hdd_context_init() - Initialize HDD context
9111 * @hdd_ctx: HDD context.
9112 *
9113 * Initialize HDD context along with all the feature specific contexts.
9114 *
9115 * return: 0 on success and errno on failure.
9116 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009117static int hdd_context_init(struct hdd_context *hdd_ctx)
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009118{
9119 int ret;
9120
9121 hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN;
9122 hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX;
9123
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009124 init_completion(&hdd_ctx->mc_sus_event_var);
9125 init_completion(&hdd_ctx->ready_to_suspend);
9126
9127 qdf_spinlock_create(&hdd_ctx->connection_status_lock);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009128 qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock);
Manishekar Chandrasekaran7f63d052016-05-07 09:54:00 +05309129
Dustin Brownbee82832018-07-23 10:10:51 -07009130 qdf_list_create(&hdd_ctx->hdd_adapters, 0);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009131
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009132 ret = hdd_scan_context_init(hdd_ctx);
9133 if (ret)
9134 goto list_destroy;
9135
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009136 hdd_rx_wake_lock_create(hdd_ctx);
9137
9138 ret = hdd_sap_context_init(hdd_ctx);
9139 if (ret)
9140 goto scan_destroy;
9141
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009142 wlan_hdd_cfg80211_extscan_init(hdd_ctx);
9143
9144 hdd_init_offloaded_packets_ctx(hdd_ctx);
9145
9146 ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy,
9147 hdd_ctx->config);
9148 if (ret)
Wu Gao02bd75b2017-10-13 18:34:02 +08009149 goto sap_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009150
Arunk Khandavalliebd1e372017-11-06 15:00:24 +05309151 qdf_wake_lock_create(&hdd_ctx->monitor_mode_wakelock,
9152 "monitor_mode_wakelock");
9153
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009154 return 0;
9155
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009156sap_destroy:
9157 hdd_sap_context_destroy(hdd_ctx);
9158
9159scan_destroy:
9160 hdd_scan_context_destroy(hdd_ctx);
9161 hdd_rx_wake_lock_destroy(hdd_ctx);
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009162list_destroy:
Jeff Johnson19fc8e42017-10-30 19:53:49 -07009163 qdf_list_destroy(&hdd_ctx->hdd_adapters);
Sandeep Puligillad0004212017-02-26 18:34:56 -08009164
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009165 return ret;
9166}
9167
Dustin Brown4c663222018-10-23 14:19:36 -07009168void hdd_psoc_idle_timer_start(struct hdd_context *hdd_ctx)
9169{
9170 uint32_t timeout_ms = hdd_ctx->config->iface_change_wait_time;
9171 enum wake_lock_reason reason =
9172 WIFI_POWER_EVENT_WAKELOCK_IFACE_CHANGE_TIMER;
9173
9174 hdd_debug("Starting psoc idle timer");
9175 qdf_sched_delayed_work(&hdd_ctx->psoc_idle_timeout_work, timeout_ms);
9176 hdd_prevent_suspend_timeout(timeout_ms, reason);
9177}
9178
9179void hdd_psoc_idle_timer_stop(struct hdd_context *hdd_ctx)
9180{
9181 qdf_cancel_delayed_work(&hdd_ctx->psoc_idle_timeout_work);
9182 hdd_debug("Stopped psoc idle timer");
9183}
9184
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009185/**
Dustin Brown3ecc8782018-09-19 16:37:13 -07009186 * hdd_psoc_idle_shutdown() - perform an idle shutdown on the given psoc
9187 * @hdd_ctx: the hdd context which should be shutdown
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309188 *
Dustin Brown3ecc8782018-09-19 16:37:13 -07009189 * When no interfaces are "up" on a psoc, an idle shutdown timer is started.
9190 * If no interfaces are brought up before the timer expires, we do an
9191 * "idle shutdown," cutting power to the physical SoC to save power. This is
9192 * done completely transparently from the perspective of userspace.
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309193 *
Dustin Brown3ecc8782018-09-19 16:37:13 -07009194 * Return: None
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309195 */
Dustin Brown3ecc8782018-09-19 16:37:13 -07009196static void hdd_psoc_idle_shutdown(struct hdd_context *hdd_ctx)
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309197{
Dustin Brown3ecc8782018-09-19 16:37:13 -07009198 struct hdd_psoc *hdd_psoc = hdd_ctx->hdd_psoc;
9199 QDF_STATUS status;
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309200
Dustin Brown491d54b2018-03-14 12:39:11 -07009201 hdd_enter();
Dustin Brown3ecc8782018-09-19 16:37:13 -07009202
9203 status = dsc_psoc_trans_start(hdd_psoc->dsc_psoc, "idle shutdown");
9204 if (QDF_IS_STATUS_ERROR(status)) {
9205 hdd_info("psoc busy, abort idle shutdown; status:%u", status);
9206 return;
9207 }
9208
9209 QDF_BUG(!hdd_wlan_stop_modules(hdd_ctx, false));
9210
9211 hdd_psoc->state = psoc_state_idle;
9212 dsc_psoc_trans_stop(hdd_psoc->dsc_psoc);
9213
Dustin Browne74003f2018-03-14 12:51:58 -07009214 hdd_exit();
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309215}
9216
Dustin Brown3ecc8782018-09-19 16:37:13 -07009217int hdd_psoc_idle_restart(struct hdd_context *hdd_ctx)
9218{
9219 struct hdd_psoc *hdd_psoc = hdd_ctx->hdd_psoc;
9220 QDF_STATUS status;
9221 int errno;
9222
9223 status = dsc_psoc_trans_start_wait(hdd_psoc->dsc_psoc, "idle restart");
9224 if (QDF_IS_STATUS_ERROR(status)) {
9225 hdd_info("unable to start 'idle restart'; status:%u", status);
9226 return qdf_status_to_os_return(status);
9227 }
9228
9229 errno = hdd_wlan_start_modules(hdd_ctx, false);
9230 if (!errno)
9231 hdd_psoc->state = psoc_state_active;
9232
9233 dsc_psoc_trans_stop(hdd_psoc->dsc_psoc);
9234
9235 return errno;
9236}
9237
9238/**
9239 * hdd_psoc_idle_timeout_callback() - Handler for psoc idle timeout
9240 * @priv: pointer to hdd context
9241 *
9242 * Return: None
9243 */
9244static void hdd_psoc_idle_timeout_callback(void *priv)
9245{
9246 struct hdd_context *hdd_ctx = priv;
9247
9248 if (wlan_hdd_validate_context(hdd_ctx))
9249 return;
9250
9251 hdd_debug("Psoc idle timeout elapsed; starting psoc shutdown");
9252 hdd_psoc_idle_shutdown(hdd_ctx);
9253}
9254
Nirav Shaheb017be2018-02-15 11:20:58 +05309255#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9256static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
9257{
9258 wlan_logging_set_log_to_console(hdd_ctx->config->
9259 wlan_logging_to_console);
9260 wlan_logging_set_active(hdd_ctx->config->wlan_logging_enable);
9261}
9262#else
9263static void hdd_set_wlan_logging(struct hdd_context *hdd_ctx)
9264{ }
9265#endif
9266
Dundi Raviteja8e338282018-09-25 17:16:04 +05309267#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
9268static void hdd_init_wlan_logging_params(struct hdd_config *config,
9269 struct wlan_objmgr_psoc *psoc)
9270{
9271 config->wlan_logging_enable = cfg_get(psoc, CFG_WLAN_LOGGING_SUPPORT);
9272
9273 config->wlan_logging_to_console =
9274 cfg_get(psoc, CFG_WLAN_LOGGING_CONSOLE_SUPPORT);
9275}
9276#else
9277static void hdd_init_wlan_logging_params(struct hdd_config *config,
9278 struct wlan_objmgr_psoc *psoc)
9279{
9280}
9281#endif
9282
9283#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
9284static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
9285 struct wlan_objmgr_psoc *psoc)
9286{
9287 config->wlan_auto_shutdown = cfg_get(psoc, CFG_WLAN_AUTO_SHUTDOWN);
9288}
9289#else
9290static void hdd_init_wlan_auto_shutdown(struct hdd_config *config,
9291 struct wlan_objmgr_psoc *psoc)
9292{
9293}
9294#endif
9295
9296#ifndef REMOVE_PKT_LOG
9297static void hdd_init_packet_log(struct hdd_config *config,
9298 struct wlan_objmgr_psoc *psoc)
9299{
9300 config->enable_packet_log = cfg_get(psoc, CFG_ENABLE_PACKET_LOG);
9301}
9302#else
9303static void hdd_init_packet_log(struct hdd_config *config,
9304 struct wlan_objmgr_psoc *psoc)
9305{
9306}
9307#endif
9308
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +05309309#ifdef FEATURE_RUNTIME_PM
9310static void hdd_init_runtime_pm(struct hdd_config *config,
9311 struct wlan_objmgr_psoc *psoc)
9312{
9313 config->runtime_pm = cfg_get(psoc, CFG_ENABLE_RUNTIME_PM);
9314}
9315#else
9316static void hdd_init_runtime_pm(struct hdd_config *config,
9317 struct wlan_objmgr_psoc *psoc)
9318
9319{
9320}
9321#endif
9322
9323#ifdef FEATURE_WLAN_DYNAMIC_CVM
9324static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
9325 struct wlan_objmgr_psoc *psoc)
9326{
9327 config->vc_mode_cfg_bitmap = cfg_get(psoc, CFG_VC_MODE_BITMAP);
9328}
9329#else
9330static void hdd_init_vc_mode_cfg_bitmap(struct hdd_config *config,
9331 struct wlan_objmgr_psoc *psoc)
9332{
9333}
9334#endif
9335
Dundi Raviteja8e338282018-09-25 17:16:04 +05309336/**
9337 * hdd_cfg_params_init() - Initialize hdd params in hdd_config strucuture
9338 * @hdd_ctx - Pointer to HDD context
9339 *
9340 * Return: None
9341 */
9342static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
9343{
9344 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
9345 struct hdd_config *config = hdd_ctx->config;
9346
9347 if (!psoc) {
9348 hdd_err("Invalid psoc");
9349 return;
9350 }
9351
9352 if (!config) {
9353 hdd_err("Invalid hdd config");
9354 return;
9355 }
9356
9357 config->bug_on_reinit_failure = cfg_get(psoc,
9358 CFG_BUG_ON_REINIT_FAILURE);
9359
9360 config->is_ramdump_enabled = cfg_get(psoc,
9361 CFG_ENABLE_RAMDUMP_COLLECTION);
9362
9363 config->iface_change_wait_time = cfg_get(psoc,
9364 CFG_INTERFACE_CHANGE_WAIT);
9365
9366 config->multicast_host_fw_msgs = cfg_get(psoc,
9367 CFG_MULTICAST_HOST_FW_MSGS);
9368
9369 config->private_wext_control = cfg_get(psoc, CFG_PRIVATE_WEXT_CONTROL);
9370 config->timer_multiplier = cfg_get(psoc, CFG_TIMER_MULTIPLIER);
9371 config->enablefwprint = cfg_get(psoc, CFG_ENABLE_FW_UART_PRINT);
9372 config->enable_fw_log = cfg_get(psoc, CFG_ENABLE_FW_LOG);
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +05309373 config->operating_channel = cfg_get(psoc, CFG_OPERATING_CHANNEL);
9374 config->num_vdevs = cfg_get(psoc, CFG_NUM_VDEV_ENABLE);
9375
9376 qdf_str_lcopy(config->enable_concurrent_sta,
9377 cfg_get(psoc, CFG_ENABLE_CONCURRENT_STA),
9378 CFG_CONCURRENT_IFACE_MAX_LEN);
9379 qdf_str_lcopy(config->dbs_scan_selection,
9380 cfg_get(psoc, CFG_DBS_SCAN_SELECTION),
9381 CFG_DBS_SCAN_PARAM_LENGTH);
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +05309382 config->inform_bss_rssi_raw = cfg_get(psoc, CFG_INFORM_BSS_RSSI_RAW);
Sourav Mohapatra58841062018-11-19 16:33:27 +05309383 config->intfMacAddr[0] = cfg_get(psoc, CFG_INTF0_MAC_ADDR);
9384 config->intfMacAddr[1] = cfg_get(psoc, CFG_INTF1_MAC_ADDR);
9385 config->intfMacAddr[2] = cfg_get(psoc, CFG_INTF2_MAC_ADDR);
9386 config->intfMacAddr[3] = cfg_get(psoc, CFG_INTF3_MAC_ADDR);
9387 config->action_oui_enable = cfg_get(psoc, CFG_ENABLE_ACTION_OUI);
9388
9389 qdf_str_lcopy(config->action_oui_str[0],
9390 cfg_get(psoc, CFG_ACTION_OUI_CONNECT_1X1),
9391 ACTION_OUI_MAX_STR_LEN);
9392 qdf_str_lcopy(config->action_oui_str[1],
9393 cfg_get(psoc, CFG_ACTION_OUI_ITO_EXTENSION),
9394 ACTION_OUI_MAX_STR_LEN);
9395 qdf_str_lcopy(config->action_oui_str[2],
9396 cfg_get(psoc, CFG_ACTION_OUI_CCKM_1X1),
9397 ACTION_OUI_MAX_STR_LEN);
9398 qdf_str_lcopy(config->action_oui_str[3],
9399 cfg_get(psoc, CFG_ACTION_OUI_ITO_ALTERNATE),
9400 ACTION_OUI_MAX_STR_LEN);
9401 qdf_str_lcopy(config->action_oui_str[4],
9402 cfg_get(psoc, CFG_ACTION_OUI_SWITCH_TO_11N_MODE),
9403 ACTION_OUI_MAX_STR_LEN);
9404 qdf_str_lcopy(config->action_oui_str[5],
9405 cfg_get(psoc,
9406 CFG_ACTION_OUI_CONNECT_1X1_WITH_1_CHAIN),
9407 ACTION_OUI_MAX_STR_LEN);
Dundi Raviteja8e338282018-09-25 17:16:04 +05309408
Sourav Mohapatra0dfe5552018-11-16 11:29:54 +05309409 hdd_init_vc_mode_cfg_bitmap(config, psoc);
9410 hdd_init_runtime_pm(config, psoc);
Dundi Raviteja8e338282018-09-25 17:16:04 +05309411 hdd_init_wlan_auto_shutdown(config, psoc);
9412 hdd_init_wlan_logging_params(config, psoc);
9413 hdd_init_packet_log(config, psoc);
jitiphil869b9f72018-09-25 17:14:01 +05309414 hdd_dp_cfg_update(psoc, hdd_ctx);
Dundi Raviteja8e338282018-09-25 17:16:04 +05309415}
9416
Dustin Brown623e7e32018-09-05 14:27:50 -07009417struct hdd_context *hdd_context_create(struct device *dev)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009418{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309419 QDF_STATUS status;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009420 int ret = 0;
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009421 struct hdd_context *hdd_ctx;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009422
Dustin Brown491d54b2018-03-14 12:39:11 -07009423 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009424
Dustin Brown92bd8382018-10-31 15:49:46 -07009425 hdd_ctx = hdd_cfg80211_wiphy_alloc();
9426 if (!hdd_ctx) {
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009427 ret = -ENOMEM;
9428 goto err_out;
9429 }
9430
Dustin Brown4c663222018-10-23 14:19:36 -07009431 qdf_create_delayed_work(&hdd_ctx->psoc_idle_timeout_work,
Dustin Brown3ecc8782018-09-19 16:37:13 -07009432 hdd_psoc_idle_timeout_callback,
Dustin Brown4c663222018-10-23 14:19:36 -07009433 hdd_ctx);
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309434
9435 mutex_init(&hdd_ctx->iface_change_lock);
9436
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009437 hdd_ctx->parent_dev = dev;
Sreelakshmi Konamkib53c6292017-03-01 13:13:23 +05309438 hdd_ctx->last_scan_reject_session_id = 0xFF;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009439
Anurag Chouhan600c3a02016-03-01 10:33:54 +05309440 hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config));
Min Liu74a1a502018-10-10 19:59:07 +08009441 if (!hdd_ctx->config) {
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009442 ret = -ENOMEM;
9443 goto err_free_hdd_context;
9444 }
9445
9446 /* Read and parse the qcom_cfg.ini file */
9447 status = hdd_parse_config_ini(hdd_ctx);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309448 if (QDF_STATUS_SUCCESS != status) {
Arun Khandavallifae92942016-08-01 13:31:08 +05309449 hdd_err("Error (status: %d) parsing INI file: %s", status,
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009450 WLAN_INI_FILE);
9451 ret = -EINVAL;
9452 goto err_free_config;
9453 }
9454
Dustin Brown84f46ea2018-02-15 11:57:36 -08009455 status = cfg_parse(WLAN_INI_FILE);
9456 if (QDF_IS_STATUS_ERROR(status))
9457 hdd_err("Failed to parse cfg %s; status:%d\n",
9458 WLAN_INI_FILE, status);
9459
Dundi Ravitejafb9357a2018-09-25 12:16:03 +05309460 ret = hdd_objmgr_create_and_store_psoc(hdd_ctx, DEFAULT_PSOC_ID);
9461 if (ret) {
Dundi Raviteja8e338282018-09-25 17:16:04 +05309462 QDF_DEBUG_PANIC("Psoc creation fails!");
Dundi Ravitejafb9357a2018-09-25 12:16:03 +05309463 goto err_free_config;
9464 }
9465
Dundi Raviteja8e338282018-09-25 17:16:04 +05309466 hdd_cfg_params_init(hdd_ctx);
9467
Dustin Brown7f939932017-05-18 15:02:17 -07009468 hdd_debug("setting timer multiplier: %u",
9469 hdd_ctx->config->timer_multiplier);
9470 qdf_timer_set_multiplier(hdd_ctx->config->timer_multiplier);
9471
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309472 cds_set_fatal_event(cfg_get(hdd_ctx->psoc,
9473 CFG_ENABLE_FATAL_EVENT_TRIGGER));
Abhishek Singh5ea86532016-04-27 14:10:53 +05309474
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009475 hdd_override_ini_config(hdd_ctx);
9476
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009477 ret = hdd_context_init(hdd_ctx);
9478
9479 if (ret)
Dundi Ravitejafb9357a2018-09-25 12:16:03 +05309480 goto err_hdd_objmgr_destroy;
Prashanth Bhatta527fd752016-04-28 12:35:23 -07009481
Anurag Chouhan6d760662016-02-20 16:05:43 +05309482 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009483 goto skip_multicast_logging;
9484
9485 cds_set_multicast_logging(hdd_ctx->config->multicast_host_fw_msgs);
9486
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07009487 ret = wlan_hdd_init_tx_rx_histogram(hdd_ctx);
9488 if (ret)
9489 goto err_deinit_hdd_context;
Nirav Shahed34b212016-04-25 10:59:16 +05309490
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -07009491 ret = hdd_init_netlink_services(hdd_ctx);
9492 if (ret)
9493 goto err_deinit_txrx_histogram;
9494
Nirav Shaheb017be2018-02-15 11:20:58 +05309495 hdd_set_wlan_logging(hdd_ctx);
Nirav Shahed34b212016-04-25 10:59:16 +05309496
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009497skip_multicast_logging:
9498 hdd_set_trace_level_for_each(hdd_ctx);
9499
Rajeev Kumar493a31b2017-09-29 14:01:24 -07009500 cds_set_context(QDF_MODULE_ID_HDD, hdd_ctx);
9501
Dustin Browne74003f2018-03-14 12:51:58 -07009502 hdd_exit();
Mahesh Kumar Kalikot Veetilb85cefd2017-08-14 14:03:32 -07009503
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009504 return hdd_ctx;
9505
Houston Hoffmanb18dc6e2017-08-11 17:43:07 -07009506err_deinit_txrx_histogram:
9507 wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
9508
Rajeev Kumarfb02a5e2016-09-20 16:16:17 -07009509err_deinit_hdd_context:
9510 hdd_context_deinit(hdd_ctx);
9511
Dundi Ravitejafb9357a2018-09-25 12:16:03 +05309512err_hdd_objmgr_destroy:
9513 hdd_objmgr_release_and_destroy_psoc(hdd_ctx);
9514
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009515err_free_config:
Anurag Chouhan600c3a02016-03-01 10:33:54 +05309516 qdf_mem_free(hdd_ctx->config);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009517
9518err_free_hdd_context:
Sourav Mohapatrafed6aa92017-11-14 18:05:11 +05309519 mutex_destroy(&hdd_ctx->iface_change_lock);
Rajeev Kumarfa55a692018-01-09 14:12:41 -08009520 wiphy_free(hdd_ctx->wiphy);
Prashanth Bhattac2a16f62015-12-03 15:06:15 -08009521
9522err_out:
9523 return ERR_PTR(ret);
9524}
9525
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009526#ifdef WLAN_OPEN_P2P_INTERFACE
9527/**
9528 * hdd_open_p2p_interface - Open P2P interface
Dustin Brown61cc3932018-10-18 16:12:13 -07009529 * @hdd_ctx: HDD context
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009530 *
Dustin Brown61cc3932018-10-18 16:12:13 -07009531 * Return: QDF_STATUS
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009532 */
Dustin Brown61cc3932018-10-18 16:12:13 -07009533static QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009534{
Jeff Johnson9d295242017-08-29 14:39:48 -07009535 struct hdd_adapter *adapter;
Dustin Brown61cc3932018-10-18 16:12:13 -07009536 bool p2p_dev_addr_admin;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009537
Dustin Brown1dbefe62018-09-11 16:32:03 -07009538 cfg_p2p_get_device_addr_admin(hdd_ctx->psoc, &p2p_dev_addr_admin);
Dustin Brown61cc3932018-10-18 16:12:13 -07009539
Wu Gaoe5689792018-07-05 19:20:13 +08009540 if (p2p_dev_addr_admin &&
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009541 !(hdd_ctx->config->intfMacAddr[0].bytes[0] & 0x02)) {
Dustin Brown61cc3932018-10-18 16:12:13 -07009542 hdd_ctx->p2p_device_address = hdd_ctx->config->intfMacAddr[0];
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009543
9544 /*
Dustin Brown61cc3932018-10-18 16:12:13 -07009545 * Generate the P2P Device Address. This consists of
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009546 * the device's primary MAC address with the locally
9547 * administered bit set.
9548 */
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07009549 hdd_ctx->p2p_device_address.bytes[0] |= 0x02;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009550 } else {
Dustin Brown61cc3932018-10-18 16:12:13 -07009551 uint8_t *p2p_dev_addr;
9552
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009553 p2p_dev_addr = wlan_hdd_get_intf_addr(hdd_ctx);
Dustin Brown61cc3932018-10-18 16:12:13 -07009554 if (!p2p_dev_addr) {
9555 hdd_err("Failed to get MAC address for new p2p device");
9556 return QDF_STATUS_E_INVAL;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009557 }
9558
Dustin Brown61cc3932018-10-18 16:12:13 -07009559 qdf_mem_copy(hdd_ctx->p2p_device_address.bytes,
Jeff Johnsonacbdb1c2017-11-02 20:42:02 -07009560 p2p_dev_addr, QDF_MAC_ADDR_SIZE);
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009561 }
9562
Krunal Soni9b04c9b2016-03-10 13:08:05 -08009563 adapter = hdd_open_adapter(hdd_ctx, QDF_P2P_DEVICE_MODE, "p2p%d",
Dustin Brown61cc3932018-10-18 16:12:13 -07009564 hdd_ctx->p2p_device_address.bytes,
9565 NET_NAME_UNKNOWN, true);
9566 if (!adapter) {
9567 hdd_err("Failed to open p2p interface");
9568 return QDF_STATUS_E_INVAL;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009569 }
9570
Dustin Brown61cc3932018-10-18 16:12:13 -07009571 return QDF_STATUS_SUCCESS;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009572}
9573#else
Dustin Brown61cc3932018-10-18 16:12:13 -07009574static inline QDF_STATUS hdd_open_p2p_interface(struct hdd_context *hdd_ctx)
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009575{
Dustin Brown61cc3932018-10-18 16:12:13 -07009576 return QDF_STATUS_SUCCESS;
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009577}
9578#endif
9579
Dustin Brown61cc3932018-10-18 16:12:13 -07009580static QDF_STATUS hdd_open_ocb_interface(struct hdd_context *hdd_ctx)
Jeff Johnson957bc272017-02-02 08:54:48 -08009581{
Jeff Johnson9d295242017-08-29 14:39:48 -07009582 struct hdd_adapter *adapter;
Jeff Johnson957bc272017-02-02 08:54:48 -08009583
9584 adapter = hdd_open_adapter(hdd_ctx, QDF_OCB_MODE, "wlanocb%d",
9585 wlan_hdd_get_intf_addr(hdd_ctx),
Dustin Brown61cc3932018-10-18 16:12:13 -07009586 NET_NAME_UNKNOWN, true);
9587 if (!adapter) {
Jeff Johnson957bc272017-02-02 08:54:48 -08009588 hdd_err("Failed to open 802.11p interface");
Dustin Brown61cc3932018-10-18 16:12:13 -07009589 return QDF_STATUS_E_INVAL;
Jeff Johnson957bc272017-02-02 08:54:48 -08009590 }
9591
Dustin Brown61cc3932018-10-18 16:12:13 -07009592 return QDF_STATUS_SUCCESS;
9593}
9594
9595static QDF_STATUS hdd_open_concurrent_interface(struct hdd_context *hdd_ctx)
9596{
9597 struct hdd_adapter *adapter;
9598
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +05309599 if (qdf_str_eq(hdd_ctx->config->enable_concurrent_sta, ""))
Dustin Brown61cc3932018-10-18 16:12:13 -07009600 return QDF_STATUS_SUCCESS;
9601
9602 adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE,
Vignesh Viswanathana0358ff2018-11-27 09:53:07 +05309603 hdd_ctx->config->enable_concurrent_sta,
Dustin Brown61cc3932018-10-18 16:12:13 -07009604 wlan_hdd_get_intf_addr(hdd_ctx),
9605 NET_NAME_UNKNOWN, true);
9606 if (!adapter) {
9607 hdd_err("Failed to open concurrent station interface");
9608 return QDF_STATUS_E_INVAL;
9609 }
9610
9611 return QDF_STATUS_SUCCESS;
Jeff Johnson957bc272017-02-02 08:54:48 -08009612}
9613
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009614/**
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309615 * hdd_start_station_adapter()- Start the Station Adapter
9616 * @adapter: HDD adapter
9617 *
9618 * This function initializes the adapter for the station mode.
9619 *
9620 * Return: 0 on success or errno on failure.
9621 */
Jeff Johnson9d295242017-08-29 14:39:48 -07009622int hdd_start_station_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309623{
9624 QDF_STATUS status;
Krunal Sonib51eec72017-11-20 21:53:01 -08009625 int ret;
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309626
Dustin Brownfdf17c12018-03-14 12:55:34 -07009627 hdd_enter_dev(adapter->dev);
Krunal Sonib51eec72017-11-20 21:53:01 -08009628 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
9629 hdd_err("session is already opened, %d",
9630 adapter->session_id);
9631 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
9632 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309633
Krunal Sonib51eec72017-11-20 21:53:01 -08009634 ret = hdd_vdev_create(adapter, hdd_sme_roam_callback, adapter);
9635 if (ret) {
9636 hdd_err("failed to create vdev: %d", ret);
9637 return ret;
9638 }
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309639 status = hdd_init_station_mode(adapter);
9640
9641 if (QDF_STATUS_SUCCESS != status) {
9642 hdd_err("Error Initializing station mode: %d", status);
9643 return qdf_status_to_os_return(status);
9644 }
9645
Arun Khandavallifae92942016-08-01 13:31:08 +05309646 hdd_register_tx_flow_control(adapter,
9647 hdd_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08009648 hdd_tx_resume_cb,
9649 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +05309650
Dustin Browne74003f2018-03-14 12:51:58 -07009651 hdd_exit();
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +05309652
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309653 return 0;
9654}
9655
9656/**
9657 * hdd_start_ap_adapter()- Start AP Adapter
9658 * @adapter: HDD adapter
9659 *
9660 * This function initializes the adapter for the AP mode.
9661 *
9662 * Return: 0 on success errno on failure.
9663 */
Jeff Johnson9d295242017-08-29 14:39:48 -07009664int hdd_start_ap_adapter(struct hdd_adapter *adapter)
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309665{
9666 QDF_STATUS status;
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08009667 bool is_ssr = false;
Krunal Sonib51eec72017-11-20 21:53:01 -08009668 int ret;
Naveen Rawat1af09392018-01-03 17:28:21 -08009669 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
Arif Hussainbd5194c2018-11-27 19:01:15 -08009670 uint32_t fine_time_meas_cap = 0;
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309671
Dustin Brown491d54b2018-03-14 12:39:11 -07009672 hdd_enter();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309673
Krunal Sonib51eec72017-11-20 21:53:01 -08009674 if (test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
9675 hdd_err("session is already opened, %d",
9676 adapter->session_id);
9677 return qdf_status_to_os_return(QDF_STATUS_SUCCESS);
9678 }
9679 /*
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08009680 * In SSR case no need to create new sap context.
9681 * Otherwise create sap context first and then create
9682 * vdev as while creating the vdev, driver needs to
9683 * register SAP callback and that callback uses sap context
Krunal Sonib51eec72017-11-20 21:53:01 -08009684 */
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08009685 if (adapter->session.ap.sap_context) {
9686 is_ssr = true;
9687 } else if (!hdd_sap_create_ctx(adapter)) {
Krunal Sonib51eec72017-11-20 21:53:01 -08009688 hdd_err("sap creation failed");
9689 return qdf_status_to_os_return(QDF_STATUS_E_FAILURE);
9690 }
9691
9692 ret = hdd_vdev_create(adapter, wlansap_roam_callback,
9693 adapter->session.ap.sap_context);
9694 if (ret) {
9695 hdd_err("failed to create vdev, status:%d", ret);
9696 hdd_sap_destroy_ctx(adapter);
9697 return ret;
9698 }
Naveen Rawat1af09392018-01-03 17:28:21 -08009699
Arif Hussainbd5194c2018-11-27 19:01:15 -08009700 if (adapter->device_mode == QDF_SAP_MODE) {
9701 ucfg_mlme_get_fine_time_meas_cap(hdd_ctx->psoc,
9702 &fine_time_meas_cap);
Naveen Rawat1af09392018-01-03 17:28:21 -08009703 sme_cli_set_command(adapter->session_id,
9704 WMI_VDEV_PARAM_ENABLE_DISABLE_RTT_RESPONDER_ROLE,
Arif Hussainbd5194c2018-11-27 19:01:15 -08009705 (bool)(fine_time_meas_cap & WMI_FW_AP_RTT_RESPR),
Naveen Rawat1af09392018-01-03 17:28:21 -08009706 VDEV_CMD);
Arif Hussainbd5194c2018-11-27 19:01:15 -08009707 }
Naveen Rawat1af09392018-01-03 17:28:21 -08009708
Tushnim Bhattacharyya18b0eaa2017-11-27 18:33:50 -08009709 status = hdd_init_ap_mode(adapter, is_ssr);
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309710
9711 if (QDF_STATUS_SUCCESS != status) {
9712 hdd_err("Error Initializing the AP mode: %d", status);
9713 return qdf_status_to_os_return(status);
9714 }
9715
Arun Khandavallifae92942016-08-01 13:31:08 +05309716 hdd_register_tx_flow_control(adapter,
9717 hdd_softap_tx_resume_timer_expired_handler,
bings284f8be2017-08-11 10:41:30 +08009718 hdd_softap_tx_resume_cb,
9719 hdd_tx_flow_control_is_pause);
Arun Khandavallifae92942016-08-01 13:31:08 +05309720
Dustin Browne74003f2018-03-14 12:51:58 -07009721 hdd_exit();
Arun Khandavalli7e857c32016-06-26 12:07:16 +05309722 return 0;
9723}
9724
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309725#ifdef QCA_LL_TX_FLOW_CONTROL_V2
9726/**
9727 * hdd_txrx_populate_cds_config() - Populate txrx cds configuration
9728 * @cds_cfg: CDS Configuration
9729 * @hdd_ctx: Pointer to hdd context
9730 *
9731 * Return: none
9732 */
9733static inline void hdd_txrx_populate_cds_config(struct cds_config_info
9734 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009735 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309736{
9737 cds_cfg->tx_flow_stop_queue_th =
jitiphil47c3d9a2018-11-08 18:30:55 +05309738 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309739 cds_cfg->tx_flow_start_queue_offset =
jitiphil47c3d9a2018-11-08 18:30:55 +05309740 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
Mohit Khanna70322002018-05-15 19:21:32 -07009741 /* configuration for DP RX Threads */
9742 cds_cfg->enable_dp_rx_threads = hdd_ctx->enable_dp_rx_threads;
9743 cds_cfg->num_dp_rx_threads = hdd_ctx->config->num_dp_rx_threads;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309744}
9745#else
9746static inline void hdd_txrx_populate_cds_config(struct cds_config_info
9747 *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009748 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309749{
9750}
9751#endif
9752
9753#ifdef FEATURE_WLAN_RA_FILTERING
9754/**
9755 * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
9756 * @cds_cfg: CDS Configuration
9757 * @hdd_ctx: Pointer to hdd context
9758 *
9759 * Return: none
9760 */
Anand Kumar3b92a912016-12-05 12:01:26 +05309761static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009762 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309763{
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05309764 bool is_rate_limit_enabled;
9765 QDF_STATUS status;
9766
9767 status = ucfg_fwol_get_is_rate_limit_enabled(hdd_ctx->psoc,
9768 &is_rate_limit_enabled);
9769 if (QDF_IS_STATUS_ERROR(status))
9770 return;
9771
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309772 cds_cfg->ra_ratelimit_interval =
9773 hdd_ctx->config->RArateLimitInterval;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +05309774 cds_cfg->is_ra_ratelimit_enabled = is_rate_limit_enabled;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309775}
9776#else
Anand Kumar3b92a912016-12-05 12:01:26 +05309777static inline void hdd_ra_populate_cds_config(struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009778 struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309779{
9780}
9781#endif
9782
9783/**
9784 * hdd_update_cds_config() - API to update cds configuration parameters
9785 * @hdd_ctx: HDD Context
9786 *
9787 * Return: 0 for Success, errno on failure
9788 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009789static int hdd_update_cds_config(struct hdd_context *hdd_ctx)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309790{
9791 struct cds_config_info *cds_cfg;
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309792 int value;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309793 uint8_t band_capability;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309794 uint8_t ito_repeat_count;
Vignesh Viswanathana851d752018-10-03 19:44:38 +05309795 bool crash_inject;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309796 bool self_recovery;
9797 bool fw_timeout_crash;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309798 QDF_STATUS status;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309799
Min Liu74a1a502018-10-10 19:59:07 +08009800 cds_cfg = qdf_mem_malloc(sizeof(*cds_cfg));
9801 if (!cds_cfg)
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309802 return -ENOMEM;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309803
Srinivas Girigowda35b00312017-06-27 21:52:03 -07009804 cds_cfg->driver_type = QDF_DRIVER_TYPE_PRODUCTION;
Bala Venkatesh46e29032018-11-14 18:24:55 +05309805 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
9806 &cds_cfg->sta_maxlimod_dtim);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309807
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309808 status = ucfg_mlme_get_crash_inject(hdd_ctx->psoc, &crash_inject);
Vignesh Viswanathana851d752018-10-03 19:44:38 +05309809 if (QDF_IS_STATUS_ERROR(status)) {
9810 hdd_err("Failed to get crash inject ini config");
9811 goto exit;
9812 }
9813
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309814 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
9815 if (QDF_IS_STATUS_ERROR(status)) {
9816 hdd_err("Failed to get self recovery ini config");
9817 goto exit;
9818 }
9819
9820 status = ucfg_mlme_get_fw_timeout_crash(hdd_ctx->psoc,
9821 &fw_timeout_crash);
9822 if (QDF_IS_STATUS_ERROR(status)) {
9823 hdd_err("Failed to get fw timeout crash ini config");
9824 goto exit;
9825 }
9826
9827 status = ucfg_mlme_get_ito_repeat_count(hdd_ctx->psoc,
9828 &ito_repeat_count);
9829 if (QDF_IS_STATUS_ERROR(status)) {
9830 hdd_err("Failed to get ITO repeat count ini config");
9831 goto exit;
9832 }
9833
Vignesh Viswanathana851d752018-10-03 19:44:38 +05309834 cds_cfg->force_target_assert_enabled = crash_inject;
SaidiReddy Yenugacc733af2016-11-09 17:45:42 +05309835
Dustin Brown05d81302018-09-11 16:49:22 -07009836 ucfg_mlme_get_sap_max_offload_peers(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309837 cds_cfg->ap_maxoffload_peers = value;
Dustin Brown05d81302018-09-11 16:49:22 -07009838 ucfg_mlme_get_sap_max_offload_reorder_buffs(hdd_ctx->psoc,
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309839 &value);
9840 cds_cfg->ap_maxoffload_reorderbuffs = value;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309841
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309842 cds_cfg->reorder_offload =
jitiphil47c3d9a2018-11-08 18:30:55 +05309843 cfg_get(hdd_ctx->psoc, CFG_DP_REORDER_OFFLOAD_SUPPORT);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309844
9845 /* IPA micro controller data path offload resource config item */
Sravan Kumar Kairam5214f652018-03-13 09:52:31 +05309846 cds_cfg->uc_offload_enabled = ucfg_ipa_uc_is_enabled();
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309847 cds_cfg->max_scan = hdd_ctx->config->max_scan_count;
9848
Jeff Johnsone2ba3cd2017-10-30 20:02:09 -07009849 cds_cfg->enable_rxthread = hdd_ctx->enable_rxthread;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309850 cds_cfg->self_gen_frm_pwr = hdd_ctx->config->self_gen_frm_pwr;
Dustin Brown05d81302018-09-11 16:49:22 -07009851 ucfg_mlme_get_sap_max_peers(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +05309852 cds_cfg->max_station = value;
Naveen Rawat64e477e2016-05-20 10:34:56 -07009853 cds_cfg->sub_20_channel_width = WLAN_SUB_20_CH_WIDTH_NONE;
Orhan K AKYILDIZ30e8cbc2017-08-11 18:00:28 -07009854 cds_cfg->max_msdus_per_rxinorderind =
jitiphil8e15ea62018-11-16 18:05:34 +05309855 cfg_get(hdd_ctx->psoc, CFG_DP_MAX_MSDUS_PER_RXIND);
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309856 cds_cfg->self_recovery_enabled = self_recovery;
9857 cds_cfg->fw_timeout_crash = fw_timeout_crash;
Nachiket Kukadee547a482018-05-22 16:43:30 +05309858 cds_cfg->active_uc_apf_mode = hdd_ctx->config->active_uc_apf_mode;
9859 cds_cfg->active_mc_bc_apf_mode = hdd_ctx->config->active_mc_bc_apf_mode;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309860
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +05309861 cds_cfg->ito_repeat_count = ito_repeat_count;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309862
9863 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
9864 if (QDF_IS_STATUS_ERROR(status))
9865 goto exit;
9866
9867 cds_cfg->bandcapability = band_capability;
Rachit Kankane0106e382018-05-16 18:59:28 +05309868 cds_cfg->num_vdevs = hdd_ctx->config->num_vdevs;
Ashish Kumar Dhanotiya9335d812017-06-30 16:57:20 +05309869
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309870 hdd_ra_populate_cds_config(cds_cfg, hdd_ctx);
9871 hdd_txrx_populate_cds_config(cds_cfg, hdd_ctx);
Jeff Johnson9078bdc2016-09-23 17:18:11 -07009872 hdd_lpass_populate_cds_config(cds_cfg, hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309873 cds_init_ini_config(cds_cfg);
9874 return 0;
SaidiReddy Yenuga466b3ce2017-05-02 18:50:25 +05309875
9876exit:
9877 qdf_mem_free(cds_cfg);
9878 return -EINVAL;
Arun Khandavallic811dcc2016-06-26 07:37:21 +05309879}
9880
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009881/**
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009882 * hdd_update_user_config() - API to update user configuration
9883 * parameters to obj mgr which are used by multiple components
9884 * @hdd_ctx: HDD Context
9885 *
9886 * Return: 0 for Success, errno on failure
9887 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009888static int hdd_update_user_config(struct hdd_context *hdd_ctx)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009889{
9890 struct wlan_objmgr_psoc_user_config *user_config;
Wu Gaoe5689792018-07-05 19:20:13 +08009891 bool skip_dfs_in_p2p_search = false;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309892 uint8_t band_capability;
Krunal Sonidf29bc42018-11-15 13:26:29 -08009893 uint8_t dual_mac_feature = DISABLE_DBS_CXN_AND_SCAN;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309894 QDF_STATUS status;
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309895 bool value = false;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309896
9897 status = ucfg_mlme_get_band_capability(hdd_ctx->psoc, &band_capability);
9898 if (QDF_IS_STATUS_ERROR(status))
9899 return -EIO;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009900
Krunal Sonidf29bc42018-11-15 13:26:29 -08009901 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
9902 &dual_mac_feature);
9903 if (QDF_IS_STATUS_ERROR(status))
9904 return -EIO;
9905
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009906 user_config = qdf_mem_malloc(sizeof(*user_config));
Min Liu74a1a502018-10-10 19:59:07 +08009907 if (!user_config)
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009908 return -ENOMEM;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009909
9910 user_config->dot11_mode = hdd_ctx->config->dot11Mode;
Krunal Sonidf29bc42018-11-15 13:26:29 -08009911 user_config->dual_mac_feature_disable = dual_mac_feature;
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009912 user_config->indoor_channel_support =
9913 hdd_ctx->config->indoor_channel_support;
Abhinav Kumard4d6eb72018-12-04 20:30:37 +05309914
9915 status = ucfg_mlme_is_11d_enabled(hdd_ctx->psoc, &value);
9916 if (!QDF_IS_STATUS_SUCCESS(status))
9917 hdd_err("Invalid 11d_enable flag");
9918 user_config->is_11d_support_enabled = value;
9919
9920 value = false;
9921 status = ucfg_mlme_is_11h_enabled(hdd_ctx->psoc, &value);
9922 if (!QDF_IS_STATUS_SUCCESS(status))
9923 hdd_err("Invalid 11h_enable flag");
9924 user_config->is_11h_support_enabled = value;
9925
Dustin Brown1dbefe62018-09-11 16:32:03 -07009926 cfg_p2p_get_skip_dfs_channel_p2p_search(hdd_ctx->psoc,
Wu Gaoe5689792018-07-05 19:20:13 +08009927 &skip_dfs_in_p2p_search);
9928 user_config->skip_dfs_chnl_in_p2p_search = skip_dfs_in_p2p_search;
Vignesh Viswanathanf97cc112018-10-03 19:17:07 +05309929 user_config->band_capability = band_capability;
Dustin Brown1dbefe62018-09-11 16:32:03 -07009930 wlan_objmgr_psoc_set_user_config(hdd_ctx->psoc, user_config);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -08009931
9932 qdf_mem_free(user_config);
9933 return 0;
9934}
9935
9936/**
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009937 * hdd_init_thermal_info - Initialize thermal level
9938 * @hdd_ctx: HDD context
9939 *
9940 * Initialize thermal level at SME layer and set the thermal level callback
9941 * which would be called when a configured thermal threshold is hit.
9942 *
9943 * Return: 0 on success and errno on failure
9944 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -07009945static int hdd_init_thermal_info(struct hdd_context *hdd_ctx)
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009946{
9947 tSmeThermalParams thermal_param;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309948 QDF_STATUS status;
Jeff Johnson16528362018-06-14 12:34:16 -07009949 mac_handle_t mac_handle;
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309950 struct wlan_fwol_thermal_temp thermal_temp = {0};
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009951
9952 thermal_param.smeThermalMgmtEnabled =
9953 hdd_ctx->config->thermalMitigationEnable;
9954 thermal_param.smeThrottlePeriod = hdd_ctx->config->throttlePeriod;
9955
Poddar, Siddarth83905022016-04-16 17:56:08 -07009956 thermal_param.sme_throttle_duty_cycle_tbl[0] =
9957 hdd_ctx->config->throttle_dutycycle_level0;
9958 thermal_param.sme_throttle_duty_cycle_tbl[1] =
9959 hdd_ctx->config->throttle_dutycycle_level1;
9960 thermal_param.sme_throttle_duty_cycle_tbl[2] =
9961 hdd_ctx->config->throttle_dutycycle_level2;
9962 thermal_param.sme_throttle_duty_cycle_tbl[3] =
9963 hdd_ctx->config->throttle_dutycycle_level3;
9964
Dustin Brown05d81302018-09-11 16:49:22 -07009965 status = ucfg_fwol_get_thermal_temp(hdd_ctx->psoc, &thermal_temp);
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309966 if (QDF_IS_STATUS_ERROR(status))
9967 return qdf_status_to_os_return(status);
9968
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009969 thermal_param.smeThermalLevels[0].smeMinTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309970 thermal_temp.thermal_temp_min_level0;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009971 thermal_param.smeThermalLevels[0].smeMaxTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309972 thermal_temp.thermal_temp_max_level0;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009973 thermal_param.smeThermalLevels[1].smeMinTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309974 thermal_temp.thermal_temp_min_level1;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009975 thermal_param.smeThermalLevels[1].smeMaxTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309976 thermal_temp.thermal_temp_max_level1;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009977 thermal_param.smeThermalLevels[2].smeMinTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309978 thermal_temp.thermal_temp_min_level2;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009979 thermal_param.smeThermalLevels[2].smeMaxTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309980 thermal_temp.thermal_temp_max_level2;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009981 thermal_param.smeThermalLevels[3].smeMinTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309982 thermal_temp.thermal_temp_min_level3;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009983 thermal_param.smeThermalLevels[3].smeMaxTempThreshold =
Dundi Raviteja47ac7092018-09-07 10:40:28 +05309984 thermal_temp.thermal_temp_max_level3;
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009985
Jeff Johnson16528362018-06-14 12:34:16 -07009986 mac_handle = hdd_ctx->mac_handle;
9987 status = sme_init_thermal_info(mac_handle, thermal_param);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009988
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05309989 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanc5548422016-02-24 18:33:27 +05309990 return qdf_status_to_os_return(status);
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009991
Jeff Johnson16528362018-06-14 12:34:16 -07009992 sme_add_set_thermal_level_callback(mac_handle,
Prashanth Bhatta5f7c9b82016-01-09 13:15:21 -08009993 hdd_set_thermal_level_cb);
9994
9995 return 0;
9996
9997}
9998
Prashanth Bhatta98f04d22016-01-08 16:46:21 -08009999#if defined(CONFIG_HDD_INIT_WITH_RTNL_LOCK)
10000/**
10001 * hdd_hold_rtnl_lock - Hold RTNL lock
10002 *
10003 * Hold RTNL lock
10004 *
10005 * Return: True if held and false otherwise
10006 */
10007static inline bool hdd_hold_rtnl_lock(void)
10008{
10009 rtnl_lock();
10010 return true;
10011}
10012
10013/**
10014 * hdd_release_rtnl_lock - Release RTNL lock
10015 *
10016 * Release RTNL lock
10017 *
10018 * Return: None
10019 */
10020static inline void hdd_release_rtnl_lock(void)
10021{
10022 rtnl_unlock();
10023}
10024#else
10025static inline bool hdd_hold_rtnl_lock(void) { return false; }
10026static inline void hdd_release_rtnl_lock(void) { }
10027#endif
10028
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010029#if !defined(REMOVE_PKT_LOG)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010030
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010031/* MAX iwpriv command support */
10032#define PKTLOG_SET_BUFF_SIZE 3
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010033#define PKTLOG_CLEAR_BUFF 4
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010034#define MAX_PKTLOG_SIZE 16
10035
10036/**
10037 * hdd_pktlog_set_buff_size() - set pktlog buffer size
10038 * @hdd_ctx: hdd context
10039 * @set_value2: pktlog buffer size value
10040 *
10041 *
10042 * Return: 0 for success or error.
10043 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010044static int hdd_pktlog_set_buff_size(struct hdd_context *hdd_ctx, int set_value2)
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010045{
10046 struct sir_wifi_start_log start_log = { 0 };
10047 QDF_STATUS status;
10048
10049 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10050 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
10051 start_log.ini_triggered = cds_is_packet_log_enabled();
10052 start_log.user_triggered = 1;
10053 start_log.size = set_value2;
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010054 start_log.is_pktlog_buff_clear = false;
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010055
Jeff Johnson16528362018-06-14 12:34:16 -070010056 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010057 if (!QDF_IS_STATUS_SUCCESS(status)) {
10058 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010059 hdd_exit();
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010060 return -EINVAL;
10061 }
10062
10063 return 0;
10064}
10065
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010066/**
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010067 * hdd_pktlog_clear_buff() - clear pktlog buffer
10068 * @hdd_ctx: hdd context
10069 *
10070 * Return: 0 for success or error.
10071 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010072static int hdd_pktlog_clear_buff(struct hdd_context *hdd_ctx)
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010073{
10074 struct sir_wifi_start_log start_log;
10075 QDF_STATUS status;
10076
10077 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10078 start_log.verbose_level = WLAN_LOG_LEVEL_OFF;
10079 start_log.ini_triggered = cds_is_packet_log_enabled();
10080 start_log.user_triggered = 1;
10081 start_log.size = 0;
10082 start_log.is_pktlog_buff_clear = true;
10083
Jeff Johnson16528362018-06-14 12:34:16 -070010084 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010085 if (!QDF_IS_STATUS_SUCCESS(status)) {
10086 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010087 hdd_exit();
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010088 return -EINVAL;
10089 }
10090
10091 return 0;
10092}
10093
10094
10095/**
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010096 * hdd_process_pktlog_command() - process pktlog command
10097 * @hdd_ctx: hdd context
10098 * @set_value: value set by user
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010099 * @set_value2: pktlog buffer size value
10100 *
10101 * This function process pktlog command.
10102 * set_value2 only matters when set_value is 3 (set buff size)
10103 * otherwise we ignore it.
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010104 *
10105 * Return: 0 for success or error.
10106 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010107int hdd_process_pktlog_command(struct hdd_context *hdd_ctx, uint32_t set_value,
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010108 int set_value2)
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010109{
10110 int ret;
10111 bool enable;
10112 uint8_t user_triggered = 0;
10113
10114 ret = wlan_hdd_validate_context(hdd_ctx);
10115 if (0 != ret)
10116 return ret;
10117
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010118 hdd_debug("set pktlog %d, set size %d", set_value, set_value2);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010119
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010120 if (set_value > PKTLOG_CLEAR_BUFF) {
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010121 hdd_err("invalid pktlog value %d", set_value);
10122 return -EINVAL;
10123 }
10124
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010125 if (set_value == PKTLOG_SET_BUFF_SIZE) {
10126 if (set_value2 <= 0) {
10127 hdd_err("invalid pktlog size %d", set_value2);
10128 return -EINVAL;
10129 } else if (set_value2 > MAX_PKTLOG_SIZE) {
10130 hdd_err("Pktlog buff size is too large. max value is 16MB.\n");
10131 return -EINVAL;
10132 }
10133 return hdd_pktlog_set_buff_size(hdd_ctx, set_value2);
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010134 } else if (set_value == PKTLOG_CLEAR_BUFF) {
10135 return hdd_pktlog_clear_buff(hdd_ctx);
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010136 }
10137
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010138 /*
10139 * set_value = 0 then disable packetlog
10140 * set_value = 1 enable packetlog forcefully
10141 * set_vlaue = 2 then disable packetlog if disabled through ini or
10142 * enable packetlog with AUTO type.
10143 */
10144 enable = ((set_value > 0) && cds_is_packet_log_enabled()) ?
10145 true : false;
10146
10147 if (1 == set_value) {
10148 enable = true;
10149 user_triggered = 1;
10150 }
10151
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010152 return hdd_pktlog_enable_disable(hdd_ctx, enable, user_triggered, 0);
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010153}
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070010154
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010155/**
10156 * hdd_pktlog_enable_disable() - Enable/Disable packet logging
10157 * @hdd_ctx: HDD context
10158 * @enable: Flag to enable/disable
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010159 * @user_triggered: triggered through iwpriv
10160 * @size: buffer size to be used for packetlog
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010161 *
10162 * Return: 0 on success; error number otherwise
10163 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010164int hdd_pktlog_enable_disable(struct hdd_context *hdd_ctx, bool enable,
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010165 uint8_t user_triggered, int size)
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010166{
10167 struct sir_wifi_start_log start_log;
10168 QDF_STATUS status;
10169
10170 start_log.ring_id = RING_ID_PER_PACKET_STATS;
10171 start_log.verbose_level =
10172 enable ? WLAN_LOG_LEVEL_ACTIVE : WLAN_LOG_LEVEL_OFF;
Srinivas Girigowdac34f11d2016-02-25 16:02:42 -080010173 start_log.ini_triggered = cds_is_packet_log_enabled();
10174 start_log.user_triggered = user_triggered;
Poddar, Siddarth176c4362016-10-03 12:25:00 +053010175 start_log.size = size;
Poddar, Siddarthab99a272017-04-10 12:53:26 +053010176 start_log.is_pktlog_buff_clear = false;
Poddar, Siddartheefe3482016-09-21 18:12:59 +053010177 /*
10178 * Use "is_iwpriv_command" flag to distinguish iwpriv command from other
10179 * commands. Host uses this flag to decide whether to send pktlog
10180 * disable command to fw without sending pktlog enable command
10181 * previously. For eg, If vendor sends pktlog disable command without
10182 * sending pktlog enable command, then host discards the packet
10183 * but for iwpriv command, host will send it to fw.
10184 */
10185 start_log.is_iwpriv_command = 1;
Jeff Johnson16528362018-06-14 12:34:16 -070010186 status = sme_wifi_start_logger(hdd_ctx->mac_handle, start_log);
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010187 if (!QDF_IS_STATUS_SUCCESS(status)) {
10188 hdd_err("sme_wifi_start_logger failed(err=%d)", status);
Dustin Browne74003f2018-03-14 12:51:58 -070010189 hdd_exit();
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010190 return -EINVAL;
10191 }
10192
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053010193 if (enable == true)
10194 hdd_ctx->is_pktlog_enabled = 1;
10195 else
10196 hdd_ctx->is_pktlog_enabled = 0;
10197
Srinivas Girigowdad9e6f7b2016-02-01 19:37:52 -080010198 return 0;
10199}
10200#endif /* REMOVE_PKT_LOG */
10201
Komal Seelam92fff912016-03-24 11:51:41 +053010202/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010203 * hdd_get_platform_wlan_mac_buff() - API to query platform driver
10204 * for MAC address
Komal Seelam92fff912016-03-24 11:51:41 +053010205 * @dev: Device Pointer
10206 * @num: Number of Valid Mac address
10207 *
10208 * Return: Pointer to MAC address buffer
10209 */
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010210static uint8_t *hdd_get_platform_wlan_mac_buff(struct device *dev,
10211 uint32_t *num)
Komal Seelam92fff912016-03-24 11:51:41 +053010212{
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010213 return pld_get_wlan_mac_address(dev, num);
Komal Seelam92fff912016-03-24 11:51:41 +053010214}
Komal Seelam92fff912016-03-24 11:51:41 +053010215
10216/**
10217 * hdd_populate_random_mac_addr() - API to populate random mac addresses
10218 * @hdd_ctx: HDD Context
10219 * @num: Number of random mac addresses needed
10220 *
10221 * Generate random addresses using bit manipulation on the base mac address
10222 *
10223 * Return: None
10224 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010225void hdd_populate_random_mac_addr(struct hdd_context *hdd_ctx, uint32_t num)
Komal Seelam92fff912016-03-24 11:51:41 +053010226{
10227 uint32_t start_idx = QDF_MAX_CONCURRENCY_PERSONA - num;
10228 uint32_t iter;
10229 struct hdd_config *ini = hdd_ctx->config;
10230 uint8_t *buf = NULL;
10231 uint8_t macaddr_b3, tmp_br3;
10232 uint8_t *src = ini->intfMacAddr[0].bytes;
10233
10234 for (iter = start_idx; iter < QDF_MAX_CONCURRENCY_PERSONA; ++iter) {
10235 buf = ini->intfMacAddr[iter].bytes;
10236 qdf_mem_copy(buf, src, QDF_MAC_ADDR_SIZE);
10237 macaddr_b3 = buf[3];
10238 tmp_br3 = ((macaddr_b3 >> 4 & INTF_MACADDR_MASK) + iter) &
10239 INTF_MACADDR_MASK;
10240 macaddr_b3 += tmp_br3;
10241 macaddr_b3 ^= (1 << INTF_MACADDR_MASK);
10242 buf[0] |= 0x02;
10243 buf[3] = macaddr_b3;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010244 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +053010245 }
10246}
10247
10248/**
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010249 * hdd_platform_wlan_mac() - API to get mac addresses from platform driver
Komal Seelam92fff912016-03-24 11:51:41 +053010250 * @hdd_ctx: HDD Context
10251 *
10252 * API to get mac addresses from platform driver and update the driver
10253 * structures and configure FW with the base mac address.
10254 * Return: int
10255 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010256static int hdd_platform_wlan_mac(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +053010257{
10258 uint32_t no_of_mac_addr, iter;
10259 uint32_t max_mac_addr = QDF_MAX_CONCURRENCY_PERSONA;
10260 uint32_t mac_addr_size = QDF_MAC_ADDR_SIZE;
10261 uint8_t *addr, *buf;
10262 struct device *dev = hdd_ctx->parent_dev;
10263 struct hdd_config *ini = hdd_ctx->config;
10264 tSirMacAddr mac_addr;
10265 QDF_STATUS status;
10266
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010267 addr = hdd_get_platform_wlan_mac_buff(dev, &no_of_mac_addr);
Komal Seelam92fff912016-03-24 11:51:41 +053010268
Dustin Brown7e761c72018-07-31 13:50:17 -070010269 if (no_of_mac_addr == 0 || !addr)
Komal Seelam92fff912016-03-24 11:51:41 +053010270 return -EINVAL;
Komal Seelam92fff912016-03-24 11:51:41 +053010271
10272 if (no_of_mac_addr > max_mac_addr)
10273 no_of_mac_addr = max_mac_addr;
10274
10275 qdf_mem_copy(&mac_addr, addr, mac_addr_size);
10276
10277 for (iter = 0; iter < no_of_mac_addr; ++iter, addr += mac_addr_size) {
10278 buf = ini->intfMacAddr[iter].bytes;
10279 qdf_mem_copy(buf, addr, QDF_MAC_ADDR_SIZE);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010280 hdd_debug(MAC_ADDRESS_STR, MAC_ADDR_ARRAY(buf));
Komal Seelam92fff912016-03-24 11:51:41 +053010281 }
10282
10283 status = sme_set_custom_mac_addr(mac_addr);
10284
10285 if (!QDF_IS_STATUS_SUCCESS(status))
10286 return -EAGAIN;
Srinivas Girigowdab841da72017-03-25 18:04:39 -070010287
Komal Seelam92fff912016-03-24 11:51:41 +053010288 if (no_of_mac_addr < max_mac_addr)
10289 hdd_populate_random_mac_addr(hdd_ctx, max_mac_addr -
10290 no_of_mac_addr);
10291 return 0;
10292}
10293
10294/**
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010295 * hdd_update_mac_addr_to_fw() - API to update wlan mac addresses to FW
10296 * @hdd_ctx: HDD Context
10297 *
10298 * Update MAC address to FW. If MAC address passed by FW is invalid, host
10299 * will generate its own MAC and update it to FW.
10300 *
10301 * Return: 0 for success
10302 * Non-zero error code for failure
10303 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010304static int hdd_update_mac_addr_to_fw(struct hdd_context *hdd_ctx)
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010305{
10306 tSirMacAddr customMacAddr;
10307 QDF_STATUS status;
10308
10309 qdf_mem_copy(&customMacAddr,
10310 &hdd_ctx->config->intfMacAddr[0].bytes[0],
10311 sizeof(tSirMacAddr));
10312 status = sme_set_custom_mac_addr(customMacAddr);
10313 if (!QDF_IS_STATUS_SUCCESS(status))
10314 return -EAGAIN;
10315 return 0;
10316}
10317
10318/**
Komal Seelam92fff912016-03-24 11:51:41 +053010319 * hdd_initialize_mac_address() - API to get wlan mac addresses
10320 * @hdd_ctx: HDD Context
10321 *
10322 * Get MAC addresses from platform driver or wlan_mac.bin. If platform driver
10323 * is provisioned with mac addresses, driver uses it, else it will use
10324 * wlan_mac.bin to update HW MAC addresses.
10325 *
10326 * Return: None
10327 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010328static void hdd_initialize_mac_address(struct hdd_context *hdd_ctx)
Komal Seelam92fff912016-03-24 11:51:41 +053010329{
10330 QDF_STATUS status;
10331 int ret;
10332
Yuanyuan Liu7145eb22016-12-01 10:59:29 -080010333 ret = hdd_platform_wlan_mac(hdd_ctx);
Dustin Brown7e761c72018-07-31 13:50:17 -070010334 if (!ret) {
10335 hdd_info("using MAC address from platform driver");
Komal Seelam92fff912016-03-24 11:51:41 +053010336 return;
Dustin Brown7e761c72018-07-31 13:50:17 -070010337 }
Komal Seelam92fff912016-03-24 11:51:41 +053010338
10339 status = hdd_update_mac_config(hdd_ctx);
Dustin Brown7e761c72018-07-31 13:50:17 -070010340 if (QDF_IS_STATUS_SUCCESS(status)) {
10341 hdd_info("using MAC address from wlan_mac.bin");
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010342 return;
Dustin Brown7e761c72018-07-31 13:50:17 -070010343 }
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010344
Dustin Brown7e761c72018-07-31 13:50:17 -070010345 hdd_info("using default MAC address");
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010346
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -080010347 if (hdd_ctx->update_mac_addr_to_fw) {
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010348 ret = hdd_update_mac_addr_to_fw(hdd_ctx);
Dustin Brown7e761c72018-07-31 13:50:17 -070010349 if (ret)
Yuanyuan Liu1c2caa32016-11-07 17:13:48 -080010350 hdd_err("MAC address out-of-sync, ret:%d", ret);
Yuanyuan Liu245a3e42016-09-14 12:15:16 -070010351 }
Komal Seelam92fff912016-03-24 11:51:41 +053010352}
10353
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010354static int hdd_set_smart_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010355{
10356 int vdev_id = 0;
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053010357 QDF_STATUS status;
10358 bool smart_chainmask_enabled;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010359 int param_id = WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010360 int vpdev = PDEV_CMD;
10361 int ret;
10362
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053010363 status = ucfg_get_smart_chainmask_enabled(hdd_ctx->psoc,
10364 &smart_chainmask_enabled);
10365 if (QDF_IS_STATUS_ERROR(status))
10366 return -EINVAL;
10367
10368 ret = sme_cli_set_command(vdev_id, param_id,
10369 (int)smart_chainmask_enabled, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010370 if (ret)
10371 hdd_err("WMI_PDEV_PARAM_SMART_CHAINMASK_SCHEME failed %d", ret);
10372
10373 return ret;
10374}
10375
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010376static int hdd_set_alternative_chainmask_enabled(struct hdd_context *hdd_ctx)
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010377{
10378 int vdev_id = 0;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010379 QDF_STATUS status;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010380 int param_id = WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010381 bool alternative_chainmask_enabled;
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010382 int vpdev = PDEV_CMD;
10383 int ret;
10384
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010385 status = ucfg_get_alternative_chainmask_enabled(
10386 hdd_ctx->psoc,
10387 &alternative_chainmask_enabled);
10388 if (QDF_IS_STATUS_ERROR(status))
10389 return -EINVAL;
10390
10391 ret = sme_cli_set_command(vdev_id, param_id,
10392 (int)alternative_chainmask_enabled, vpdev);
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010393 if (ret)
10394 hdd_err("WMI_PDEV_PARAM_ALTERNATIVE_CHAINMASK_SCHEME failed %d",
10395 ret);
10396
10397 return ret;
10398}
10399
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010400static int hdd_set_ani_enabled(struct hdd_context *hdd_ctx)
Jeff Johnson12a744b2017-04-04 08:19:37 -070010401{
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010402 QDF_STATUS status;
Jeff Johnson12a744b2017-04-04 08:19:37 -070010403 int vdev_id = 0;
10404 int param_id = WMI_PDEV_PARAM_ANI_ENABLE;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010405 bool value;
Jeff Johnson12a744b2017-04-04 08:19:37 -070010406 int vpdev = PDEV_CMD;
10407 int ret;
10408
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010409 status = ucfg_fwol_get_ani_enabled(hdd_ctx->psoc, &value);
10410 if (QDF_IS_STATUS_ERROR(status))
10411 return -EINVAL;
10412
10413 ret = sme_cli_set_command(vdev_id, param_id, (int)value, vpdev);
Jeff Johnson12a744b2017-04-04 08:19:37 -070010414 if (ret)
10415 hdd_err("WMI_PDEV_PARAM_ANI_ENABLE failed %d", ret);
10416
10417 return ret;
10418}
10419
Jeff Johnson89c66ff2016-04-22 15:21:37 -070010420/**
Prashanth Bhatta07998752016-04-28 12:35:33 -070010421 * hdd_pre_enable_configure() - Configurations prior to cds_enable
10422 * @hdd_ctx: HDD context
10423 *
10424 * Pre configurations to be done at lower layer before calling cds enable.
10425 *
10426 * Return: 0 on success and errno on failure.
10427 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010428static int hdd_pre_enable_configure(struct hdd_context *hdd_ctx)
Prashanth Bhatta07998752016-04-28 12:35:33 -070010429{
10430 int ret;
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053010431 uint8_t val = 0;
Prashanth Bhatta07998752016-04-28 12:35:33 -070010432 QDF_STATUS status;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010433 uint32_t arp_ac_category;
Leo Changfdb45c32016-10-28 11:09:23 -070010434 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010435
Leo Changfdb45c32016-10-28 11:09:23 -070010436 cdp_register_pause_cb(soc, wlan_hdd_txrx_pause_cb);
Ajit Pal Singh5d269612018-04-19 16:29:12 +053010437 /* Register HL netdev flow control callback */
10438 cdp_hl_fc_register(soc, wlan_hdd_txrx_pause_cb);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010439
10440 /*
10441 * Note that the cds_pre_enable() sequence triggers the cfg download.
10442 * The cfg download must occur before we update the SME config
10443 * since the SME config operation must access the cfg database
10444 */
10445 status = hdd_set_sme_config(hdd_ctx);
10446
10447 if (QDF_STATUS_SUCCESS != status) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010448 hdd_err("Failed hdd_set_sme_config: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010449 ret = qdf_status_to_os_return(status);
10450 goto out;
10451 }
10452
Tushnim Bhattacharyyaba8ee932017-03-23 09:27:40 -070010453 status = hdd_set_policy_mgr_user_cfg(hdd_ctx);
10454 if (QDF_STATUS_SUCCESS != status) {
10455 hdd_alert("Failed hdd_set_policy_mgr_user_cfg: %d", status);
10456 ret = qdf_status_to_os_return(status);
10457 goto out;
10458 }
10459
Dustin Brown1dbefe62018-09-11 16:32:03 -070010460 status = ucfg_mlme_get_tx_chainmask_1ss(hdd_ctx->psoc, &val);
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053010461 if (QDF_STATUS_SUCCESS != status) {
10462 hdd_err("Get tx_chainmask_1ss from mlme failed");
10463 ret = qdf_status_to_os_return(status);
10464 goto out;
10465 }
10466 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS, val,
Prashanth Bhatta07998752016-04-28 12:35:33 -070010467 PDEV_CMD);
10468 if (0 != ret) {
10469 hdd_err("WMI_PDEV_PARAM_TX_CHAIN_MASK_1SS failed %d", ret);
10470 goto out;
10471 }
10472
Jeff Johnsona89e25d2017-02-24 12:25:07 -080010473 ret = hdd_set_smart_chainmask_enabled(hdd_ctx);
10474 if (ret)
10475 goto out;
10476
10477 ret = hdd_set_alternative_chainmask_enabled(hdd_ctx);
10478 if (ret)
10479 goto out;
10480
Jeff Johnson12a744b2017-04-04 08:19:37 -070010481 ret = hdd_set_ani_enabled(hdd_ctx);
10482 if (ret)
10483 goto out;
10484
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010485 status = ucfg_get_arp_ac_category(hdd_ctx->psoc, &arp_ac_category);
10486
10487 if (QDF_IS_STATUS_ERROR(status))
10488 return -EINVAL;
10489
Naveen Rawat247a8682017-06-05 15:00:31 -070010490 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_ARP_AC_OVERRIDE,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010491 arp_ac_category,
Srinivas Girigowda70e169a2017-03-07 23:55:57 -080010492 PDEV_CMD);
10493 if (0 != ret) {
10494 hdd_err("WMI_PDEV_PARAM_ARP_AC_OVERRIDE ac: %d ret: %d",
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053010495 arp_ac_category, ret);
Srinivas Girigowda70e169a2017-03-07 23:55:57 -080010496 goto out;
10497 }
10498
Prashanth Bhatta07998752016-04-28 12:35:33 -070010499 status = hdd_set_sme_chan_list(hdd_ctx);
10500 if (status != QDF_STATUS_SUCCESS) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010501 hdd_err("Failed to init channel list: %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010502 ret = qdf_status_to_os_return(status);
10503 goto out;
10504 }
10505
10506 /* Apply the cfg.ini to cfg.dat */
Krunal Sonidf0f8742016-09-26 14:56:31 -070010507 if (!hdd_update_config_cfg(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080010508 hdd_err("config update failed");
Prashanth Bhatta07998752016-04-28 12:35:33 -070010509 ret = -EINVAL;
10510 goto out;
10511 }
10512
Prashanth Bhatta07998752016-04-28 12:35:33 -070010513 /*
10514 * Set the MAC Address Currently this is used by HAL to add self sta.
10515 * Remove this once self sta is added as part of session open.
10516 */
Jeff Johnson16528362018-06-14 12:34:16 -070010517 status = sme_cfg_set_str(hdd_ctx->mac_handle, WNI_CFG_STA_ID,
Jeff Johnsonbae59f92018-06-01 17:05:43 -070010518 hdd_ctx->config->intfMacAddr[0].bytes,
10519 sizeof(hdd_ctx->config->intfMacAddr[0]));
Prashanth Bhatta07998752016-04-28 12:35:33 -070010520
Jeff Johnsonbae59f92018-06-01 17:05:43 -070010521 if (QDF_IS_STATUS_ERROR(status)) {
10522 hdd_err("Failed to set MAC Address, status %d", status);
Prashanth Bhatta07998752016-04-28 12:35:33 -070010523 ret = -EINVAL;
10524 goto out;
10525 }
10526
10527 hdd_init_channel_avoidance(hdd_ctx);
10528
10529out:
10530 return ret;
10531}
10532
Rachit Kankane026e77a2018-07-31 16:21:09 +053010533#ifdef FEATURE_P2P_LISTEN_OFFLOAD
Prashanth Bhatta07998752016-04-28 12:35:33 -070010534/**
Peng Xu8fdaa492016-06-22 10:20:47 -070010535 * wlan_hdd_p2p_lo_event_callback - P2P listen offload stop event handler
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070010536 * @context: context registered with sme_register_p2p_lo_event(). HDD
10537 * always registers a hdd context pointer
10538 * @evt:event structure pointer
Peng Xu8fdaa492016-06-22 10:20:47 -070010539 *
10540 * This is the p2p listen offload stop event handler, it sends vendor
10541 * event back to supplicant to notify the stop reason.
10542 *
10543 * Return: None
10544 */
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070010545static void wlan_hdd_p2p_lo_event_callback(void *context,
10546 struct sir_p2p_lo_event *evt)
Peng Xu8fdaa492016-06-22 10:20:47 -070010547{
Jeff Johnsonf7e36d62018-07-04 21:14:02 -070010548 struct hdd_context *hdd_ctx = context;
Peng Xu8fdaa492016-06-22 10:20:47 -070010549 struct sk_buff *vendor_event;
Jeff Johnson9d295242017-08-29 14:39:48 -070010550 struct hdd_adapter *adapter;
Peng Xu8fdaa492016-06-22 10:20:47 -070010551
Dustin Brown491d54b2018-03-14 12:39:11 -070010552 hdd_enter();
Peng Xu8fdaa492016-06-22 10:20:47 -070010553
10554 if (hdd_ctx == NULL) {
10555 hdd_err("Invalid HDD context pointer");
10556 return;
10557 }
10558
Peng Xu5c682812017-08-06 07:39:13 -070010559 adapter = hdd_get_adapter_by_vdev(hdd_ctx, evt->vdev_id);
10560 if (!adapter) {
10561 hdd_err("Cannot find adapter by vdev_id = %d",
10562 evt->vdev_id);
10563 return;
10564 }
10565
Peng Xu8fdaa492016-06-22 10:20:47 -070010566 vendor_event =
10567 cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
Peng Xu5c682812017-08-06 07:39:13 -070010568 &(adapter->wdev), sizeof(uint32_t) + NLMSG_HDRLEN,
Peng Xu8fdaa492016-06-22 10:20:47 -070010569 QCA_NL80211_VENDOR_SUBCMD_P2P_LO_EVENT_INDEX,
10570 GFP_KERNEL);
10571
10572 if (!vendor_event) {
10573 hdd_err("cfg80211_vendor_event_alloc failed");
10574 return;
10575 }
10576
10577 if (nla_put_u32(vendor_event,
10578 QCA_WLAN_VENDOR_ATTR_P2P_LISTEN_OFFLOAD_STOP_REASON,
10579 evt->reason_code)) {
10580 hdd_err("nla put failed");
10581 kfree_skb(vendor_event);
10582 return;
10583 }
10584
10585 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Peng Xu5c682812017-08-06 07:39:13 -070010586 hdd_debug("Sent P2P_LISTEN_OFFLOAD_STOP event for vdev_id = %d",
10587 evt->vdev_id);
Peng Xu8fdaa492016-06-22 10:20:47 -070010588}
Rachit Kankane026e77a2018-07-31 16:21:09 +053010589#else
10590static void wlan_hdd_p2p_lo_event_callback(void *context,
10591 struct sir_p2p_lo_event *evt)
10592{
10593}
10594#endif
Peng Xu8fdaa492016-06-22 10:20:47 -070010595
Rachit Kankanef6834c42018-08-02 18:47:50 +053010596#ifdef FEATURE_WLAN_DYNAMIC_CVM
10597static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
10598{
10599 return sme_set_vc_mode_config(hdd_ctx->config->vc_mode_cfg_bitmap);
10600}
10601#else
10602static inline int hdd_set_vc_mode_config(struct hdd_context *hdd_ctx)
10603{
10604 return QDF_STATUS_SUCCESS;
10605}
10606#endif
10607
Peng Xu8fdaa492016-06-22 10:20:47 -070010608/**
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010609 * hdd_adaptive_dwelltime_init() - initialization for adaptive dwell time config
10610 * @hdd_ctx: HDD context
10611 *
10612 * This function sends the adaptive dwell time config configuration to the
10613 * firmware via WMA
10614 *
10615 * Return: 0 - success, < 0 - failure
10616 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010617static int hdd_adaptive_dwelltime_init(struct hdd_context *hdd_ctx)
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010618{
10619 QDF_STATUS status;
10620 struct adaptive_dwelltime_params dwelltime_params;
10621
10622 dwelltime_params.is_enabled =
10623 hdd_ctx->config->adaptive_dwell_mode_enabled;
10624 dwelltime_params.dwelltime_mode =
10625 hdd_ctx->config->global_adapt_dwelltime_mode;
10626 dwelltime_params.lpf_weight =
10627 hdd_ctx->config->adapt_dwell_lpf_weight;
10628 dwelltime_params.passive_mon_intval =
10629 hdd_ctx->config->adapt_dwell_passive_mon_intval;
10630 dwelltime_params.wifi_act_threshold =
10631 hdd_ctx->config->adapt_dwell_wifi_act_threshold;
10632
Jeff Johnson16528362018-06-14 12:34:16 -070010633 status = sme_set_adaptive_dwelltime_config(hdd_ctx->mac_handle,
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010634 &dwelltime_params);
10635
10636 hdd_debug("Sending Adaptive Dwelltime Configuration to fw");
10637 if (!QDF_IS_STATUS_SUCCESS(status)) {
10638 hdd_err("Failed to send Adaptive Dwelltime configuration!");
10639 return -EAGAIN;
10640 }
10641 return 0;
10642}
10643
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010644int hdd_dbs_scan_selection_init(struct hdd_context *hdd_ctx)
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010645{
10646 QDF_STATUS status;
10647 struct wmi_dbs_scan_sel_params dbs_scan_params;
10648 uint32_t i = 0;
10649 uint8_t count = 0, numentries = 0;
Krunal Sonidf29bc42018-11-15 13:26:29 -080010650 uint8_t dual_mac_feature;
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010651 uint8_t dbs_scan_config[CDS_DBS_SCAN_PARAM_PER_CLIENT
10652 * CDS_DBS_SCAN_CLIENTS_MAX];
10653
Krunal Sonidf29bc42018-11-15 13:26:29 -080010654 status = ucfg_policy_mgr_get_dual_mac_feature(hdd_ctx->psoc,
10655 &dual_mac_feature);
10656
10657 if (status != QDF_STATUS_SUCCESS) {
10658 hdd_err("can't get dual mac feature flag");
10659 return -EINVAL;
10660 }
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010661 /* check if DBS is enabled or supported */
Krunal Sonidf29bc42018-11-15 13:26:29 -080010662 if ((dual_mac_feature == DISABLE_DBS_CXN_AND_SCAN) ||
10663 (dual_mac_feature == ENABLE_DBS_CXN_AND_DISABLE_DBS_SCAN))
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010664 return -EINVAL;
10665
10666 hdd_string_to_u8_array(hdd_ctx->config->dbs_scan_selection,
10667 dbs_scan_config, &numentries,
10668 (CDS_DBS_SCAN_PARAM_PER_CLIENT
10669 * CDS_DBS_SCAN_CLIENTS_MAX));
10670
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010671 if (!numentries) {
Dustin Brown6a8d39b2018-08-14 15:27:26 -070010672 hdd_debug("Do not send scan_selection_config");
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010673 return 0;
10674 }
10675
10676 /* hdd_set_fw_log_params */
10677 dbs_scan_params.num_clients = 0;
10678 while (count < (numentries - 2)) {
10679 dbs_scan_params.module_id[i] = dbs_scan_config[count];
10680 dbs_scan_params.num_dbs_scans[i] = dbs_scan_config[count + 1];
10681 dbs_scan_params.num_non_dbs_scans[i] =
10682 dbs_scan_config[count + 2];
10683 dbs_scan_params.num_clients++;
10684 hdd_debug("module:%d NDS:%d NNDS:%d",
10685 dbs_scan_params.module_id[i],
10686 dbs_scan_params.num_dbs_scans[i],
10687 dbs_scan_params.num_non_dbs_scans[i]);
10688 count += CDS_DBS_SCAN_PARAM_PER_CLIENT;
10689 i++;
10690 }
10691
10692 dbs_scan_params.pdev_id = 0;
10693
10694 hdd_debug("clients:%d pdev:%d",
10695 dbs_scan_params.num_clients, dbs_scan_params.pdev_id);
10696
Jeff Johnson16528362018-06-14 12:34:16 -070010697 status = sme_set_dbs_scan_selection_config(hdd_ctx->mac_handle,
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010698 &dbs_scan_params);
10699 hdd_debug("Sending DBS Scan Selection Configuration to fw");
10700 if (!QDF_IS_STATUS_SUCCESS(status)) {
10701 hdd_err("Failed to send DBS Scan selection configuration!");
10702 return -EAGAIN;
10703 }
10704 return 0;
10705}
10706
Arun Khandavallid4349a92016-07-25 11:10:43 +053010707#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
10708/**
10709 * hdd_set_auto_shutdown_cb() - Set auto shutdown callback
10710 * @hdd_ctx: HDD context
10711 *
10712 * Set auto shutdown callback to get indications from firmware to indicate
10713 * userspace to shutdown WLAN after a configured amount of inactivity.
10714 *
10715 * Return: 0 on success and errno on failure.
10716 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010717static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010718{
10719 QDF_STATUS status;
10720
Dundi Raviteja8e338282018-09-25 17:16:04 +053010721 if (!hdd_ctx->config->wlan_auto_shutdown)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010722 return 0;
10723
Jeff Johnson16528362018-06-14 12:34:16 -070010724 status = sme_set_auto_shutdown_cb(hdd_ctx->mac_handle,
Arun Khandavallid4349a92016-07-25 11:10:43 +053010725 wlan_hdd_auto_shutdown_cb);
10726 if (status != QDF_STATUS_SUCCESS)
10727 hdd_err("Auto shutdown feature could not be enabled: %d",
10728 status);
10729
10730 return qdf_status_to_os_return(status);
10731}
10732#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010733static int hdd_set_auto_shutdown_cb(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010734{
10735 return 0;
10736}
10737#endif
10738
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053010739#ifdef MWS_COEX
10740/**
10741 * hdd_set_mws_coex() - Set MWS coex configurations
10742 * @hdd_ctx: HDD context
10743 *
10744 * This function sends MWS-COEX 4G quick FTDM and
10745 * MWS-COEX 5G-NR power limit to FW
10746 *
10747 * Return: 0 on success and errno on failure.
10748 */
10749static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
10750{
10751 int ret = 0;
10752
10753 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_MWSCOEX_4G_ALLOW_QUICK_FTDM,
10754 hdd_ctx->config->mws_coex_4g_quick_tdm,
10755 PDEV_CMD);
10756 if (ret) {
10757 hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy");
10758 return ret;
10759 }
10760
10761 ret = sme_cli_set_command(0, WMI_PDEV_PARAM_MWSCOEX_SET_5GNR_PWR_LIMIT,
10762 hdd_ctx->config->mws_coex_5g_nr_pwr_limit,
10763 PDEV_CMD);
10764 if (ret) {
10765 hdd_warn("Unable to send MWS-COEX 4G quick FTDM policy");
10766 return ret;
10767 }
10768 return ret;
10769}
10770#else
10771static int hdd_init_mws_coex(struct hdd_context *hdd_ctx)
10772{
10773 return 0;
10774}
10775#endif
10776
Arun Khandavallid4349a92016-07-25 11:10:43 +053010777/**
10778 * hdd_features_init() - Init features
10779 * @hdd_ctx: HDD context
Arun Khandavallid4349a92016-07-25 11:10:43 +053010780 *
10781 * Initialize features and their feature context after WLAN firmware is up.
10782 *
10783 * Return: 0 on success and errno on failure.
10784 */
Dustin Browne7e71d32018-05-11 16:00:08 -070010785static int hdd_features_init(struct hdd_context *hdd_ctx)
Arun Khandavallid4349a92016-07-25 11:10:43 +053010786{
10787 tSirTxPowerLimit hddtxlimit;
10788 QDF_STATUS status;
10789 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -070010790 mac_handle_t mac_handle;
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070010791 struct hdd_config *cfg;
Wu Gao93816212018-08-31 16:49:54 +080010792 bool b_cts2self;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010793
Dustin Brown491d54b2018-03-14 12:39:11 -070010794 hdd_enter();
Arun Khandavallid4349a92016-07-25 11:10:43 +053010795
Dustin Brownad698ae2018-09-05 17:19:30 -070010796 ret = hdd_update_country_code(hdd_ctx);
10797 if (ret) {
10798 hdd_err("Failed to update country code; errno:%d", ret);
10799 return -EINVAL;
10800 }
10801
Dundi Ravitejaeab3b8d2018-07-17 18:10:41 +053010802 ret = hdd_init_mws_coex(hdd_ctx);
10803 if (ret)
10804 hdd_warn("Error initializing mws-coex");
10805
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070010806 cfg = hdd_ctx->config;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010807 /* FW capabilities received, Set the Dot11 mode */
Jeff Johnson16528362018-06-14 12:34:16 -070010808 mac_handle = hdd_ctx->mac_handle;
10809 sme_setdef_dot11mode(mac_handle);
Kiran Kumar Lokere1a43bcf2018-05-15 15:51:58 -070010810 sme_set_etsi13_srd_ch_in_master_mode(mac_handle,
10811 cfg->
10812 etsi13_srd_chan_in_master_mode);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010813
10814 if (hdd_ctx->config->fIsImpsEnabled)
10815 hdd_set_idle_ps_config(hdd_ctx, true);
10816 else
10817 hdd_set_idle_ps_config(hdd_ctx, false);
10818
Poddar, Siddarth37033032017-10-11 15:47:40 +053010819 /* Send Enable/Disable data stall detection cmd to FW */
10820 sme_cli_set_command(0, WMI_PDEV_PARAM_DATA_STALL_DETECT_ENABLE,
jitiphil377bcc12018-10-05 19:46:08 +053010821 cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC),
10822 cfg_dp_enable_data_stall), PDEV_CMD);
Poddar, Siddarth37033032017-10-11 15:47:40 +053010823
Dustin Brown1dbefe62018-09-11 16:32:03 -070010824 ucfg_mlme_get_go_cts2self_for_sta(hdd_ctx->psoc, &b_cts2self);
Wu Gao93816212018-08-31 16:49:54 +080010825 if (b_cts2self)
Jeff Johnson16528362018-06-14 12:34:16 -070010826 sme_set_cts2self_for_p2p_go(mac_handle);
Agrawal Ashish642ec9b2017-02-22 14:45:30 +053010827
Rachit Kankanef6834c42018-08-02 18:47:50 +053010828 if (hdd_set_vc_mode_config(hdd_ctx))
Nachiket Kukade8983cf62017-10-12 18:14:48 +053010829 hdd_warn("Error in setting Voltage Corner mode config to FW");
10830
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070010831 if (hdd_rx_ol_init(hdd_ctx))
10832 hdd_err("Unable to initialize Rx LRO/GRO in fw");
Arun Khandavallid4349a92016-07-25 11:10:43 +053010833
10834 if (hdd_adaptive_dwelltime_init(hdd_ctx))
10835 hdd_err("Unable to send adaptive dwelltime setting to FW");
10836
Nitesh Shahf9a09ff2017-05-22 15:46:25 +053010837 if (hdd_dbs_scan_selection_init(hdd_ctx))
10838 hdd_err("Unable to send DBS scan selection setting to FW");
10839
Arun Khandavallid4349a92016-07-25 11:10:43 +053010840 ret = hdd_init_thermal_info(hdd_ctx);
10841 if (ret) {
10842 hdd_err("Error while initializing thermal information");
Dustin Browne7e71d32018-05-11 16:00:08 -070010843 return ret;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010844 }
10845
Poddar, Siddarth61fbc932017-12-19 14:27:55 +053010846 /**
10847 * In case of SSR/PDR, if pktlog was enabled manually before
10848 * SSR/PDR, Then enabled it again automatically after Wlan
10849 * device up.
10850 */
10851 if (cds_is_driver_recovering()) {
10852 if (hdd_ctx->is_pktlog_enabled)
10853 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
Alok Kumar5a75b9d2018-08-31 10:55:43 +053010854 } else if (cds_is_packet_log_enabled())
10855 hdd_pktlog_enable_disable(hdd_ctx, true, 0, 0);
Poddar, Siddarth66a46592017-02-22 11:44:44 +053010856
gaurank kathpalia3d2e3852018-10-03 22:03:23 +053010857 hddtxlimit.txPower2g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_2G);
10858 hddtxlimit.txPower5g = ucfg_get_tx_power(hdd_ctx->psoc, BAND_5G);
Jeff Johnson16528362018-06-14 12:34:16 -070010859 status = sme_txpower_limit(mac_handle, &hddtxlimit);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010860 if (!QDF_IS_STATUS_SUCCESS(status))
10861 hdd_err("Error setting txlimit in sme: %d", status);
10862
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010863 wlan_hdd_tsf_init(hdd_ctx);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010864
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053010865 status = sme_enable_disable_chanavoidind_event(mac_handle, 0);
10866 if (QDF_IS_STATUS_ERROR(status) && (status != QDF_STATUS_E_NOSUPPORT)) {
10867 hdd_err("Failed to disable Chan Avoidance Indication");
Sourav Mohapatra674925f2018-04-16 11:16:58 +053010868 return -EINVAL;
Selvaraj, Sridhar371f55e2017-02-21 10:36:15 +053010869 }
Arun Khandavallid4349a92016-07-25 11:10:43 +053010870
10871 /* register P2P Listen Offload event callback */
10872 if (wma_is_p2p_lo_capable())
Jeff Johnson16528362018-06-14 12:34:16 -070010873 sme_register_p2p_lo_event(mac_handle, hdd_ctx,
10874 wlan_hdd_p2p_lo_event_callback);
Arun Khandavallid4349a92016-07-25 11:10:43 +053010875
10876 ret = hdd_set_auto_shutdown_cb(hdd_ctx);
10877
10878 if (ret)
Sourav Mohapatra674925f2018-04-16 11:16:58 +053010879 return -EINVAL;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010880
Dustin Brown11638b72018-01-25 17:37:25 +053010881 wlan_hdd_init_chan_info(hdd_ctx);
Varun Reddy Yeturu3c9f89c2018-04-18 19:10:34 -070010882 wlan_hdd_twt_init(hdd_ctx);
Dustin Brown11638b72018-01-25 17:37:25 +053010883
Dustin Browne74003f2018-03-14 12:51:58 -070010884 hdd_exit();
Arun Khandavallid4349a92016-07-25 11:10:43 +053010885 return 0;
Arun Khandavallid4349a92016-07-25 11:10:43 +053010886}
10887
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010888/**
10889 * hdd_features_deinit() - Deinit features
10890 * @hdd_ctx: HDD context
10891 *
10892 * De-Initialize features and their feature context.
10893 *
10894 * Return: none.
10895 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010896static void hdd_features_deinit(struct hdd_context *hdd_ctx)
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010897{
Varun Reddy Yeturu3c9f89c2018-04-18 19:10:34 -070010898 wlan_hdd_twt_deinit(hdd_ctx);
Dustin Brown11638b72018-01-25 17:37:25 +053010899 wlan_hdd_deinit_chan_info(hdd_ctx);
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010900 wlan_hdd_tsf_deinit(hdd_ctx);
jitiphil4e3bef42018-11-14 14:31:13 +053010901 if (cds_is_packet_log_enabled())
10902 hdd_pktlog_enable_disable(hdd_ctx, false, 0, 0);
Yu Wangf5d5b5f2017-05-25 22:38:32 +080010903}
10904
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010905/**
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070010906 * hdd_register_bcn_cb() - register scan beacon callback
10907 * @hdd_ctx - Pointer to the HDD context
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010908 *
Sandeep Puligilla0a11f8d2017-06-23 15:53:29 -070010909 * Return: QDF_STATUS
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010910 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070010911static inline QDF_STATUS hdd_register_bcn_cb(struct hdd_context *hdd_ctx)
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010912{
10913 QDF_STATUS status;
10914
Dustin Brown1dbefe62018-09-11 16:32:03 -070010915 status = ucfg_scan_register_bcn_cb(hdd_ctx->psoc,
Abhishek Singh6092fbb2017-01-25 18:10:31 +053010916 wlan_cfg80211_inform_bss_frame,
10917 SCAN_CB_TYPE_INFORM_BCN);
10918 if (!QDF_IS_STATUS_SUCCESS(status)) {
10919 hdd_err("failed with status code %08d [x%08x]",
10920 status, status);
10921 return status;
10922 }
10923
10924 return QDF_STATUS_SUCCESS;
10925}
Arun Khandavallid4349a92016-07-25 11:10:43 +053010926
Gupta, Kapil96c7f2f2016-04-25 19:13:41 +053010927/**
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070010928 * hdd_v2_flow_pool_map() - Flow pool create callback when vdev is active
10929 * @vdev_id: vdev_id, corresponds to flow_pool
10930 *
10931 * Return: none.
10932 */
10933static void hdd_v2_flow_pool_map(int vdev_id)
10934{
10935 QDF_STATUS status;
10936
10937 status = cdp_flow_pool_map(cds_get_context(QDF_MODULE_ID_SOC),
10938 cds_get_context(QDF_MODULE_ID_TXRX),
10939 vdev_id);
10940 /*
10941 * For Adrastea flow control v2 is based on FW MAP events,
10942 * so this above callback is not implemented.
10943 * Hence this is not actual failure. Dont return failure
10944 */
10945 if ((status != QDF_STATUS_SUCCESS) &&
10946 (status != QDF_STATUS_E_INVAL)) {
10947 hdd_err("vdev_id: %d, failed to create flow pool status %d",
10948 vdev_id, status);
10949 }
10950}
10951
10952/**
10953 * hdd_v2_flow_pool_unmap() - Flow pool create callback when vdev is not active
10954 * @vdev_id: vdev_id, corresponds to flow_pool
10955 *
10956 * Return: none.
10957 */
10958static void hdd_v2_flow_pool_unmap(int vdev_id)
10959{
10960 cdp_flow_pool_unmap(cds_get_context(QDF_MODULE_ID_SOC),
10961 cds_get_context(QDF_MODULE_ID_TXRX), vdev_id);
10962}
10963
10964/**
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053010965 * hdd_action_oui_config() - Configure action_oui strings
10966 * @hdd_ctx: pointer to hdd context
10967 *
10968 * This is a HDD wrapper function which invokes ucfg api
10969 * of action_oui component to parse action oui strings.
10970 *
10971 * Return: None
10972 */
10973static void hdd_action_oui_config(struct hdd_context *hdd_ctx)
10974{
10975 QDF_STATUS status;
10976 uint32_t id;
10977 uint8_t *str;
10978
10979 if (!hdd_ctx->config->action_oui_enable)
10980 return;
10981
10982 for (id = 0; id < ACTION_OUI_MAXIMUM_ID; id++) {
10983 str = hdd_ctx->config->action_oui_str[id];
10984 if (!qdf_str_len(str))
10985 continue;
10986
Dustin Brown1dbefe62018-09-11 16:32:03 -070010987 status = ucfg_action_oui_parse(hdd_ctx->psoc, str, id);
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053010988 if (!QDF_IS_STATUS_SUCCESS(status))
10989 hdd_err("Failed to parse action_oui str: %u", id);
10990 }
10991}
10992
10993/**
10994 * hdd_action_oui_send() - Send action_oui extensions to firmware
10995 * @hdd_ctx: pointer to hdd context
10996 *
10997 * This is a HDD wrapper function which invokes ucfg api
10998 * of action_oui component to send action oui extensions to firmware.
10999 *
11000 * Return: None
11001 */
11002static void hdd_action_oui_send(struct hdd_context *hdd_ctx)
11003{
11004 QDF_STATUS status;
11005
11006 if (!hdd_ctx->config->action_oui_enable)
11007 return;
11008
Dustin Brown1dbefe62018-09-11 16:32:03 -070011009 status = ucfg_action_oui_send(hdd_ctx->psoc);
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011010 if (!QDF_IS_STATUS_SUCCESS(status))
11011 hdd_err("Failed to send one or all action_ouis");
11012}
11013
11014/**
Arun Khandavallifae92942016-08-01 13:31:08 +053011015 * hdd_configure_cds() - Configure cds modules
11016 * @hdd_ctx: HDD context
11017 * @adapter: Primary adapter context
11018 *
11019 * Enable Cds modules after WLAN firmware is up.
11020 *
11021 * Return: 0 on success and errno on failure.
11022 */
Dustin Browne7e71d32018-05-11 16:00:08 -070011023int hdd_configure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053011024{
11025 int ret;
11026 QDF_STATUS status;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011027 int set_value;
Jeff Johnson16528362018-06-14 12:34:16 -070011028 mac_handle_t mac_handle;
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011029 bool enable_rts_sifsbursting;
11030 uint8_t enable_phy_reg_retention;
Krunal Sonidf29bc42018-11-15 13:26:29 -080011031 uint8_t max_mpdus_inampdu, is_force_1x1 = 0;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011032 uint32_t num_abg_tx_chains = 0;
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011033 uint16_t num_11b_tx_chains = 0;
11034 uint16_t num_11ag_tx_chains = 0;
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070011035 struct policy_mgr_dp_cbacks dp_cbs = {0};
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053011036 bool value;
Wu Gao66454f12018-09-26 19:55:41 +080011037 enum pmo_auto_pwr_detect_failure_mode auto_power_fail_mode;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053011038 bool bval = false;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011039
Jeff Johnson16528362018-06-14 12:34:16 -070011040 mac_handle = hdd_ctx->mac_handle;
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011041
11042 hdd_action_oui_send(hdd_ctx);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011043 status = ucfg_policy_mgr_get_force_1x1(hdd_ctx->psoc, &is_force_1x1);
11044 if (status != QDF_STATUS_SUCCESS) {
11045 hdd_err("Failed to get force 1x1 value");
11046 goto out;
11047 }
11048 if (is_force_1x1)
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011049 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_SET_IOT_PATTERN,
11050 1, PDEV_CMD);
11051 /* set chip power save failure detected callback */
Jeff Johnson16528362018-06-14 12:34:16 -070011052 sme_set_chip_pwr_save_fail_cb(mac_handle,
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011053 hdd_chip_pwr_save_fail_detected_cb);
11054
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011055 status = ucfg_get_max_mpdus_inampdu(hdd_ctx->psoc,
11056 &max_mpdus_inampdu);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011057 if (status) {
11058 hdd_err("Failed to get max mpdus in ampdu value");
11059 goto out;
11060 }
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011061
11062 if (max_mpdus_inampdu) {
11063 set_value = max_mpdus_inampdu;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011064 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_MAX_MPDUS_IN_AMPDU,
11065 set_value, PDEV_CMD);
11066 }
11067
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011068 status = ucfg_get_enable_rts_sifsbursting(hdd_ctx->psoc,
11069 &enable_rts_sifsbursting);
Krunal Sonidf29bc42018-11-15 13:26:29 -080011070 if (status) {
11071 hdd_err("Failed to get rts sifs bursting value");
11072 goto out;
11073 }
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011074
11075 if (enable_rts_sifsbursting) {
11076 set_value = enable_rts_sifsbursting;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011077 sme_cli_set_command(0,
11078 (int)WMI_PDEV_PARAM_ENABLE_RTS_SIFS_BURSTING,
11079 set_value, PDEV_CMD);
11080 }
11081
Dustin Brown05d81302018-09-11 16:49:22 -070011082 ucfg_mlme_get_sap_get_peer_info(hdd_ctx->psoc, &value);
Bala Venkatesh2fde2c62018-09-11 20:33:24 +053011083 if (value) {
11084 set_value = value;
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011085 sme_cli_set_command(0,
11086 (int)WMI_PDEV_PARAM_PEER_STATS_INFO_ENABLE,
11087 set_value, PDEV_CMD);
11088 }
11089
Dustin Brown1dbefe62018-09-11 16:32:03 -070011090 status = ucfg_mlme_get_num_11b_tx_chains(hdd_ctx->psoc,
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011091 &num_11b_tx_chains);
11092 if (status != QDF_STATUS_SUCCESS) {
11093 hdd_err("Failed to get num_11b_tx_chains");
11094 goto out;
11095 }
11096
Dustin Brown1dbefe62018-09-11 16:32:03 -070011097 status = ucfg_mlme_get_num_11ag_tx_chains(hdd_ctx->psoc,
Pragaspathi Thilagaraj00bd8bc2018-08-18 01:23:01 +053011098 &num_11ag_tx_chains);
11099 if (status != QDF_STATUS_SUCCESS) {
11100 hdd_err("Failed to get num_11ag_tx_chains");
11101 goto out;
11102 }
11103
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053011104 status = ucfg_mlme_get_vht_enable2x2(hdd_ctx->psoc, &bval);
11105 if (!QDF_IS_STATUS_SUCCESS(status))
11106 hdd_err("unable to get vht_enable2x2");
11107
11108 if (!bval) {
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011109 if (num_11b_tx_chains > 1)
11110 num_11b_tx_chains = 1;
11111 if (num_11ag_tx_chains > 1)
11112 num_11ag_tx_chains = 1;
11113 }
11114 WMI_PDEV_PARAM_SET_11B_TX_CHAIN_NUM(num_abg_tx_chains,
11115 num_11b_tx_chains);
11116 WMI_PDEV_PARAM_SET_11AG_TX_CHAIN_NUM(num_abg_tx_chains,
11117 num_11ag_tx_chains);
11118 sme_cli_set_command(0, (int)WMI_PDEV_PARAM_ABG_MODE_TX_CHAIN_NUM,
11119 num_abg_tx_chains, PDEV_CMD);
Arun Khandavallifae92942016-08-01 13:31:08 +053011120
Paul Zhang02526cd2018-09-20 17:47:46 +080011121 if (!ucfg_reg_is_regdb_offloaded(hdd_ctx->psoc))
11122 ucfg_reg_program_default_cc(hdd_ctx->pdev,
11123 hdd_ctx->reg.reg_domain);
11124
Arun Khandavallifae92942016-08-01 13:31:08 +053011125 ret = hdd_pre_enable_configure(hdd_ctx);
11126 if (ret) {
11127 hdd_err("Failed to pre-configure cds");
11128 goto out;
11129 }
11130
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080011131 /* Always get latest IPA resources allocated from cds_open and configure
11132 * IPA module before configuring them to FW. Sequence required as crash
11133 * observed otherwise.
11134 */
Dustin Brown07901ec2018-09-07 11:02:41 -070011135 if (ucfg_ipa_uc_ol_init(hdd_ctx->pdev,
11136 cds_get_context(QDF_MODULE_ID_QDF_DEVICE))) {
Manikandan Mohan2e803a02017-02-14 14:57:53 -080011137 hdd_err("Failed to setup pipes");
11138 goto out;
Manikandan Mohanbb8a7ee2017-02-09 11:26:53 -080011139 }
11140
Arun Khandavallifae92942016-08-01 13:31:08 +053011141 /*
11142 * Start CDS which starts up the SME/MAC/HAL modules and everything
11143 * else
11144 */
Dustin Brown1dbefe62018-09-11 16:32:03 -070011145 status = cds_enable(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053011146
11147 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011148 hdd_err("cds_enable failed");
Arun Khandavallifae92942016-08-01 13:31:08 +053011149 goto out;
11150 }
11151
11152 status = hdd_post_cds_enable_config(hdd_ctx);
11153 if (!QDF_IS_STATUS_SUCCESS(status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011154 hdd_err("hdd_post_cds_enable_config failed");
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011155 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053011156 }
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011157 status = hdd_register_bcn_cb(hdd_ctx);
11158 if (!QDF_IS_STATUS_SUCCESS(status)) {
Paul Zhange03cf4c2018-01-19 18:33:22 +080011159 hdd_err("hdd_register_bcn_cb failed");
Abhishek Singh6092fbb2017-01-25 18:10:31 +053011160 goto cds_disable;
11161 }
Arun Khandavallifae92942016-08-01 13:31:08 +053011162
Dustin Browne7e71d32018-05-11 16:00:08 -070011163 ret = hdd_features_init(hdd_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053011164 if (ret)
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011165 goto cds_disable;
Arun Khandavallifae92942016-08-01 13:31:08 +053011166
Manjunathappa Prakash7b0ad462018-04-15 00:37:16 -070011167 if (hdd_ctx->ol_enable)
11168 dp_cbs.hdd_disable_rx_ol_in_concurrency =
11169 hdd_disable_rx_ol_in_concurrency;
Yun Parkff6a16a2017-09-26 16:38:18 -070011170 dp_cbs.hdd_set_rx_mode_rps_cb = hdd_set_rx_mode_rps;
jiadbb47e132018-03-30 16:28:30 +080011171 dp_cbs.hdd_ipa_set_mcc_mode_cb = hdd_ipa_set_mcc_mode;
Manjunathappa Prakasha0cbc922018-05-08 19:48:34 -070011172 dp_cbs.hdd_v2_flow_pool_map = hdd_v2_flow_pool_map;
11173 dp_cbs.hdd_v2_flow_pool_unmap = hdd_v2_flow_pool_unmap;
Dustin Brown1dbefe62018-09-11 16:32:03 -070011174 status = policy_mgr_register_dp_cb(hdd_ctx->psoc, &dp_cbs);
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011175 if (!QDF_IS_STATUS_SUCCESS(status)) {
Yun Parkff6a16a2017-09-26 16:38:18 -070011176 hdd_debug("Failed to register DP cb with Policy Manager");
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011177 goto cds_disable;
11178 }
Dustin Brown1dbefe62018-09-11 16:32:03 -070011179 status = policy_mgr_register_mode_change_cb(hdd_ctx->psoc,
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011180 wlan_hdd_send_mode_change_event);
11181 if (!QDF_IS_STATUS_SUCCESS(status)) {
11182 hdd_debug("Failed to register mode change cb with Policy Manager");
11183 goto cds_disable;
11184 }
Manjunathappa Prakash7b6cb002017-10-09 00:40:24 -070011185
Jeff Johnson8bb61112018-03-31 13:33:54 -070011186 if (hdd_green_ap_enable_egap(hdd_ctx))
Nachiket Kukadefbd1afc2017-07-12 17:41:54 +053011187 hdd_debug("enhance green ap is not enabled");
11188
Nachiket Kukadedd302662017-07-13 17:31:44 +053011189 if (0 != wlan_hdd_set_wow_pulse(hdd_ctx, true))
11190 hdd_debug("Failed to set wow pulse");
11191
Ashish Kumar Dhanotiyacb14b112018-01-19 19:26:44 +053011192 sme_cli_set_command(0, WMI_PDEV_PARAM_GCMP_SUPPORT_ENABLE,
11193 hdd_ctx->config->gcmp_enabled, PDEV_CMD);
Wu Gao66454f12018-09-26 19:55:41 +080011194
11195 auto_power_fail_mode =
11196 ucfg_pmo_get_auto_power_fail_mode(hdd_ctx->psoc);
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +053011197 sme_cli_set_command(0, WMI_PDEV_AUTO_DETECT_POWER_FAILURE,
Wu Gao66454f12018-09-26 19:55:41 +080011198 auto_power_fail_mode, PDEV_CMD);
Hanumanth Reddy Pothulaab395952017-09-05 19:12:26 +053011199
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011200 status = ucfg_get_enable_phy_reg_retention(hdd_ctx->psoc,
11201 &enable_phy_reg_retention);
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053011202
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011203 if (QDF_IS_STATUS_ERROR(status))
11204 return -EINVAL;
11205
11206 if (enable_phy_reg_retention)
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053011207 wma_cli_set_command(0, WMI_PDEV_PARAM_FAST_PWR_TRANSITION,
Sourav Mohapatrad9387d82018-09-07 12:28:52 +053011208 enable_phy_reg_retention, PDEV_CMD);
Ravi Kumar Bokka990edcc2017-01-09 20:02:58 +053011209
Arun Khandavallifae92942016-08-01 13:31:08 +053011210 return 0;
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011211
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011212cds_disable:
Dustin Brown1dbefe62018-09-11 16:32:03 -070011213 cds_disable(hdd_ctx->psoc);
Houston Hoffman8d1a6f02016-10-10 17:48:58 -070011214
Arun Khandavallifae92942016-08-01 13:31:08 +053011215out:
11216 return -EINVAL;
11217}
11218
11219/**
11220 * hdd_deconfigure_cds() -De-Configure cds
11221 * @hdd_ctx: HDD context
11222 *
11223 * Deconfigure Cds modules before WLAN firmware is down.
11224 *
11225 * Return: 0 on success and errno on failure.
11226 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011227static int hdd_deconfigure_cds(struct hdd_context *hdd_ctx)
Arun Khandavallifae92942016-08-01 13:31:08 +053011228{
11229 QDF_STATUS qdf_status;
Houston Hoffman6640cf32016-10-10 16:44:29 -070011230 int ret = 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053011231
Dustin Brown491d54b2018-03-14 12:39:11 -070011232 hdd_enter();
Yu Wangf5d5b5f2017-05-25 22:38:32 +080011233
11234 /* De-init features */
11235 hdd_features_deinit(hdd_ctx);
11236
Dustin Brown1dbefe62018-09-11 16:32:03 -070011237 qdf_status = policy_mgr_deregister_mode_change_cb(hdd_ctx->psoc);
Srinivas Girigowdad2412882018-09-07 15:42:04 -070011238 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011239 hdd_debug("Failed to deregister mode change cb with Policy Manager");
Yeshwanth Sriram Guntuka2d6204f2018-01-23 18:52:14 +053011240
Dustin Brown1dbefe62018-09-11 16:32:03 -070011241 qdf_status = cds_disable(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053011242 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11243 hdd_err("Failed to Disable the CDS Modules! :%d",
11244 qdf_status);
Houston Hoffman6640cf32016-10-10 16:44:29 -070011245 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011246 }
11247
Dustin Brown07901ec2018-09-07 11:02:41 -070011248 if (ucfg_ipa_uc_ol_deinit(hdd_ctx->pdev) != QDF_STATUS_SUCCESS) {
Sravan Kumar Kairam71121712017-04-15 00:34:42 +053011249 hdd_err("Failed to disconnect pipes");
11250 ret = -EINVAL;
11251 }
11252
Dustin Browne74003f2018-03-14 12:51:58 -070011253 hdd_exit();
Houston Hoffman6640cf32016-10-10 16:44:29 -070011254 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053011255}
11256
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070011257#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
11258static void hdd_deregister_policy_manager_callback(
11259 struct wlan_objmgr_psoc *psoc)
11260{
11261 if (QDF_STATUS_SUCCESS !=
11262 policy_mgr_deregister_hdd_cb(psoc)) {
11263 hdd_err("HDD callback deregister with policy manager failed");
11264 }
11265}
11266#else
11267static void hdd_deregister_policy_manager_callback(
11268 struct wlan_objmgr_psoc *psoc)
11269{
11270}
11271#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053011272
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011273int hdd_wlan_stop_modules(struct hdd_context *hdd_ctx, bool ftm_mode)
Arun Khandavallifae92942016-08-01 13:31:08 +053011274{
11275 void *hif_ctx;
11276 qdf_device_t qdf_ctx;
11277 QDF_STATUS qdf_status;
Dustin Brown4bc0a622017-12-06 15:56:50 -080011278 bool is_recovery_stop = cds_is_driver_recovering();
Sourav Mohapatra808e3d42018-07-04 09:34:23 +053011279 int ret = 0;
Dustin Brown70111822017-03-30 15:31:40 -070011280 int active_threads;
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053011281 int debugfs_threads;
Arunk Khandavallia6305a32018-01-25 11:19:18 +053011282 struct target_psoc_info *tgt_hdl;
Arun Khandavallifae92942016-08-01 13:31:08 +053011283
Dustin Brown491d54b2018-03-14 12:39:11 -070011284 hdd_enter();
Arun Khandavallifae92942016-08-01 13:31:08 +053011285
Dustin Brown1dbefe62018-09-11 16:32:03 -070011286 hdd_deregister_policy_manager_callback(hdd_ctx->psoc);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070011287
Arun Khandavallifae92942016-08-01 13:31:08 +053011288 qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
11289 if (!qdf_ctx) {
11290 hdd_err("QDF device context NULL");
11291 return -EINVAL;
11292 }
11293
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011294 mutex_lock(&hdd_ctx->iface_change_lock);
11295 hdd_ctx->stop_modules_in_progress = true;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070011296 cds_set_module_stop_in_progress(true);
Arun Khandavallifae92942016-08-01 13:31:08 +053011297
Dustin Brown70111822017-03-30 15:31:40 -070011298 active_threads = cds_return_external_threads_count();
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053011299 debugfs_threads = hdd_return_debugfs_threads_count();
Dustin Brown70111822017-03-30 15:31:40 -070011300
Rajeev Kumar Sirasanagandla197d4172018-02-15 19:03:29 +053011301 if (active_threads > 0 || debugfs_threads > 0 ||
11302 hdd_ctx->is_wiphy_suspended) {
11303 hdd_warn("External threads %d, Debugfs threads %d, wiphy suspend %d",
11304 active_threads, debugfs_threads,
11305 hdd_ctx->is_wiphy_suspended);
11306
11307 if (active_threads)
11308 cds_print_external_threads();
Dustin Brown70111822017-03-30 15:31:40 -070011309
Sourav Mohapatra808e3d42018-07-04 09:34:23 +053011310 if (IS_IDLE_STOP && !ftm_mode) {
Dustin Brown70111822017-03-30 15:31:40 -070011311 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown4c663222018-10-23 14:19:36 -070011312 hdd_psoc_idle_timer_start(hdd_ctx);
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070011313 hdd_ctx->stop_modules_in_progress = false;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070011314 cds_set_module_stop_in_progress(false);
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011315
Dustin Brown70111822017-03-30 15:31:40 -070011316 return 0;
11317 }
Rajeev Kumar86177c22017-03-16 19:44:39 -070011318 }
11319
Kabilan Kannan6edafeb2017-11-16 16:34:34 -080011320 /* free user wowl patterns */
11321 hdd_free_user_wowl_ptrns();
11322
Arun Khandavallifae92942016-08-01 13:31:08 +053011323 switch (hdd_ctx->driver_status) {
11324 case DRIVER_MODULES_UNINITIALIZED:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011325 hdd_debug("Modules not initialized just return");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011326 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053011327 case DRIVER_MODULES_CLOSED:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011328 hdd_debug("Modules already closed");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011329 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053011330 case DRIVER_MODULES_ENABLED:
Dustin Brown1a20b082018-08-03 17:27:15 -070011331 hdd_info("Wlan transitioning (CLOSED <- ENABLED)");
11332
11333 if (hdd_get_conparam() == QDF_GLOBAL_FTM_MODE)
11334 break;
Dustin Brown550f6d22017-12-14 15:44:01 -080011335
Komal Seelamf2136bb2016-09-28 18:30:44 +053011336 hdd_disable_power_management();
Arun Khandavallifae92942016-08-01 13:31:08 +053011337 if (hdd_deconfigure_cds(hdd_ctx)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011338 hdd_err("Failed to de-configure CDS");
Arun Khandavallifae92942016-08-01 13:31:08 +053011339 QDF_ASSERT(0);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011340 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011341 }
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011342 hdd_debug("successfully Disabled the CDS modules!");
Dustin Brown550f6d22017-12-14 15:44:01 -080011343
Arun Khandavallifae92942016-08-01 13:31:08 +053011344 break;
11345 default:
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011346 QDF_DEBUG_PANIC("Unknown driver state:%d",
Arun Khandavallifae92942016-08-01 13:31:08 +053011347 hdd_ctx->driver_status);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011348 ret = -EINVAL;
11349 goto done;
Arun Khandavallifae92942016-08-01 13:31:08 +053011350 }
11351
Arunk Khandavalli890f6d92018-10-30 20:18:28 +053011352 hdd_sysfs_destroy_powerstats_interface();
Amar Singhal18081642018-01-26 16:04:13 -080011353 hdd_sysfs_destroy_version_interface();
Arunk Khandavalli890f6d92018-10-30 20:18:28 +053011354 hdd_sysfs_destroy_driver_root_obj();
Dustin Brown550f6d22017-12-14 15:44:01 -080011355 hdd_debug("Closing CDS modules!");
Amar Singhal18081642018-01-26 16:04:13 -080011356
Rajeev Kumarbe021242017-02-16 16:12:23 -080011357 qdf_status = cds_post_disable();
Govind Singhb048e872016-09-27 22:07:43 +053011358 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11359 hdd_err("Failed to process post CDS disable Modules! :%d",
11360 qdf_status);
11361 ret = -EINVAL;
11362 QDF_ASSERT(0);
11363 }
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070011364
Sourav Mohapatra674925f2018-04-16 11:16:58 +053011365 /* De-register the SME callbacks */
11366 hdd_deregister_cb(hdd_ctx);
11367
psimhadeea0a12017-12-18 14:50:02 -080011368 hdd_runtime_suspend_context_deinit(hdd_ctx);
11369
Dustin Brown1dbefe62018-09-11 16:32:03 -070011370 qdf_status = cds_dp_close(hdd_ctx->psoc);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070011371 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
11372 hdd_warn("Failed to stop CDS DP: %d", qdf_status);
11373 ret = -EINVAL;
11374 QDF_ASSERT(0);
11375 }
11376
Dustin Brown1dbefe62018-09-11 16:32:03 -070011377 qdf_status = cds_close(hdd_ctx->psoc);
Arun Khandavallifae92942016-08-01 13:31:08 +053011378 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011379 hdd_warn("Failed to stop CDS: %d", qdf_status);
Govind Singhb048e872016-09-27 22:07:43 +053011380 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011381 QDF_ASSERT(0);
11382 }
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053011383
11384 qdf_status = wbuff_module_deinit();
11385 if (!QDF_IS_STATUS_SUCCESS(qdf_status))
11386 hdd_err("WBUFF de-init unsuccessful; status: %d", qdf_status);
11387
Sandeep Puligillab7beb472018-08-13 22:54:20 -070011388 hdd_component_pdev_close(hdd_ctx->pdev);
Rakshith Suresh Patkard9f4e612018-09-12 12:10:38 +053011389
Dustin Brown1dbefe62018-09-11 16:32:03 -070011390 hdd_component_psoc_close(hdd_ctx->psoc);
Dustin Brown07901ec2018-09-07 11:02:41 -070011391 dispatcher_pdev_close(hdd_ctx->pdev);
Liangwei Dong50a64a72018-01-11 01:17:00 -050011392 ret = hdd_objmgr_release_and_destroy_pdev(hdd_ctx);
11393 if (ret) {
11394 hdd_err("Failed to destroy pdev; errno:%d", ret);
11395 QDF_ASSERT(0);
11396 }
11397
11398 /*
11399 * Reset total mac phy during module stop such that during
11400 * next module start same psoc is used to populate new service
11401 * ready data
11402 */
Dustin Brown1dbefe62018-09-11 16:32:03 -070011403 tgt_hdl = wlan_psoc_get_tgt_if_handle(hdd_ctx->psoc);
Arunk Khandavallia6305a32018-01-25 11:19:18 +053011404 if (tgt_hdl)
11405 target_psoc_set_total_mac_phy_cnt(tgt_hdl, 0);
11406
Liangwei Dong50a64a72018-01-11 01:17:00 -050011407
Arun Khandavallifae92942016-08-01 13:31:08 +053011408 hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
11409 if (!hif_ctx) {
11410 hdd_err("Hif context is Null");
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011411 ret = -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053011412 }
11413
Arunk Khandavalli4b404332017-09-26 12:46:00 +053011414 if (hdd_ctx->target_hw_name) {
11415 qdf_mem_free(hdd_ctx->target_hw_name);
11416 hdd_ctx->target_hw_name = NULL;
11417 }
11418
Sravan Kumar Kairam27296782017-04-21 22:04:18 +053011419 hdd_hif_close(hdd_ctx, hif_ctx);
Arun Khandavallifae92942016-08-01 13:31:08 +053011420
11421 ol_cds_free();
11422
Dustin Brownc2a156e2018-10-25 16:56:27 -070011423 if (IS_IDLE_STOP) {
Arun Khandavallifae92942016-08-01 13:31:08 +053011424 ret = pld_power_off(qdf_ctx->dev);
11425 if (ret)
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011426 hdd_err("Failed to power down device; errno:%d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053011427 }
Dustin Brown1e3ec6b2018-08-07 11:18:47 -070011428
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011429 /* Free the cache channels of the command SET_DISABLE_CHANNEL_LIST */
11430 wlan_hdd_free_cache_channels(hdd_ctx);
Arunk Khandavalli847969d2017-09-25 15:15:36 +053011431
Dustin Brown29533f22018-07-24 13:11:56 -070011432 hdd_check_for_leaks(hdd_ctx, is_recovery_stop);
Dustin Brown26b3d042017-12-21 11:13:27 -080011433 hdd_debug_domain_set(QDF_DEBUG_DOMAIN_INIT);
Dustin Brown4bc0a622017-12-06 15:56:50 -080011434
Arunk Khandavalli847969d2017-09-25 15:15:36 +053011435 /* Once the firmware sequence is completed reset this flag */
11436 hdd_ctx->imps_enabled = false;
Arun Khandavallifae92942016-08-01 13:31:08 +053011437 hdd_ctx->driver_status = DRIVER_MODULES_CLOSED;
Dustin Brown550f6d22017-12-14 15:44:01 -080011438 hdd_info("Wlan transitioned (now CLOSED)");
Arun Khandavallifae92942016-08-01 13:31:08 +053011439
Kai Liueabb1df2018-11-08 14:58:54 +080011440 pld_request_bus_bandwidth(hdd_ctx->parent_dev, PLD_BUS_WIDTH_NONE);
11441
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011442done:
11443 hdd_ctx->stop_modules_in_progress = false;
Manjunathappa Prakash71c74a42017-10-19 23:28:43 -070011444 cds_set_module_stop_in_progress(false);
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011445 mutex_unlock(&hdd_ctx->iface_change_lock);
Dustin Brown4bc0a622017-12-06 15:56:50 -080011446
Dustin Browne74003f2018-03-14 12:51:58 -070011447 hdd_exit();
Arun Khandavallifae92942016-08-01 13:31:08 +053011448
Arun Khandavallia172c3e2016-08-26 17:33:13 +053011449 return ret;
Arun Khandavallifae92942016-08-01 13:31:08 +053011450}
11451
Arun Khandavallifae92942016-08-01 13:31:08 +053011452
Wen Gong3f003382018-05-14 14:26:37 +080011453#ifdef WLAN_FEATURE_MEMDUMP_ENABLE
Arun Khandavallifae92942016-08-01 13:31:08 +053011454/**
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011455 * hdd_state_info_dump() - prints state information of hdd layer
11456 * @buf: buffer pointer
11457 * @size: size of buffer to be filled
11458 *
11459 * This function is used to dump state information of hdd layer
11460 *
11461 * Return: None
11462 */
11463static void hdd_state_info_dump(char **buf_ptr, uint16_t *size)
11464{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011465 struct hdd_context *hdd_ctx;
Jeff Johnson40dae4e2017-08-29 14:00:25 -070011466 struct hdd_station_ctx *hdd_sta_ctx;
Jeff Johnson9d295242017-08-29 14:39:48 -070011467 struct hdd_adapter *adapter;
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011468 uint16_t len = 0;
11469 char *buf = *buf_ptr;
11470
11471 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
11472 if (!hdd_ctx) {
11473 hdd_err("Failed to get hdd context ");
11474 return;
11475 }
11476
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080011477 hdd_debug("size of buffer: %d", *size);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011478
11479 len += scnprintf(buf + len, *size - len,
Jeff Johnson214671b2017-10-30 19:45:23 -070011480 "\n is_wiphy_suspended %d", hdd_ctx->is_wiphy_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011481 len += scnprintf(buf + len, *size - len,
Rajeev Kumareada0d02016-12-08 17:44:17 -080011482 "\n is_scheduler_suspended %d",
11483 hdd_ctx->is_scheduler_suspended);
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011484
Dustin Brown920397d2017-12-13 16:27:50 -080011485 hdd_for_each_adapter(hdd_ctx, adapter) {
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011486 if (adapter->dev)
11487 len += scnprintf(buf + len, *size - len,
11488 "\n device name: %s", adapter->dev->name);
wadesong42968e92017-06-08 14:11:21 +080011489 len += scnprintf(buf + len, *size - len,
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011490 "\n device_mode: %d", adapter->device_mode);
11491 switch (adapter->device_mode) {
11492 case QDF_STA_MODE:
11493 case QDF_P2P_CLIENT_MODE:
11494 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
11495 len += scnprintf(buf + len, *size - len,
11496 "\n connState: %d",
11497 hdd_sta_ctx->conn_info.connState);
11498 break;
11499
11500 default:
11501 break;
11502 }
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011503 }
11504
11505 *size -= len;
11506 *buf_ptr += len;
11507}
11508
11509/**
11510 * hdd_register_debug_callback() - registration function for hdd layer
11511 * to print hdd state information
11512 *
11513 * Return: None
11514 */
11515static void hdd_register_debug_callback(void)
11516{
11517 qdf_register_debug_callback(QDF_MODULE_ID_HDD, &hdd_state_info_dump);
11518}
Wen Gong3f003382018-05-14 14:26:37 +080011519#else /* WLAN_FEATURE_MEMDUMP_ENABLE */
Wen Gongaa6d55d2018-04-26 16:33:21 +080011520static void hdd_register_debug_callback(void)
11521{
11522}
Wen Gong3f003382018-05-14 14:26:37 +080011523#endif /* WLAN_FEATURE_MEMDUMP_ENABLE */
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053011524
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053011525/*
11526 * wlan_init_bug_report_lock() - Initialize bug report lock
11527 *
11528 * This function is used to create bug report lock
11529 *
11530 * Return: None
11531 */
11532static void wlan_init_bug_report_lock(void)
11533{
Jeff Johnson2b6982c2018-05-29 14:56:11 -070011534 struct cds_context *p_cds_context;
SaidiReddy Yenuga699d90e2017-04-14 16:09:24 +053011535
11536 p_cds_context = cds_get_global_context();
11537 if (!p_cds_context) {
11538 hdd_err("cds context is NULL");
11539 return;
11540 }
11541
11542 qdf_spinlock_create(&p_cds_context->bug_report_lock);
11543}
11544
Nirav Shahd21a2e32018-04-20 16:34:43 +053011545#ifdef CONFIG_DP_TRACE
Mohit Khannaf8f96822017-05-17 17:11:59 -070011546void hdd_dp_trace_init(struct hdd_config *config)
11547{
Mohit Khannaf8f96822017-05-17 17:11:59 -070011548 bool live_mode = DP_TRACE_CONFIG_DEFAULT_LIVE_MODE;
11549 uint8_t thresh = DP_TRACE_CONFIG_DEFAULT_THRESH;
11550 uint16_t thresh_time_limit = DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT;
11551 uint8_t verbosity = DP_TRACE_CONFIG_DEFAULT_VERBOSTY;
11552 uint8_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP;
11553 uint8_t config_params[DP_TRACE_CONFIG_NUM_PARAMS];
11554 uint8_t num_entries = 0;
Lin Baiaa7f8d72017-10-18 17:23:45 +080011555 uint32_t bw_compute_interval;
Mohit Khannaf8f96822017-05-17 17:11:59 -070011556
Nirav Shahd21a2e32018-04-20 16:34:43 +053011557 if (!config->enable_dp_trace) {
11558 hdd_err("dp trace is disabled from ini");
11559 return;
11560 }
11561
Mohit Khannaf8f96822017-05-17 17:11:59 -070011562 hdd_string_to_u8_array(config->dp_trace_config, config_params,
11563 &num_entries, sizeof(config_params));
11564
11565 /* calculating, num bw timer intervals in a second (1000ms) */
Lin Baiaa7f8d72017-10-18 17:23:45 +080011566 bw_compute_interval = GET_BW_COMPUTE_INTV(config);
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080011567 if (bw_compute_interval <= 1000 && bw_compute_interval > 0)
Lin Baiaa7f8d72017-10-18 17:23:45 +080011568 thresh_time_limit = 1000 / bw_compute_interval;
Jiachao Wu1b00ecb2017-07-05 19:13:41 +080011569 else if (bw_compute_interval > 1000) {
11570 hdd_err("busBandwidthComputeInterval > 1000, using 1000");
11571 thresh_time_limit = 1;
11572 } else
Mohit Khannaf8f96822017-05-17 17:11:59 -070011573 hdd_err("busBandwidthComputeInterval is 0, using defaults");
11574
11575 switch (num_entries) {
11576 case 4:
11577 proto_bitmap = config_params[3];
Alok Kumarb5a33a22018-05-07 18:09:14 +053011578 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070011579 case 3:
11580 verbosity = config_params[2];
Alok Kumarb5a33a22018-05-07 18:09:14 +053011581 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070011582 case 2:
11583 thresh = config_params[1];
Alok Kumarb5a33a22018-05-07 18:09:14 +053011584 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070011585 case 1:
11586 live_mode = config_params[0];
Alok Kumarb5a33a22018-05-07 18:09:14 +053011587 /* fall through */
Mohit Khannaf8f96822017-05-17 17:11:59 -070011588 default:
Dustin Browna7bb6ae2018-08-16 16:51:50 -070011589 hdd_debug("live_mode %u thresh %u time_limit %u verbosity %u bitmap 0x%x",
11590 live_mode, thresh, thresh_time_limit,
11591 verbosity, proto_bitmap);
Mohit Khannaf8f96822017-05-17 17:11:59 -070011592 };
11593
11594 qdf_dp_trace_init(live_mode, thresh, thresh_time_limit,
11595 verbosity, proto_bitmap);
11596
11597}
Nirav Shahd21a2e32018-04-20 16:34:43 +053011598#endif
11599
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011600#ifdef DISABLE_CHANNEL_LIST
Dustin Brown623e7e32018-09-05 14:27:50 -070011601static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011602{
11603 return qdf_mutex_create(&hdd_ctx->cache_channel_lock);
11604}
11605#else
Dustin Brown623e7e32018-09-05 14:27:50 -070011606static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011607{
Dustin Brown623e7e32018-09-05 14:27:50 -070011608 return QDF_STATUS_SUCCESS;
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011609}
11610#endif
11611
Dustin Brown61cc3932018-10-18 16:12:13 -070011612static QDF_STATUS
11613hdd_open_adapters_for_mission_mode(struct hdd_context *hdd_ctx)
Dustin Browna2deeb72018-10-18 14:19:27 -070011614{
11615 struct hdd_adapter *adapter;
11616 enum dot11p_mode dot11p_mode;
Dustin Brown61cc3932018-10-18 16:12:13 -070011617 QDF_STATUS status;
Dustin Browna2deeb72018-10-18 14:19:27 -070011618
11619 ucfg_mlme_get_dot11p_mode(hdd_ctx->psoc, &dot11p_mode);
11620
11621 /* Create only 802.11p interface? */
11622 if (dot11p_mode == CFG_11P_STANDALONE)
Dustin Brown61cc3932018-10-18 16:12:13 -070011623 return hdd_open_ocb_interface(hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070011624
11625 adapter = hdd_open_adapter(hdd_ctx, QDF_STA_MODE, "wlan%d",
11626 wlan_hdd_get_intf_addr(hdd_ctx),
11627 NET_NAME_UNKNOWN, true);
11628 if (!adapter)
Dustin Brown61cc3932018-10-18 16:12:13 -070011629 return QDF_STATUS_E_INVAL;
Dustin Browna2deeb72018-10-18 14:19:27 -070011630
Dustin Brown61cc3932018-10-18 16:12:13 -070011631 /* opening concurrent STA is best effort, continue on error */
11632 hdd_open_concurrent_interface(hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070011633
Dustin Brown61cc3932018-10-18 16:12:13 -070011634 status = hdd_open_p2p_interface(hdd_ctx);
11635 if (status)
Dustin Browna2deeb72018-10-18 14:19:27 -070011636 goto err_close_adapters;
11637
11638 /* Open 802.11p Interface */
11639 if (dot11p_mode == CFG_11P_CONCURRENT) {
Dustin Brown61cc3932018-10-18 16:12:13 -070011640 status = hdd_open_ocb_interface(hdd_ctx);
11641 if (QDF_IS_STATUS_ERROR(status))
Dustin Browna2deeb72018-10-18 14:19:27 -070011642 goto err_close_adapters;
11643 }
11644
Dustin Brown61cc3932018-10-18 16:12:13 -070011645 return QDF_STATUS_SUCCESS;
Dustin Browna2deeb72018-10-18 14:19:27 -070011646
11647err_close_adapters:
11648 hdd_close_all_adapters(hdd_ctx, true);
11649
Dustin Brown61cc3932018-10-18 16:12:13 -070011650 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070011651}
11652
Dustin Brown61cc3932018-10-18 16:12:13 -070011653static QDF_STATUS hdd_open_adapters_for_ftm_mode(struct hdd_context *hdd_ctx)
Dustin Browna2deeb72018-10-18 14:19:27 -070011654{
11655 struct hdd_adapter *adapter;
Dustin Brown61cc3932018-10-18 16:12:13 -070011656
11657 adapter = hdd_open_adapter(hdd_ctx, QDF_FTM_MODE, "wlan%d",
11658 wlan_hdd_get_intf_addr(hdd_ctx),
11659 NET_NAME_UNKNOWN, true);
11660
11661 return adapter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_INVAL;
11662}
11663
11664static QDF_STATUS
11665hdd_open_adapters_for_monitor_mode(struct hdd_context *hdd_ctx)
11666{
11667 struct hdd_adapter *adapter;
11668
11669 adapter = hdd_open_adapter(hdd_ctx, QDF_MONITOR_MODE, "wlan%d",
11670 wlan_hdd_get_intf_addr(hdd_ctx),
11671 NET_NAME_UNKNOWN, true);
11672
11673 return adapter ? QDF_STATUS_SUCCESS : QDF_STATUS_E_INVAL;
11674}
11675
11676static QDF_STATUS hdd_open_adapters_for_epping_mode(struct hdd_context *hdd_ctx)
11677{
Dustin Browna2deeb72018-10-18 14:19:27 -070011678 QDF_STATUS status;
Dustin Brown61cc3932018-10-18 16:12:13 -070011679 qdf_device_t qdf_dev;
Dustin Browna2deeb72018-10-18 14:19:27 -070011680
11681 qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
11682 QDF_BUG(qdf_dev);
11683 if (!qdf_dev)
Dustin Brown61cc3932018-10-18 16:12:13 -070011684 return QDF_STATUS_E_INVAL;
11685
11686 status = epping_open();
11687 if (QDF_IS_STATUS_ERROR(status))
11688 return status;
11689
11690 if (epping_enable(qdf_dev->dev)) {
11691 status = QDF_STATUS_E_INVAL;
11692 goto epping_close;
11693 }
11694
11695 return QDF_STATUS_SUCCESS;
11696
11697epping_close:
11698 epping_close();
11699
11700 return status;
11701}
11702
11703typedef QDF_STATUS (*hdd_open_mode_handler)(struct hdd_context *hdd_ctx);
11704
11705static const hdd_open_mode_handler
11706hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = {
11707 [QDF_GLOBAL_MISSION_MODE] = hdd_open_adapters_for_mission_mode,
11708 [QDF_GLOBAL_FTM_MODE] = hdd_open_adapters_for_ftm_mode,
11709 [QDF_GLOBAL_MONITOR_MODE] = hdd_open_adapters_for_monitor_mode,
11710 [QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode,
11711};
11712
Dustin Brown92bd8382018-10-31 15:49:46 -070011713static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
11714 enum QDF_GLOBAL_MODE driver_mode)
Dustin Brown61cc3932018-10-18 16:12:13 -070011715{
11716 QDF_STATUS status;
11717
11718 if (driver_mode < 0 ||
11719 driver_mode >= QDF_GLOBAL_MAX_MODE ||
11720 !hdd_open_mode_handlers[driver_mode]) {
11721 hdd_err("Driver mode %d not supported", driver_mode);
11722 return -ENOTSUPP;
11723 }
Dustin Browna2deeb72018-10-18 14:19:27 -070011724
11725 hdd_hold_rtnl_lock();
Dustin Brown61cc3932018-10-18 16:12:13 -070011726 status = hdd_open_mode_handlers[driver_mode](hdd_ctx);
Dustin Browna2deeb72018-10-18 14:19:27 -070011727 hdd_release_rtnl_lock();
11728
Dustin Brown92bd8382018-10-31 15:49:46 -070011729 return status;
Dustin Browna2deeb72018-10-18 14:19:27 -070011730}
11731
Dustin Brown623e7e32018-09-05 14:27:50 -070011732int hdd_wlan_startup(struct hdd_context *hdd_ctx)
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080011733{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053011734 QDF_STATUS status;
Dustin Brown623e7e32018-09-05 14:27:50 -070011735 int errno;
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080011736
Dustin Brown491d54b2018-03-14 12:39:11 -070011737 hdd_enter();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080011738
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053011739 hdd_action_oui_config(hdd_ctx);
11740
Sravan Kumar Kairam6b727a42017-08-29 15:39:58 +053011741 qdf_nbuf_init_replenish_timer();
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011742
Dustin Brown623e7e32018-09-05 14:27:50 -070011743 status = wlan_hdd_cache_chann_mutex_create(hdd_ctx);
11744 if (QDF_IS_STATUS_ERROR(status))
11745 return qdf_status_to_os_return(status);
Ashish Kumar Dhanotiya3f78e682018-03-14 11:19:27 +053011746
Ajit Pal Singh2c7aecd2017-05-19 15:09:23 +053011747#ifdef FEATURE_WLAN_CH_AVOID
11748 mutex_init(&hdd_ctx->avoid_freq_lock);
11749#endif
Arun Khandavallifae92942016-08-01 13:31:08 +053011750
Naveen Rawate02f8f52018-04-05 11:58:04 -070011751 osif_request_manager_init();
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053011752 qdf_atomic_init(&hdd_ctx->con_mode_flag);
Dustin Brown021cecd2017-12-11 13:56:43 -080011753 hdd_driver_memdump_init();
Dustin Brown86d196b2018-08-02 11:51:49 -070011754 hdd_bus_bandwidth_init(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -080011755
Dustin Brown623e7e32018-09-05 14:27:50 -070011756 errno = hdd_wlan_start_modules(hdd_ctx, false);
11757 if (errno) {
11758 hdd_err("Failed to start modules; errno:%d", errno);
11759 goto memdump_deinit;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011760 }
11761
Yingying Tang80e15f32016-09-27 18:23:01 +080011762 wlan_hdd_update_wiphy(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011763
Dustin Brown623e7e32018-09-05 14:27:50 -070011764 hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
11765 if (!hdd_ctx->mac_handle) {
Jeff Johnson16528362018-06-14 12:34:16 -070011766 hdd_err("Mac Handle is null");
Dustin Brown623e7e32018-09-05 14:27:50 -070011767 goto stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011768 }
11769
Dustin Brown623e7e32018-09-05 14:27:50 -070011770 errno = hdd_wiphy_init(hdd_ctx);
11771 if (errno) {
11772 hdd_err("Failed to initialize wiphy; errno:%d", errno);
11773 goto stop_modules;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011774 }
11775
Nirav Shahd21a2e32018-04-20 16:34:43 +053011776 hdd_dp_trace_init(hdd_ctx->config);
Nirav Shahcc1f1ae2016-04-26 11:41:29 +053011777
Yuanyuan Liuc98370e2016-10-13 11:22:13 -070011778 hdd_initialize_mac_address(hdd_ctx);
Prashanth Bhatta75fa9a12016-01-11 18:30:08 -080011779
Dustin Brown623e7e32018-09-05 14:27:50 -070011780 errno = register_netdevice_notifier(&hdd_netdev_notifier);
11781 if (errno) {
11782 hdd_err("register_netdevice_notifier failed; errno:%d", errno);
11783 goto unregister_wiphy;
Paul Zhangfb02f452017-12-22 11:58:43 +080011784 }
Arun Khandavalli08479ba2017-08-07 19:56:23 +053011785
Dustin Brown623e7e32018-09-05 14:27:50 -070011786 errno = register_reboot_notifier(&system_reboot_notifier);
11787 if (errno) {
11788 hdd_err("Failed to register reboot notifier; errno:%d", errno);
11789 goto unregister_netdev;
Arunk Khandavalli830c9692018-03-22 12:17:40 +053011790 }
11791
Yingying Tang3ba3dbc2016-09-27 16:36:58 +080011792 wlan_hdd_update_11n_mode(hdd_ctx->config);
11793
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011794#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
Anurag Chouhan210db072016-02-22 18:42:15 +053011795 status = qdf_mc_timer_init(&hdd_ctx->skip_acs_scan_timer,
Anurag Chouhan6d760662016-02-20 16:05:43 +053011796 QDF_TIMER_TYPE_SW,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011797 hdd_skip_acs_scan_timer_handler,
Dustin Browna2deeb72018-10-18 14:19:27 -070011798 hdd_ctx);
Dustin Brown92bd8382018-10-31 15:49:46 -070011799 if (QDF_IS_STATUS_ERROR(status))
Jeff Johnson34c88b72016-08-15 14:27:11 -070011800 hdd_err("Failed to init ACS Skip timer");
Dustin Brown92bd8382018-10-31 15:49:46 -070011801
Liangwei Dongaef84342016-10-21 05:28:00 -040011802 qdf_spinlock_create(&hdd_ctx->acs_skip_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011803#endif
11804
Arunk Khandavalli40943af2017-05-15 19:25:34 +053011805 hdd_lpass_notify_wlan_version(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011806
Dustin Brown623e7e32018-09-05 14:27:50 -070011807 errno = hdd_register_notifiers(hdd_ctx);
11808 if (errno)
11809 goto unregister_reboot;
Prashanth Bhatta9b03ab32016-04-28 12:35:13 -070011810
Paul Zhangfb02f452017-12-22 11:58:43 +080011811 status = wlansap_global_init();
Dustin Brown92bd8382018-10-31 15:49:46 -070011812 if (QDF_IS_STATUS_ERROR(status))
11813 goto unregister_notifiers;
Paul Zhangfb02f452017-12-22 11:58:43 +080011814
Dustin Brown92bd8382018-10-31 15:49:46 -070011815 hdd_set_idle_ps_config(hdd_ctx, hdd_ctx->config->fIsImpsEnabled);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011816
Dustin Brown92bd8382018-10-31 15:49:46 -070011817 hdd_exit();
11818
11819 return 0;
11820
11821unregister_notifiers:
11822 hdd_unregister_notifiers(hdd_ctx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011823
Dustin Brown623e7e32018-09-05 14:27:50 -070011824unregister_reboot:
Arunk Khandavalli830c9692018-03-22 12:17:40 +053011825 unregister_reboot_notifier(&system_reboot_notifier);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011826
Dustin Brown623e7e32018-09-05 14:27:50 -070011827unregister_netdev:
Poddar, Siddarthaee8ff62017-10-04 12:53:22 +053011828 unregister_netdevice_notifier(&hdd_netdev_notifier);
11829
Dustin Brown623e7e32018-09-05 14:27:50 -070011830unregister_wiphy:
Rachit Kankane30807332018-06-27 18:39:36 +053011831 qdf_dp_trace_deinit();
Prashanth Bhattac2a16f62015-12-03 15:06:15 -080011832 wiphy_unregister(hdd_ctx->wiphy);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011833
Dustin Brown623e7e32018-09-05 14:27:50 -070011834stop_modules:
Rajeev Kumar3fef4e82017-03-31 20:25:23 -070011835 hdd_wlan_stop_modules(hdd_ctx, false);
Arun Khandavallifae92942016-08-01 13:31:08 +053011836
Dustin Brown623e7e32018-09-05 14:27:50 -070011837memdump_deinit:
Dustin Brown86d196b2018-08-02 11:51:49 -070011838 hdd_bus_bandwidth_deinit(hdd_ctx);
Dustin Brown021cecd2017-12-11 13:56:43 -080011839 hdd_driver_memdump_deinit();
Naveen Rawate02f8f52018-04-05 11:58:04 -070011840 osif_request_manager_deinit();
Dustin Brown623e7e32018-09-05 14:27:50 -070011841 qdf_nbuf_deinit_replenish_timer();
Ryan Hsucfef0ae2016-04-28 10:20:46 -070011842
Nachiket Kukade8003d252017-03-30 15:55:58 +053011843 if (cds_is_fw_down())
11844 hdd_err("Not setting the complete event as fw is down");
11845 else
Dustin Brown623e7e32018-09-05 14:27:50 -070011846 hdd_start_complete(errno);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011847
Dustin Browne74003f2018-03-14 12:51:58 -070011848 hdd_exit();
Dustin Brown92bd8382018-10-31 15:49:46 -070011849
Dustin Brown623e7e32018-09-05 14:27:50 -070011850 return errno;
Dustin Brown92bd8382018-10-31 15:49:46 -070011851}
11852
11853QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx)
11854{
11855 enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam();
11856 QDF_STATUS status;
11857
11858 status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode);
11859 if (QDF_IS_STATUS_ERROR(status)) {
11860 hdd_err("Failed to create vdevs; status:%d", status);
11861 return status;
11862 }
11863
11864 if (hdd_ctx->rps)
11865 hdd_set_rps_cpu_mask(hdd_ctx);
11866
11867 if (driver_mode != QDF_GLOBAL_FTM_MODE)
11868 hdd_psoc_idle_timer_start(hdd_ctx);
11869
11870 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011871}
11872
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080011873/**
Arun Khandavallifae92942016-08-01 13:31:08 +053011874 * hdd_wlan_update_target_info() - update target type info
11875 * @hdd_ctx: HDD context
11876 * @context: hif context
11877 *
11878 * Update target info received from firmware in hdd context
11879 * Return:None
11880 */
11881
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011882void hdd_wlan_update_target_info(struct hdd_context *hdd_ctx, void *context)
Arun Khandavallifae92942016-08-01 13:31:08 +053011883{
11884 struct hif_target_info *tgt_info = hif_get_target_info_handle(context);
11885
11886 if (!tgt_info) {
11887 hdd_err("Target info is Null");
11888 return;
11889 }
11890
11891 hdd_ctx->target_type = tgt_info->target_type;
11892}
11893
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011894void hdd_get_nud_stats_cb(void *data, struct rsp_stats *rsp, void *context)
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011895{
11896 struct hdd_context *hdd_ctx = (struct hdd_context *)data;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011897 int status;
11898 struct hdd_adapter *adapter = NULL;
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011899 struct osif_request *request = NULL;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011900
Dustin Brown491d54b2018-03-14 12:39:11 -070011901 hdd_enter();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011902
11903 if (!rsp) {
11904 hdd_err("data is null");
11905 return;
11906 }
11907
11908 status = wlan_hdd_validate_context(hdd_ctx);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011909 if (status != 0)
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011910 return;
11911
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011912 request = osif_request_get(context);
Dundi Raviteja3bcf3a82018-05-22 13:24:18 +053011913 if (!request) {
11914 hdd_err("obselete request");
11915 return;
11916 }
11917
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011918 adapter = hdd_get_adapter_by_vdev(hdd_ctx, rsp->vdev_id);
11919 if ((NULL == adapter) || (WLAN_HDD_ADAPTER_MAGIC != adapter->magic)) {
11920 hdd_err("Invalid adapter or adapter has invalid magic");
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011921 osif_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011922 return;
11923 }
11924
Alok Kumarce2c29a2018-10-12 15:44:02 +053011925 hdd_debug("rsp->arp_req_enqueue :%x", rsp->arp_req_enqueue);
11926 hdd_debug("rsp->arp_req_tx_success :%x", rsp->arp_req_tx_success);
11927 hdd_debug("rsp->arp_req_tx_failure :%x", rsp->arp_req_tx_failure);
11928 hdd_debug("rsp->arp_rsp_recvd :%x", rsp->arp_rsp_recvd);
11929 hdd_debug("rsp->out_of_order_arp_rsp_drop_cnt :%x",
11930 rsp->out_of_order_arp_rsp_drop_cnt);
11931 hdd_debug("rsp->dad_detected :%x", rsp->dad_detected);
11932 hdd_debug("rsp->connect_status :%x", rsp->connect_status);
11933 hdd_debug("rsp->ba_session_establishment_status :%x",
11934 rsp->ba_session_establishment_status);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011935
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011936 adapter->hdd_stats.hdd_arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd;
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011937 adapter->dad |= rsp->dad_detected;
11938 adapter->con_status = rsp->connect_status;
11939
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011940 /* Flag true indicates connectivity check stats present. */
11941 if (rsp->connect_stats_present) {
Alok Kumarce2c29a2018-10-12 15:44:02 +053011942 hdd_debug("rsp->tcp_ack_recvd :%x", rsp->tcp_ack_recvd);
11943 hdd_debug("rsp->icmpv4_rsp_recvd :%x", rsp->icmpv4_rsp_recvd);
Poddar, Siddarth31797fa2018-01-22 17:24:15 +053011944 adapter->hdd_stats.hdd_tcp_stats.rx_fw_cnt = rsp->tcp_ack_recvd;
11945 adapter->hdd_stats.hdd_icmpv4_stats.rx_fw_cnt =
11946 rsp->icmpv4_rsp_recvd;
11947 }
11948
Jeff Johnsonf1a99ea2018-06-28 13:27:01 -070011949 osif_request_complete(request);
11950 osif_request_put(request);
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011951
Dustin Browne74003f2018-03-14 12:51:58 -070011952 hdd_exit();
Anurag Chouhan3920c0f2017-09-11 17:10:56 +053011953}
11954
11955/**
Arun Khandavallifae92942016-08-01 13:31:08 +053011956 * hdd_register_cb - Register HDD callbacks.
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011957 * @hdd_ctx: HDD context
11958 *
11959 * Register the HDD callbacks to CDS/SME.
11960 *
11961 * Return: 0 for success or Error code for failure
11962 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070011963int hdd_register_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011964{
11965 QDF_STATUS status;
11966 int ret = 0;
Jeff Johnson16528362018-06-14 12:34:16 -070011967 mac_handle_t mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011968
Dustin Brown491d54b2018-03-14 12:39:11 -070011969 hdd_enter();
Sourav Mohapatra674925f2018-04-16 11:16:58 +053011970 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
11971 hdd_err("in ftm mode, no need to register callbacks");
11972 return ret;
11973 }
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011974
Jeff Johnson16528362018-06-14 12:34:16 -070011975 mac_handle = hdd_ctx->mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011976
Jeff Johnson16528362018-06-14 12:34:16 -070011977 sme_register_oem_data_rsp_callback(mac_handle,
11978 hdd_send_oem_data_rsp_msg);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011979
Jeff Johnson16528362018-06-14 12:34:16 -070011980 sme_register_mgmt_frame_ind_callback(mac_handle,
Deepthi Gowrid5a58fe2016-09-03 16:01:28 +053011981 hdd_indicate_mgmt_frame);
Jeff Johnson16528362018-06-14 12:34:16 -070011982 sme_set_tsfcb(mac_handle, hdd_get_tsf_cb, hdd_ctx);
11983 sme_nan_register_callback(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011984 wlan_hdd_cfg80211_nan_callback);
Jeff Johnson16528362018-06-14 12:34:16 -070011985 sme_stats_ext_register_callback(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011986 wlan_hdd_cfg80211_stats_ext_callback);
11987
Jeff Johnson16528362018-06-14 12:34:16 -070011988 sme_ext_scan_register_callback(mac_handle,
11989 wlan_hdd_cfg80211_extscan_callback);
11990 sme_stats_ext2_register_callback(mac_handle,
lifeng66831662017-05-19 16:01:35 +080011991 wlan_hdd_cfg80211_stats_ext2_callback);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011992
Jeff Johnson16528362018-06-14 12:34:16 -070011993 sme_set_rssi_threshold_breached_cb(mac_handle,
11994 hdd_rssi_threshold_breached);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011995
Jeff Johnson16528362018-06-14 12:34:16 -070011996 sme_set_link_layer_stats_ind_cb(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053011997 wlan_hdd_cfg80211_link_layer_stats_callback);
11998
Jeff Johnson16528362018-06-14 12:34:16 -070011999 sme_rso_cmd_status_cb(mac_handle, wlan_hdd_rso_cmd_status_cb);
Sreelakshmi Konamki88a2a412017-04-14 15:11:55 +053012000
Jeff Johnson16528362018-06-14 12:34:16 -070012001 sme_set_link_layer_ext_cb(mac_handle,
Zhang Qianca38fb12016-12-23 11:10:48 +080012002 wlan_hdd_cfg80211_link_layer_stats_ext_callback);
12003
Jeff Johnson16528362018-06-14 12:34:16 -070012004 status = sme_set_lost_link_info_cb(mac_handle,
Sreelakshmi Konamki58c72432016-11-09 17:06:44 +053012005 hdd_lost_link_info_cb);
12006 /* print error and not block the startup process */
12007 if (!QDF_IS_STATUS_SUCCESS(status))
12008 hdd_err("set lost link info callback failed");
12009
Poddar, Siddarth34872782017-08-10 14:08:51 +053012010 ret = hdd_register_data_stall_detect_cb();
12011 if (ret) {
12012 hdd_err("Register data stall detect detect callback failed.");
12013 return ret;
12014 }
12015
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012016 wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx);
12017
Jeff Johnson16528362018-06-14 12:34:16 -070012018 sme_register_set_connection_info_cb(mac_handle,
12019 hdd_set_connection_in_progress,
12020 hdd_is_connection_in_progress);
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +053012021
Jeff Johnson16528362018-06-14 12:34:16 -070012022 status = sme_congestion_register_callback(mac_handle,
12023 hdd_update_cca_info_cb);
Padma, Santhosh Kumar16dacfb2017-03-21 19:05:40 +053012024 if (!QDF_IS_STATUS_SUCCESS(status))
12025 hdd_err("set congestion callback failed");
12026
Jeff Johnson16528362018-06-14 12:34:16 -070012027 status = sme_set_bt_activity_info_cb(mac_handle,
Vidyullatha Kanchanapallybe0ebb32017-03-23 14:36:21 +053012028 hdd_bt_activity_cb);
12029 if (!QDF_IS_STATUS_SUCCESS(status))
12030 hdd_err("set bt activity info callback failed");
12031
Jeff Johnson16528362018-06-14 12:34:16 -070012032 status = sme_register_tx_queue_cb(mac_handle,
Varun Reddy Yeturu076eaa82018-01-16 12:16:14 -080012033 hdd_tx_queue_cb);
12034 if (!QDF_IS_STATUS_SUCCESS(status))
12035 hdd_err("Register tx queue callback failed");
12036
Dustin Browne74003f2018-03-14 12:51:58 -070012037 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012038
12039 return ret;
12040}
12041
12042/**
12043 * hdd_deregister_cb() - De-Register HDD callbacks.
12044 * @hdd_ctx: HDD context
12045 *
12046 * De-Register the HDD callbacks to CDS/SME.
12047 *
12048 * Return: void
12049 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012050void hdd_deregister_cb(struct hdd_context *hdd_ctx)
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012051{
12052 QDF_STATUS status;
Poddar, Siddarth34872782017-08-10 14:08:51 +053012053 int ret;
Jeff Johnson16528362018-06-14 12:34:16 -070012054 mac_handle_t mac_handle;
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012055
Dustin Brown491d54b2018-03-14 12:39:11 -070012056 hdd_enter();
Sourav Mohapatra674925f2018-04-16 11:16:58 +053012057 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
12058 hdd_err("in ftm mode, no need to deregister callbacks");
12059 return;
12060 }
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012061
Jeff Johnson16528362018-06-14 12:34:16 -070012062 mac_handle = hdd_ctx->mac_handle;
12063 sme_deregister_tx_queue_cb(mac_handle);
12064 status = sme_deregister_for_dcc_stats_event(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012065 if (!QDF_IS_STATUS_SUCCESS(status))
12066 hdd_err("De-register of dcc stats callback failed: %d",
12067 status);
12068
Jeff Johnson16528362018-06-14 12:34:16 -070012069 sme_reset_link_layer_stats_ind_cb(mac_handle);
12070 sme_reset_rssi_threshold_breached_cb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012071
Jeff Johnson16528362018-06-14 12:34:16 -070012072 sme_stats_ext_register_callback(mac_handle,
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012073 wlan_hdd_cfg80211_stats_ext_callback);
12074
Jeff Johnson16528362018-06-14 12:34:16 -070012075 sme_nan_deregister_callback(mac_handle);
12076 status = sme_reset_tsfcb(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012077 if (!QDF_IS_STATUS_SUCCESS(status))
12078 hdd_err("Failed to de-register tsfcb the callback:%d",
12079 status);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012080
Poddar, Siddarth34872782017-08-10 14:08:51 +053012081 ret = hdd_deregister_data_stall_detect_cb();
12082 if (ret)
12083 hdd_err("Failed to de-register data stall detect event callback");
12084
Jeff Johnson16528362018-06-14 12:34:16 -070012085 sme_deregister_oem_data_rsp_callback(mac_handle);
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012086
Dustin Browne74003f2018-03-14 12:51:58 -070012087 hdd_exit();
Arun Khandavalli4b55da72016-07-19 19:55:01 +053012088}
12089
12090/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012091 * hdd_softap_sta_deauth() - handle deauth req from HDD
12092 * @adapter: Pointer to the HDD
12093 * @enable: bool value
12094 *
12095 * This to take counter measure to handle deauth req from HDD
12096 *
12097 * Return: None
12098 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012099QDF_STATUS hdd_softap_sta_deauth(struct hdd_adapter *adapter,
Jeff Johnsone6bf7192017-11-07 15:16:09 -080012100 struct csr_del_sta_params *pDelStaParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012101{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012102 QDF_STATUS qdf_status = QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012103
Dustin Brown491d54b2018-03-14 12:39:11 -070012104 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012105
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012106 /* Ignore request to deauth bcmc station */
12107 if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012108 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012109
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012110 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012111 wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
12112 pDelStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012113
Dustin Browne74003f2018-03-14 12:51:58 -070012114 hdd_exit();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012115 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012116}
12117
12118/**
12119 * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
12120 * @adapter: Pointer to the HDD
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053012121 * @p_del_sta_params: pointer to station deletion parameters
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012122 *
12123 * This to take counter measure to handle deauth req from HDD
12124 *
12125 * Return: None
12126 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012127void hdd_softap_sta_disassoc(struct hdd_adapter *adapter,
Jeff Johnsone6bf7192017-11-07 15:16:09 -080012128 struct csr_del_sta_params *pDelStaParams)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012129{
Dustin Brown491d54b2018-03-14 12:39:11 -070012130 hdd_enter();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012131
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012132 /* Ignore request to disassoc bcmc station */
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053012133 if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012134 return;
12135
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012136 wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
Deepthi Gowrib3bfefd2016-09-13 15:14:34 +053012137 pDelStaParams);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012138}
12139
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012140/**
12141 * hdd_issta_p2p_clientconnected() - check if sta or p2p client is connected
12142 * @hdd_ctx: HDD Context
12143 *
12144 * API to find if there is any STA or P2P-Client is connected
12145 *
12146 * Return: true if connected; false otherwise
12147 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012148QDF_STATUS hdd_issta_p2p_clientconnected(struct hdd_context *hdd_ctx)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012149{
Jeff Johnson16528362018-06-14 12:34:16 -070012150 return sme_is_sta_p2p_client_connected(hdd_ctx->mac_handle);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012151}
12152
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012153void wlan_hdd_disable_roaming(struct hdd_adapter *cur_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012154{
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012155 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
12156 struct hdd_adapter *adapter = NULL;
12157 struct csr_roam_profile *roam_profile;
12158 struct hdd_station_ctx *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012159
Dustin Brown1dbefe62018-09-11 16:32:03 -070012160 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012161 hdd_debug("No active sta session");
12162 return;
12163 }
12164
12165 hdd_for_each_adapter(hdd_ctx, adapter) {
12166 roam_profile = hdd_roam_profile(adapter);
12167 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
12168
12169 if (cur_adapter->session_id != adapter->session_id &&
12170 adapter->device_mode == QDF_STA_MODE &&
12171 hdd_conn_is_connected(sta_ctx)) {
12172 hdd_debug("%d Disable roaming", adapter->session_id);
Jeff Johnson16528362018-06-14 12:34:16 -070012173 sme_stop_roaming(hdd_ctx->mac_handle,
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012174 adapter->session_id,
12175 ecsr_driver_disabled);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012176 }
12177 }
12178}
12179
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012180void wlan_hdd_enable_roaming(struct hdd_adapter *cur_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012181{
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012182 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(cur_adapter);
12183 struct hdd_adapter *adapter = NULL;
12184 struct csr_roam_profile *roam_profile;
12185 struct hdd_station_ctx *sta_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012186
Dustin Brown1dbefe62018-09-11 16:32:03 -070012187 if (!policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) {
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012188 hdd_debug("No active sta session");
12189 return;
12190 }
12191
12192 hdd_for_each_adapter(hdd_ctx, adapter) {
12193 roam_profile = hdd_roam_profile(adapter);
12194 sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
12195
12196 if (cur_adapter->session_id != adapter->session_id &&
12197 adapter->device_mode == QDF_STA_MODE &&
12198 hdd_conn_is_connected(sta_ctx)) {
12199 hdd_debug("%d Enable roaming", adapter->session_id);
Jeff Johnson16528362018-06-14 12:34:16 -070012200 sme_start_roaming(hdd_ctx->mac_handle,
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053012201 adapter->session_id,
12202 REASON_DRIVER_ENABLED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012203 }
12204 }
12205}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012206
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053012207/**
12208 * nl_srv_bcast_svc() - Wrapper function to send bcast msgs to SVC mcast group
12209 * @skb: sk buffer pointer
12210 *
12211 * Sends the bcast message to SVC multicast group with generic nl socket
12212 * if CNSS_GENL is enabled. Else, use the legacy netlink socket to send.
12213 *
12214 * Return: None
12215 */
12216static void nl_srv_bcast_svc(struct sk_buff *skb)
12217{
12218#ifdef CNSS_GENL
12219 nl_srv_bcast(skb, CLD80211_MCGRP_SVC_MSGS, WLAN_NL_MSG_SVC);
12220#else
12221 nl_srv_bcast(skb);
12222#endif
12223}
12224
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012225void wlan_hdd_send_svc_nlink_msg(int radio, int type, void *data, int len)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012226{
12227 struct sk_buff *skb;
12228 struct nlmsghdr *nlh;
12229 tAniMsgHdr *ani_hdr;
12230 void *nl_data = NULL;
12231 int flags = GFP_KERNEL;
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012232 struct radio_index_tlv *radio_info;
12233 int tlv_len;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012234
12235 if (in_interrupt() || irqs_disabled() || in_atomic())
12236 flags = GFP_ATOMIC;
12237
12238 skb = alloc_skb(NLMSG_SPACE(WLAN_NL_MAX_PAYLOAD), flags);
12239
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012240 if (skb == NULL)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012241 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012242
12243 nlh = (struct nlmsghdr *)skb->data;
12244 nlh->nlmsg_pid = 0; /* from kernel */
12245 nlh->nlmsg_flags = 0;
12246 nlh->nlmsg_seq = 0;
12247 nlh->nlmsg_type = WLAN_NL_MSG_SVC;
12248
12249 ani_hdr = NLMSG_DATA(nlh);
12250 ani_hdr->type = type;
12251
12252 switch (type) {
12253 case WLAN_SVC_FW_CRASHED_IND:
Komal Seelam78ff65a2016-08-18 15:25:24 +053012254 case WLAN_SVC_FW_SHUTDOWN_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012255 case WLAN_SVC_LTE_COEX_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012256 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND:
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070012257 case WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012258 ani_hdr->length = 0;
12259 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012260 break;
12261 case WLAN_SVC_WLAN_STATUS_IND:
12262 case WLAN_SVC_WLAN_VERSION_IND:
12263 case WLAN_SVC_DFS_CAC_START_IND:
12264 case WLAN_SVC_DFS_CAC_END_IND:
12265 case WLAN_SVC_DFS_RADAR_DETECT_IND:
12266 case WLAN_SVC_DFS_ALL_CHANNEL_UNAVAIL_IND:
12267 case WLAN_SVC_WLAN_TP_IND:
Mohit Khannae71e2262015-11-10 09:37:24 -080012268 case WLAN_SVC_WLAN_TP_TX_IND:
Nirav Shahbd36b062016-07-18 11:12:59 +053012269 case WLAN_SVC_RPS_ENABLE_IND:
Orhan K AKYILDIZe7445a22017-01-19 21:21:47 -080012270 case WLAN_SVC_CORE_MINFREQ:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012271 ani_hdr->length = len;
12272 nlh->nlmsg_len = NLMSG_LENGTH((sizeof(tAniMsgHdr) + len));
12273 nl_data = (char *)ani_hdr + sizeof(tAniMsgHdr);
12274 memcpy(nl_data, data, len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012275 break;
12276
12277 default:
Jeff Johnson34c88b72016-08-15 14:27:11 -070012278 hdd_err("WLAN SVC: Attempt to send unknown nlink message %d",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012279 type);
12280 kfree_skb(skb);
12281 return;
12282 }
12283
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012284 /*
Jeff Johnson0d52c7a2017-01-12 08:46:55 -080012285 * Add radio index at the end of the svc event in TLV format
12286 * to maintain the backward compatibility with userspace
12287 * applications.
12288 */
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012289
12290 tlv_len = 0;
12291
12292 if ((sizeof(*ani_hdr) + len + sizeof(struct radio_index_tlv))
12293 < WLAN_NL_MAX_PAYLOAD) {
12294 radio_info = (struct radio_index_tlv *)((char *) ani_hdr +
12295 sizeof(*ani_hdr) + len);
12296 radio_info->type = (unsigned short) WLAN_SVC_WLAN_RADIO_INDEX;
12297 radio_info->length = (unsigned short) sizeof(radio_info->radio);
12298 radio_info->radio = radio;
12299 tlv_len = sizeof(*radio_info);
Dustin Browna2868622018-03-20 11:38:14 -070012300 hdd_debug("Added radio index tlv - radio index %d",
12301 radio_info->radio);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012302 }
12303
12304 nlh->nlmsg_len += tlv_len;
12305 skb_put(skb, NLMSG_SPACE(sizeof(tAniMsgHdr) + len + tlv_len));
12306
Selvaraj, Sridhar046d77d2017-03-07 14:53:13 +053012307 nl_srv_bcast_svc(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012308}
12309
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012310#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
12311void wlan_hdd_auto_shutdown_cb(void)
12312{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012313 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012314
12315 if (!hdd_ctx)
12316 return;
12317
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012318 hdd_debug("Wlan Idle. Sending Shutdown event..");
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012319 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
12320 WLAN_SVC_WLAN_AUTO_SHUTDOWN_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012321}
12322
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012323void wlan_hdd_auto_shutdown_enable(struct hdd_context *hdd_ctx, bool enable)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012324{
Jeff Johnson9d295242017-08-29 14:39:48 -070012325 struct hdd_adapter *adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012326 bool ap_connected = false, sta_connected = false;
Jeff Johnson16528362018-06-14 12:34:16 -070012327 mac_handle_t mac_handle;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012328
Jeff Johnson16528362018-06-14 12:34:16 -070012329 mac_handle = hdd_ctx->mac_handle;
12330 if (!mac_handle)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012331 return;
12332
Dundi Raviteja8e338282018-09-25 17:16:04 +053012333 if (hdd_ctx->config->wlan_auto_shutdown == 0)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012334 return;
12335
12336 if (enable == false) {
Jeff Johnson16528362018-06-14 12:34:16 -070012337 if (sme_set_auto_shutdown_timer(mac_handle, 0) !=
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012338 QDF_STATUS_SUCCESS) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012339 hdd_err("Failed to stop wlan auto shutdown timer");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012340 }
Kondabattini, Ganesh96ac37b2016-09-02 23:12:15 +053012341 wlan_hdd_send_svc_nlink_msg(hdd_ctx->radio_index,
Manikandan Mohan5b1980a2016-05-06 12:41:18 -070012342 WLAN_SVC_WLAN_AUTO_SHUTDOWN_CANCEL_IND, NULL, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012343 return;
12344 }
12345
12346 /* To enable shutdown timer check conncurrency */
Dustin Brown1dbefe62018-09-11 16:32:03 -070012347 if (policy_mgr_concurrent_open_sessions_running(hdd_ctx->psoc)) {
Dustin Brown920397d2017-12-13 16:27:50 -080012348 hdd_for_each_adapter(hdd_ctx, adapter) {
12349 if (adapter->device_mode == QDF_STA_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012350 if (WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
12351 conn_info.connState ==
12352 eConnectionState_Associated) {
12353 sta_connected = true;
12354 break;
12355 }
12356 }
Dustin Brown920397d2017-12-13 16:27:50 -080012357
12358 if (adapter->device_mode == QDF_SAP_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012359 if (WLAN_HDD_GET_AP_CTX_PTR(adapter)->
Jeff Johnson136c51b2017-10-27 20:02:41 -070012360 ap_active == true) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012361 ap_connected = true;
12362 break;
12363 }
12364 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012365 }
12366 }
12367
12368 if (ap_connected == true || sta_connected == true) {
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012369 hdd_debug("CC Session active. Shutdown timer not enabled");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012370 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012371 }
Jeff Johnson68755312017-02-10 11:46:55 -080012372
Jeff Johnson16528362018-06-14 12:34:16 -070012373 if (sme_set_auto_shutdown_timer(mac_handle,
Dundi Raviteja8e338282018-09-25 17:16:04 +053012374 hdd_ctx->config->wlan_auto_shutdown)
Jeff Johnson68755312017-02-10 11:46:55 -080012375 != QDF_STATUS_SUCCESS)
12376 hdd_err("Failed to start wlan auto shutdown timer");
12377 else
Dustin Brown5e89ef82018-03-14 11:50:23 -070012378 hdd_info("Auto Shutdown timer for %d seconds enabled",
Dundi Raviteja8e338282018-09-25 17:16:04 +053012379 hdd_ctx->config->wlan_auto_shutdown);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012380}
12381#endif
12382
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070012383struct hdd_adapter *
12384hdd_get_con_sap_adapter(struct hdd_adapter *this_sap_adapter,
12385 bool check_start_bss)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012386{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012387 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(this_sap_adapter);
Jeff Johnson9d295242017-08-29 14:39:48 -070012388 struct hdd_adapter *adapter, *con_sap_adapter;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012389
12390 con_sap_adapter = NULL;
12391
Dustin Brown920397d2017-12-13 16:27:50 -080012392 hdd_for_each_adapter(hdd_ctx, adapter) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080012393 if (adapter && ((adapter->device_mode == QDF_SAP_MODE) ||
12394 (adapter->device_mode == QDF_P2P_GO_MODE)) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012395 adapter != this_sap_adapter) {
12396 if (check_start_bss) {
12397 if (test_bit(SOFTAP_BSS_STARTED,
12398 &adapter->event_flags)) {
12399 con_sap_adapter = adapter;
12400 break;
12401 }
12402 } else {
12403 con_sap_adapter = adapter;
12404 break;
12405 }
12406 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012407 }
12408
12409 return con_sap_adapter;
12410}
12411
12412#ifdef MSM_PLATFORM
Jeff Johnson9d295242017-08-29 14:39:48 -070012413static inline bool hdd_adapter_is_sta(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012414{
Dustin Brown5ec6b552017-03-31 12:11:40 -070012415 return adapter->device_mode == QDF_STA_MODE ||
12416 adapter->device_mode == QDF_P2P_CLIENT_MODE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012417}
12418
Jeff Johnson9d295242017-08-29 14:39:48 -070012419static inline bool hdd_adapter_is_ap(struct hdd_adapter *adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012420{
Dustin Brown5ec6b552017-03-31 12:11:40 -070012421 return adapter->device_mode == QDF_SAP_MODE ||
12422 adapter->device_mode == QDF_P2P_GO_MODE;
12423}
12424
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012425static bool hdd_any_adapter_is_assoc(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012426{
Dustin Brown920397d2017-12-13 16:27:50 -080012427 struct hdd_adapter *adapter;
Dustin Brown5ec6b552017-03-31 12:11:40 -070012428
Dustin Brown920397d2017-12-13 16:27:50 -080012429 hdd_for_each_adapter(hdd_ctx, adapter) {
12430 if (hdd_adapter_is_sta(adapter) &&
Dustin Brown5ec6b552017-03-31 12:11:40 -070012431 WLAN_HDD_GET_STATION_CTX_PTR(adapter)->
12432 conn_info.connState == eConnectionState_Associated) {
12433 return true;
12434 }
12435
Dustin Brown920397d2017-12-13 16:27:50 -080012436 if (hdd_adapter_is_ap(adapter) &&
Jeff Johnson136c51b2017-10-27 20:02:41 -070012437 WLAN_HDD_GET_AP_CTX_PTR(adapter)->ap_active) {
Dustin Brown5ec6b552017-03-31 12:11:40 -070012438 return true;
12439 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070012440 }
12441
12442 return false;
12443}
12444
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012445static bool hdd_bus_bw_compute_timer_is_running(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012446{
12447 bool is_running;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012448
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +053012449 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012450 is_running = hdd_ctx->bus_bw_timer_running;
Poddar, Siddarth57f4d3f2017-01-27 12:58:37 +053012451 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012452
Dustin Brown5ec6b552017-03-31 12:11:40 -070012453 return is_running;
12454}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012455
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012456static void __hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012457{
12458 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
12459 hdd_ctx->bus_bw_timer_running = true;
12460 qdf_timer_start(&hdd_ctx->bus_bw_timer,
jitiphil869b9f72018-09-25 17:14:01 +053012461 hdd_ctx->config->bus_bw_compute_interval);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012462 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
12463}
12464
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012465void hdd_bus_bw_compute_timer_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012466{
Dustin Brown491d54b2018-03-14 12:39:11 -070012467 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012468
12469 if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
12470 hdd_debug("Bandwidth compute timer already started");
12471 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012472 }
12473
Dustin Brown5ec6b552017-03-31 12:11:40 -070012474 __hdd_bus_bw_compute_timer_start(hdd_ctx);
12475
Dustin Browne74003f2018-03-14 12:51:58 -070012476 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012477}
12478
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012479void hdd_bus_bw_compute_timer_try_start(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012480{
Dustin Brown491d54b2018-03-14 12:39:11 -070012481 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012482
12483 if (hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
12484 hdd_debug("Bandwidth compute timer already started");
12485 return;
Ravi Joshib89e7f72016-09-07 13:43:15 -070012486 }
Dustin Brown5ec6b552017-03-31 12:11:40 -070012487
12488 if (hdd_any_adapter_is_assoc(hdd_ctx))
12489 __hdd_bus_bw_compute_timer_start(hdd_ctx);
12490
Dustin Browne74003f2018-03-14 12:51:58 -070012491 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012492}
12493
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012494static void __hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012495{
Dustin Brown07901ec2018-09-07 11:02:41 -070012496 ucfg_ipa_set_perf_level(hdd_ctx->pdev, 0, 0);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012497
12498 qdf_spinlock_acquire(&hdd_ctx->bus_bw_timer_lock);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012499 hdd_ctx->bus_bw_timer_running = false;
Dustin Brown35008ba2018-08-23 14:34:21 -070012500 qdf_timer_sync_cancel(&hdd_ctx->bus_bw_timer);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012501 qdf_spinlock_release(&hdd_ctx->bus_bw_timer_lock);
12502
Dustin Brown35008ba2018-08-23 14:34:21 -070012503 /* work callback is long running; flush outside of lock */
12504 cancel_work_sync(&hdd_ctx->bus_bw_work);
Dustin Brown5ec6b552017-03-31 12:11:40 -070012505 hdd_reset_tcp_delack(hdd_ctx);
12506}
12507
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012508void hdd_bus_bw_compute_timer_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012509{
Dustin Brown491d54b2018-03-14 12:39:11 -070012510 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012511
12512 if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
12513 hdd_debug("Bandwidth compute timer already stopped");
12514 return;
12515 }
12516
12517 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
12518
Dustin Browne74003f2018-03-14 12:51:58 -070012519 hdd_exit();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012520}
12521
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012522void hdd_bus_bw_compute_timer_try_stop(struct hdd_context *hdd_ctx)
Dustin Brown5ec6b552017-03-31 12:11:40 -070012523{
Dustin Brown491d54b2018-03-14 12:39:11 -070012524 hdd_enter();
Dustin Brown5ec6b552017-03-31 12:11:40 -070012525
12526 if (!hdd_bus_bw_compute_timer_is_running(hdd_ctx)) {
12527 hdd_debug("Bandwidth compute timer already stopped");
12528 return;
12529 }
12530
12531 if (!hdd_any_adapter_is_assoc(hdd_ctx))
12532 __hdd_bus_bw_compute_timer_stop(hdd_ctx);
12533
Dustin Browne74003f2018-03-14 12:51:58 -070012534 hdd_exit();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012535}
12536#endif
12537
12538/**
12539 * wlan_hdd_check_custom_con_channel_rules() - This function checks the sap's
12540 * and sta's operating channel.
12541 * @sta_adapter: Describe the first argument to foobar.
12542 * @ap_adapter: Describe the second argument to foobar.
12543 * @roam_profile: Roam profile of AP to which STA wants to connect.
12544 * @concurrent_chnl_same: If both SAP and STA channels are same then
12545 * set this flag to true else false.
12546 *
12547 * This function checks the sap's operating channel and sta's operating channel.
12548 * if both are same then it will return false else it will restart the sap in
12549 * sta's channel and return true.
12550 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012551 * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_FAILURE.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012552 */
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070012553QDF_STATUS
12554wlan_hdd_check_custom_con_channel_rules(struct hdd_adapter *sta_adapter,
12555 struct hdd_adapter *ap_adapter,
Jeff Johnson61b5e982018-03-15 11:33:31 -070012556 struct csr_roam_profile *roam_profile,
Jeff Johnson6dff3ee2017-10-06 14:58:57 -070012557 tScanResultHandle *scan_cache,
12558 bool *concurrent_chnl_same)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012559{
Jeff Johnson87251032017-08-29 13:31:11 -070012560 struct hdd_ap_ctx *hdd_ap_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012561 uint8_t channel_id;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012562 QDF_STATUS status;
Jeff Johnsonc1e62782017-11-09 09:50:17 -080012563 enum QDF_OPMODE device_mode = ap_adapter->device_mode;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012564 *concurrent_chnl_same = true;
12565
12566 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
12567 status =
Archana Ramachandran2eb7a612017-03-23 22:58:42 -070012568 sme_get_ap_channel_from_scan_cache(roam_profile,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012569 scan_cache,
12570 &channel_id);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012571 if (QDF_STATUS_SUCCESS == status) {
Krunal Soni9b04c9b2016-03-10 13:08:05 -080012572 if ((QDF_SAP_MODE == device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012573 (channel_id < SIR_11A_CHANNEL_BEGIN)) {
Jeff Johnson01206862017-10-27 20:55:59 -070012574 if (hdd_ap_ctx->operating_channel != channel_id) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012575 *concurrent_chnl_same = false;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012576 hdd_debug("channels are different");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012577 }
Krunal Soni9b04c9b2016-03-10 13:08:05 -080012578 } else if ((QDF_P2P_GO_MODE == device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012579 (channel_id >= SIR_11A_CHANNEL_BEGIN)) {
Jeff Johnson01206862017-10-27 20:55:59 -070012580 if (hdd_ap_ctx->operating_channel != channel_id) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012581 *concurrent_chnl_same = false;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012582 hdd_debug("channels are different");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012583 }
12584 }
12585 } else {
12586 /*
12587 * Lets handle worst case scenario here, Scan cache lookup is
12588 * failed so we have to stop the SAP to avoid any channel
12589 * discrepancy between SAP's channel and STA's channel.
12590 * Return the status as failure so caller function could know
12591 * that scan look up is failed.
12592 */
Jeff Johnson28f8a772016-08-15 15:30:36 -070012593 hdd_err("Finding AP from scan cache failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012594 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012595 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012596 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012597}
12598
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012599/**
12600 * wlan_hdd_stop_sap() - This function stops bss of SAP.
12601 * @ap_adapter: SAP adapter
12602 *
12603 * This function will process the stopping of sap adapter.
12604 *
12605 * Return: None
12606 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012607void wlan_hdd_stop_sap(struct hdd_adapter *ap_adapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012608{
Jeff Johnson87251032017-08-29 13:31:11 -070012609 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070012610 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053012611 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012612 struct hdd_context *hdd_ctx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012613
12614 if (NULL == ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012615 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012616 return;
12617 }
12618
12619 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
12620 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Abhishek Singh23edd1c2016-05-05 11:56:06 +053012621 if (wlan_hdd_validate_context(hdd_ctx))
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012622 return;
Abhishek Singh23edd1c2016-05-05 11:56:06 +053012623
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012624 mutex_lock(&hdd_ctx->sap_lock);
12625 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
Ryan Hsu8ecb0fa2016-01-18 15:40:55 -080012626 wlan_hdd_del_station(ap_adapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012627 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012628 hdd_debug("Now doing SAP STOPBSS");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +053012629 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012630 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx->
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070012631 sap_context)) {
Nachiket Kukade0396b732017-11-14 16:35:16 +053012632 qdf_status = qdf_wait_for_event_completion(&hostapd_state->
Naveen Rawatb56880c2016-12-13 17:56:03 -080012633 qdf_stop_bss_event,
Vignesh Viswanathan865daaa2018-10-11 19:30:44 +053012634 SME_CMD_START_STOP_BSS_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +053012635 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012636 mutex_unlock(&hdd_ctx->sap_lock);
Jeff Johnson28f8a772016-08-15 15:30:36 -070012637 hdd_err("SAP Stop Failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012638 return;
12639 }
12640 }
12641 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -070012642 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012643 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070012644 ap_adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070012645 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053012646 false);
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012647 hdd_debug("SAP Stop Success");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012648 } else {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012649 hdd_err("Can't stop ap because its not started");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012650 }
12651 mutex_unlock(&hdd_ctx->sap_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012652}
12653
12654/**
12655 * wlan_hdd_start_sap() - this function starts bss of SAP.
12656 * @ap_adapter: SAP adapter
12657 *
12658 * This function will process the starting of sap adapter.
12659 *
12660 * Return: None
12661 */
Jeff Johnson9d295242017-08-29 14:39:48 -070012662void wlan_hdd_start_sap(struct hdd_adapter *ap_adapter, bool reinit)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012663{
Jeff Johnson87251032017-08-29 13:31:11 -070012664 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070012665 struct hdd_hostapd_state *hostapd_state;
Anurag Chouhance0dc992016-02-16 18:18:03 +053012666 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012667 struct hdd_context *hdd_ctx;
Jeff Johnsone4c11db2018-05-05 23:22:32 -070012668 tsap_config_t *sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012669
12670 if (NULL == ap_adapter) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012671 hdd_err("ap_adapter is NULL here");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012672 return;
12673 }
12674
Krunal Soni9b04c9b2016-03-10 13:08:05 -080012675 if (QDF_SAP_MODE != ap_adapter->device_mode) {
Peng Xuf5d60c82015-10-02 17:17:03 -070012676 hdd_err("SoftAp role has not been enabled");
12677 return;
12678 }
12679
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012680 hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
12681 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
12682 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
Jeff Johnsonb9424862017-10-30 08:49:35 -070012683 sap_config = &ap_adapter->session.ap.sap_config;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012684
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012685 mutex_lock(&hdd_ctx->sap_lock);
12686 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
12687 goto end;
12688
12689 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012690 hdd_err("SAP Not able to set AP IEs");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012691 goto end;
12692 }
Dustin Brown07901ec2018-09-07 11:02:41 -070012693 wlan_reg_set_channel_params(hdd_ctx->pdev,
Abhinav Kumar6f694482018-09-04 16:07:39 +053012694 hdd_ap_ctx->sap_config.channel, 0,
12695 &hdd_ap_ctx->sap_config.ch_params);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012696
Wei Song2f76f642016-11-18 16:32:53 +080012697 qdf_event_reset(&hostapd_state->qdf_event);
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070012698 if (wlansap_start_bss(hdd_ap_ctx->sap_context, hdd_hostapd_sap_event_cb,
Jeff Johnson91df29d2017-10-27 19:29:50 -070012699 &hdd_ap_ctx->sap_config,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012700 ap_adapter->dev)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +053012701 != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012702 goto end;
12703
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080012704 hdd_debug("Waiting for SAP to start");
Nachiket Kukade0396b732017-11-14 16:35:16 +053012705 qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Vignesh Viswanathan865daaa2018-10-11 19:30:44 +053012706 SME_CMD_START_STOP_BSS_TIMEOUT);
Anurag Chouhance0dc992016-02-16 18:18:03 +053012707 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson28f8a772016-08-15 15:30:36 -070012708 hdd_err("SAP Start failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012709 goto end;
12710 }
Jeff Johnson28f8a772016-08-15 15:30:36 -070012711 hdd_info("SAP Start Success");
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053012712 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012713 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053012714 if (hostapd_state->bss_state == BSS_START) {
Dustin Brown1dbefe62018-09-11 16:32:03 -070012715 policy_mgr_incr_active_session(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080012716 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070012717 ap_adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070012718 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053012719 true);
12720 }
Sourav Mohapatra9bc67112017-11-08 09:36:11 +053012721 mutex_unlock(&hdd_ctx->sap_lock);
12722
12723 return;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012724end:
Vignesh Viswanathan85b455e2018-01-17 19:54:33 +053012725 wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012726 mutex_unlock(&hdd_ctx->sap_lock);
Manikandan Mohan3dad1a42017-06-14 10:50:18 -070012727 /* SAP context and beacon cleanup will happen during driver unload
12728 * in hdd_stop_adapter
12729 */
12730 hdd_err("SAP restart after SSR failed! Reload WLAN and try SAP again");
12731
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012732}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012733
12734/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012735 * hdd_get_fw_version() - Get FW version
12736 * @hdd_ctx: pointer to HDD context.
12737 * @major_spid: FW version - major spid.
12738 * @minor_spid: FW version - minor spid
12739 * @ssid: FW version - ssid
12740 * @crmid: FW version - crmid
12741 *
12742 * This function is called to get the firmware build version stored
12743 * as part of the HDD context
12744 *
12745 * Return: None
12746 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070012747void hdd_get_fw_version(struct hdd_context *hdd_ctx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012748 uint32_t *major_spid, uint32_t *minor_spid,
12749 uint32_t *siid, uint32_t *crmid)
12750{
12751 *major_spid = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
12752 *minor_spid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
12753 *siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
12754 *crmid = hdd_ctx->target_fw_version & 0x7fff;
12755}
12756
12757#ifdef QCA_CONFIG_SMP
12758/**
12759 * wlan_hdd_get_cpu() - get cpu_index
12760 *
12761 * Return: cpu_index
12762 */
12763int wlan_hdd_get_cpu(void)
12764{
12765 int cpu_index = get_cpu();
Srinivas Girigowdab841da72017-03-25 18:04:39 -070012766
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080012767 put_cpu();
12768 return cpu_index;
12769}
12770#endif
12771
12772/**
12773 * hdd_get_fwpath() - get framework path
12774 *
12775 * This function is used to get the string written by
12776 * userspace to start the wlan driver
12777 *
12778 * Return: string
12779 */
12780const char *hdd_get_fwpath(void)
12781{
12782 return fwpath.string;
12783}
12784
Dustin Brown94ce20f2018-09-04 13:11:38 -070012785static inline int hdd_state_query_cb(void)
12786{
12787 return !!wlan_hdd_validate_context(cds_get_context(QDF_MODULE_ID_HDD));
12788}
12789
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012790/**
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012791 * hdd_init() - Initialize Driver
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012792 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012793 * This function initilizes CDS global context with the help of cds_init. This
12794 * has to be the first function called after probe to get a valid global
12795 * context.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012796 *
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012797 * Return: 0 for success, errno on failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012798 */
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012799int hdd_init(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012800{
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070012801 QDF_STATUS status;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012802 int ret = 0;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012803
Jeff Johnson7aaeeea2017-09-26 13:16:24 -070012804 status = cds_init();
wadesongae4ffd12017-10-24 16:45:54 +080012805 if (QDF_IS_STATUS_ERROR(status)) {
12806 hdd_err("Failed to allocate CDS context");
12807 ret = -ENOMEM;
12808 goto err_out;
12809 }
Dustin Brown94ce20f2018-09-04 13:11:38 -070012810 qdf_register_module_state_query_callback(hdd_state_query_cb);
Hanumanth Reddy Pothula788a37e2017-08-17 18:40:11 +053012811
12812 wlan_init_bug_report_lock();
12813
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012814#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12815 wlan_logging_sock_init_svc();
12816#endif
12817
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053012818 qdf_timer_init(NULL, &hdd_drv_ops_inactivity_timer,
12819 (void *)hdd_drv_ops_inactivity_handler, NULL,
12820 QDF_TIMER_TYPE_SW);
12821
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012822 hdd_trace_init();
Padma, Santhosh Kumar9aba02f2016-08-11 16:30:25 +053012823 hdd_register_debug_callback();
Qiwei Caiad9b01c2018-07-09 17:21:31 +080012824 wlan_roam_debug_init();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012825
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012826err_out:
12827 return ret;
12828}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012829
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012830/**
12831 * hdd_deinit() - Deinitialize Driver
12832 *
12833 * This function frees CDS global context with the help of cds_deinit. This
12834 * has to be the last function call in remove callback to free the global
12835 * context.
12836 */
12837void hdd_deinit(void)
12838{
Qiwei Caiad9b01c2018-07-09 17:21:31 +080012839 wlan_roam_debug_deinit();
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053012840 qdf_timer_free(&hdd_drv_ops_inactivity_timer);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012841
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012842#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
12843 wlan_logging_sock_deinit_svc();
12844#endif
Qiwei Caiad9b01c2018-07-09 17:21:31 +080012845
12846 wlan_destroy_bug_report_lock();
12847 cds_deinit();
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012848}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012849
Yue Ma6e7b1a02017-04-03 14:17:46 -070012850#ifdef QCA_WIFI_NAPIER_EMULATION
12851#define HDD_WLAN_START_WAIT_TIME ((CDS_WMA_TIMEOUT + 5000) * 100)
12852#else
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012853#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
Yue Ma6e7b1a02017-04-03 14:17:46 -070012854#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080012855
Sachin Ahujadddd2632017-03-07 19:07:24 +053012856static int wlan_hdd_state_ctrl_param_open(struct inode *inode,
12857 struct file *file)
12858{
12859 return 0;
12860}
12861
12862static ssize_t wlan_hdd_state_ctrl_param_write(struct file *filp,
12863 const char __user *user_buf,
12864 size_t count,
12865 loff_t *f_pos)
12866{
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012867 char buf[3];
Sachin Ahujadddd2632017-03-07 19:07:24 +053012868 static const char wlan_off_str[] = "OFF";
12869 static const char wlan_on_str[] = "ON";
12870 int ret;
12871 unsigned long rc;
12872
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012873 if (copy_from_user(buf, user_buf, 3)) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053012874 pr_err("Failed to read buffer\n");
12875 return -EINVAL;
12876 }
12877
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012878 if (strncmp(buf, wlan_off_str, strlen(wlan_off_str)) == 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053012879 pr_debug("Wifi turning off from UI\n");
12880 goto exit;
12881 }
12882
Srinivas Girigowdad2412882018-09-07 15:42:04 -070012883 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) == 0)
Sachin Ahuja16904db2017-12-13 19:56:57 +053012884 pr_info("Wifi Turning On from UI\n");
Sachin Ahuja16904db2017-12-13 19:56:57 +053012885
SaidiReddy Yenugac356f152017-04-06 17:43:01 +053012886 if (strncmp(buf, wlan_on_str, strlen(wlan_on_str)) != 0) {
Sachin Ahujadddd2632017-03-07 19:07:24 +053012887 pr_err("Invalid value received from framework");
12888 goto exit;
12889 }
12890
12891 if (!cds_is_driver_loaded()) {
Sachin Ahujaee62b542017-04-21 14:14:16 +053012892 init_completion(&wlan_start_comp);
Sachin Ahujadddd2632017-03-07 19:07:24 +053012893 rc = wait_for_completion_timeout(&wlan_start_comp,
12894 msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
12895 if (!rc) {
Srinivas Girigowda09625b02018-09-10 15:28:09 -070012896 hdd_alert("Timed-out!!");
Sachin Ahujadddd2632017-03-07 19:07:24 +053012897 ret = -EINVAL;
Sachin Ahujadddd2632017-03-07 19:07:24 +053012898 return ret;
12899 }
12900
12901 hdd_start_complete(0);
12902 }
12903
12904exit:
12905 return count;
12906}
12907
12908
12909const struct file_operations wlan_hdd_state_fops = {
12910 .owner = THIS_MODULE,
12911 .open = wlan_hdd_state_ctrl_param_open,
12912 .write = wlan_hdd_state_ctrl_param_write,
12913};
12914
12915static int wlan_hdd_state_ctrl_param_create(void)
12916{
12917 unsigned int wlan_hdd_state_major = 0;
12918 int ret;
12919 struct device *dev;
12920
12921 device = MKDEV(wlan_hdd_state_major, 0);
12922
12923 ret = alloc_chrdev_region(&device, 0, dev_num, "qcwlanstate");
12924 if (ret) {
12925 pr_err("Failed to register qcwlanstate");
12926 goto dev_alloc_err;
12927 }
12928 wlan_hdd_state_major = MAJOR(device);
12929
12930 class = class_create(THIS_MODULE, WLAN_MODULE_NAME);
12931 if (IS_ERR(class)) {
12932 pr_err("wlan_hdd_state class_create error");
12933 goto class_err;
12934 }
12935
12936 dev = device_create(class, NULL, device, NULL, WLAN_MODULE_NAME);
12937 if (IS_ERR(dev)) {
12938 pr_err("wlan_hdd_statedevice_create error");
12939 goto err_class_destroy;
12940 }
12941
12942 cdev_init(&wlan_hdd_state_cdev, &wlan_hdd_state_fops);
12943 ret = cdev_add(&wlan_hdd_state_cdev, device, dev_num);
12944 if (ret) {
12945 pr_err("Failed to add cdev error");
12946 goto cdev_add_err;
12947 }
12948
12949 pr_info("wlan_hdd_state %s major(%d) initialized",
12950 WLAN_MODULE_NAME, wlan_hdd_state_major);
12951
12952 return 0;
12953
12954cdev_add_err:
12955 device_destroy(class, device);
12956err_class_destroy:
12957 class_destroy(class);
12958class_err:
12959 unregister_chrdev_region(device, dev_num);
12960dev_alloc_err:
12961 return -ENODEV;
12962}
12963
12964static void wlan_hdd_state_ctrl_param_destroy(void)
12965{
12966 cdev_del(&wlan_hdd_state_cdev);
12967 device_destroy(class, device);
12968 class_destroy(class);
12969 unregister_chrdev_region(device, dev_num);
12970
12971 pr_info("Device node unregistered");
12972}
12973
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080012974/**
Dustin Brownd585cb32018-09-12 17:12:23 -070012975 * hdd_component_init() - Initialize all components
Mukul Sharmad75a6672017-06-22 15:40:53 +053012976 *
Dustin Brownd585cb32018-09-12 17:12:23 -070012977 * Return: QDF_STATUS
Mukul Sharmad75a6672017-06-22 15:40:53 +053012978 */
Dustin Brownd585cb32018-09-12 17:12:23 -070012979static QDF_STATUS hdd_component_init(void)
Mukul Sharmad75a6672017-06-22 15:40:53 +053012980{
Dustin Brownd585cb32018-09-12 17:12:23 -070012981 QDF_STATUS status;
12982
12983 /* initialize converged components */
12984 status = dispatcher_init();
12985 if (QDF_IS_STATUS_ERROR(status))
12986 return status;
12987
12988 /* initialize non-converged components */
12989 status = ucfg_mlme_init();
12990 if (QDF_IS_STATUS_ERROR(status))
12991 goto dispatcher_deinit;
12992
12993 status = ucfg_fwol_init();
12994 if (QDF_IS_STATUS_ERROR(status))
12995 goto mlme_deinit;
12996
12997 status = disa_init();
12998 if (QDF_IS_STATUS_ERROR(status))
12999 goto fwol_deinit;
13000
13001 status = pmo_init();
13002 if (QDF_IS_STATUS_ERROR(status))
13003 goto disa_deinit;
13004
13005 status = ucfg_ocb_init();
13006 if (QDF_IS_STATUS_ERROR(status))
13007 goto pmo_deinit;
13008
13009 status = ipa_init();
13010 if (QDF_IS_STATUS_ERROR(status))
13011 goto ocb_deinit;
13012
13013 status = ucfg_action_oui_init();
13014 if (QDF_IS_STATUS_ERROR(status))
13015 goto ipa_deinit;
13016
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013017 status = nan_init();
13018 if (QDF_IS_STATUS_ERROR(status))
13019 goto action_oui_deinit;
13020
Wu Gao637d58a2018-12-08 10:37:34 +080013021 status = ucfg_p2p_init();
13022 if (QDF_IS_STATUS_ERROR(status))
13023 goto nan_deinit;
13024
Wu Gaod6b5e402018-12-03 22:09:24 +080013025 status = policy_mgr_init();
13026 if (QDF_IS_STATUS_ERROR(status))
13027 goto p2p_deinit;
13028
Wu Gao5f793402018-12-08 11:04:00 +080013029 status = ucfg_tdls_init();
13030 if (QDF_IS_STATUS_ERROR(status))
13031 goto policy_deinit;
13032
Dustin Brownd585cb32018-09-12 17:12:23 -070013033 return QDF_STATUS_SUCCESS;
13034
Wu Gao5f793402018-12-08 11:04:00 +080013035policy_deinit:
13036 policy_mgr_deinit();
Wu Gaod6b5e402018-12-03 22:09:24 +080013037p2p_deinit:
13038 ucfg_p2p_deinit();
Wu Gao637d58a2018-12-08 10:37:34 +080013039nan_deinit:
13040 nan_deinit();
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013041action_oui_deinit:
13042 ucfg_action_oui_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013043ipa_deinit:
13044 ipa_deinit();
13045ocb_deinit:
13046 ucfg_ocb_deinit();
13047pmo_deinit:
13048 pmo_deinit();
13049disa_deinit:
13050 disa_deinit();
13051fwol_deinit:
13052 ucfg_fwol_deinit();
13053mlme_deinit:
13054 ucfg_mlme_deinit();
13055dispatcher_deinit:
13056 dispatcher_deinit();
13057
13058 return status;
Mukul Sharmad75a6672017-06-22 15:40:53 +053013059}
13060
13061/**
Dustin Brownd585cb32018-09-12 17:12:23 -070013062 * hdd_component_deinit() - Deinitialize all components
Mukul Sharmad75a6672017-06-22 15:40:53 +053013063 *
13064 * Return: None
13065 */
Dustin Brownd585cb32018-09-12 17:12:23 -070013066static void hdd_component_deinit(void)
Mukul Sharmad75a6672017-06-22 15:40:53 +053013067{
Dustin Brownd585cb32018-09-12 17:12:23 -070013068 /* deinitialize non-converged components */
Wu Gao5f793402018-12-08 11:04:00 +080013069 ucfg_tdls_deinit();
Wu Gaod6b5e402018-12-03 22:09:24 +080013070 policy_mgr_deinit();
Wu Gao637d58a2018-12-08 10:37:34 +080013071 ucfg_p2p_deinit();
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013072 nan_deinit();
Rajeev Kumar Sirasanagandla4725ae42018-05-24 22:33:34 +053013073 ucfg_action_oui_deinit();
Sravan Kumar Kairam4af61cf2018-02-22 17:53:44 +053013074 ipa_deinit();
Zhang Qian47e22ce2018-01-04 15:38:38 +080013075 ucfg_ocb_deinit();
Mukul Sharmad75a6672017-06-22 15:40:53 +053013076 pmo_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013077 disa_deinit();
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013078 ucfg_fwol_deinit();
Vignesh Viswanathana0921c42018-09-04 19:03:35 +053013079 ucfg_mlme_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013080
13081 /* deinitialize converged components */
13082 dispatcher_deinit();
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013083}
13084
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013085QDF_STATUS hdd_component_psoc_open(struct wlan_objmgr_psoc *psoc)
13086{
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013087 QDF_STATUS status;
13088
13089 status = ucfg_mlme_psoc_open(psoc);
13090 if (QDF_IS_STATUS_ERROR(status))
13091 return status;
13092
13093 status = ucfg_fwol_psoc_open(psoc);
13094 if (QDF_IS_STATUS_ERROR(status))
Wu Gao66454f12018-09-26 19:55:41 +080013095 goto err_fwol;
13096
13097 status = ucfg_pmo_psoc_open(psoc);
13098 if (QDF_IS_STATUS_ERROR(status))
13099 goto err_pmo;
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013100
Krunal Sonie9c12f52018-10-04 11:45:42 -070013101 status = ucfg_policy_mgr_psoc_open(psoc);
13102 if (QDF_IS_STATUS_ERROR(status))
13103 goto err_plcy_mgr;
13104
Wu Gao637d58a2018-12-08 10:37:34 +080013105 status = ucfg_p2p_psoc_open(psoc);
13106 if (QDF_IS_STATUS_ERROR(status))
13107 goto err_p2p;
Wu Gao5f793402018-12-08 11:04:00 +080013108
13109 status = ucfg_tdls_psoc_open(psoc);
13110 if (QDF_IS_STATUS_ERROR(status))
13111 goto err_tdls;
13112
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013113 return status;
13114
Wu Gao5f793402018-12-08 11:04:00 +080013115err_tdls:
13116 ucfg_tdls_psoc_close(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013117err_p2p:
13118 ucfg_p2p_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070013119err_plcy_mgr:
13120 ucfg_pmo_psoc_close(psoc);
Wu Gao66454f12018-09-26 19:55:41 +080013121err_pmo:
13122 ucfg_fwol_psoc_close(psoc);
13123err_fwol:
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013124 ucfg_mlme_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070013125
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013126 return status;
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013127}
13128
13129void hdd_component_psoc_close(struct wlan_objmgr_psoc *psoc)
13130{
Wu Gao5f793402018-12-08 11:04:00 +080013131 ucfg_tdls_psoc_close(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013132 ucfg_p2p_psoc_close(psoc);
Krunal Sonie9c12f52018-10-04 11:45:42 -070013133 ucfg_policy_mgr_psoc_close(psoc);
Wu Gao66454f12018-09-26 19:55:41 +080013134 ucfg_pmo_psoc_close(psoc);
Sourav Mohapatra113685f2018-08-29 14:21:55 +053013135 ucfg_fwol_psoc_close(psoc);
Vignesh Viswanathana0921c42018-09-04 19:03:35 +053013136 ucfg_mlme_psoc_close(psoc);
Vignesh Viswanathan21c58cb2018-05-24 15:53:58 +053013137}
13138
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013139void hdd_component_psoc_enable(struct wlan_objmgr_psoc *psoc)
13140{
Zhang Qian47e22ce2018-01-04 15:38:38 +080013141 ocb_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013142 disa_psoc_enable(psoc);
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013143 nan_psoc_enable(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013144 p2p_psoc_enable(psoc);
Wu Gaod6b5e402018-12-03 22:09:24 +080013145 policy_mgr_psoc_enable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013146}
13147
13148void hdd_component_psoc_disable(struct wlan_objmgr_psoc *psoc)
13149{
Wu Gaod6b5e402018-12-03 22:09:24 +080013150 policy_mgr_psoc_disable(psoc);
Wu Gao637d58a2018-12-08 10:37:34 +080013151 p2p_psoc_disable(psoc);
Nachiket Kukade63bb63d2018-11-21 14:42:14 +053013152 nan_psoc_disable(psoc);
Nachiket Kukade98f562a2017-12-15 12:18:07 +053013153 disa_psoc_disable(psoc);
Zhang Qian47e22ce2018-01-04 15:38:38 +080013154 ocb_psoc_disable(psoc);
Mukul Sharmad75a6672017-06-22 15:40:53 +053013155}
13156
Sandeep Puligillab7beb472018-08-13 22:54:20 -070013157QDF_STATUS hdd_component_pdev_open(struct wlan_objmgr_pdev *pdev)
13158{
13159 return ucfg_mlme_pdev_open(pdev);
13160}
13161
13162void hdd_component_pdev_close(struct wlan_objmgr_pdev *pdev)
13163{
13164 ucfg_mlme_pdev_close(pdev);
13165}
13166
Dustin Brown21a1d462018-07-31 15:13:06 -070013167static struct hdd_driver __hdd_driver;
13168
13169static QDF_STATUS hdd_driver_ctx_init(struct hdd_driver *hdd_driver)
13170{
13171 QDF_BUG(hdd_driver);
13172 if (!hdd_driver)
13173 return QDF_STATUS_E_INVAL;
13174
13175 hdd_driver->state = driver_state_uninit;
13176
13177 return dsc_driver_create(&hdd_driver->dsc_driver);
13178}
13179
13180static void hdd_driver_ctx_deinit(struct hdd_driver *hdd_driver)
13181{
13182 QDF_BUG(hdd_driver);
13183 if (!hdd_driver)
13184 return;
13185
13186 dsc_driver_destroy(&hdd_driver->dsc_driver);
13187 qdf_mem_zero(hdd_driver, sizeof(*hdd_driver));
13188}
13189
13190struct hdd_driver *hdd_driver_get(void)
13191{
13192 return &__hdd_driver;
13193}
13194
Dustin Browna2a39dc2018-09-17 15:29:59 -070013195static QDF_STATUS hdd_qdf_print_init(void)
13196{
13197 QDF_STATUS status;
13198 int qdf_print_idx;
13199
13200 status = qdf_print_setup();
13201 if (QDF_IS_STATUS_ERROR(status)) {
13202 pr_err("Failed qdf_print_setup; status:%u\n", status);
13203 return status;
13204 }
13205
13206 qdf_print_idx = qdf_print_ctrl_register(cinfo, NULL, NULL, "MCL_WLAN");
13207 if (qdf_print_idx < 0) {
13208 pr_err("Failed to register for qdf_print_ctrl\n");
13209 return QDF_STATUS_E_FAILURE;
13210 }
13211
13212 qdf_set_pidx(qdf_print_idx);
13213
13214 return QDF_STATUS_SUCCESS;
13215}
13216
13217static void hdd_qdf_print_deinit(void)
13218{
13219 int qdf_pidx = qdf_get_pidx();
13220
13221 qdf_set_pidx(-1);
13222 qdf_print_ctrl_cleanup(qdf_pidx);
13223
13224 /* currently, no qdf print 'un-setup'*/
13225}
13226
13227static QDF_STATUS hdd_qdf_init(void)
13228{
13229 QDF_STATUS status;
13230
13231 status = hdd_qdf_print_init();
13232 if (QDF_IS_STATUS_ERROR(status))
13233 goto exit;
13234
13235 status = qdf_debugfs_init();
13236 if (QDF_IS_STATUS_ERROR(status)) {
13237 hdd_err("Failed to init debugfs; status:%u", status);
13238 goto print_deinit;
13239 }
13240
13241 qdf_lock_stats_init();
13242 qdf_mem_init();
13243 qdf_mc_timer_manager_init();
13244 qdf_event_list_init();
13245
Dustin Brownd315c452018-11-27 11:28:48 -080013246 status = qdf_talloc_feature_init();
13247 if (QDF_IS_STATUS_ERROR(status)) {
13248 hdd_err("Failed to init talloc; status:%u", status);
13249 goto event_deinit;
13250 }
13251
Dustin Browna2a39dc2018-09-17 15:29:59 -070013252 status = qdf_cpuhp_init();
13253 if (QDF_IS_STATUS_ERROR(status)) {
13254 hdd_err("Failed to init cpuhp; status:%u", status);
Dustin Brownd315c452018-11-27 11:28:48 -080013255 goto talloc_deinit;
Dustin Browna2a39dc2018-09-17 15:29:59 -070013256 }
13257
13258 status = qdf_trace_spin_lock_init();
13259 if (QDF_IS_STATUS_ERROR(status)) {
13260 hdd_err("Failed to init spinlock; status:%u", status);
13261 goto cpuhp_deinit;
13262 }
13263
13264 qdf_trace_init();
13265 qdf_register_debugcb_init();
13266
13267 return QDF_STATUS_SUCCESS;
13268
13269cpuhp_deinit:
13270 qdf_cpuhp_deinit();
Dustin Brownd315c452018-11-27 11:28:48 -080013271talloc_deinit:
13272 qdf_talloc_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070013273event_deinit:
13274 qdf_event_list_destroy();
13275 qdf_mc_timer_manager_exit();
13276 qdf_mem_exit();
13277 qdf_lock_stats_deinit();
13278 qdf_debugfs_exit();
13279print_deinit:
13280 hdd_qdf_print_deinit();
13281
13282exit:
13283 return status;
13284}
13285
13286static void hdd_qdf_deinit(void)
13287{
13288 /* currently, no debugcb deinit */
13289
13290 qdf_trace_deinit();
13291
13292 /* currently, no trace spinlock deinit */
13293
13294 qdf_cpuhp_deinit();
Dustin Brownd315c452018-11-27 11:28:48 -080013295 qdf_talloc_feature_deinit();
Dustin Browna2a39dc2018-09-17 15:29:59 -070013296 qdf_event_list_destroy();
13297 qdf_mc_timer_manager_exit();
13298 qdf_mem_exit();
13299 qdf_lock_stats_deinit();
13300 qdf_debugfs_exit();
13301 hdd_qdf_print_deinit();
13302}
Dustin Brownf0f70562018-09-14 10:29:38 -070013303
13304/**
13305 * hdd_driver_load() - Perform the driver-level load operation
13306 *
13307 * Note: this is used in both static and DLKM driver builds
13308 *
13309 * Return: Errno
13310 */
13311static int hdd_driver_load(void)
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013312{
Dustin Brown21a1d462018-07-31 15:13:06 -070013313 struct hdd_driver *hdd_driver = hdd_driver_get();
Dustin Brownd585cb32018-09-12 17:12:23 -070013314 QDF_STATUS status;
Dustin Brownf0f70562018-09-14 10:29:38 -070013315 int errno;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013316
Rajeev Kumare555e2d2018-09-17 11:52:37 -070013317 pr_err("%s: Loading driver v%s\n",
Dustin Brownab482ac2017-06-09 17:00:44 -070013318 WLAN_MODULE_NAME,
Rajeev Kumare555e2d2018-09-17 11:52:37 -070013319 g_wlan_driver_version);
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013320
Dustin Browna2a39dc2018-09-17 15:29:59 -070013321 status = hdd_qdf_init();
13322 if (QDF_IS_STATUS_ERROR(status)) {
13323 errno = qdf_status_to_os_return(status);
13324 goto exit;
13325 }
13326
Dustin Brown21a1d462018-07-31 15:13:06 -070013327 status = hdd_driver_ctx_init(hdd_driver);
13328 if (QDF_IS_STATUS_ERROR(status)) {
13329 hdd_err("Failed to init driver context; status:%u", status);
13330 errno = qdf_status_to_os_return(status);
13331 goto qdf_deinit;
13332 }
13333
13334 status = dsc_driver_trans_start(hdd_driver->dsc_driver, "load");
13335 QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
13336 if (QDF_IS_STATUS_ERROR(status)) {
13337 errno = qdf_status_to_os_return(status);
13338 goto hdd_driver_deinit;
13339 }
13340
Dustin Brownf0f70562018-09-14 10:29:38 -070013341 errno = hdd_init();
13342 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013343 hdd_err("Failed to init HDD; errno:%d", errno);
Dustin Brown21a1d462018-07-31 15:13:06 -070013344 goto trans_stop;
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013345 }
13346
Dustin Brownd585cb32018-09-12 17:12:23 -070013347 status = hdd_component_init();
13348 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013349 hdd_err("Failed to init components; status:%u", status);
Dustin Brownf0f70562018-09-14 10:29:38 -070013350 errno = qdf_status_to_os_return(status);
Dustin Brownd585cb32018-09-12 17:12:23 -070013351 goto hdd_deinit;
13352 }
Mukul Sharmad75a6672017-06-22 15:40:53 +053013353
Dustin Brownf0f70562018-09-14 10:29:38 -070013354 status = qdf_wake_lock_create(&wlan_wake_lock, "wlan");
13355 if (QDF_IS_STATUS_ERROR(status)) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013356 hdd_err("Failed to create wake lock; status:%u", status);
Dustin Brownf0f70562018-09-14 10:29:38 -070013357 errno = qdf_status_to_os_return(status);
13358 goto comp_deinit;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013359 }
13360
Dustin Brownf0f70562018-09-14 10:29:38 -070013361 hdd_set_conparam(con_mode);
13362
Dustin Brownf0f70562018-09-14 10:29:38 -070013363 errno = wlan_hdd_state_ctrl_param_create();
13364 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013365 hdd_err("Failed to create ctrl param; errno:%d", errno);
Dustin Brown4b9dbe62018-09-14 15:41:11 -070013366 goto wakelock_destroy;
13367 }
13368
Dustin Brown25843ad2018-09-17 14:54:33 -070013369 errno = pld_init();
13370 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013371 hdd_err("Failed to init PLD; errno:%d", errno);
Dustin Brown25843ad2018-09-17 14:54:33 -070013372 goto param_destroy;
13373 }
13374
Dustin Brown21a1d462018-07-31 15:13:06 -070013375 hdd_driver->state = driver_state_loaded;
13376 dsc_driver_trans_stop(hdd_driver->dsc_driver);
13377
13378 /* psoc probe can happen in registration; do after 'load' transition */
Dustin Brown4b9dbe62018-09-14 15:41:11 -070013379 errno = wlan_hdd_register_driver();
13380 if (errno) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013381 hdd_err("Failed to register driver; errno:%d", errno);
Dustin Brown25843ad2018-09-17 14:54:33 -070013382 goto pld_deinit;
Sachin Ahuja16904db2017-12-13 19:56:57 +053013383 }
13384
Dustin Browna2a39dc2018-09-17 15:29:59 -070013385 hdd_debug("%s: driver loaded", WLAN_MODULE_NAME);
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013386
13387 return 0;
Dustin Brownd585cb32018-09-12 17:12:23 -070013388
Dustin Brown25843ad2018-09-17 14:54:33 -070013389pld_deinit:
Dustin Brown21a1d462018-07-31 15:13:06 -070013390 status = dsc_driver_trans_start(hdd_driver->dsc_driver, "unload");
13391 QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
13392
Dustin Brown25843ad2018-09-17 14:54:33 -070013393 pld_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070013394
Dustin Brown4b9dbe62018-09-14 15:41:11 -070013395param_destroy:
13396 wlan_hdd_state_ctrl_param_destroy();
Dustin Brownf0f70562018-09-14 10:29:38 -070013397wakelock_destroy:
Anurag Chouhana37b5b72016-02-21 14:53:42 +053013398 qdf_wake_lock_destroy(&wlan_wake_lock);
Dustin Brownf0f70562018-09-14 10:29:38 -070013399comp_deinit:
Dustin Brownd585cb32018-09-12 17:12:23 -070013400 hdd_component_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013401hdd_deinit:
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013402 hdd_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070013403trans_stop:
13404 hdd_driver->state = driver_state_deinit;
13405 dsc_driver_trans_stop(hdd_driver->dsc_driver);
13406hdd_driver_deinit:
13407 hdd_driver_ctx_deinit(hdd_driver);
Dustin Browna2a39dc2018-09-17 15:29:59 -070013408qdf_deinit:
13409 hdd_qdf_deinit();
Dustin Brownd585cb32018-09-12 17:12:23 -070013410
Dustin Brown25843ad2018-09-17 14:54:33 -070013411exit:
Dustin Brownf0f70562018-09-14 10:29:38 -070013412 return errno;
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013413}
13414
13415/**
Dustin Brownf0f70562018-09-14 10:29:38 -070013416 * hdd_driver_unload() - Performs the driver-level unload operation
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013417 *
Dustin Brownf0f70562018-09-14 10:29:38 -070013418 * Note: this is used in both static and DLKM driver builds
13419 *
13420 * Return: None
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013421 */
Dustin Brownf0f70562018-09-14 10:29:38 -070013422static void hdd_driver_unload(void)
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013423{
Dustin Brown21a1d462018-07-31 15:13:06 -070013424 struct hdd_driver *hdd_driver = hdd_driver_get();
Will Huang36049722018-04-13 11:48:51 +080013425 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Dustin Brown21a1d462018-07-31 15:13:06 -070013426 QDF_STATUS status;
Ashish Kumar Dhanotiya7a031ce2017-01-23 13:11:30 +053013427
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013428 pr_info("%s: Unloading driver v%s\n", WLAN_MODULE_NAME,
13429 QWLAN_VERSIONSTR);
13430
Dustin Brown21a1d462018-07-31 15:13:06 -070013431 status = dsc_driver_trans_start_wait(hdd_driver->dsc_driver, "unload");
13432 QDF_BUG(QDF_IS_STATUS_SUCCESS(status));
13433 if (QDF_IS_STATUS_ERROR(status)) {
13434 hdd_err("Unable to unload wlan; status:%u", status);
Arunk Khandavalli830c9692018-03-22 12:17:40 +053013435 return;
Dustin Brown21a1d462018-07-31 15:13:06 -070013436 }
13437
13438 dsc_driver_wait_for_ops(hdd_driver->dsc_driver);
13439
13440 if (!hdd_wait_for_recovery_completion()) {
13441 dsc_driver_trans_stop(hdd_driver->dsc_driver);
13442 return;
13443 }
Arunk Khandavalli07ec8f62016-09-27 21:51:01 +053013444
Will Huangba035ec2018-07-05 11:13:30 +080013445 cds_set_driver_loaded(false);
13446 cds_set_unload_in_progress(true);
13447
13448 if (!cds_wait_for_external_threads_completion(__func__))
13449 hdd_warn("External threads are still active attempting "
13450 "driver unload anyway");
13451
Rajeev Kumar3505ae52018-05-10 18:44:45 -070013452 if (hdd_ctx)
Dustin Brown4c663222018-10-23 14:19:36 -070013453 hdd_psoc_idle_timer_stop(hdd_ctx);
Will Huang36049722018-04-13 11:48:51 +080013454
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013455 wlan_hdd_unregister_driver();
Dustin Brown25843ad2018-09-17 14:54:33 -070013456 pld_deinit();
Dustin Brown4b9dbe62018-09-14 15:41:11 -070013457 wlan_hdd_state_ctrl_param_destroy();
Dustin Brownf0f70562018-09-14 10:29:38 -070013458 hdd_set_conparam(0);
Anurag Chouhana37b5b72016-02-21 14:53:42 +053013459 qdf_wake_lock_destroy(&wlan_wake_lock);
Dustin Brownd585cb32018-09-12 17:12:23 -070013460 hdd_component_deinit();
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013461 hdd_deinit();
Dustin Brown21a1d462018-07-31 15:13:06 -070013462
13463 hdd_driver->state = driver_state_deinit;
13464 dsc_driver_trans_stop(hdd_driver->dsc_driver);
Dustin Brown623e7e32018-09-05 14:27:50 -070013465
Dustin Brown21a1d462018-07-31 15:13:06 -070013466 hdd_driver_ctx_deinit(hdd_driver);
13467
Dustin Browna2a39dc2018-09-17 15:29:59 -070013468 hdd_qdf_deinit();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013469}
13470
Arun Khandavallifae92942016-08-01 13:31:08 +053013471#ifndef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013472/**
Arun Khandavallifae92942016-08-01 13:31:08 +053013473 * wlan_boot_cb() - Wlan boot callback
13474 * @kobj: object whose directory we're creating the link in.
13475 * @attr: attribute the user is interacting with
13476 * @buff: the buffer containing the user data
13477 * @count: number of bytes in the buffer
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013478 *
Arun Khandavallifae92942016-08-01 13:31:08 +053013479 * This callback is invoked when the fs is ready to start the
13480 * wlan driver initialization.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013481 *
Arun Khandavallifae92942016-08-01 13:31:08 +053013482 * Return: 'count' on success or a negative error code in case of failure
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013483 */
Arun Khandavallifae92942016-08-01 13:31:08 +053013484static ssize_t wlan_boot_cb(struct kobject *kobj,
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013485 struct kobj_attribute *attr,
13486 const char *buf,
13487 size_t count)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013488{
Arun Khandavallifae92942016-08-01 13:31:08 +053013489
Arun Khandavallifae92942016-08-01 13:31:08 +053013490 if (wlan_loader->loaded_state) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013491 hdd_err("wlan driver already initialized");
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013492 return -EALREADY;
Arun Khandavallifae92942016-08-01 13:31:08 +053013493 }
13494
Dustin Brownf0f70562018-09-14 10:29:38 -070013495 if (hdd_driver_load())
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013496 return -EIO;
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013497
13498 wlan_loader->loaded_state = MODULE_INITIALIZED;
Arun Khandavallifae92942016-08-01 13:31:08 +053013499
13500 return count;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013501}
Arun Khandavallifae92942016-08-01 13:31:08 +053013502
13503/**
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013504 * hdd_sysfs_cleanup() - cleanup sysfs
13505 *
13506 * Return: None
13507 *
13508 */
13509static void hdd_sysfs_cleanup(void)
13510{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013511 /* remove from group */
13512 if (wlan_loader->boot_wlan_obj && wlan_loader->attr_group)
13513 sysfs_remove_group(wlan_loader->boot_wlan_obj,
13514 wlan_loader->attr_group);
13515
13516 /* unlink the object from parent */
13517 kobject_del(wlan_loader->boot_wlan_obj);
13518
13519 /* free the object */
13520 kobject_put(wlan_loader->boot_wlan_obj);
13521
13522 kfree(wlan_loader->attr_group);
13523 kfree(wlan_loader);
13524
13525 wlan_loader = NULL;
13526}
13527
13528/**
Arun Khandavallifae92942016-08-01 13:31:08 +053013529 * wlan_init_sysfs() - Creates the sysfs to be invoked when the fs is
13530 * ready
13531 *
13532 * This is creates the syfs entry boot_wlan. Which shall be invoked
13533 * when the filesystem is ready.
13534 *
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013535 * QDF API cannot be used here since this function is called even before
13536 * initializing WLAN driver.
13537 *
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070013538 * Return: 0 for success, errno on failure
Arun Khandavallifae92942016-08-01 13:31:08 +053013539 */
13540static int wlan_init_sysfs(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013541{
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013542 int ret = -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053013543
13544 wlan_loader = kzalloc(sizeof(*wlan_loader), GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070013545 if (!wlan_loader)
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013546 return -ENOMEM;
Arun Khandavallifae92942016-08-01 13:31:08 +053013547
13548 wlan_loader->boot_wlan_obj = NULL;
13549 wlan_loader->attr_group = kzalloc(sizeof(*(wlan_loader->attr_group)),
13550 GFP_KERNEL);
Srinivas Girigowdab841da72017-03-25 18:04:39 -070013551 if (!wlan_loader->attr_group)
Arun Khandavallifae92942016-08-01 13:31:08 +053013552 goto error_return;
Arun Khandavallifae92942016-08-01 13:31:08 +053013553
13554 wlan_loader->loaded_state = 0;
13555 wlan_loader->attr_group->attrs = attrs;
13556
Qun Zhang4a83a462018-09-11 16:28:51 +080013557 wlan_loader->boot_wlan_obj = kobject_create_and_add(WLAN_LOADER_NAME,
Arun Khandavallifae92942016-08-01 13:31:08 +053013558 kernel_kobj);
13559 if (!wlan_loader->boot_wlan_obj) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013560 hdd_err("sysfs create and add failed");
Arun Khandavallifae92942016-08-01 13:31:08 +053013561 goto error_return;
13562 }
13563
13564 ret = sysfs_create_group(wlan_loader->boot_wlan_obj,
13565 wlan_loader->attr_group);
13566 if (ret) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013567 hdd_err("sysfs create group failed; errno:%d", ret);
Arun Khandavallifae92942016-08-01 13:31:08 +053013568 goto error_return;
13569 }
13570
13571 return 0;
13572
13573error_return:
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013574 hdd_sysfs_cleanup();
Arun Khandavallifae92942016-08-01 13:31:08 +053013575
13576 return ret;
13577}
13578
13579/**
13580 * wlan_deinit_sysfs() - Removes the sysfs created to initialize the wlan
13581 *
13582 * Return: 0 on success or errno on failure
13583 */
13584static int wlan_deinit_sysfs(void)
13585{
Arun Khandavallifae92942016-08-01 13:31:08 +053013586 if (!wlan_loader) {
Dustin Browna2a39dc2018-09-17 15:29:59 -070013587 hdd_err("wlan_loader is null");
Arun Khandavallifae92942016-08-01 13:31:08 +053013588 return -EINVAL;
13589 }
13590
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013591 hdd_sysfs_cleanup();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013592 return 0;
13593}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013594
Mahesh Kumar Kalikot Veetil5a3dec62016-11-02 12:46:40 -070013595#endif /* MODULE */
Arun Khandavallifae92942016-08-01 13:31:08 +053013596
13597#ifdef MODULE
13598/**
Dustin Brownf0f70562018-09-14 10:29:38 -070013599 * hdd_module_init() - Module init helper
Arun Khandavallifae92942016-08-01 13:31:08 +053013600 *
13601 * Module init helper function used by both module and static driver.
13602 *
13603 * Return: 0 for success, errno on failure
13604 */
13605static int hdd_module_init(void)
13606{
Dustin Brownf0f70562018-09-14 10:29:38 -070013607 if (hdd_driver_load())
Dustin Brownab482ac2017-06-09 17:00:44 -070013608 return -EINVAL;
Arun Khandavallifae92942016-08-01 13:31:08 +053013609
Dustin Brownab482ac2017-06-09 17:00:44 -070013610 return 0;
Arun Khandavallifae92942016-08-01 13:31:08 +053013611}
13612#else
13613static int __init hdd_module_init(void)
13614{
13615 int ret = -EINVAL;
13616
13617 ret = wlan_init_sysfs();
Srinivas Girigowda5e7dafe2016-11-02 14:09:13 -070013618 if (ret)
Dustin Browna2a39dc2018-09-17 15:29:59 -070013619 hdd_err("Failed to create sysfs entry");
Arun Khandavallifae92942016-08-01 13:31:08 +053013620
13621 return ret;
13622}
13623#endif
13624
13625
13626#ifdef MODULE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013627/**
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013628 * hdd_module_exit() - Exit function
13629 *
13630 * This is the driver exit point (invoked when module is unloaded using rmmod)
13631 *
13632 * Return: None
13633 */
13634static void __exit hdd_module_exit(void)
13635{
Dustin Brownf0f70562018-09-14 10:29:38 -070013636 hdd_driver_unload();
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013637}
Arun Khandavallifae92942016-08-01 13:31:08 +053013638#else
13639static void __exit hdd_module_exit(void)
13640{
Dustin Brownf0f70562018-09-14 10:29:38 -070013641 hdd_driver_unload();
Arun Khandavallifae92942016-08-01 13:31:08 +053013642 wlan_deinit_sysfs();
13643}
13644#endif
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013645
Srinivas Girigowda841da292018-02-21 16:33:00 -080013646static int fwpath_changed_handler(const char *kmessage,
13647 const struct kernel_param *kp)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013648{
13649 return param_set_copystring(kmessage, kp);
13650}
Prashanth Bhatta5da711e2015-11-30 14:28:52 -080013651
Nirav Shah73713f72018-05-17 14:50:41 +053013652#ifdef FEATURE_MONITOR_MODE_SUPPORT
13653static bool is_monitor_mode_supported(void)
13654{
13655 return true;
13656}
13657#else
13658static bool is_monitor_mode_supported(void)
13659{
13660 pr_err("Monitor mode not supported!");
13661 return false;
13662}
13663#endif
13664
13665#ifdef WLAN_FEATURE_EPPING
13666static bool is_epping_mode_supported(void)
13667{
13668 return true;
13669}
13670#else
13671static bool is_epping_mode_supported(void)
13672{
13673 pr_err("Epping mode not supported!");
13674 return false;
13675}
13676#endif
13677
Ryan Hsu6e9db0b2018-06-01 10:45:51 -070013678#ifdef QCA_WIFI_FTM
13679static bool is_ftm_mode_supported(void)
13680{
13681 return true;
13682}
13683#else
13684static bool is_ftm_mode_supported(void)
13685{
13686 pr_err("FTM mode not supported!");
13687 return false;
13688}
13689#endif
13690
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013691/**
13692 * is_con_mode_valid() check con mode is valid or not
13693 * @mode: global con mode
13694 *
13695 * Return: TRUE on success FALSE on failure
13696 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080013697static bool is_con_mode_valid(enum QDF_GLOBAL_MODE mode)
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013698{
13699 switch (mode) {
13700 case QDF_GLOBAL_MONITOR_MODE:
Nirav Shah73713f72018-05-17 14:50:41 +053013701 return is_monitor_mode_supported();
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013702 case QDF_GLOBAL_EPPING_MODE:
Nirav Shah73713f72018-05-17 14:50:41 +053013703 return is_epping_mode_supported();
13704 case QDF_GLOBAL_FTM_MODE:
Ryan Hsu6e9db0b2018-06-01 10:45:51 -070013705 return is_ftm_mode_supported();
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013706 case QDF_GLOBAL_MISSION_MODE:
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013707 return true;
13708 default:
13709 return false;
13710 }
13711}
13712
Dustin Brown27cd9942017-09-27 16:11:44 -070013713static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080013714 enum QDF_GLOBAL_MODE curr_mode)
Dustin Brown27cd9942017-09-27 16:11:44 -070013715{
13716 if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
13717 return;
13718
13719 switch (curr_mode) {
Dustin Brown27cd9942017-09-27 16:11:44 -070013720 case QDF_GLOBAL_MONITOR_MODE:
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053013721 hdd_info("Release wakelock for monitor mode!");
13722 qdf_wake_lock_release(&hdd_ctx->monitor_mode_wakelock,
13723 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
Dundi Raviteja0a2a65b2018-04-30 12:34:11 +053013724 /* fallthrough */
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053013725 case QDF_GLOBAL_MISSION_MODE:
Dustin Brown27cd9942017-09-27 16:11:44 -070013726 case QDF_GLOBAL_FTM_MODE:
13727 hdd_abort_mac_scan_all_adapters(hdd_ctx);
Dustin Brown07901ec2018-09-07 11:02:41 -070013728 wlan_cfg80211_cleanup_scan_queue(hdd_ctx->pdev, NULL);
Dustin Browndb2a8be2017-12-20 11:49:56 -080013729 hdd_stop_all_adapters(hdd_ctx);
Ashish Kumar Dhanotiya6ff329e2018-10-05 20:38:10 +053013730 hdd_deinit_all_adapters(hdd_ctx, false);
Dustin Brown27cd9942017-09-27 16:11:44 -070013731
Dustin Brown27cd9942017-09-27 16:11:44 -070013732 break;
13733 default:
13734 break;
13735 }
13736}
13737
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013738static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
Jeff Johnson876c1a62017-12-12 10:43:07 -080013739 enum QDF_GLOBAL_MODE curr_mode)
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013740{
Ashish Kumar Dhanotiya00243132017-01-24 16:37:34 +053013741 int driver_status;
13742
13743 driver_status = hdd_ctx->driver_status;
13744
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013745 switch (curr_mode) {
13746 case QDF_GLOBAL_MISSION_MODE:
13747 case QDF_GLOBAL_MONITOR_MODE:
13748 case QDF_GLOBAL_FTM_MODE:
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013749 hdd_close_all_adapters(hdd_ctx, false);
13750 break;
13751 case QDF_GLOBAL_EPPING_MODE:
13752 epping_disable();
13753 epping_close();
13754 break;
13755 default:
13756 return;
13757 }
13758}
13759
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013760static int
13761hdd_parse_driver_mode(const char *mode_str, enum QDF_GLOBAL_MODE *out_mode)
13762{
13763 int mode;
13764 int errno;
13765
Dustin Brown62743f42018-10-24 14:53:18 -070013766 *out_mode = QDF_GLOBAL_MAX_MODE;
13767
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013768 errno = kstrtoint(mode_str, 0, &mode);
13769 if (!errno)
13770 *out_mode = (enum QDF_GLOBAL_MODE)mode;
13771
13772 return errno;
13773}
13774
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013775/**
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013776 * __con_mode_handler() - Handles module param con_mode change
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013777 * @kmessage: con mode name on which driver to be bring up
13778 * @kp: The associated kernel parameter
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013779 * @hdd_ctx: Pointer to the global HDD context
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013780 *
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013781 * This function is invoked when user updates con mode using sys entry,
13782 * to initialize and bring-up driver in that specific mode.
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013783 *
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013784 * Return: Errno
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013785 */
Srinivas Girigowda841da292018-02-21 16:33:00 -080013786static int __con_mode_handler(const char *kmessage,
13787 const struct kernel_param *kp,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013788 struct hdd_context *hdd_ctx)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013789{
Jeff Johnson876c1a62017-12-12 10:43:07 -080013790 enum QDF_GLOBAL_MODE curr_mode;
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013791 enum QDF_GLOBAL_MODE next_mode;
13792 int errno;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013793
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013794 hdd_info("Driver mode changing to %s", kmessage);
Dustin Brownab6029b2017-05-24 13:04:19 -070013795
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013796 errno = wlan_hdd_validate_context(hdd_ctx);
13797 if (errno)
13798 return errno;
13799
13800 errno = hdd_parse_driver_mode(kmessage, &next_mode);
13801 if (errno) {
13802 hdd_err_rl("Failed to parse driver mode '%s'", kmessage);
13803 return errno;
13804 }
13805
13806 if (!is_con_mode_valid(next_mode)) {
13807 hdd_err_rl("Requested driver mode is invalid");
13808 return -EINVAL;
13809 }
Arunk Khandavalli2dc0c962016-10-20 12:37:26 +053013810
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053013811 qdf_atomic_set(&hdd_ctx->con_mode_flag, 1);
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053013812 mutex_lock(&hdd_init_deinit_lock);
Arun Khandavallifae92942016-08-01 13:31:08 +053013813
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013814 curr_mode = hdd_get_conparam();
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013815 if (curr_mode == next_mode) {
13816 hdd_err_rl("Driver is already in the requested mode");
13817 errno = 0;
13818 goto unlock;
Hanumanth Reddy Pothula7d51b1d2016-09-21 19:11:20 +053013819 }
13820
Dustin Brown27cd9942017-09-27 16:11:44 -070013821 /* ensure adapters are stopped */
13822 hdd_stop_present_mode(hdd_ctx, curr_mode);
13823
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013824 errno = hdd_wlan_stop_modules(hdd_ctx, true);
13825 if (errno) {
Arun Khandavallifae92942016-08-01 13:31:08 +053013826 hdd_err("Stop wlan modules failed");
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013827 goto unlock;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013828 }
13829
Dustin Browndd4e50f2018-05-24 15:43:42 -070013830 /* Cleanup present mode before switching to new mode */
13831 hdd_cleanup_present_mode(hdd_ctx, curr_mode);
Ashish Kumar Dhanotiyacda57662017-08-14 14:45:25 +053013832
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013833 hdd_set_conparam(next_mode);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013834
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013835 errno = hdd_wlan_start_modules(hdd_ctx, false);
13836 if (errno) {
13837 hdd_err("Start wlan modules failed: %d", errno);
13838 goto unlock;
Arun Khandavallifae92942016-08-01 13:31:08 +053013839 }
13840
jitiphil7af5cf22018-10-26 16:06:27 +053013841 errno = hdd_open_adapters_for_mode(hdd_ctx, next_mode);
13842 if (errno) {
13843 hdd_err("Failed to open adapters");
13844 goto unlock;
13845 }
13846
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013847 if (next_mode == QDF_GLOBAL_MONITOR_MODE) {
Dustin Browne7e71d32018-05-11 16:00:08 -070013848 struct hdd_adapter *adapter =
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013849 hdd_get_adapter(hdd_ctx, QDF_MONITOR_MODE);
Dustin Browne7e71d32018-05-11 16:00:08 -070013850
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013851 QDF_BUG(adapter);
Dustin Browne7e71d32018-05-11 16:00:08 -070013852 if (!adapter) {
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013853 hdd_err("Failed to get monitor adapter");
13854 goto unlock;
Dustin Browne7e71d32018-05-11 16:00:08 -070013855 }
13856
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013857 errno = hdd_start_adapter(adapter);
13858 if (errno) {
13859 hdd_err("Failed to start monitor adapter");
13860 goto unlock;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013861 }
Arun Khandavallifae92942016-08-01 13:31:08 +053013862
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013863 hdd_info("Acquire wakelock for monitor mode");
Arunk Khandavalliebd1e372017-11-06 15:00:24 +053013864 qdf_wake_lock_acquire(&hdd_ctx->monitor_mode_wakelock,
13865 WIFI_POWER_EVENT_WAKELOCK_MONITOR_MODE);
13866 }
13867
Dustin Brown20024e32018-01-03 12:34:58 -080013868 /* con_mode is a global module parameter */
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013869 con_mode = next_mode;
13870 hdd_info("Driver mode successfully changed to %s", kmessage);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013871
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013872 errno = 0;
13873
13874unlock:
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053013875 mutex_unlock(&hdd_init_deinit_lock);
Sourav Mohapatra421d42b2017-12-29 16:33:23 +053013876 qdf_atomic_set(&hdd_ctx->con_mode_flag, 0);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013877
Dustin Brownc07ce8e2018-10-23 17:01:58 -070013878 return errno;
13879}
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013880
Srinivas Girigowda841da292018-02-21 16:33:00 -080013881static int con_mode_handler(const char *kmessage, const struct kernel_param *kp)
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013882{
Dustin Brown67d30412018-09-20 12:10:22 -070013883 struct hdd_driver *hdd_driver = hdd_driver_get();
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013884 struct hdd_context *hdd_ctx;
Dustin Brown67d30412018-09-20 12:10:22 -070013885 QDF_STATUS status;
13886 int errno;
13887
13888 hdd_enter();
13889
Dustin Brown13fa9872018-11-13 10:57:45 -080013890 /* This handler will be invoked before module init when the wlan driver
13891 * is loaded using 'insmod wlan.ko con_mode=5' for example. Return
13892 * success in this case, as module init will bring up the correct
13893 * con_mode when it runs.
13894 */
13895 if (hdd_driver->state == driver_state_uninit)
13896 return 0;
13897
Dustin Brown67d30412018-09-20 12:10:22 -070013898 status = dsc_driver_trans_start_wait(hdd_driver->dsc_driver,
13899 "mode change");
13900 if (QDF_IS_STATUS_ERROR(status)) {
13901 hdd_err("Failed to start 'mode change'; status:%u", status);
13902 errno = qdf_status_to_os_return(status);
13903 goto exit;
13904 }
13905
13906 dsc_driver_wait_for_ops(hdd_driver->dsc_driver);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013907
13908 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Dustin Brown67d30412018-09-20 12:10:22 -070013909 errno = wlan_hdd_validate_context(hdd_ctx);
13910 if (errno)
13911 goto trans_stop;
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013912
Ashish Kumar Dhanotiya759b3272018-05-18 17:49:46 +053013913 if (!cds_wait_for_external_threads_completion(__func__)) {
13914 hdd_warn("External threads are still active, can not change mode");
Dustin Brown67d30412018-09-20 12:10:22 -070013915 errno = -EAGAIN;
13916 goto trans_stop;
Ashish Kumar Dhanotiya759b3272018-05-18 17:49:46 +053013917 }
13918
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013919 cds_ssr_protect(__func__);
Dustin Brown67d30412018-09-20 12:10:22 -070013920 errno = __con_mode_handler(kmessage, kp, hdd_ctx);
Arun Khandavalli16fd1ee2016-10-08 17:47:07 +053013921 cds_ssr_unprotect(__func__);
13922
Dustin Brown67d30412018-09-20 12:10:22 -070013923trans_stop:
13924 dsc_driver_trans_stop(hdd_driver->dsc_driver);
13925
13926exit:
13927 hdd_exit();
13928
13929 return errno;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013930}
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013931
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053013932static int con_mode_handler_ftm(const char *kmessage,
Srinivas Girigowda841da292018-02-21 16:33:00 -080013933 const struct kernel_param *kp)
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053013934{
13935 int ret;
13936
13937 ret = param_set_int(kmessage, kp);
13938
13939 if (con_mode_ftm != QDF_GLOBAL_FTM_MODE) {
13940 pr_err("Only FTM mode supported!");
13941 return -ENOTSUPP;
13942 }
13943
13944 hdd_set_conparam(con_mode_ftm);
13945 con_mode = con_mode_ftm;
13946
13947 return ret;
13948}
13949
Nirav Shah73713f72018-05-17 14:50:41 +053013950#ifdef FEATURE_MONITOR_MODE_SUPPORT
Ravi Joshia307f632017-07-17 23:41:41 -070013951static int con_mode_handler_monitor(const char *kmessage,
Srinivas Girigowda841da292018-02-21 16:33:00 -080013952 const struct kernel_param *kp)
Ravi Joshia307f632017-07-17 23:41:41 -070013953{
13954 int ret;
13955
13956 ret = param_set_int(kmessage, kp);
13957
13958 if (con_mode_monitor != QDF_GLOBAL_MONITOR_MODE) {
13959 pr_err("Only Monitor mode supported!");
13960 return -ENOTSUPP;
13961 }
13962
13963 hdd_set_conparam(con_mode_monitor);
13964 con_mode = con_mode_monitor;
13965
13966 return ret;
13967}
Nirav Shah73713f72018-05-17 14:50:41 +053013968#endif
Ravi Joshia307f632017-07-17 23:41:41 -070013969
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013970/**
13971 * hdd_get_conparam() - driver exit point
13972 *
13973 * This is the driver exit point (invoked when module is unloaded using rmmod)
13974 *
Jeff Johnson876c1a62017-12-12 10:43:07 -080013975 * Return: enum QDF_GLOBAL_MODE
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013976 */
Jeff Johnson876c1a62017-12-12 10:43:07 -080013977enum QDF_GLOBAL_MODE hdd_get_conparam(void)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013978{
Jeff Johnson876c1a62017-12-12 10:43:07 -080013979 return (enum QDF_GLOBAL_MODE) curr_con_mode;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013980}
13981
Dustin Brownf0f70562018-09-14 10:29:38 -070013982void hdd_set_conparam(int32_t con_param)
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013983{
Prashanth Bhatta05aaf012015-12-10 17:34:24 -080013984 curr_con_mode = con_param;
Prashanth Bhattaedd6ca22015-12-10 17:21:29 -080013985}
13986
Komal Seelamc11bb222016-01-27 18:57:10 +053013987/**
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053013988 * hdd_clean_up_pre_cac_interface() - Clean up the pre cac interface
13989 * @hdd_ctx: HDD context
13990 *
13991 * Cleans up the pre cac interface, if it exists
13992 *
13993 * Return: None
13994 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070013995void hdd_clean_up_pre_cac_interface(struct hdd_context *hdd_ctx)
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053013996{
13997 uint8_t session_id;
13998 QDF_STATUS status;
Jeff Johnson85b5c112017-08-11 15:15:23 -070013999 struct hdd_adapter *precac_adapter;
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014000
Jeff Johnson16528362018-06-14 12:34:16 -070014001 status = wlan_sap_get_pre_cac_vdev_id(hdd_ctx->mac_handle, &session_id);
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014002 if (QDF_IS_STATUS_ERROR(status)) {
14003 hdd_err("failed to get pre cac vdev id");
14004 return;
14005 }
14006
14007 precac_adapter = hdd_get_adapter_by_vdev(hdd_ctx, session_id);
14008 if (!precac_adapter) {
Jeff Johnsondd2f1fc2018-05-06 11:22:52 -070014009 hdd_err("invalid pre cac adapter");
Manishekar Chandrasekaran9e8c7be2016-08-03 14:57:14 +053014010 return;
14011 }
14012
14013 qdf_create_work(0, &hdd_ctx->sap_pre_cac_work,
14014 wlan_hdd_sap_pre_cac_failure,
14015 (void *)precac_adapter);
14016 qdf_sched_work(0, &hdd_ctx->sap_pre_cac_work);
14017
14018}
14019
14020/**
Komal Seelamec702b02016-02-24 18:42:16 +053014021 * hdd_update_ol_config - API to update ol configuration parameters
14022 * @hdd_ctx: HDD context
Komal Seelamc11bb222016-01-27 18:57:10 +053014023 *
Komal Seelamc11bb222016-01-27 18:57:10 +053014024 * Return: void
14025 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014026static void hdd_update_ol_config(struct hdd_context *hdd_ctx)
Komal Seelamc11bb222016-01-27 18:57:10 +053014027{
Komal Seelamec702b02016-02-24 18:42:16 +053014028 struct ol_config_info cfg;
Anurag Chouhandf2b2682016-02-29 14:15:27 +053014029 struct ol_context *ol_ctx = cds_get_context(QDF_MODULE_ID_BMI);
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014030 bool self_recovery = false;
14031 QDF_STATUS status;
Komal Seelamc11bb222016-01-27 18:57:10 +053014032
Komal Seelamec702b02016-02-24 18:42:16 +053014033 if (!ol_ctx)
14034 return;
14035
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014036 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
14037 if (QDF_IS_STATUS_ERROR(status))
14038 hdd_err("Failed to get self recovery ini config");
14039
14040 cfg.enable_self_recovery = self_recovery;
Komal Seelamec702b02016-02-24 18:42:16 +053014041 cfg.enable_uart_print = hdd_ctx->config->enablefwprint;
14042 cfg.enable_fw_log = hdd_ctx->config->enable_fw_log;
14043 cfg.enable_ramdump_collection = hdd_ctx->config->is_ramdump_enabled;
Jeff Johnsonb8bf9072016-09-23 17:39:27 -070014044 cfg.enable_lpass_support = hdd_lpass_is_supported(hdd_ctx);
Komal Seelamec702b02016-02-24 18:42:16 +053014045
14046 ol_init_ini_config(ol_ctx, &cfg);
14047}
14048
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014049#ifdef FEATURE_RUNTIME_PM
14050/**
14051 * hdd_populate_runtime_cfg() - populate runtime configuration
14052 * @hdd_ctx: hdd context
14053 * @cfg: pointer to the configuration memory being populated
14054 *
14055 * Return: void
14056 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014057static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014058 struct hif_config_info *cfg)
14059{
14060 cfg->enable_runtime_pm = hdd_ctx->config->runtime_pm;
Wu Gao66454f12018-09-26 19:55:41 +080014061 cfg->runtime_pm_delay =
14062 ucfg_pmo_get_runtime_pm_delay(hdd_ctx->psoc);
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014063}
14064#else
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014065static void hdd_populate_runtime_cfg(struct hdd_context *hdd_ctx,
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014066 struct hif_config_info *cfg)
14067{
14068}
14069#endif
14070
Komal Seelamec702b02016-02-24 18:42:16 +053014071/**
14072 * hdd_update_hif_config - API to update HIF configuration parameters
14073 * @hdd_ctx: HDD Context
14074 *
14075 * Return: void
14076 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014077static void hdd_update_hif_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053014078{
Anurag Chouhandf2b2682016-02-29 14:15:27 +053014079 struct hif_opaque_softc *scn = cds_get_context(QDF_MODULE_ID_HIF);
Komal Seelamec702b02016-02-24 18:42:16 +053014080 struct hif_config_info cfg;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014081 bool prevent_link_down = false;
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014082 bool self_recovery = false;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014083 QDF_STATUS status;
Komal Seelamec702b02016-02-24 18:42:16 +053014084
14085 if (!scn)
14086 return;
14087
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014088 status = ucfg_mlme_get_prevent_link_down(hdd_ctx->psoc,
14089 &prevent_link_down);
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014090 if (QDF_IS_STATUS_ERROR(status))
14091 hdd_err("Failed to get prevent_link_down config");
14092
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014093 status = ucfg_mlme_get_self_recovery(hdd_ctx->psoc, &self_recovery);
14094 if (QDF_IS_STATUS_ERROR(status))
14095 hdd_err("Failed to get self recovery ini config");
14096
14097 cfg.enable_self_recovery = self_recovery;
Houston Hoffmanc7c69f02016-03-24 22:45:52 -070014098 hdd_populate_runtime_cfg(hdd_ctx, &cfg);
Komal Seelamec702b02016-02-24 18:42:16 +053014099 hif_init_ini_config(scn, &cfg);
Dustin Brownee3e0592017-09-07 13:50:11 -070014100
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014101 if (prevent_link_down)
Dustin Brownee3e0592017-09-07 13:50:11 -070014102 hif_vote_link_up(scn);
Komal Seelamec702b02016-02-24 18:42:16 +053014103}
14104
14105/**
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014106 * hdd_update_dp_config() - Propagate config parameters to Lithium
14107 * datapath
14108 * @hdd_ctx: HDD Context
14109 *
14110 * Return: 0 for success/errno for failure
14111 */
14112static int hdd_update_dp_config(struct hdd_context *hdd_ctx)
14113{
14114 struct cdp_config_params params;
14115 QDF_STATUS status;
jitiphil377bcc12018-10-05 19:46:08 +053014116 void *soc;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014117
jitiphil377bcc12018-10-05 19:46:08 +053014118 soc = cds_get_context(QDF_MODULE_ID_SOC);
14119 params.tso_enable = cfg_get(hdd_ctx->psoc, CFG_DP_TSO);
14120 params.lro_enable = cfg_get(hdd_ctx->psoc, CFG_DP_LRO);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014121#ifdef QCA_LL_TX_FLOW_CONTROL_V2
14122 params.tx_flow_stop_queue_threshold =
jitiphil47c3d9a2018-11-08 18:30:55 +053014123 cfg_get(hdd_ctx->psoc, CFG_DP_TX_FLOW_STOP_QUEUE_TH);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014124 params.tx_flow_start_queue_offset =
jitiphil47c3d9a2018-11-08 18:30:55 +053014125 cfg_get(hdd_ctx->psoc,
14126 CFG_DP_TX_FLOW_START_QUEUE_OFFSET);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014127#endif
jitiphil377bcc12018-10-05 19:46:08 +053014128 params.flow_steering_enable =
14129 cfg_get(hdd_ctx->psoc, CFG_DP_FLOW_STEERING_ENABLED);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014130 params.napi_enable = hdd_ctx->napi_enable;
14131 params.tcp_udp_checksumoffload =
jitiphil377bcc12018-10-05 19:46:08 +053014132 cfg_get(hdd_ctx->psoc,
14133 CFG_DP_TCP_UDP_CKSUM_OFFLOAD);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014134
jitiphil377bcc12018-10-05 19:46:08 +053014135 status = cdp_update_config_parameters(soc, &params);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014136 if (status) {
Dustin Browna2868622018-03-20 11:38:14 -070014137 hdd_err("Failed to attach config parameters");
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014138 return status;
14139 }
14140
14141 return 0;
14142}
14143
14144/**
Komal Seelamec702b02016-02-24 18:42:16 +053014145 * hdd_update_config() - Initialize driver per module ini parameters
14146 * @hdd_ctx: HDD Context
14147 *
14148 * API is used to initialize all driver per module configuration parameters
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014149 * Return: 0 for success, errno for failure
Komal Seelamec702b02016-02-24 18:42:16 +053014150 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014151int hdd_update_config(struct hdd_context *hdd_ctx)
Komal Seelamec702b02016-02-24 18:42:16 +053014152{
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014153 int ret;
14154
Wu Gao66454f12018-09-26 19:55:41 +080014155 if (ucfg_pmo_is_ns_offloaded(hdd_ctx->psoc))
14156 hdd_ctx->ns_offload_enable = true;
14157
Komal Seelamec702b02016-02-24 18:42:16 +053014158 hdd_update_ol_config(hdd_ctx);
14159 hdd_update_hif_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014160 if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam())
14161 ret = hdd_update_cds_config_ftm(hdd_ctx);
14162 else
14163 ret = hdd_update_cds_config(hdd_ctx);
Tushnim Bhattacharyya329514d2017-02-07 09:14:25 -080014164 ret = hdd_update_user_config(hdd_ctx);
Arun Khandavallic811dcc2016-06-26 07:37:21 +053014165
14166 return ret;
Komal Seelamc11bb222016-01-27 18:57:10 +053014167}
14168
Mukul Sharma9d797a02017-01-05 20:26:03 +053014169#ifdef FEATURE_WLAN_RA_FILTERING
14170/**
14171 * hdd_ra_populate_cds_config() - Populate RA filtering cds configuration
14172 * @psoc_cfg: pmo psoc Configuration
14173 * @hdd_ctx: Pointer to hdd context
14174 *
14175 * Return: none
14176 */
14177static inline void hdd_ra_populate_pmo_config(
14178 struct pmo_psoc_cfg *psoc_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014179 struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053014180{
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053014181 bool is_rate_limit_enabled;
14182 QDF_STATUS status;
14183
14184 status = ucfg_fwol_get_is_rate_limit_enabled(hdd_ctx->psoc,
14185 &is_rate_limit_enabled);
14186 if (QDF_IS_STATUS_ERROR(status))
14187 return;
14188
Mukul Sharma9d797a02017-01-05 20:26:03 +053014189 psoc_cfg->ra_ratelimit_interval =
14190 hdd_ctx->config->RArateLimitInterval;
14191 psoc_cfg->ra_ratelimit_enable =
Sourav Mohapatra0f3b8572018-09-12 10:03:51 +053014192 is_rate_limit_enabled;
Mukul Sharma9d797a02017-01-05 20:26:03 +053014193}
14194#else
14195static inline void hdd_ra_populate_pmo_config(
14196 struct cds_config_info *cds_cfg,
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014197 struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053014198{
14199}
14200#endif
Will Huang3cd2b7c2017-11-17 13:16:56 +080014201
Mukul Sharma9d797a02017-01-05 20:26:03 +053014202/**
14203 * hdd_update_pmo_config - API to update pmo configuration parameters
14204 * @hdd_ctx: HDD context
14205 *
14206 * Return: void
14207 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014208static int hdd_update_pmo_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053014209{
Mukul Sharma9d797a02017-01-05 20:26:03 +053014210 struct pmo_psoc_cfg psoc_cfg;
14211 QDF_STATUS status;
Wu Gao66454f12018-09-26 19:55:41 +080014212 enum pmo_wow_enable_type wow_enable;
14213
14214 ucfg_pmo_get_psoc_config(hdd_ctx->psoc, &psoc_cfg);
Mukul Sharma9d797a02017-01-05 20:26:03 +053014215
14216 /*
14217 * Value of hdd_ctx->wowEnable can be,
14218 * 0 - Disable both magic pattern match and pattern byte match.
14219 * 1 - Enable magic pattern match on all interfaces.
14220 * 2 - Enable pattern byte match on all interfaces.
14221 * 3 - Enable both magic patter and pattern byte match on
14222 * all interfaces.
14223 */
Wu Gao66454f12018-09-26 19:55:41 +080014224 wow_enable = ucfg_pmo_get_wow_enable(hdd_ctx->psoc);
14225 psoc_cfg.magic_ptrn_enable = (wow_enable & 0x01) ? true : false;
Mukul Sharma9d797a02017-01-05 20:26:03 +053014226 psoc_cfg.ptrn_match_enable_all_vdev =
Wu Gao66454f12018-09-26 19:55:41 +080014227 (wow_enable & 0x02) ? true : false;
Dustin Brownb9987af2018-03-01 17:15:11 -080014228 psoc_cfg.packet_filter_enabled = !hdd_ctx->config->disablePacketFilter;
Mukul Sharma9d797a02017-01-05 20:26:03 +053014229 psoc_cfg.ap_arpns_support = hdd_ctx->ap_arpns_support;
Will Huang3cd2b7c2017-11-17 13:16:56 +080014230 psoc_cfg.d0_wow_supported = wma_d0_wow_is_supported();
Bala Venkatesh46e29032018-11-14 18:24:55 +053014231 ucfg_mlme_get_sap_max_modulated_dtim(hdd_ctx->psoc,
14232 &psoc_cfg.sta_max_li_mod_dtim);
14233
Mukul Sharma9d797a02017-01-05 20:26:03 +053014234
14235 hdd_ra_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9223f232017-03-08 18:42:27 +053014236 hdd_lpass_populate_pmo_config(&psoc_cfg, hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053014237
Dustin Brown1dbefe62018-09-11 16:32:03 -070014238 status = ucfg_pmo_update_psoc_config(hdd_ctx->psoc, &psoc_cfg);
Dustin Brownb9987af2018-03-01 17:15:11 -080014239 if (QDF_IS_STATUS_ERROR(status))
14240 hdd_err("failed pmo psoc configuration; status:%d", status);
14241
14242 return qdf_status_to_os_return(status);
Mukul Sharma9d797a02017-01-05 20:26:03 +053014243}
14244
Abhishek Singhb20db962017-03-03 21:28:46 +053014245#ifdef FEATURE_WLAN_SCAN_PNO
14246static inline void hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
Wu Gao1ab05582018-11-08 16:22:49 +080014247 struct hdd_context *hdd_ctx)
Abhishek Singhb20db962017-03-03 21:28:46 +053014248{
Varun Reddy Yeturubba32e92017-09-06 13:31:40 -070014249 struct nlo_mawc_params *mawc_cfg = &pno_cfg->mawc_params;
Wu Gao1ab05582018-11-08 16:22:49 +080014250 struct hdd_config *cfg = hdd_ctx->config;
14251 bool mawc_enabled;
Varun Reddy Yeturubba32e92017-09-06 13:31:40 -070014252
Abhishek Singhb20db962017-03-03 21:28:46 +053014253 pno_cfg->channel_prediction = cfg->pno_channel_prediction;
14254 pno_cfg->top_k_num_of_channels = cfg->top_k_num_of_channels;
14255 pno_cfg->stationary_thresh = cfg->stationary_thresh;
14256 pno_cfg->adaptive_dwell_mode = cfg->adaptive_dwell_mode_enabled;
14257 pno_cfg->channel_prediction_full_scan =
14258 cfg->channel_prediction_full_scan;
Wu Gao1ab05582018-11-08 16:22:49 +080014259
14260 ucfg_mlme_is_mawc_enabled(hdd_ctx->psoc, &mawc_enabled);
14261 mawc_cfg->enable = mawc_enabled && cfg->mawc_nlo_enabled;
Varun Reddy Yeturubba32e92017-09-06 13:31:40 -070014262 mawc_cfg->exp_backoff_ratio = cfg->mawc_nlo_exp_backoff_ratio;
14263 mawc_cfg->init_scan_interval = cfg->mawc_nlo_init_scan_interval;
14264 mawc_cfg->max_scan_interval = cfg->mawc_nlo_max_scan_interval;
Abhishek Singhb20db962017-03-03 21:28:46 +053014265}
14266#else
14267static inline void
14268hdd_update_pno_config(struct pno_user_cfg *pno_cfg,
Wu Gao1ab05582018-11-08 16:22:49 +080014269 struct hdd_context *hdd_ctx)
Abhishek Singhb20db962017-03-03 21:28:46 +053014270{
Abhishek Singhb20db962017-03-03 21:28:46 +053014271}
14272#endif
14273
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014274void hdd_update_ie_whitelist_attr(struct probe_req_whitelist_attr *ie_whitelist,
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014275 struct hdd_context *hdd_ctx)
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014276{
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014277 struct wlan_fwol_ie_whitelist whitelist = {0};
14278 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014279 QDF_STATUS status;
14280 bool is_ie_whitelist_enable = false;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014281 uint8_t i = 0;
14282
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014283 status = ucfg_fwol_get_ie_whitelist(psoc, &is_ie_whitelist_enable);
14284 if (QDF_IS_STATUS_ERROR(status)) {
14285 hdd_err("Unable to get IE whitelist param");
14286 return;
14287 }
14288
14289 ie_whitelist->white_list = is_ie_whitelist_enable;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014290 if (!ie_whitelist->white_list)
14291 return;
14292
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014293 status = ucfg_fwol_get_all_whitelist_params(psoc, &whitelist);
14294 if (QDF_IS_STATUS_ERROR(status)) {
14295 hdd_err("Unable to get all whitelist params");
14296 return;
14297 }
14298
14299 ie_whitelist->ie_bitmap[0] = whitelist.ie_bitmap_0;
14300 ie_whitelist->ie_bitmap[1] = whitelist.ie_bitmap_1;
14301 ie_whitelist->ie_bitmap[2] = whitelist.ie_bitmap_2;
14302 ie_whitelist->ie_bitmap[3] = whitelist.ie_bitmap_3;
14303 ie_whitelist->ie_bitmap[4] = whitelist.ie_bitmap_4;
14304 ie_whitelist->ie_bitmap[5] = whitelist.ie_bitmap_5;
14305 ie_whitelist->ie_bitmap[6] = whitelist.ie_bitmap_6;
14306 ie_whitelist->ie_bitmap[7] = whitelist.ie_bitmap_7;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014307
Dundi Raviteja9ab4e7b2018-09-28 14:18:28 +053014308 ie_whitelist->num_vendor_oui = whitelist.no_of_probe_req_ouis;
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014309 for (i = 0; i < ie_whitelist->num_vendor_oui; i++)
Dundi Raviteja9ab4e7b2018-09-28 14:18:28 +053014310 ie_whitelist->voui[i] = whitelist.probe_req_voui[i];
Rajeev Kumar Sirasanagandlaaec0b082017-06-21 11:59:41 +053014311}
14312
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014313uint32_t hdd_limit_max_per_index_score(uint32_t per_index_score)
14314{
14315 uint8_t i, score;
14316
14317 for (i = 0; i < MAX_INDEX_PER_INI; i++) {
14318 score = WLAN_GET_SCORE_PERCENTAGE(per_index_score, i);
14319 if (score > MAX_INDEX_SCORE)
14320 WLAN_SET_SCORE_PERCENTAGE(per_index_score,
14321 MAX_INDEX_SCORE, i);
14322 }
14323
14324 return per_index_score;
14325}
14326
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014327QDF_STATUS hdd_update_score_config(
14328 struct scoring_config *score_config, struct hdd_context *hdd_ctx)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014329{
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014330 struct hdd_config *cfg = hdd_ctx->config;
gaurank kathpaliaae52c982018-10-04 01:35:18 +053014331 QDF_STATUS status;
gaurank kathpalia651abcd2018-11-12 22:41:23 +053014332 struct wlan_mlme_nss_chains vdev_ini_cfg;
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014333 bool bval = false;
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014334
gaurank kathpalia651abcd2018-11-12 22:41:23 +053014335 /* Populate the nss chain params from ini for this vdev type */
14336 sme_populate_nss_chain_params(hdd_ctx->mac_handle, &vdev_ini_cfg,
14337 QDF_STA_MODE,
14338 hdd_ctx->num_rf_chains);
14339
14340 score_config->vdev_nss_24g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_2GHZ];
14341 score_config->vdev_nss_24g = vdev_ini_cfg.rx_nss[NSS_CHAINS_BAND_5GHZ];
14342
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053014343 sme_update_score_config(hdd_ctx->mac_handle, score_config);
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014344
14345 score_config->cb_mode_24G = cfg->nChannelBondingMode24GHz;
14346 score_config->cb_mode_5G = cfg->nChannelBondingMode5GHz;
gaurank kathpaliaae52c982018-10-04 01:35:18 +053014347
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014348 if (cfg->dot11Mode == eHDD_DOT11_MODE_AUTO ||
14349 cfg->dot11Mode == eHDD_DOT11_MODE_11ax ||
14350 cfg->dot11Mode == eHDD_DOT11_MODE_11ax_ONLY)
14351 score_config->he_cap = 1;
14352
14353 if (score_config->he_cap ||
14354 cfg->dot11Mode == eHDD_DOT11_MODE_11ac ||
14355 cfg->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)
14356 score_config->vht_cap = 1;
14357
14358 if (score_config->vht_cap || cfg->dot11Mode == eHDD_DOT11_MODE_11n ||
14359 cfg->dot11Mode == eHDD_DOT11_MODE_11n_ONLY)
14360 score_config->ht_cap = 1;
14361
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014362 status = ucfg_mlme_get_vht_for_24ghz(hdd_ctx->psoc, &bval);
14363 if (!QDF_IS_STATUS_SUCCESS(status))
14364 hdd_err("Failed to get vht_for_24ghz");
14365 if (score_config->vht_cap && bval)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014366 score_config->vht_24G_cap = 1;
14367
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014368 status = ucfg_mlme_get_vht_enable_tx_bf(hdd_ctx->psoc,
14369 &bval);
14370 if (!QDF_IS_STATUS_SUCCESS(status))
14371 hdd_err("unable to get vht_enable_tx_bf");
14372
14373 if (bval)
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014374 score_config->beamformee_cap = 1;
14375
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053014376 return QDF_STATUS_SUCCESS;
Abhishek Singhb6cdaf12017-11-10 14:43:39 +053014377}
14378
Abhishek Singh257a9482017-03-06 16:52:39 +053014379/**
bings81fe50a2017-11-27 14:33:26 +080014380 * hdd_update_dfs_config() - API to update dfs configuration parameters.
14381 * @hdd_ctx: HDD context
14382 *
14383 * Return: 0 if success else err
14384 */
14385static int hdd_update_dfs_config(struct hdd_context *hdd_ctx)
14386{
Dustin Brown1dbefe62018-09-11 16:32:03 -070014387 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
bings81fe50a2017-11-27 14:33:26 +080014388 struct dfs_user_config dfs_cfg;
14389 QDF_STATUS status;
14390
Arif Hussain224d3812018-11-16 17:58:38 -080014391 ucfg_mlme_get_dfs_filter_offload(hdd_ctx->psoc,
14392 &dfs_cfg.dfs_is_phyerr_filter_offload);
bings81fe50a2017-11-27 14:33:26 +080014393 status = ucfg_dfs_update_config(psoc, &dfs_cfg);
14394 if (QDF_IS_STATUS_ERROR(status)) {
14395 hdd_err("failed dfs psoc configuration");
14396 return -EINVAL;
14397 }
14398
14399 return 0;
14400}
14401
14402/**
Abhishek Singh257a9482017-03-06 16:52:39 +053014403 * hdd_update_scan_config - API to update scan configuration parameters
14404 * @hdd_ctx: HDD context
14405 *
14406 * Return: 0 if success else err
14407 */
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014408static int hdd_update_scan_config(struct hdd_context *hdd_ctx)
Abhishek Singh257a9482017-03-06 16:52:39 +053014409{
Dustin Brown1dbefe62018-09-11 16:32:03 -070014410 struct wlan_objmgr_psoc *psoc = hdd_ctx->psoc;
Abhishek Singh257a9482017-03-06 16:52:39 +053014411 struct scan_user_cfg scan_cfg;
14412 struct hdd_config *cfg = hdd_ctx->config;
14413 QDF_STATUS status;
Wu Gaoca416ff2018-09-17 11:05:07 +080014414 uint8_t scan_bucket_thre;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014415 uint8_t select_5ghz_margin;
Wu Gao1ab05582018-11-08 16:22:49 +080014416 bool roam_prefer_5ghz;
Krunal Sonid2c33e12018-12-06 15:02:37 -080014417 uint32_t mcast_mcc_rest_time = 0;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014418
Vignesh Viswanathana1f3a1a2018-10-04 13:10:46 +053014419 status = ucfg_mlme_get_select_5ghz_margin(hdd_ctx->psoc,
14420 &select_5ghz_margin);
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014421 if (QDF_IS_STATUS_ERROR(status)) {
14422 hdd_err("Failed to get select_5ghz_margin");
14423 return -EIO;
14424 }
Abhishek Singh257a9482017-03-06 16:52:39 +053014425
14426 scan_cfg.active_dwell = cfg->nActiveMaxChnTime;
14427 scan_cfg.passive_dwell = cfg->nPassiveMaxChnTime;
14428 scan_cfg.conc_active_dwell = cfg->nActiveMaxChnTimeConc;
14429 scan_cfg.conc_passive_dwell = cfg->nPassiveMaxChnTimeConc;
14430 scan_cfg.conc_max_rest_time = cfg->nRestTimeConc;
14431 scan_cfg.conc_min_rest_time = cfg->min_rest_time_conc;
14432 scan_cfg.conc_idle_time = cfg->idle_time_conc;
Abhishek Singh158fe252017-03-23 11:09:34 +053014433 /* convert to ms */
14434 scan_cfg.scan_cache_aging_time =
14435 cfg->scanAgingTimeout * 1000;
Wu Gao1ab05582018-11-08 16:22:49 +080014436 ucfg_mlme_is_roam_prefer_5ghz(hdd_ctx->psoc, &roam_prefer_5ghz);
14437 scan_cfg.prefer_5ghz = (uint32_t)roam_prefer_5ghz;
Vignesh Viswanathana851d752018-10-03 19:44:38 +053014438 scan_cfg.select_5ghz_margin = select_5ghz_margin;
Dustin Brown1dbefe62018-09-11 16:32:03 -070014439 ucfg_mlme_get_first_scan_bucket_threshold(hdd_ctx->psoc,
Wu Gaoca416ff2018-09-17 11:05:07 +080014440 &scan_bucket_thre);
14441 scan_cfg.scan_bucket_threshold = (int32_t)scan_bucket_thre;
Abhishek Singh158fe252017-03-23 11:09:34 +053014442 scan_cfg.rssi_cat_gap = cfg->nRssiCatGap;
Abhishek Singh257a9482017-03-06 16:52:39 +053014443 scan_cfg.scan_dwell_time_mode = cfg->scan_adaptive_dwell_mode;
Kapil Guptafa9a8c62017-04-10 15:25:40 +053014444 scan_cfg.is_snr_monitoring_enabled = cfg->fEnableSNRMonitoring;
Jeff Johnson81c00d02017-11-07 12:34:36 -080014445 scan_cfg.usr_cfg_probe_rpt_time = cfg->scan_probe_repeat_time;
14446 scan_cfg.usr_cfg_num_probes = cfg->scan_num_probes;
Abhishek Singhb58164a2017-07-19 18:47:23 +053014447 scan_cfg.is_bssid_hint_priority = cfg->is_bssid_hint_priority;
Kiran Kumar Lokered547fdd2017-09-13 17:20:55 -070014448 scan_cfg.enable_mac_spoofing = cfg->enable_mac_spoofing;
Krunal Sonid2c33e12018-12-06 15:02:37 -080014449 status = ucfg_mlme_get_sta_miracast_mcc_rest_time(hdd_ctx->psoc,
14450 &mcast_mcc_rest_time);
14451 if (!QDF_IS_STATUS_SUCCESS(status)) {
14452 hdd_err("ucfg_mlme_get_sta_miracast_mcc_rest_time, use def");
14453 return -EIO;
14454 }
14455 scan_cfg.sta_miracast_mcc_rest_time = mcast_mcc_rest_time;
Wu Gao1ab05582018-11-08 16:22:49 +080014456 hdd_update_pno_config(&scan_cfg.pno_cfg, hdd_ctx);
Dundi Raviteja85a240a2018-09-10 15:03:07 +053014457 hdd_update_ie_whitelist_attr(&scan_cfg.ie_whitelist, hdd_ctx);
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053014458
Abhinav Kumarb074f2f2018-09-15 15:32:11 +053014459 status = hdd_update_score_config(&scan_cfg.score_config, hdd_ctx);
Vignesh Viswanathan987f0bb2018-09-17 17:00:29 +053014460 if (QDF_IS_STATUS_ERROR(status)) {
14461 hdd_err("Failed to update scoring config");
14462 return -EINVAL;
14463 }
Abhishek Singhb20db962017-03-03 21:28:46 +053014464
Abhishek Singh257a9482017-03-06 16:52:39 +053014465 status = ucfg_scan_update_user_config(psoc, &scan_cfg);
14466 if (status != QDF_STATUS_SUCCESS) {
14467 hdd_err("failed pmo psoc configuration");
14468 return -EINVAL;
14469 }
Liangwei Dongac3ddde2018-09-10 23:25:12 -040014470 ucfg_scan_set_global_config(
14471 psoc, SCAN_CFG_DROP_BCN_ON_CHANNEL_MISMATCH,
14472 cfg_get(psoc, CFG_DROP_BCN_ON_CHANNEL_MISMATCH));
Abhishek Singh257a9482017-03-06 16:52:39 +053014473
14474 return 0;
14475}
Abhishek Singh257a9482017-03-06 16:52:39 +053014476
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014477int hdd_update_components_config(struct hdd_context *hdd_ctx)
Mukul Sharma9d797a02017-01-05 20:26:03 +053014478{
14479 int ret;
14480
14481 ret = hdd_update_pmo_config(hdd_ctx);
Abhishek Singh257a9482017-03-06 16:52:39 +053014482 if (ret)
14483 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014484
Abhishek Singh257a9482017-03-06 16:52:39 +053014485 ret = hdd_update_scan_config(hdd_ctx);
Frank Liud4b2fa02017-03-29 11:46:48 +080014486 if (ret)
14487 return ret;
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014488
Frank Liud4b2fa02017-03-29 11:46:48 +080014489 ret = hdd_update_tdls_config(hdd_ctx);
Venkata Sharath Chandra Manchala4aaae0f2017-07-10 11:59:19 -070014490 if (ret)
14491 return ret;
14492
14493 ret = hdd_update_dp_config(hdd_ctx);
bings81fe50a2017-11-27 14:33:26 +080014494 if (ret)
14495 return ret;
14496
14497 ret = hdd_update_dfs_config(hdd_ctx);
Mukul Sharma9d797a02017-01-05 20:26:03 +053014498
14499 return ret;
14500}
14501
Agrawal Ashish65634612016-08-18 13:24:32 +053014502/**
14503 * wlan_hdd_get_dfs_mode() - get ACS DFS mode
14504 * @mode : cfg80211 DFS mode
14505 *
14506 * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE
14507 */
14508enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode)
14509{
14510 switch (mode) {
14511 case DFS_MODE_ENABLE:
14512 return ACS_DFS_MODE_ENABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053014513 case DFS_MODE_DISABLE:
14514 return ACS_DFS_MODE_DISABLE;
Agrawal Ashish65634612016-08-18 13:24:32 +053014515 case DFS_MODE_DEPRIORITIZE:
14516 return ACS_DFS_MODE_DEPRIORITIZE;
Agrawal Ashish65634612016-08-18 13:24:32 +053014517 default:
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080014518 hdd_debug("ACS dfs mode is NONE");
14519 return ACS_DFS_MODE_NONE;
Agrawal Ashish65634612016-08-18 13:24:32 +053014520 }
14521}
14522
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014523/**
14524 * hdd_enable_disable_ca_event() - enable/disable channel avoidance event
14525 * @hddctx: pointer to hdd context
14526 * @set_value: enable/disable
14527 *
14528 * When Host sends vendor command enable, FW will send *ONE* CA ind to
14529 * Host(even though it is duplicate). When Host send vendor command
14530 * disable,FW doesn't perform any action. Whenever any change in
14531 * CA *and* WLAN is in SAP/P2P-GO mode, FW sends CA ind to host.
14532 *
14533 * return - 0 on success, appropriate error values on failure.
14534 */
Jeff Johnson16528362018-06-14 12:34:16 -070014535int hdd_enable_disable_ca_event(struct hdd_context *hdd_ctx, uint8_t set_value)
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014536{
14537 QDF_STATUS status;
14538
Jeff Johnson16528362018-06-14 12:34:16 -070014539 if (0 != wlan_hdd_validate_context(hdd_ctx))
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014540 return -EAGAIN;
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014541
Jeff Johnson16528362018-06-14 12:34:16 -070014542 status = sme_enable_disable_chanavoidind_event(hdd_ctx->mac_handle,
14543 set_value);
Selvaraj, Sridharebda0f22016-08-29 16:05:23 +053014544 if (!QDF_IS_STATUS_SUCCESS(status)) {
14545 hdd_err("Failed to send chan avoid command to SME");
14546 return -EINVAL;
14547 }
14548 return 0;
14549}
Agrawal Ashish65634612016-08-18 13:24:32 +053014550
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014551/**
14552 * hdd_set_roaming_in_progress() - to set the roaming in progress flag
14553 * @value: value to set
14554 *
14555 * This function will set the passed value to roaming in progress flag.
14556 *
14557 * Return: None
14558 */
14559void hdd_set_roaming_in_progress(bool value)
14560{
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014561 struct hdd_context *hdd_ctx;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014562
14563 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14564 if (!hdd_ctx) {
14565 hdd_err("HDD context is NULL");
14566 return;
14567 }
14568
14569 hdd_ctx->roaming_in_progress = value;
Srinivas Girigowda3d5250d2017-03-06 17:32:16 -080014570 hdd_debug("Roaming in Progress set to %d", value);
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014571}
14572
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053014573bool hdd_is_roaming_in_progress(struct hdd_context *hdd_ctx)
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014574{
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014575 if (!hdd_ctx) {
14576 hdd_err("HDD context is NULL");
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053014577 return false;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014578 }
Varun Reddy Yeturua5784142017-03-10 12:11:44 -080014579
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053014580 hdd_debug("roaming_in_progress = %d", hdd_ctx->roaming_in_progress);
14581
14582 return hdd_ctx->roaming_in_progress;
Varun Reddy Yeturudce1c562016-11-18 10:00:45 -080014583}
14584
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014585/**
14586 * hdd_is_connection_in_progress() - check if connection is in
14587 * progress
14588 * @session_id: session id
14589 * @reason: scan reject reason
14590 *
14591 * Go through each adapter and check if Connection is in progress
14592 *
14593 * Return: true if connection is in progress else false
14594 */
14595bool hdd_is_connection_in_progress(uint8_t *session_id,
14596 enum scan_reject_states *reason)
14597{
Jeff Johnson40dae4e2017-08-29 14:00:25 -070014598 struct hdd_station_ctx *hdd_sta_ctx = NULL;
Jeff Johnson9d295242017-08-29 14:39:48 -070014599 struct hdd_adapter *adapter = NULL;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014600 uint8_t sta_id = 0;
14601 uint8_t *sta_mac = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014602 struct hdd_context *hdd_ctx;
Jeff Johnson16528362018-06-14 12:34:16 -070014603 mac_handle_t mac_handle;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014604
14605 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14606 if (!hdd_ctx) {
14607 hdd_err("HDD context is NULL");
14608 return false;
14609 }
14610
Jeff Johnson16528362018-06-14 12:34:16 -070014611 mac_handle = hdd_ctx->mac_handle;
14612
Dustin Brown920397d2017-12-13 16:27:50 -080014613 hdd_for_each_adapter(hdd_ctx, adapter) {
Tushnim Bhattacharyya929afa42018-06-01 15:04:44 -070014614 hdd_debug("Adapter with device mode %s(%d) exists",
Dustin Brown458027c2018-10-19 12:26:27 -070014615 qdf_opmode_str(adapter->device_mode),
14616 adapter->device_mode);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014617 if (((QDF_STA_MODE == adapter->device_mode)
14618 || (QDF_P2P_CLIENT_MODE == adapter->device_mode)
14619 || (QDF_P2P_DEVICE_MODE == adapter->device_mode))
14620 && (eConnectionState_Connecting ==
14621 (WLAN_HDD_GET_STATION_CTX_PTR(adapter))->
14622 conn_info.connState)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014623 hdd_debug("%pK(%d) Connection is in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014624 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070014625 adapter->session_id);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014626 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070014627 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014628 *reason = CONNECTION_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014629 }
14630 return true;
14631 }
Archana Ramachandran62886ce2017-03-24 14:46:32 -070014632 /*
14633 * sme_neighbor_middle_of_roaming is for LFR2
14634 * hdd_is_roaming_in_progress is for LFR3
14635 */
14636 if (((QDF_STA_MODE == adapter->device_mode) &&
14637 sme_neighbor_middle_of_roaming(
Jeff Johnson16528362018-06-14 12:34:16 -070014638 mac_handle,
Jeff Johnson1b780e42017-10-31 14:11:45 -070014639 adapter->session_id)) ||
Padma, Santhosh Kumar86747ec2018-05-29 18:28:29 +053014640 hdd_is_roaming_in_progress(hdd_ctx)) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014641 hdd_debug("%pK(%d) Reassociation in progress",
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014642 WLAN_HDD_GET_STATION_CTX_PTR(adapter),
Jeff Johnson1b780e42017-10-31 14:11:45 -070014643 adapter->session_id);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014644 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070014645 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014646 *reason = REASSOC_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014647 }
14648 return true;
14649 }
14650 if ((QDF_STA_MODE == adapter->device_mode) ||
14651 (QDF_P2P_CLIENT_MODE == adapter->device_mode) ||
14652 (QDF_P2P_DEVICE_MODE == adapter->device_mode)) {
14653 hdd_sta_ctx =
14654 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
14655 if ((eConnectionState_Associated ==
Vignesh Viswanathan0a569292018-02-14 15:34:47 +053014656 hdd_sta_ctx->conn_info.connState)
14657 && sme_is_sta_key_exchange_in_progress(
Jeff Johnson16528362018-06-14 12:34:16 -070014658 mac_handle, adapter->session_id)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014659 sta_mac = (uint8_t *)
Jeff Johnson1e851a12017-10-28 14:36:12 -070014660 &(adapter->mac_addr.bytes[0]);
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014661 hdd_debug("client " MAC_ADDRESS_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014662 " is in middle of WPS/EAPOL exchange.",
14663 MAC_ADDR_ARRAY(sta_mac));
14664 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070014665 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014666 *reason = EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014667 }
14668 return true;
14669 }
14670 } else if ((QDF_SAP_MODE == adapter->device_mode) ||
14671 (QDF_P2P_GO_MODE == adapter->device_mode)) {
14672 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT;
14673 sta_id++) {
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070014674 if (!((adapter->sta_info[sta_id].in_use)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014675 && (OL_TXRX_PEER_STATE_CONN ==
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070014676 adapter->sta_info[sta_id].peer_state)))
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014677 continue;
14678
14679 sta_mac = (uint8_t *)
Jeff Johnsonbb8b56a2017-10-23 07:02:36 -070014680 &(adapter->sta_info[sta_id].
Jeff Johnsonf2356512017-10-21 16:04:12 -070014681 sta_mac.bytes[0]);
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014682 hdd_debug("client " MAC_ADDRESS_STR
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014683 " of SAP/GO is in middle of WPS/EAPOL exchange",
14684 MAC_ADDR_ARRAY(sta_mac));
14685 if (session_id && reason) {
Jeff Johnson1b780e42017-10-31 14:11:45 -070014686 *session_id = adapter->session_id;
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014687 *reason = SAP_EAPOL_IN_PROGRESS;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014688 }
14689 return true;
14690 }
14691 if (hdd_ctx->connection_in_progress) {
Vignesh Viswanathan82bd2532017-09-20 11:17:12 +053014692 hdd_debug("AP/GO: connection is in progress");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014693 return true;
14694 }
14695 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014696 }
Dustin Brown920397d2017-12-13 16:27:50 -080014697
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014698 return false;
14699}
14700
14701/**
14702 * hdd_restart_sap() - to restart SAP in driver internally
Jeff Johnson9d295242017-08-29 14:39:48 -070014703 * @ap_adapter: Pointer to SAP struct hdd_adapter structure
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014704 *
14705 * Return: None
14706 */
Jeff Johnson9d295242017-08-29 14:39:48 -070014707void hdd_restart_sap(struct hdd_adapter *ap_adapter)
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014708{
Jeff Johnson87251032017-08-29 13:31:11 -070014709 struct hdd_ap_ctx *hdd_ap_ctx;
Jeff Johnsonca2530c2017-09-30 18:25:40 -070014710 struct hdd_hostapd_state *hostapd_state;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014711 QDF_STATUS qdf_status;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014712 struct hdd_context *hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
Jeff Johnsone4c11db2018-05-05 23:22:32 -070014713 tsap_config_t *sap_config;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014714 void *sap_ctx;
14715
14716 hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
Jeff Johnson91df29d2017-10-27 19:29:50 -070014717 sap_config = &hdd_ap_ctx->sap_config;
Jeff Johnson0bbe66f2017-10-27 19:23:49 -070014718 sap_ctx = hdd_ap_ctx->sap_context;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014719
14720 mutex_lock(&hdd_ctx->sap_lock);
14721 if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags)) {
14722 wlan_hdd_del_station(ap_adapter);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014723 hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
14724 qdf_event_reset(&hostapd_state->qdf_stop_bss_event);
14725 if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) {
14726 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053014727 qdf_wait_for_event_completion(&hostapd_state->
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014728 qdf_stop_bss_event,
Vignesh Viswanathan865daaa2018-10-11 19:30:44 +053014729 SME_CMD_START_STOP_BSS_TIMEOUT);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014730
14731 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014732 hdd_err("SAP Stop Failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014733 goto end;
14734 }
14735 }
14736 clear_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Dustin Brown1dbefe62018-09-11 16:32:03 -070014737 policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
Jeff Johnson1b780e42017-10-31 14:11:45 -070014738 ap_adapter->device_mode, ap_adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070014739 hdd_green_ap_start_state_mc(hdd_ctx, ap_adapter->device_mode,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053014740 false);
Jeff Johnson6867ec32017-09-29 20:30:20 -070014741 hdd_err("SAP Stop Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014742
14743 if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014744 hdd_err("SAP Not able to set AP IEs");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014745 wlansap_reset_sap_config_add_ie(sap_config,
14746 eUPDATE_IE_ALL);
14747 goto end;
14748 }
14749
14750 qdf_event_reset(&hostapd_state->qdf_event);
14751 if (wlansap_start_bss(sap_ctx, hdd_hostapd_sap_event_cb,
14752 sap_config,
14753 ap_adapter->dev) != QDF_STATUS_SUCCESS) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014754 hdd_err("SAP Start Bss fail");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014755 wlansap_reset_sap_config_add_ie(sap_config,
14756 eUPDATE_IE_ALL);
14757 goto end;
14758 }
14759
Jeff Johnson6867ec32017-09-29 20:30:20 -070014760 hdd_info("Waiting for SAP to start");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014761 qdf_status =
Nachiket Kukade0396b732017-11-14 16:35:16 +053014762 qdf_wait_for_event_completion(&hostapd_state->qdf_event,
Vignesh Viswanathan865daaa2018-10-11 19:30:44 +053014763 SME_CMD_START_STOP_BSS_TIMEOUT);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014764 wlansap_reset_sap_config_add_ie(sap_config,
14765 eUPDATE_IE_ALL);
14766 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014767 hdd_err("SAP Start failed");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014768 goto end;
14769 }
Jeff Johnson6867ec32017-09-29 20:30:20 -070014770 hdd_err("SAP Start Success");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014771 set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053014772 if (hostapd_state->bss_state == BSS_START) {
Dustin Brown1dbefe62018-09-11 16:32:03 -070014773 policy_mgr_incr_active_session(hdd_ctx->psoc,
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014774 ap_adapter->device_mode,
Jeff Johnson1b780e42017-10-31 14:11:45 -070014775 ap_adapter->session_id);
Jeff Johnsone8846ab2018-03-31 11:54:45 -070014776 hdd_green_ap_start_state_mc(hdd_ctx,
Himanshu Agarwal813b2bf2018-01-22 16:32:15 +053014777 ap_adapter->device_mode,
14778 true);
14779 }
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014780 }
14781end:
14782 mutex_unlock(&hdd_ctx->sap_lock);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014783}
14784
14785/**
14786 * hdd_check_and_restart_sap_with_non_dfs_acs() - Restart SAP
14787 * with non dfs acs
14788 *
14789 * Restarts SAP in non-DFS ACS mode when STA-AP mode DFS is not supported
14790 *
14791 * Return: None
14792 */
14793void hdd_check_and_restart_sap_with_non_dfs_acs(void)
14794{
Jeff Johnson9d295242017-08-29 14:39:48 -070014795 struct hdd_adapter *ap_adapter;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014796 struct hdd_context *hdd_ctx;
Jeff Johnson2b6982c2018-05-29 14:56:11 -070014797 struct cds_context *cds_ctx;
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053014798 uint8_t restart_chan;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014799
14800 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14801 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014802 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014803 return;
14804 }
14805
14806 cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
14807 if (!cds_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014808 hdd_err("Invalid CDS Context");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014809 return;
14810 }
14811
Dustin Brown1dbefe62018-09-11 16:32:03 -070014812 if (policy_mgr_get_concurrency_mode(hdd_ctx->psoc)
Tushnim Bhattacharyyade1070d2017-03-09 13:23:55 -080014813 != (QDF_STA_MASK | QDF_SAP_MASK)) {
Dustin Brown7e761c72018-07-31 13:50:17 -070014814 hdd_debug("Concurrency mode is not SAP");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014815 return;
14816 }
14817
14818 ap_adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
Dustin Brown07901ec2018-09-07 11:02:41 -070014819 if (ap_adapter &&
14820 test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags) &&
14821 wlan_reg_is_dfs_ch(hdd_ctx->pdev,
14822 ap_adapter->session.ap.operating_channel)) {
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014823
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053014824 hdd_warn("STA-AP Mode DFS not supported, Switch SAP channel to Non DFS");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014825
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053014826 restart_chan =
14827 hdd_get_safe_channel_from_pcl_and_acs_range(ap_adapter);
14828 if (!restart_chan ||
Dustin Brown07901ec2018-09-07 11:02:41 -070014829 wlan_reg_is_dfs_ch(hdd_ctx->pdev, restart_chan))
Rajeev Kumar Sirasanagandla4133d862018-08-23 12:21:36 +053014830 restart_chan = SAP_DEFAULT_5GHZ_CHANNEL;
14831
14832 hdd_switch_sap_channel(ap_adapter, restart_chan, true);
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014833 }
14834}
14835
14836/**
14837 * hdd_set_connection_in_progress() - to set the connection in
14838 * progress flag
14839 * @value: value to set
14840 *
14841 * This function will set the passed value to connection in progress flag.
14842 * If value is previously being set to true then no need to set it again.
14843 *
14844 * Return: true if value is being set correctly and false otherwise.
14845 */
14846bool hdd_set_connection_in_progress(bool value)
14847{
14848 bool status = true;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014849 struct hdd_context *hdd_ctx;
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014850
14851 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
14852 if (!hdd_ctx) {
Jeff Johnson6867ec32017-09-29 20:30:20 -070014853 hdd_err("HDD context is NULL");
Tushnim Bhattacharyya9e81b4c2017-02-15 17:11:14 -080014854 return false;
14855 }
14856
14857 qdf_spin_lock(&hdd_ctx->connection_status_lock);
14858 /*
14859 * if the value is set to true previously and if someone is
14860 * trying to make it true again then it could be some race
14861 * condition being triggered. Avoid this situation by returning
14862 * false
14863 */
14864 if (hdd_ctx->connection_in_progress && value)
14865 status = false;
14866 else
14867 hdd_ctx->connection_in_progress = value;
14868 qdf_spin_unlock(&hdd_ctx->connection_status_lock);
14869 return status;
14870}
14871
Jeff Johnson9d295242017-08-29 14:39:48 -070014872int wlan_hdd_send_p2p_quota(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070014873{
14874 if (!adapter) {
14875 hdd_err("Invalid adapter");
14876 return -EINVAL;
14877 }
14878 hdd_info("Send MCC P2P QUOTA to WMA: %d", set_value);
Jeff Johnson1b780e42017-10-31 14:11:45 -070014879 sme_cli_set_command(adapter->session_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070014880 WMA_VDEV_MCC_SET_TIME_QUOTA,
14881 set_value, VDEV_CMD);
14882 return 0;
14883
14884}
14885
Jeff Johnson9d295242017-08-29 14:39:48 -070014886int wlan_hdd_send_mcc_latency(struct hdd_adapter *adapter, int set_value)
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070014887{
14888 if (!adapter) {
14889 hdd_err("Invalid adapter");
14890 return -EINVAL;
14891 }
14892
14893 hdd_info("Send MCC latency WMA: %d", set_value);
Jeff Johnson1b780e42017-10-31 14:11:45 -070014894 sme_cli_set_command(adapter->session_id,
Archana Ramachandranb8c04f92017-03-17 20:05:47 -070014895 WMA_VDEV_MCC_SET_TIME_LATENCY,
14896 set_value, VDEV_CMD);
14897 return 0;
14898}
14899
Jeff Johnson9d295242017-08-29 14:39:48 -070014900struct hdd_adapter *wlan_hdd_get_adapter_from_vdev(struct wlan_objmgr_psoc
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070014901 *psoc, uint8_t vdev_id)
14902{
Jeff Johnson9d295242017-08-29 14:39:48 -070014903 struct hdd_adapter *adapter = NULL;
Jeff Johnsond49c4a12017-08-28 12:08:05 -070014904 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Archana Ramachandranea34c4f2017-03-19 18:56:18 -070014905
14906 /*
14907 * Currently PSOC is not being used. But this logic will
14908 * change once we have the converged implementation of
14909 * HDD context per PSOC in place. This would break if
14910 * multiple vdev objects reuse the vdev id.
14911 */
14912 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
14913 if (!adapter)
14914 hdd_err("Get adapter by vdev id failed");
14915
14916 return adapter;
14917}
14918
Jeff Johnson9d295242017-08-29 14:39:48 -070014919int hdd_get_rssi_snr_by_bssid(struct hdd_adapter *adapter, const uint8_t *bssid,
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053014920 int8_t *rssi, int8_t *snr)
14921{
14922 QDF_STATUS status;
Jeff Johnson16528362018-06-14 12:34:16 -070014923 mac_handle_t mac_handle;
Jeff Johnson025618c2018-03-18 14:41:00 -070014924 struct csr_roam_profile *roam_profile;
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053014925
Jeff Johnson025618c2018-03-18 14:41:00 -070014926 roam_profile = hdd_roam_profile(adapter);
Jeff Johnson16528362018-06-14 12:34:16 -070014927 mac_handle = hdd_adapter_get_mac_handle(adapter);
14928 status = sme_get_rssi_snr_by_bssid(mac_handle,
Jeff Johnson025618c2018-03-18 14:41:00 -070014929 roam_profile, bssid, rssi, snr);
Hanumanth Reddy Pothula90051782017-05-04 22:14:43 +053014930 if (QDF_STATUS_SUCCESS != status) {
14931 hdd_warn("sme_get_rssi_snr_by_bssid failed");
14932 return -EINVAL;
14933 }
14934
14935 return 0;
14936}
14937
Ganesh Kondabattini35739572017-06-21 16:26:39 +053014938/**
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014939 * hdd_reset_limit_off_chan() - reset limit off-channel command parameters
14940 * @adapter - HDD adapter
14941 *
14942 * Return: 0 on success and non zero value on failure
14943 */
14944int hdd_reset_limit_off_chan(struct hdd_adapter *adapter)
14945{
14946 struct hdd_context *hdd_ctx;
14947 int ret;
14948 QDF_STATUS status;
Krunal Sonie71838d2018-09-27 10:45:05 -070014949 uint8_t sys_pref = 0;
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014950
14951 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
14952 ret = wlan_hdd_validate_context(hdd_ctx);
14953 if (ret < 0)
14954 return ret;
14955
Krunal Sonie71838d2018-09-27 10:45:05 -070014956 ucfg_policy_mgr_get_sys_pref(hdd_ctx->psoc,
14957 &sys_pref);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014958 /* set the system preferece to default */
Krunal Sonie71838d2018-09-27 10:45:05 -070014959 policy_mgr_set_cur_conc_system_pref(hdd_ctx->psoc, sys_pref);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014960
14961 /* clear the bitmap */
14962 adapter->active_ac = 0;
14963
14964 hdd_debug("reset ac_bitmap for session %hu active_ac %0x",
Jeff Johnson16528362018-06-14 12:34:16 -070014965 adapter->session_id, adapter->active_ac);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014966
Jeff Johnson16528362018-06-14 12:34:16 -070014967 status = sme_send_limit_off_channel_params(hdd_ctx->mac_handle,
14968 adapter->session_id,
14969 false, 0, 0, false);
Ganesh Kondabattini479a8ae2017-10-03 16:49:24 +053014970 if (!QDF_IS_STATUS_SUCCESS(status)) {
14971 hdd_err("failed to reset limit off chan params");
14972 ret = -EINVAL;
14973 }
Ganesh Kondabattini35739572017-06-21 16:26:39 +053014974
14975 return ret;
14976}
14977
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014978/**
14979 * hdd_start_driver_ops_timer() - Starts driver ops inactivity timer
14980 * @drv_op: Enum indicating driver op
14981 *
14982 * Return: none
14983 */
14984void hdd_start_driver_ops_timer(int drv_op)
14985{
14986 memset(drv_ops_string, 0, MAX_OPS_NAME_STRING_SIZE);
14987 switch (drv_op) {
Jeff Johnson5794d4f2018-12-04 11:57:09 -080014988 case HDD_DRV_OP_PROBE:
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014989 memcpy(drv_ops_string, "probe", sizeof("probe"));
14990 break;
Jeff Johnson5794d4f2018-12-04 11:57:09 -080014991 case HDD_DRV_OP_REMOVE:
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014992 memcpy(drv_ops_string, "remove", sizeof("remove"));
14993 break;
Jeff Johnson5794d4f2018-12-04 11:57:09 -080014994 case HDD_DRV_OP_SHUTDOWN:
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014995 memcpy(drv_ops_string, "shutdown", sizeof("shutdown"));
14996 break;
Jeff Johnson5794d4f2018-12-04 11:57:09 -080014997 case HDD_DRV_OP_REINIT:
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053014998 memcpy(drv_ops_string, "reinit", sizeof("reinit"));
14999 break;
Jeff Johnson5794d4f2018-12-04 11:57:09 -080015000 case HDD_DRV_OP_IFF_UP:
Arunk Khandavallie9ef42a2017-10-04 14:49:51 +053015001 memcpy(drv_ops_string, "iff_up", sizeof("iff_up"));
15002 break;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053015003 }
15004
Dustin Brown45ed4bb2017-12-18 12:00:13 -080015005 hdd_drv_ops_task = current;
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053015006 qdf_timer_start(&hdd_drv_ops_inactivity_timer,
Dustin Browncfc54fe2018-06-18 16:17:41 -070015007 HDD_OPS_INACTIVITY_TIMEOUT * qdf_timer_get_multiplier());
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053015008}
15009
15010/**
15011 * hdd_stop_driver_ops_timer() - Stops driver ops inactivity timer
15012 *
15013 * Return: none
15014 */
15015void hdd_stop_driver_ops_timer(void)
15016{
15017 qdf_timer_sync_cancel(&hdd_drv_ops_inactivity_timer);
15018}
15019
15020/**
15021 * hdd_drv_ops_inactivity_handler() - Timeout handler for driver ops
15022 * inactivity timer
15023 *
15024 * Return: None
15025 */
15026void hdd_drv_ops_inactivity_handler(void)
15027{
Rajeev Kumar4471f1b2018-06-08 14:18:28 -070015028 hdd_err("WLAN_BUG_RCA %s: %d Sec timer expired while in .%s",
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053015029 __func__, HDD_OPS_INACTIVITY_TIMEOUT/1000, drv_ops_string);
15030
Dustin Brown45ed4bb2017-12-18 12:00:13 -080015031 if (hdd_drv_ops_task) {
15032 printk("Call stack for \"%s\"\n", hdd_drv_ops_task->comm);
15033 qdf_print_thread_trace(hdd_drv_ops_task);
15034 } else {
15035 hdd_err("hdd_drv_ops_task is null");
15036 }
15037
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053015038 /* Driver shutdown is stuck, no recovery possible at this point */
15039 if (0 == qdf_mem_cmp(&drv_ops_string[0], "shutdown",
15040 sizeof("shutdown")))
15041 QDF_BUG(0);
15042
Rajeev Kumar1e57b9c2018-01-04 16:17:10 -080015043 if (cds_is_fw_down()) {
15044 hdd_err("FW is down");
15045 return;
15046 }
15047
Dustin Brown83044c22018-08-13 15:00:44 -070015048 cds_trigger_recovery(QDF_REASON_UNSPECIFIED);
Nachiket Kukadebe8850b2017-09-18 15:37:00 +053015049}
15050
Yun Parkff6a16a2017-09-26 16:38:18 -070015051/**
15052 * hdd_set_rx_mode_rps() - Enable/disable RPS in SAP mode
15053 * @struct hdd_context *hdd_ctx
15054 * @struct hdd_adapter *padapter
15055 * @bool enble
15056 *
15057 * Return: none
15058 */
15059void hdd_set_rx_mode_rps(bool enable)
15060{
15061 struct cds_config_info *cds_cfg = cds_get_ini_config();
Ryan Hsu0e878fa2018-05-04 15:22:09 -070015062 struct hdd_context *hdd_ctx;
15063 struct hdd_adapter *adapter;
Yun Parkff6a16a2017-09-26 16:38:18 -070015064
Ryan Hsu0e878fa2018-05-04 15:22:09 -070015065 if (!cds_cfg)
15066 return;
15067
15068 hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
15069 if (!hdd_ctx)
15070 return;
15071
15072 adapter = hdd_get_adapter(hdd_ctx, QDF_SAP_MODE);
15073 if (!adapter)
15074 return;
15075
15076 if (!hdd_ctx->rps && cds_cfg->uc_offload_enabled) {
Yun Parkff6a16a2017-09-26 16:38:18 -070015077 if (enable && !cds_cfg->rps_enabled)
15078 hdd_send_rps_ind(adapter);
15079 else if (!enable && cds_cfg->rps_enabled)
15080 hdd_send_rps_disable_ind(adapter);
15081 }
15082}
15083
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015084/* Register the module init/exit functions */
15085module_init(hdd_module_init);
15086module_exit(hdd_module_exit);
15087
15088MODULE_LICENSE("Dual BSD/GPL");
15089MODULE_AUTHOR("Qualcomm Atheros, Inc.");
15090MODULE_DESCRIPTION("WLAN HOST DEVICE DRIVER");
15091
Srinivas Girigowda841da292018-02-21 16:33:00 -080015092static const struct kernel_param_ops con_mode_ops = {
15093 .set = con_mode_handler,
15094 .get = param_get_int,
15095};
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015096
Srinivas Girigowda841da292018-02-21 16:33:00 -080015097static const struct kernel_param_ops con_mode_ftm_ops = {
15098 .set = con_mode_handler_ftm,
15099 .get = param_get_int,
15100};
Arunk Khandavalliba3d5582017-07-11 19:48:32 +053015101
Nirav Shah73713f72018-05-17 14:50:41 +053015102#ifdef FEATURE_MONITOR_MODE_SUPPORT
Srinivas Girigowda841da292018-02-21 16:33:00 -080015103static const struct kernel_param_ops con_mode_monitor_ops = {
15104 .set = con_mode_handler_monitor,
15105 .get = param_get_int,
15106};
Nirav Shah73713f72018-05-17 14:50:41 +053015107#endif
Ravi Joshia307f632017-07-17 23:41:41 -070015108
Srinivas Girigowda841da292018-02-21 16:33:00 -080015109static const struct kernel_param_ops fwpath_ops = {
15110 .set = fwpath_changed_handler,
15111 .get = param_get_string,
15112};
15113
15114module_param_cb(con_mode, &con_mode_ops, &con_mode,
15115 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
15116
15117module_param_cb(con_mode_ftm, &con_mode_ftm_ops, &con_mode_ftm,
15118 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
15119
Nirav Shah73713f72018-05-17 14:50:41 +053015120#ifdef FEATURE_MONITOR_MODE_SUPPORT
Srinivas Girigowda841da292018-02-21 16:33:00 -080015121module_param_cb(con_mode_monitor, &con_mode_monitor_ops, &con_mode_monitor,
15122 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Nirav Shah73713f72018-05-17 14:50:41 +053015123#endif
Srinivas Girigowda841da292018-02-21 16:33:00 -080015124
15125module_param_cb(fwpath, &fwpath_ops, &fwpath,
15126 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080015127
15128module_param(enable_dfs_chan_scan, int, S_IRUSR | S_IRGRP | S_IROTH);
15129
15130module_param(enable_11d, int, S_IRUSR | S_IRGRP | S_IROTH);
15131
15132module_param(country_code, charp, S_IRUSR | S_IRGRP | S_IROTH);